8c3388ead5dd0ec2e7ae4846b0cf02881f29e42e
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 | - |