La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Comunicare con Arduino

Presentazioni simili


Presentazione sul tema: "Comunicare con Arduino"— Transcript della presentazione:

1 Comunicare con Arduino
Tx-Rx Bluetooth RS485

2 Introduzione La nascita dei microcontrollori è dovuta alla necessità di controllare diverse grandezze fisiche in tempo reale La società attuale va così di corsa che l’uomo da solo non riesce a far fronte a tutte le esigenze dettate Ciò non basta, c’è la necessità di accorciare le distanze; le diverse grandezze misurate devono essere elaborate e controllate in altri posti remoti dal trasduttore Si è aggiunta allora la necessità di far comunicare più dispositivi tra loro La scheda arduino può far fronte a queste esigenze con i metodi elencati nella slide successiva

3 Modi per comunicare Modo seriale: basta mettere i pin di due schede in collegamento; tale comunicazione è per piccolissime distanze e può servire per ampliare le capacità della scheda. Tale metodo è detto I2C ed è il più semplice TX-RX: comunicazione in radiofrequenza; non è simmetrica in quanto uno fa da trasmettitore e l’altro da ricevitore Bluethoot: un dispositivo dotato di bluethoot può comunicare con la scheda arduino alla quale viene collegato comunque un modulo bluethoot Ethernet: esiste una scheda di rete che si può collegare alla scheda arduino e quindi, ad una rete locale Wifi: tramite una antenna, si può collegare arduino ad una rete locale

4 I2C Arduino dispone di due pin analogici per la comunicazione: il pin A4 detto anche SDA,serial data e, A5 SCL serial Clock Se si vuol far comunicare due schede arduino, basta collegare il A4 dell’uno con il A4 dell’altro e A5 dell’uno con A5 dell’altro. La comunicazione non è simmetrica in quanto uno farà da master e l’altro da slave.

5

6

7 Accensione di un led con I2C
Una scheda arduino invia un comando per far accendere un led situato su un’altra scheda arduino Il programma master è il seguente: //master #include <Wire.h> void setup() {   Wire.begin();         pinMode (2,OUTPUT); } void loop()   Wire.requestFrom(2, 1); // richiedi 1 byte al dispositivo presente all'indirizzo 2.   String b = "";   char c = Wire.read();   b = b + c;   delay (100);   if (b == "a")   {     digitalWrite(2, HIGH);   }   else     digitalWrite(2, LOW);   delay(10);

8 Programma slave #include <Wire.h> void setup() {
  pinMode(2, INPUT);   pinMode(3,OUTPUT);   Wire.begin(2);  // I2C con indirizzo 2   Wire.onRequest(requestEvent); } void loop()   delay(100); void requestEvent()   if (digitalRead(2) == HIGH){     Wire.write("a");           digitalWrite(3,HIGH);     }   else   {     Wire.write("s");         digitalWrite(3,LOW);

9 Tx-Rx

10 Funzioni di configurazione
vw_set_tx_pin(transmit_pin) Imposta il pin di trasmissione. Il pin di default impostato nella libreria è il 12. vw_set_rx_pin(receive_pin) Imposta il pin per la ricezione. Il pin di default impostato nella libreria è il 11. vw_setup(baudrate) Inizializza la libreria. Prima di mandare in esecuzione tale comando tutti i pin devono essere già stati impostati. L'argomento è la velocità di trasferimento (numero di bit al secondo).

11 Funzioni di trasmissione
vw_send(message, length)  Trasmette il messaggio. "message" è un array di byte mentre length è il numero di byte da spedire. Questa funzione ritorna il controllo al programma chiamante immediatamente ed esegue l'invio mediante un processo in background basato su interrupt. Restituisce true se il messaggio è stato accettato per la trasmissione false se il messaggio è troppo lungo (maggiore diVW_MAX_MESSAGE_LEN - 3).   vw_tx_active()  Ritorna true se il messaggio è in spedizione altrimenti false. E' utilizzato per testare se, dopo il comando di spedizione, il messaggio è stato completamente trasmesso.   vw_wait_tx()  Aspetta che il messaggio sia completamente spedito. Solitamente è utilizzato dopo il comando vw_send(). 

12 Funzioni di ricezione Funzioni di Ricezione
vw_rx_start()  Attiva il processo di ricezione. E' necessario effettuare una chiamata a tale funzione prima di procedere con qualsiasi ricezione. Attiva un processo in background basato su interrupt che controlla se ci sono dati in arrivo. vw_have_message()  Ritorna true se il messaggio è stato ricevuto. E' analogo ai comandi  "available" presenti in molte librerie. vw_wait_rx()  Attende l'arrivo di un messaggio. Tale funzione termina solo quando arriva il messaggio altrimenti resta in attesa per sempre. vw_wait_rx_max(timeout_ms)  Aspetta l'arrivo di un messaggio per un tempo definito in "timeout_ms". Restituisce true se arriva un messaggio nell'intervallo stabilito, false altrimenti.  vw_get_message(buf, &buflen))  Legge l'ultimo messaggio ricevuto. Tale funzione dovrebbe essere chiamata solo quando si è verificato l'arrivo di un messaggio mediante una delle 3 precedenti funzioni. "buf" è un array dove verrà depositato il messaggio in arrivo. "buflen" contiene inizialmente la dimensione dell'array e successivamente il numero di byte letti. La funzione restituisce true se il messaggio ricevuto è corretto altrimenti false se il messaggio appare corrotto (non ). vw_rx_stop()  Disabilita il processo di ricezione

13 Circuito

14 Programma TX #include <VirtualWire.h> const int TX_DIO_Pin = 2; const int PIN_BUTTON1 = A0; const int PIN_BUTTON2 = A1; const int PIN_BUTTON3 = A2; const int PIN_BUTTON4 = A3; const int PIN_BUTTON5 = A4; const int PIN_BUTTON6 = A5; unsigned int Data; void setup() {Serial.begin(9600); pinMode(13, OUTPUT); vw_set_tx_pin(TX_DIO_Pin); vw_set_ptt_inverted(true); vw_setup(1000); } void loop() { if(hasBeenPressed(PIN_BUTTON1)){ Data = 1; sendData(Data); Serial.println("HF- DeltaLoop"); // Visualizzo il messaggio sul display if(hasBeenPressed(PIN_BUTTON2)){ Data = 2; Serial.println("HF- MoreGain"); } if(hasBeenPressed(PIN_BUTTON3)){ Data = 3; Serial.println("HF- 15mt Dipole"); } if(hasBeenPressed(PIN_BUTTON4)){ Data = 4; sendData(Data); Serial.println("V/UHF- Quadrifil"); // Visualizzo il messaggio sul display } if(hasBeenPressed(PIN_BUTTON5)){ Data = 5; Serial.println("V/UHF-Yagi V/UHF"); // Visualizzo il messaggio sul display boolean hasBeenPressed(int pin){ if(analogRead(pin)>1000){ return true; }else{ return false; void sendData(int Data){ byte TxBuffer[2]; TxBuffer[0] = Data >> 8; TxBuffer[1] = Data; digitalWrite(13, HIGH); vw_send((byte *)TxBuffer, 2); vw_wait_tx(); digitalWrite(13, LOW); delay(1000);

15 Programma RX #include <VirtualWire.h> const int RX_DIO_Pin = 2; const int PIN_RELAY4 = 10;//antenne V/UHF Quadrifilare const int PIN_RELAY5 = 11;//antenne V/UHF Yagi const int PIN_RELAY1 = 3;//antenne HF Dipolo const int PIN_RELAY2 = 4;//antenne HF MoreGain const int PIN_RELAY3 = 5;//antenne HF Delta Loop const int PIN_RELAYvhfOFF = 6;// resetta tutti i relè V/UHF const int PIN_RELAYhfOFF = 7;// resetta tutti i relè HF boolean RELAY1 = false; boolean RELAY2 = false; boolean RELAY3 = false; boolean RELAY4 = false; boolean RELAY5 = false; boolean RELAYvhfOFF = false; boolean RELAYhfOFF = false; void setup(){ pinMode(13, OUTPUT); Serial.begin(9600); pinMode(PIN_RELAY1,OUTPUT); pinMode(PIN_RELAY2,OUTPUT); pinMode(PIN_RELAY3,OUTPUT); pinMode(PIN_RELAY4,OUTPUT); pinMode(PIN_RELAY5,OUTPUT); pinMode(PIN_RELAYvhfOFF,OUTPUT); pinMode(PIN_RELAYhfOFF,OUTPUT); vw_set_rx_pin(RX_DIO_Pin); vw_setup(1000); vw_rx_start();}

16 Programma RX void loop(){ uint8_t Buffer_Size = 2; unsigned int Data; uint8_t RxBuffer[Buffer_Size]; if (vw_get_message(RxBuffer, &Buffer_Size)){ Data = RxBuffer[0] << 8 | RxBuffer[1]; } if(Data==1){ //antenne HF Serial.println(Data); digitalWrite(PIN_RELAYhfOFF,HIGH);// azzera tutti i relè delay(500); digitalWrite(PIN_RELAYhfOFF,LOW);// li lascia aperti digitalWrite(PIN_RELAY3,HIGH);//attiva il relè. delay(2000);// attendi due secondi. digitalWrite(PIN_RELAY3,LOW);//stacca corrente (il relè rimane nel suo stato).} if(Data==2){ digitalWrite(PIN_RELAY2,HIGH);//attiva il relè 2. digitalWrite(PIN_RELAY2,LOW);//stacca corrente (il relè rimane nel suo stato). if(Data==3){ Serial.println(Data); digitalWrite(PIN_RELAYhfOFF,HIGH);// azzera tutti i relè delay(500); digitalWrite(PIN_RELAYhfOFF,LOW);// li lascia aperti digitalWrite(PIN_RELAY1,HIGH);//attiva il relè 2. delay(2000);. digitalWrite(PIN_RELAY1,LOW);} if(Data==4){ digitalWrite(PIN_RELAYvhfOFF,HIGH);// azzera tutti i digitalWrite(PIN_RELAYvhfOFF,LOW);// li lascia aperti digitalWrite(PIN_RELAY4,HIGH);//attiva il relè 2. delay(2000);// attendi due secondi. digitalWrite(PIN_RELAY4,LOW);.} if(Data==5){ digitalWrite(PIN_RELAYvhfOFF,HIGH);// azzera tutti i relè digitalWrite(PIN_RELAY5,HIGH);//attiva il relè 2. digitalWrite(PIN_RELAY5,LOW);} }

17 Introduzione al bluetooth
In telecomunicazione è uno standard tecnico industriale per le comunicazioni senza filo ad onde radio La distanza coperta con questa tecnica è dell’ordine dei dieci metri Questa tecnica mette in comunicazione dispositivi elettronici anche differenti come palmari, cellulari, pc, tv, stampanti, fotocamere. La tecnica è stata messa in atto dalla Ericson La frequenza di lavoro è di 2.45 GHz e la velocità di trasferimento dati è 2 Mbps

18 HC-05 Modulo bluetooth

19 Schema elettrico Il modulo HC05 è dotato di 4 pin: VCC GND
TX che va su RX di Arduino RX che va su TX di Arduino

20 Bluetooth: codice //Il codice è molto semplice, è quello di una banale comunicazione seriale, tanto è vero che non richiede librerie aggiuntive int value; int led = 5; void setup() { pinMode(led, OUTPUT); Serial.begin(9600); } void loop() if( Serial.available()>0 ) value = Serial.read(); if( value == 'H' ) digitalWrite(led, HIGH); else if( value == 'L' ) digitalWrite(led, LOW); delay(100);

21 Bluetooth La comunicazione bluetooth avviene tramite seriale di un qualsiasi pc; il programma è infatti, un semplice controllo di led o interruttori tramite la seriale del pc. Nel caso del bluetooth, bisogna controllare la porta virtuale del pc dove viene installato il modulo HC-05. La porta seriale attraverso la quale il pc comunica con arduino è diversa da quella attraverso la quale il pc comunica con il modulo HC-05. Per evitare eventuali conflitti, conviene prima passare il programma compilato al microcontrollore e poi, montare il modulo bluetooth. I comandi al bluetooth possono essere passati anche tramite il monitor seriale di arduino cambiando la porta di accesso. Ciò però può portare dei conflitti e allora, conviene installare un programma che interfacci il bluetooh al pc. Un programma molto utile è PuTTY, è un programma molto semplice da usare ed è free.

22 Dispositivi e stampanti

23 Codice

24 PuTTY Prima della connessione

25 Bluetooth e PuTTY Per connettere il Bloutooth bisogna
avviare il programma PuTTY Appena avviato, compare la schermata a lato

26 Bluetooth e PuTTY Il primo passo da fare è quello di selezionare il
monitor seriale

27 Bluetooth e PuTTY Il passo successivo è quello
di inserire la porta seriale

28 Bluetooth e PuTTY Se tutto va a buon fine, comparirà la seguente schermata

29 Connessione Anche HC-05 è connesso

30 Bluetooth e PuTTY Se la porta non è quella giusta
o è occupata, la schermata è questa

31 Monitor seriale Si piò anche utilizzare il monitor seriale di Arduino, basta selezionare la porta in cui si trova il bluetooth, in questo caso la com12

32 RS485 È una connessione fisica, cablata; il trasferimento dei dati avviene tramite seriale; non è un protocollo. La velocità di trasmissione è di circa 100 Kb/s per 1200m La connessione può essere fatta tra due o più device dello stesso tipo; si possono collegare fino a 32 dispositivi; è un sistema a single master e multi slave nel senso che c’è un solo master e più slave. Gli slave non comunicano tra loro ma solo con il master. In questa sede, viene trattata la comunicazione tra due schede Arduino 1 La comunicazione avviene in maniera differenziale e in half duplex secondo le direttive EIA/TIA-485

33 rs485 I pin sono DI = data in RO = ricevitore out DE= data enable
RE= receive enable VCC=alimentazione + GND=massa - A e B

34 Collegamenti

35

36 Comunicazione differenziale
La comunicazione RS485 è di tipo speculare: ci sono due livelli logici, quello di trasmissione e il suo complementare, quello speculare che a livello logico alto fa corrispondere uno basso e viceversa. La comunicazione avviene quindi su due cavi. La comunicazione è differenziale. Su un cavo viaggia un segnale e sull’altro cavo viaggia il segnale speculare. In questo modo, il livello logico alto corrisponde non a 5V di uscita ma a 10 V perché si misura la differenza tra i due livelli; il livello logico basso corrisponde quindi a 5V Questa tecnica fa in modo che la comunicazione RS485 è immune da disturbi

37 Comunicazione differenziale
All'uscita del trasmettitore la differenza di potenziale tra le linee A e B deve essere di almeno 4 V e la tensione di modo comune deve essere minore di 7 V (normalmente una linea vale 0 V e l'altra circa 5 V). Il ricevitore deve essere in grado di interpretare correttamente lo stato della linea quando la differenza di potenziale è superiore in modulo a 200 mV. In appendice ho riportato una tabella con tutti i valori elettrici definiti dallo standard

38 Comunicazione half duplex
Per comunicazione half duplex si intende la trasmissione dati che avviene nei due versi, su uno stesso cavo ma non contemporaneamente Un solo cavo viene quindi utilizzato sia per la ricezione che per la trasmissione ma in tempi differenti, prima l’una e poi l’altra. Differente è la full duplex, tecnica che permette la comunicazione in entrambe i versi, sullo stesso cavo e negli stessi istanti ma, non adottata in questo caso. Conviene utilizzare un cavo twistato perché è immune da disturbi

39 RS485

40 Adattatori di impedenza
Ciascun cavo è caratterizzato da resistenza, capacità ed induttanza. La capacità di un cavo di buona qualità varia tra i 50 pF/m e i 100 pF/m. La capacità varia anche con il baud rate secondo questa tabella

41 Uno dei disturbi ai quali si può far fronte è quello della riflessione del segnale
Per evitare questo disturbo basta aggiungere una resistenza di terminazione detta adattatore di impedenza Se la durata di un singolo bit trasmesso SBTx è maggiore di almeno 10 volte del tempo tp che il segnale impiega a percorrere tutta la linea allora la terminazione non serve.

42 Collegamento di più dispositivi

43 Esempio di adattamento di impedenza
La velocità del segnale all’interno del cavo è 2/3 della velocità della luce Se il cavo è lungo 1,2 Km, il tempo per attraversare il cavo sarà tp=1.2/(0.666*c)= 6 us Se la velocità di trasmissione è 9600 baud (9600 bit per secondo) allora il tempo di bit è SBTx= 1/9600 = us 104.66>6*10 Quindi non serve la terminazione Se invece fosse necessario terminare la linea quello che si fa è mettere sul nodo più lontano dal master una resistenza a carbone collegata tra A e B il cui valore deve essere pari all'impedenza caratteristica della linea ZL. Il problema è determinare in modo corretto l'impedenza ZL che è legata all'impedenza del cavo Zo e all'impedenza dei chip 485. In generale l'impedenza ZL varia tra i 120 e 560 ohm ma con i moderni 485 si arriva anche a Kohm.

44 Diagramma a occhio Per poter visualizzare la correttezza dei collegamenti basta visualizzare il segnale con un oscilloscopio con ingresso differenziale

45 Collegamenti

46 Schema DI= Data Input può essere collegato sul pin D11
RO= Receive Output può essere collegato sul pin D10 RE= Receive Enable può andare su D3 DE= Data Enable può andare sullo stesso D3 GND Vcc=5v di arduino A e B sono le uscite che vanno su A e B del corrispondente RS285

47 Codice Arduino master #include <SoftwareSerial.h>
#define SSerialRX #define SSerialTX #define SSerialTxControl 3 #define RS485Transmit HIGH #define RS485Receive LOW #define Pin13LED SoftwareSerial RS485Serial(SSerialRX, SSerialTX); int byteReceived; int byteSend; void setup() { Serial.begin(9600); Serial.println("YourDuino.com SoftwareSerial remote loop example"); Serial.println("Use Serial Monitor"); pinMode(Pin13LED, OUTPUT); pinMode(SSerialTxControl, OUTPUT); digitalWrite(SSerialTxControl, RS485Receive); RS485Serial.begin(4800); } void loop() { digitalWrite(Pin13LED, HIGH); if (Serial.available()) { byteReceived = Serial.read(); digitalWrite(SSerialTxControl, RS485Transmit); RS485Serial.write(byteReceived); digitalWrite(Pin13LED, LOW); delay(10); } if (RS485Serial.available()) { byteReceived = RS485Serial.read(); Serial.write(byteReceived);

48 Codice di un device remoto
#include <SoftwareSerial.h> #define SSerialRX #define SSerialTX #define SSerialTxControl 3 #define RS485Transmit HIGH #define RS485Receive LOW #define Pin13LED SoftwareSerial RS485Serial(SSerialRX, SSerialTX); int byteReceived; int byteSend; void setup() {Serial.begin(9600); Serial.println("SerialRemote"); pinMode(Pin13LED, OUTPUT); pinMode(SSerialTxControl, OUTPUT); digitalWrite(SSerialTxControl, RS485Receive); RS485Serial.begin(4800); } void loop() { if (RS485Serial.available()) byteSend = RS485Serial.read(); digitalWrite(Pin13LED, HIGH); delay(10); digitalWrite(Pin13LED, LOW); digitalWrite(SSerialTxControl, RS485Transmit); RS485Serial.write(byteSend); delay(100);

49 Commento ai codici Il codice per la comunicazione RS485 è molto semplice e non è altro che una comunicazione seriale Sono state evidenziate le righe specifiche per questo modulo SoftwareSerial RS485Serial(SSerialRX, SSerialTX); è la dichiarazione dell’oggetto in funzione rispettivamente del ricevitore e del trasmettitore RS485Serial.begin(4800); inizializza la comunicazione seriale di RS485 a 4800 baud RS485Serial.available() chiede la disponibilità della RS485 RS485Serial.read(); legge I dati inviati tramite RS485 RS485Serial.write(byteSend); invia dei dati

50 RS485 send #include <RS485.h> #include <SPI.h>
RS485 myDevice = RS485(); void setup() { Serial.begin(115200); delay(100); if ( myDevice.begin() == 0) { Serial.println("RS-485 module started successfully");} else { Serial.println("RS-485 did not initialize correctly"); } // Configure the baud rate of the module myDevice.baudRateConfig(9600); // Configure the parity bit as disabled myDevice.parityBit(DISABLE); // Use one stop bit configuration myDevice.stopBitConfig(1); // Print hello message Serial.println("Hello this is RS-485 communication send data example."); void loop() { // Reading the analog input 1 int analog1 = analogRead(A1); //Reading the analog input 2 int analog2 = analogRead(A2); // Send data through RS-485 line myDevice.send("Data from analog1 input : "); myDevice.send(analog1); myDevice.send("\n"); myDevice.send("Data from analog2 input : "); myDevice.send(analog2); delay(1000);

51 RS485 receive #include <RS485.h> // Include the SPI library #include <SPI.h> // Create an instance RS485 myDevice = RS485(); void setup() { Serial.begin(115200); delay(100); if ( myDevice.begin() == 0) { Serial.println("RS-485 module started successfully"); } else { Serial.println("RS-485 did not initialize correctly"); } myDevice.baudRateConfig(115200); // Configure the parity bit as disabled myDevice.parityBit(DISABLE); // Use one stop bit configuration myDevice.stopBitConfig(1); // Print hello message Serial.println("This is RS-485 communication receive data example."); void loop() { if (myDevice.available()) { while (myDevice.available()) { // Read one byte from the buffer char data = myDevice.read(); // Print data received in the serial monitor Serial.print(data); delay(10);

52 Vantaggi e svantaggi CAN-bus: RS485: Ethernet: Vantaggi:
E' multi-master; Si trovano già alcuni microcontrollori equipaggiati di unità CAN. Esistono in commercio chip che si possono interfacciare con arduino a basso costo; E' uno standard de facto ed è open source, quindi c'è solo da studiare com'è strutturato il protocollo; Immune ai disturbi ed elevata velocità di comunicazione; Efficiente gestione delle collisioni; Svantaggi: Trama trasmessa parecchio articolata; L'implementazione su Arduino dipenderebbe dal tipo di chip CAN-controller utilizzato. RS485: E' sufficiente collegare un chip RS485-transceiver alla seriale di Arduino. Basso costo e semplicità; Elevata velocità di comunicazione (fino a 100Kbit/s a 1200m); Buona immunità ai disturbi; Siccome il protocollo spetta a noi, possiamo decidere come comporre il messaggio da trasmettere; RS485 non è un procollo ma solo uno standard di livello fisico. A noi spetterebbe l'ideazione di un protocollo ad hoc (magari ispirandoci al DMX). Ethernet: E' una configurazione distribuita; Esistenza di protocolli di comunicazione consolidati, affidabili e documentati; Semplicita` di amministrazione remota; Struttura versatile e diffusa del collegamento, anche su TV e altri elettrodomestici; possibilita` di PoE, con ulteriore semplificazione dei cablaggi; Implica l'uso di tante schede arduino quanti i nodi del sistema. Il costo delle singole schede probabilmente supera quello delle altre soluzioni. Il cablaggio in un impianto esistente puo` essere impegnativo


Scaricare ppt "Comunicare con Arduino"

Presentazioni simili


Annunci Google