howto/come_gestire_comunicazione_rs485/gestione_rs485_con_schede_syel.md
... ...
@@ -1,270 +0,0 @@
1
-# Come gestire la comunicazione RS485 con schede SYEL
2
-
3
-Se la periferica è SYEL, si può utilizzare come protocollo seriale il SYEL BLOCK MODE 1.
4
-
5
-Di seguito, un **esempio** sulla gestione della comunicazione RS485 in SYEL BLOCK MODE 1 in cui la centrale invia informazioni sulle operazioni che la periferica deve fare e la periferica risponde in base al pacchetto ricevuto.
6
-
7
-In questo programma specifico la centrale comunica alla periferica:
8
-- quali uscite (1 - 10) attivare/disattivare
9
-- se attivare il pwm sull'uscita 1 (e quanto impostare la frequenza e duty cycle)
10
-- quanto potente (veloce) deve essere l'uscita chiamata pomp (gestita da uno slider grafico)
11
-- richiedere il valore degli ingressi In e Potenz
12
-
13
-Nel **common.h** (o comunque in un file .h incluso nel common):
14
-
15
- // Nel seguente esempio sono state omesse alcune definizioni e fuzioni (presenti nel progetto originale) che non erano
16
- // necessarie al fine di spiegare la gestione RS485
17
-
18
- #define PortaCOM COM2 // definisce PortaCOM (in questo caso è la COM2)
19
- #define BAUD_RATE 115200 // deifnisce il baud rate della porta COM (in questo caso 115200)
20
-
21
- // definizione comandi ralativi alla periferica del progetto
22
- /***************************************
23
- ;Comando per settate singolo out
24
- ;0-0-0-3-1-3-'K'(H4B)-dato1=N°CH-dato2=freq.-dato3=pwm. Pwm =0-7 freq= 7sempre on, 6 512mSec, 5 256mSec, 4 128 mSec ecc
25
- ***************************************/
26
- #define OUT_ON_OFF 0x4B
27
-
28
- /***************************************
29
- ;Comando per settare velocità pompa
30
- ;0-0-0-3-1-2-'p'(H70)-valore%
31
- ***************************************/
32
- #define POMP_VEL 0x70
33
-
34
- /***************************************
35
- ;Comando per leggere digitale+analogico
36
- ;0-0-0-3-1-1-'i' Risposta 1dato digitale+2dato analogico
37
- ***************************************/
38
- #define READ_IN 0x69
39
-
40
-
41
- //---------------------funzioni----------------------
42
- void init_serial_Rs485(void); // funzione per inizializzare la seriale
43
- void init_out(void); // funzione per inizializzare lo stato iniziale delle uscite
44
- void TaskCOM485(void); // funzione principale per la comunicazione seriale 485
45
- void tx485(void); // funzione per flag del tx della seriale
46
- void subrx(void); // subroutine per la lettura dei messaggi ricevuti
47
- void update_bufferTX_out(int); // funzione che aggiorna il buffer con i dati da inviare (bufferTX) relativi alle uscite
48
- void update_bufferTX_pomp(void); // funzione che aggiorna il buffer con i dati da inviare relativi al settaggio dell' uscita pomp
49
- void clear_bufferRX(void); // funzione che svuota il buffer in cui vengono salvati i dati arrivati (bufferRX)
50
-
51
- //--------------------costanti e variabili--------------------
52
- const int num_centr = 128; // numero della centrale (in questo caso 128)
53
- const int num_perif = 1; // numero della periferica (in questo caso 1)
54
- const int dim_bufferTX = 129; // dimensioni massime del buffer con i dati da inviare (bufferTX)
55
- const int dim_bufferRX = 16; // dimensioni massime del buffer in cui vengono salvati i dati ricevuti (bufferRX)
56
- const int num_out = 10; // numero totale di uscite digitali
57
-
58
- volatile char bufferTX[dim_bufferTX]; // dichiara il buffer in cui prendere i dati da inviare
59
- volatile char bufferRX[dim_bufferRX]; // dichiara il buffer in cui salvare i dati ricevuti
60
-
61
- volatile int flag_tx485 = 0; // flag relativa al tx della seriale
62
-
63
- volatile int flag_out_on_off[num_out]; // flag realtive allo stato delle uscite
64
- volatile int flag_out_on_off_prec[num_out]; // flag previste realtive allo stato delle uscite
65
- // (utili per capire quando ha cambiato stato)
66
-
67
- volatile int flag_pomp_on_off; // flag realtive allo stato dell' uscita pomp
68
- volatile int flag_pomp_on_off_prec; // flag previste realtive allo stato dell' uscita pomp
69
-
70
- volatile int flag_pwm_on_off; // flag realtive all' attivazione/disattivazione del pwm sulla prima uscita
71
- volatile int flag_pwm_on_off_prec; // flag previste realtive all' attivazione/disattivazione del pwm sulla prima uscita
72
-
73
- volatile short int TXX = 0; // variabile per il conteggio dei pacchetti inviati
74
- volatile short int RXX = 0; // variabile per il conteggio dei pacchetti ricevuti
75
-
76
- volatile int controllo_comando_uscite = 0; // variabile per il controllo della corretta ricezione della periferica
77
- // 0 = fail, 1 = ok (uscite digitali)
78
-
79
- volatile int controllo_comando_pomp = 0; // variabile per il controllo della corrretta ricezione della periferica
80
- // 0 = fail, 1 = ok (uscita pomp)
81
-
82
- volatile int controllo_lettura_ingressi = 0; // variabile per il controllo della corretta ricezione della periferica
83
- // 0 = fail, 1 = ok (ingressi In e Potenz)
84
- volatile U8 In; // prima variabile per lettura ingressi
85
- volatile U8 Potenz; // seconda variabile per lettura ingressi
86
- volatile char freq = 0; // variabile relativa alla frequanza del pwm
87
- volatile char pwm = 0; // variabile relativa al duty cycle del pwm
88
- volatile int p; // variabile ralativa al valore % della velocità dell'uscita pomp
89
-
90
- //-------------------------------------------
91
- // funzione di inizializzazione seriale RS485
92
- void init_serial_Rs485(void)
93
- {
94
- com_open(PortaCOM, BAUD_RATE); // apre la porta specificando il baud rate
95
- com_disable(PortaCOM); // disabilita la porta
96
- protocol_mode(PortaCOM, 1); // imposta il protocollo della seriale su 1 (SYEL BLOCK MODE 1)
97
- PortaCOM->centr = num_centr; // imposta il numero della centrale
98
- PortaCOM->perif = num_perif; // imposta il numero della periferica
99
- onrx(PortaCOM, subrx); // funzione che richiama la subroutine subrx quando ci sono dei dati ricevuti
100
- com_enable(PortaCOM); // riabilita la porta
101
- }
102
-
103
- // subroutine che viene chiamata da onrx quando è arrivato un pacchetto dati
104
- void subrx(void)
105
- {
106
- int n = bload(PortaCOM, bufferRX, 8); // la funzione bload salva il messaggio arrivato, sul bufferRX
107
- if (n != -1) // se bload restituisce un valore diverso da -1 ha letto correttemente il messaggio
108
- {
109
- if (bufferRX[0] == (char)OUT_ON_OFF) // se la periferica ha risposto con il primo byte OUT_ON_OFF
110
- controllo_comando_uscita = 1; // lo scambio dati ha avutp successo, la variabile di controllo viene messa a 1
111
-
112
- else if (bufferRX[0] == (char)POMP_VEL) // se la periferica ha risposto con il primo byte POMP_VEL
113
- controllo_comando_pomp = 1; // lo scambio dati ha avuto successso, la variabile di controllo viene messa a 1
114
-
115
- else
116
- {
117
- controllo_lettura_ingressi = 1; // la lettura degli ingressi ha avuto successo, la variabile di controllo viene messa a 1
118
- In = bufferRX[0]; // il valore della variabile In diventa il valore del primo byte del pacchetto
119
- Potenz = bufferRX[1]; // il valore della variabile Potenz diventa il valore del secondo byte del pacchetto
120
- }
121
- RXX++; // incremento del contatore dei pacchetti ricevuti
122
- }
123
- clear_bufferRX(); // svuotamento del bufferRX
124
- }
125
-
126
- // funzione che inizializza lo stato iniziale delle uscite all' avvio
127
- void init_out(void)
128
- {
129
- // inizializzazione uscite digitali
130
- for (int i = 0; i < num_out; i++)
131
- {
132
- flag_out_on_off[i] = 0; // le flag delle uscite vengono messe tutte a 0 perchè all'avvio sono tutte spente
133
- flag_out_on_off_prec[i] = 0;
134
- update_bufferTX_out(i); // agiorna il bufferTX per ogni uscita
135
- bsave(PortaCOM, bufferTX, 4); // il comando bsave invia i dati contenuti nel bufferTX (comunicando che ogni uscita è spenta)
136
- wait(10); // aspetta 10 ms per dar tempo di eseguire lo scambio dati
137
- TXX++; // incremento del contatore dei pacchetti inviati
138
- }
139
- flag_pwm_on_off = 0; // la flag del pwm viene messsa a 0 perchè all' avvio il pwm è disattivo
140
- flag_pwm_on_off_prec = 0;
141
-
142
- // inizializzazione dell'uscita pomp
143
- flag_pomp_on_off = 0; // la flag dell' uscita pomp è 0 perchè all' avvio è spenta
144
- flag_pomp_on_off_prec = 0;
145
- update_bufferTX_pomp(); // aggiorna il bufferTX con i dati relativi all' uscita pomp (comunicando che è spenta)
146
- bsave(PortaCOM, bufferTX, 2); // invia i dati del bufferTX
147
- wait(10);
148
- TXX++;
149
- }
150
-
151
- // funzione principale per la gestione della comunicazione RS485 che verrà richiamata nello start.c
152
- void TaskCOM485(void)
153
- {
154
- while(1)
155
- {
156
- if (flag_tx485)
157
- {
158
- flag_tx485 = 0; // ogni 100 ms (vedi start.c)
159
-
160
- // controlllo uscite digitali
161
- for (int i = 0; i < num_out; i++)
162
- if (flag_out_on_off[i] != flag_out_on_off_prec[i]) // se un' uscita ha cambiato stato
163
- {
164
- flag_out_on_off_prec[i] = flag_out_on_off[i];
165
- update_bufferTX_out(i); // aggiorna il bufferTX
166
- TXX++;
167
- bsave(PortaCOM, bufferTX, 4); // invia il bufferTX
168
- // (comunicando attivazione/disattivazione dell'uscita i)
169
- wait(10);
170
- }
171
-
172
- // controllo uscita pomp
173
- if (flag_pomp_on_off != flag_pomp_on_off_prec) // se ha cambiato stato
174
- {
175
- flag_pomp_on_off_prec = flag_pomp_on_off;
176
- update_bufferTX_pomp(); // aggiorna il bufferTX con i dati sul valore di pomp
177
- TXX++;
178
- bsave(PortaCOM, bufferTX, 2); // invia il bufferTX
179
- wait(10);
180
- }
181
- if (flag_pomp_on_off) // se comunque pomp è accesa
182
- {
183
- update_bufferTX_pomp(); // aggiorna il bufferTX con il valore di pomp
184
- TXX++;
185
- bsave(PortaCOM, bufferTX, 2); // invia il bufferTX
186
- wait(10);
187
- }
188
-
189
- // controllo pwm sull' uscita 1
190
- if (flag_pwm_on_off != flag_pwm_on_off_prec) // se ha cambiato stato
191
- {
192
- flag_pwm_on_off_prec = flag_pwm_on_off;
193
- update_bufferTX_out(0); // aggiorna il bufferTX con l' uscita 1 (0)
194
- TXX++;
195
- bsave(PortaCOM, bufferTX, 4); // invia il bufferTX
196
- wait(10);
197
- }
198
-
199
- // lettura ingressi
200
- bufferTX[0] = READ_IN; // il primo byte del bufferTX viene impostato col comando READ_IN per comunicare che la
201
- // centrale vuole ricevere come risposta il valore di In e Potenz
202
- TXX++;
203
- bsave(PortaCOM, bufferTX, 1); // invia il bufferTX
204
- wait(10);
205
- }
206
- }
207
- }
208
-
209
- // ogni 100 ms imposta la flag del tx della seriale a 1 (vedi start.c)
210
- void tx485(void)
211
- {
212
- flag_tx485 = 1;
213
- }
214
-
215
- // funzione che aggiorna il bufferTX con i dati relativi allo stato delle uscite
216
- // il parametro in ingresso è il numero dell'uscita che ha cambiato stato
217
- void update_bufferTX_out(int x)
218
- {
219
- bufferTX[0] = OUT_ON_OFF; // imposta il primo byte del bufferTX con il comando OUT_ON_OFF
220
- bufferTX[1] = x; // imposta il secondo byte del bufferTX con il numero dell'uscita
221
- if (flag_out_on_off[x] == 0) // se l' uscita ha cambiato stato spengendosi
222
- { // il terzo e quarto byte del bufferTX vengono impostati a 0 (off)
223
- bufferTX[2] = 0;
224
- bufferTX[3] = 0;
225
- }
226
- else // se ha cambiato stato accendendosi
227
- {
228
- if (x == 0 && flag_pwm_on_off) // se l' uscita è la 1 (x == 0) e se il pwm è attivo
229
- { // il terzo e quarto byte del bufferTX vengono impostati con freq e pwm
230
- bufferTX[2] = freq; // freq e pwm possono essere modificati tramite dei pulsanti grafici su una pagina
231
- bufferTX[3] = pwm;
232
- }
233
- else // se l' uscita non è la 1 o se il pwm è disattivo
234
- { // il terzo e quarto byte del bufferTX vengono impostati a 7 (on)
235
- bufferTX[2] = 7;
236
- bufferTX[3] = 7;
237
- }
238
- }
239
- }
240
-
241
- // funzione che aggiorna il bufferTX con il dati per settare l' uscita pomp;
242
- void update_bufferTX_pomp(void)
243
- {
244
- bufferTX[0] = POMP_VEL; // imposta il primo byte del bufferTX con il comando POMP_VEL
245
- if (flag_pomp_on_off) // se la pomp cambia stato accendendosi
246
- bufferTX[1] = p; // imposta il secondo byte del bufferTX con il valore della variabile relativa alla velocità di pomp
247
- // p dipende dal vaolore dello slider sl1 che si trova su una pagina grafica del progetto
248
- // p = sl1->val;
249
- else // se la pomp cambia stato spengendosi
250
- bufferTX[1] = 0; // imposta il secondo byte del bufferTX con il valore 0 (off)
251
- // p dipende dal vaolore dello slider sl1 che si trova su una pagina grafica del progetto
252
- // p = sl1->val;
253
- }
254
-
255
- // funzione che svuota il bufferRX
256
- void clear_bufferRX(void)
257
- {
258
- for (int i = 0; i < dim_bufferRX; i++) // tutti i valori del bufferRX vengono messi a 0
259
- bufferRX[i] = 0;
260
- }
261
-
262
-Nello **start.c**:
263
-
264
- init_serial_RS485(); // inizializza la seriale RS485
265
- init_out(); // inizializza le uscite
266
-
267
- exec_timer(tx485, 100, 0); // esegue ogni 100 ms tx485
268
- exec_task(TaskCOM485, 0, 4); // esegue la TaskCOM485
269
-
270
-