La scheda Arduino Uno IL MICROCONTROLLORE La scheda Arduino si concentra attorno ad un microcontrollore Atmega 328. Questo non è altro che il grosso integrato a 28 piedini, che sostanzialmente svolge e/o coordina tutte le operazioni realizzate dalla scheda Arduino. Questo microcontrollore ha un parallelismo interno a 8 bit (cioè lavora su un byte alla volta), ha 20 piedini di ingresso/uscita ed è dotato delle seguenti memorie: memoria di programma FLASH da 32 KB: qui sarà memorizzato il programma scritto. Di questa memoria 0,5 KB sono riservati al bootloader (cioè al sistema base che rende Arduino utilizzabile e che gli permette di ricevere ed eseguire i nostri “sketch”) Memoria dati volatile SRAM da 2 KB : qui saranno salvati i dati “volatili” Memoria Eeprom da 1KB: qui è possibile salvare in modo permanente eventuali dati che devono restar memorizzati anche se dovesse venire a mancare l'alimentazione del sistema (per ulteriori dettagli su come fare potete consultare http://www.mauroalfieri.it/elettronica/tutorial-usare-la-eeprom-di-arduino.html). Il Clock del sistema è di 16 Mhz (viene generato da un apposito circuito presente sulla scheda) ALIMENTAZIONE La scheda Arduino per funzionare correttamente necessita di una tensione di alimentazione di 5 V. Questa può essere fornita in due modi (in realtà tre, ma due sono equivalenti): attraverso la porta USB collegata ad un PC. La porta USB dei PC (e di qualsiasi altro dispositivo connesso ad una sua alimentazione) ha la caratteristica di fornire una tensione stabile proprio di 5V attraverso il connettore Jack dove va fornita una tensione tra i 7 e i 12 V (che sarà poi convertita opportunamente nei 5V necessari) plausibilmente ottenuta da un normale alimentatore AC/DC. Questa metodo può effettuarsi anche applicando la tensione direttamente sui terminali VIN e GND presenti sul connettore marcato con Power (nella parte basa della figura). Se si utilizza questo tipo di alimentazione viene automaticamente esclusa quella eventuale ricevuta dalla porta USB. INGRESSI E USCITE Ingressi/uscite digitali Arduino dispone di 14 pin utilizzabili come ingressi o uscite (pin da 0 a 13) Per utilizzare questi pin occorre prima specificare il modo di funzionamento con i seguenti comandi: pinMode(pin, OUTPUT); pinMode(pin, INPUT); la variabile pin dovrà contenere ovviamente un numero valido di un piedino. In alternativa si può indicare direttamente il numero del piedino. Se un determinato Pin è impostato come uscita, il suo livello può essere impostato come alto o basso con i seguenti comandi digitalWrite(pin,HIGH); digitalWrite(pin,LOW); Se invece un pin è impostato come ingresso è possibile leggerne il relativo valore e assegnarlo ad una opportuna variabile con il seguente comando: val = digitalRead(pin); Nota Bene: I livelli di tensione utilizzati sono 0 e 5V, le correnti erogate o assorbite dai piedini sono al massimo di 40 mA. Ingressi/uscite analogici Su di un apposito connettore sono disponibili 6 ingressi analogici indicati da A0 ad A5 Questi piedini possono ricevere in ingresso valori analogici variabili tra 0V e 5V e convertirli proporzionalmente in un valore numerico compreso tra 0 e 1023 (quindi ad esempio se in ingresso è presente 2,5 V il corrispondente valore sarà 511) Per leggere il dato presente su questi piedini occorre effettuare il seguente comando: val = analogRead(pin) dove pin dovrà essere il numero di uno dei 6 piedini (da 0 a 5 quindi) Per effettuare la scrittura di un dato analogico si può usare la tecnica PWM disponibile sui piedini 3, 5,6 9,10 e 11, opportunamente marcati Questa tecnica consiste nel variare il Duty Cycle di un'onda quadra, producendo di fatto una opportuna variazione del suo valore medio tra 0 e 5V Il comando da utilizzare è il seguente: analogWrite(pin,valore); il parametro valore deve essere compreso tra 0 e 255 e produrrà un valore analogico in modo proporzionale tra 0 e 5V GESTIONE DELLA PORTA USB Per effettuare la comunicazione attraverso la porta seriale USB occorre come prima cosa attivarla, specificando la velocità di comunicazione in bit al secondo con un comando del tipo: Serial.begin(9600); per le comunicazioni con un pc la velocità di comunicazione di 9600 bit per secondo è abbastanza comune ma si possono impostare velocità diverse. Per inviare i dati da Arduino al PC (o altro dispositivo) il comando da utilizzare è: Serial.print(dato) dove dato può essere o direttamente un 'valore' o una variabile Con print() i numeri sono stampati utilizzando un carattere ASCII per ogni cifra, i float allo stesso modo ma con solo due numeri decimali, caratteri e stringhe vengono stampate senza nessuna conversione. Esempi: Comando nel programma Cosa viene stampato sullo schermo Serial.print(35) 35 Serial.print(9.123456) 9.12 Serial.print(‘X’) X Serial.print(“una frase a caso”) una frase a caso Se invece del comando Serial.print(dato) si utilizza Serial.println(dato) al termine di ogni riga si viene inviati a capo (Serial.print al contrario non lo fa quindi viene tutto scritto di fila anche usando diversi comandi Serial.print uno dopo l'altro) Per visualizzare i dati ricevuti dalla porta USB sullo schermo del computer occorre aprire l'opportuna interfaccia dal programma di sviluppo di Arduino, chiamata monitor seriale, come mostrato in figura Per ricevere i dati dalla seriale bisogna come prima cosa verificare che sia stato ricevuto un dato con il comando Serial.available che ci dice quanti dati sono in attesa di essere letti. Se ci sono dati in attesa allora si potranno leggere con il comando Serial.read Esempio Serial.begin(9600); if (Serial.available()>0) { A=Serial.read(); ALTRI COMANDI COMUNI delay(tempo) genera un ritardo espresso in millisecondi delayMicrosecond(tempo) genera un ritardo espresso in microsecondi tone (pin, frequenza, durata) genera sul pin indicato un tono della frequenza e durata indicata: la frequenza è espressa in Hz, la durata in millisecondi noTone(pin) interrompe la generazione del tono CONTROLLO DI UN SERVOMOTORE Per pilotare un semplice servomotore con Arduino occorre come prima cosa utilizzare l'opportuna libreria #include <Servo.h> Quindi in fase di dichiarazione delle variabili va dichiarata una opportuna variabile di tipo servo: Servo servomotore1; Quindi nella procedura setup va dichiarato a quale piedino va collegato il servomotore (similarmente al comando pinMode quando utilizziamo Led in uscita o tasti in ingresso) Void Setup(){ servomotore1.attach(4); } Il piedino utilizzato può essere uno qualsiasi dei piedini digitali. A questo piedino va connesso uno dei tre contatti del servomotore (il filo di controllo che tipicamente è di colore giallo). I restanti due fili del servomotore sono la sua alimentazione che va opportunamente connessa Per far muovere il servomotore nella procedura Loop si utilizzerà un opportuno comando per specificare l'angolo di rotazione del servomotore: servomotore1.write(angolo) ho scritto servomotore1 sempre in rosso per far presente che quello è il nome della variabile scelto... se avessimo scelto come nome della variabile “motorino” i comandi sarebbero stati ripettivamente Servo motorino; motorino.attach(4); motorino.write(angolo); Va tenuto presente che alcuni servomotori funzionano in modo leggermente differente, andando in rotazione continua a una velocità che può essere impostata. Per tali servomori il comando servomotore1.write(angolo) funzionerebbe nel seguente modo: quando angolo = 0 si ha rotazione a velocità massima in un senso quando angolo = 90 il servomotore resta fermo quando angolo = 180 si ha rotazione a velocità massima nel senso opposto ovviamente sono possibili valori intermedi in modo proporzionale Per sapere se il servomotore che si sta utilizzando è di un tipo o dell'altro occorre consultare il relativo datasheet Esempio di programma per pilotare un servomotore: Questo programmino fa girare il servomotore di un grado ogni 15 millesecondi, usando un ciclo for #include <Servo.h> Servo myservo; int pos = 0; void setup() { myservo.attach(9); } void loop() { for(pos = 0; pos < 180; pos += 1) { myservo.write(pos); delay(15); } } SCHEDE AGGIUNTIVE Esistono schede aggiuntive che possono essere gestite con Arduino come ad esempio: ULTRASUONI: Questo tipo di schede è dotato di un trasmettitore e un ricevitore di ultrasuoni. In base al tempo che un'onda emessa impiega per tornare indietro si può stabilire la distanza di un eventuale oggetto presente davanti al sensore Esistono diverse schede di questo tipo come ad esempio la HC SR04 Questa scheda ha 2 pin di alimentazione, uno per farle inviare impulsi (trigger) e uno per leggere impulsi di ritorno (echo) Per farla funzionare correttamente occorre inviare sul piedino di output di arduino connesso al pin trigger della scheda un impulso alto di durata superiore ai 10 microsecondi, ad esempio: digitalWrite( trigger, HIGH ); delayMicroseconds( 15 ); digitalWrite( trigger, LOW ); Dove trigger è il piedino di output La scheda risponderà quindi sul suo piedino echo con un impulso di durata proporzionale al tempo necessario per avere un'onda di ritorno. Per interpretare correttamente questo dato occorre usare il seguente comando durata = pulseIn( echo, HIGH ) volendo sapere la distanza dell'oggetto in centimetri occorre sviluppare una formula che tenga in conto della velocità del suono... fortunatamente qualcuno ha già fatto i calcoli è la formula sarà: distanza = 0.034 * durata / 2; Maggiori dettagli alla pagina https://barcadero.wordpress.com/2012/02/14/sensore-a-ultrasuoni-hc-sr04-e-arduino/ Esistono diversi altri tipi di schede a ultrasuoni, ma il funzionamento e l'utilizzo sarà del tutto similare a quello della SR04 LCD: Per il controllo dei display LCD vi rimando direttamente ai tutorial di Arduino o alla seguente pagina (che essendo in italiano sicuramente sarà più comprensibile per la maggior parte di voi) http://www.maffucci.it/2012/02/17/appunti-su-arduino-pilotare-un-display-lcd/ In rete c'è anche un buon video in proposito https://www.youtube.com/watch?v=Q0oW7QcORW8 Il tutto ovviamente si baserà sull'utilizzo della libreria LiquidCrystal.h MOTOR SHIELD In questo caso si tratta di una scheda che va montata direttamente sopra Arduino e permette di pilotare motori in continua. Vi rimando alla pagina seguente per ulteriori dettagli di come fare http://www.logicaprogrammabile.it/motor-shield-arduino-netduino/ GLOSSARIO Sketck: si tratta del programma scritto per Arduino, nel suo linguaggio specifico che è di derivazione dal linguaggio C, mantenendone tutte le strutture sintattiche e di controllo. Classificazione delle Memorie RAM : Random Access Memory: Memoria ad accesso Casuale: è la memoria volatile (il dato viene perso quando si toglie l'alimentazione) che può essere sia scritta che letta. Il fatto che la memoria sia ad accesso casuale vuol dire che alla memoria si può accedere in qualsiasi punto sempre nello stesso tempo (al contrario nelle memorie ad accesso seriale questo non è vero, dovendo prima 'arrivare' al punto della memoria che ci interessa, come ad esempio sui vecchi nastri magnetici) SRAM: Static RAM: si tratta di una memoria RAM statica, realizzata sostanzialmente con un gran numero di flip flop D, e pertanto tipicamente abbastanza 'lente' DRAM Dynamic RAM: memorie RAM di tipo dinamico, realizzate sfruttando fenomeni capacitivi all'interno dei transistor. Poiché i condensatori tendono a scaricarsi (e quindi si ha la tendenza a perdere il dato in essi memorizzato) c'è bisogno ogni tanto di ricaricarli al valore opportuno effettuando quella che viene chiamata operazione di REFRESH. Questo svantaggio è largamente compensato dalla loro elevata velocità di funzionamento ROM Read Only Memory: Memorie di sola lettura. Sono di tipo permanente (cioè i dati in esse contenuti non vanno persi quando si toglie l'alimentazione). Sotto il punto di vista della modalità di accesso anche queste sono ad accesso casuale e quindi il tempo di accesso in qualsiasi punto della memoria è sempre lo stesso PROM Programmable ROM. Sono memorie ROM che possono essere Scritte una sola volta dall'utente. Vengono acquistate completamente vuote e l'utente, attraverso opportune procedure (che richiedono opportuni apparecchi) può inserirvi EPROM Erasable PROM: sono memorie ROM riscrivibili. Per poterle scrivere vanno prima cancellate attraverso un opportuno procedimento (tipicamente esposizione della parte interna del chip alla luce ultravioletta) EEPROM Electically Erasable PROM. La cancellazione e scrittura della memoria viene effettuata tutta elettricamente (tipicamente usando livelli di tensioni più elevati rispetto a quelli usati normalmente per la lettura)