Domotica Arduino Integrazioni dispositivi generici
From Aino Wiki
Contents
Pulsanti
Con Arduino posson esser usati in INPUT per determinare dei comportamenti specifici sui circuiti creati. Basta usare dei pin sui qualis i determinerà se è stato premuto o meno un pulsante in base alla corrente che rileveranno, per i pin digitali si capterà se la tensione è alta (5V = HIGH) o bassa (0V = LOW, a massa).
Pulsanti in pull down
Per cui il PIN 8 riceverà lo stato HIGH solo quando il pulsante sarà premuto altrimenti sarà collegato a massa tramite una resistenza da 10K Ohm
Pulsanti in pull Up
E' il funzionamento opposto a quello del pull down per cui in questo caso il PIN 8 riceverà sempre corrente attraverso la resistenza, chiamata resistenza di pull up, (quindi sarà in stato HIGH), la pressione del pulsante chiuderà il circuito togliendo corrente al PIN 8.
Pull up senza resistore
Esiste una speciale impostazione di Arduino che consente l'aggiunta di un pulsante senza la necessità di aggiungere una resistenza nel controllo dello stato 0V. Basta configurare un PIN come pin destinato all'ingresso e con la costante "INPUT_PULLUP", sarà lo stesso microcontrollore a collegare una resistenza interna al pin. Semplicemente il pulsante sarà collegato al PIN e ad un pin di ground di Arduino.
Pulsante su linea analogica
Possiamo usare un solo pin analogico su cui impostare n pulsanti, su ogniuno di questi c'è una opportuna resistenza, la lettura di questo pin analogico ci dirà quale pulsante è stato premuto. Tutto questo circuito pulsanti e resistenze è un partitore di tensione. Per mantenere stabile l'ingresso analogico, è necessario collegare il partitore a massa con una resistenza R5 di 1 MΩ. R5 è abastanza grande da non interferire col partitore.
E' una tecnica per cui dei resistori in serie si attivano alla pressione di bottoni ed il valore della resistenza finale indica quale bottone è stato premuto.
Per questo esempio si usano:
- 3 pulsanti: BT1, BT2, BT3;
- 4 resistori da 4.7 KΩ;
- 1 resistore da 1 MΩ, R5.
I pulsanti si nominano da sinistra verso destra, il primo a sx è BT1 che se premuto restituirà una tensione maggiore.
Il partitore dividerà la tensione in 3 livelli: 1.25V, 2.25V, 3.75V. Premendo BT1 il pin A0 leggerà 3.75V, premendo BT2 2.5V e con BT3 avremo 1.25V.
Sketch
#include <Arduino.h> const int m_soglia = 10; // Soglia per prevenire rumore nella tensione rilevata void setup() { Serial.begin(115200); while (!Serial) { } } void loop() { // Si legge l'ingresso analogico A0 int valoreAnalogico = analogRead(A0); //da 0 a5V corrispomndenti a 0-1023 //Se il valore è compreso tra due livelli si può riconoscere quale dei 3 pulsanti è stato premuto if ((valoreAnalogico > 255 - m_soglia) && (valoreAnalogico < 255 + m_soglia)) { Serial.println("Premuto pulsante BT3"); } else if ((valoreAnalogico > 509 - m_soglia) && (valoreAnalogico < 509 + m_soglia)) { Serial.println("Premuto pulsante BT2"); } else if ((valoreAnalogico > 765 - m_soglia) && (valoreAnalogico < 765 + m_soglia)) { Serial.println("Premuto pulsante BT1"); } else { Serial.println("Nessun pulsante premuto"); } }
Dalla doc Arduino qui c'è un esempio per calcolare il voltaggio corrispondente al valore restituito da analogRead()</code>
Debouncing
Guardando lo sketch nel paragrafo dedicato al pulsante di Pull Up si noterà che si sono registrate più pressioni del pulsante di quelle attese, ebbene questo fenomeno si chiama debouncing ovvero "rimbalzo". Sostanzialmente si verificano dei falsi contatti, il fenomeno si elimina introducendo delle pause dopo la rilevazione della pressione del pulsante. Nel seguente NON si usano i delay() perché costosi in termini di risorse, al loro posto si usa millis().
#define BUTTON = 8; unsigned long t = 0; const unsigned long debounce_delay = 200; //Millisecondi void setup() { Serial.begin(9600); while (!Serial) {} //Utile da Arduino Uno R4 in sù pinMode(BUTTON, INPUT); } void loop() { int tasto = digitalRead(BUTTON); if (tasto) { if (millis() - t) > debounce_delay { //Si suppone che i rimbalzi siano finiti Serial.println("Pemuto pulsante"); t = millis(); //Si fotografa il momento } } }
LED
Ogni LED che collegheremo ad Arduino deve essere accompagnato da una resistenza adatta alla sua tensione di alimentazione ed alla corrente (questa è comunque una regola generale), la tensione è di 5V (o 3.3V su alcuni modelli) e la corrente solitamente è 10 o 15 mA. (link interno sui LED)
Hanno due terminali, + anodo, - catodo. Il catodo è la gamba più corta e sotto la 'cupola' termina come una specie di mazza da golf.
| Colore | Tensione (volt); | Resistenza consigliata (*) Alimentazione=5V - Corrente 12mA |
Resistenza per corrente a 6mA Arduino Uno R4 |
|---|---|---|---|
| Rosso | 1,8 V. | 266Ω ~270Ω | 533Ω ~560Ω |
| Giallo | 1,9 V. | ~260Ω | Ω |
| Verde | 2,0 V. | 250Ω | 500Ω ~470Ω |
| Blu | 3,5 V. | 125Ω | 250Ω ~220Ω |
| Bianco | 3,0 V. | ~170Ω | Ω |
| Infrarosso | 1,3 V. | ~310Ω | Ω |
(*) TEORIA Si applicano il Secondo teorema di Kirchhoff ((o Legge delle Maglie)) e la Legge di Ohm. ATTENZIONE Tra una versione di Arduino ed un altra la corrente può cambiare!
Per Kirchhoff, in ogni percorso chiuso (maglia), la somma algebrica di tutte le tensioni (forze elettromotrici e cadute di tensione) è zero, perché l'energia si conserva tornando al punto di partenza. Pertanto se usassimo un LED Verde, nel ns caso (ipotesi: tensione 5V e corrente 12mA ovvero 0.012A):
VArduino - Vresistenza - Vled = 0
Applicando la Ohm per cui: V=R*i
5V - Vled = Vresistenza ovvero 5V-2V = Vresistenza ovvero 5V-2V = R * i ovvero 3V = R * 12mA ovvero R = 3V / 0,012A = 250Ω
E' intuibile che i LED possono essere collegati a due pin qualsiasi di Arduiono (usando comunque la resistenza) per l'accensione l'importante è che questi due pin abbiano stato opposto (uno in stato HIGH e l'altro LOW). Quando il PIN 11 è in stato alto il LED verde si accende ed il Rosso rimane spendo e viceversa quando il PIN 11 si spegne.
LED RGB
Sono LEd che possono generare TUTTI i colori variando la luminosità dei colori base, infatti, essi contengono 3 led: rosso, verde, blu (RGB). Hanno 4 piedini, quello più lungo in genere è il catodo (-) chiamato anche "comune".La regolazione della luminosità dei 3 led si fa usando la funzionalità,analogWrite(), del pin PWM di Arduino (quelli con la ~), supponiamo di usare i pin 9, 10 e 11. Il collegamento NON sarà diretto ma poiché i led lavorano con tensioni diverse (vedi tabella precedente) richiedono resistenze diverse, supponendo di sperimentare con Arduino Uno R4 le resistenze saranno da:
- 560Ω per il led rosso, R. Calcoli: (5V - 1.8V) * 0.006A = 3.2V * 0.006A = 533Ω
- 470Ω per il led verde, G. Calcoli: (5V - 2V) * 0.006A = 3V * 0.006A = 500Ω
- 220Ω per il led blu, B. Calcoli: (5V - 3.5V) * 0.006A = 1.5V * 0.006A = 250Ω
Sketch
#include <Arduino.h> int m_loopMax = 1000; void setup() { Serial.begin(9600); int i = 0; while (!Serial) { i++; if (i > m_loopMax) { break; } delay(10); } Serial.println("Test Led RGB"); //-- randomSeed(analogRead(A0)); } void loop() { // Si generano 3 numeri casuali tra 0 e 255 int red = random(0, 256); int green = random(0, 256); int blue = random(0, 256); // Si imposta la luminosità del led RGB usando la funzionalità dei pin PWM analogWrite(9, red); analogWrite(10, green); analogWrite(11, blue); delay(400); }
LED RGB con potenziometro
Con la versione seguente si regola la luminosità usando dei potenziometri\trimmer
Sketch
#include <Arduino.h> int m_loopMax = 1000; int m_red = 0; int m_green = 0; int m_blue = 0; void setup() { Serial.begin(9600); int i = 0; while (!Serial) { i++; if (i > m_loopMax) { break; } delay(10); } Serial.println("Test Led RGB"); //-- randomSeed(analogRead(A0)); // Si generano 3 numeri casuali tra 0 e 255 m_red = random(0, 256); m_green = random(0, 256); m_blue = random(0, 256); } void loop() { //Si leggono i valori di 3 potenziometri per regolare la luminosità dei tre colori m_red = analogRead(A0) / 4; // Si divide per 4 perché il valore letto è tra 0 e 1023 m_green = analogRead(A1) / 4; m_blue = analogRead(A2) / 4; Serial1.print("R:"); Serial1.print(m_red); Serial1.print(" G:"); Serial1.print(m_green); Serial1.print(" B:"); Serial1.println(m_blue); // Si imposta la luminosità del led RGB usando la funzionalità dei pin PWM analogWrite(9, m_red); analogWrite(10, m_green); analogWrite(11, m_blue); }
Display
I displositivi generici son stati spostati al link interno: Integrazioni Display
Relay
Ad esempio se si vogliono attivare delle luci o dei motori con Arduino o altro dispositivo in grado di generare un "impulso" di corrente da 5V (ma anche da altre tensioni), serve collegarlo ad un relè che con tale impulso farà chiudere un circuito aziondo quel che si vuole.
In poche parole un relè è un interruttore magnetico che viene sollecitato da un impulso di corrente, in questa semplice formula fintanto che c'è flusso l'interruttore magnetico e conseguentemente il circuito, posson rimanere chiusi (o aperti a seconda di come si sceglie di farlo funzionare).
- Il relè ha due circuiti totalmente indipendenti, uno di controllo ad es. a corrente continua (DC) che è per azionare il magnete interruttore ed un altro ad es. a corrente alternata (AC), che serve per attivare un carico.
- può funzionare con diverso voltaggio ma il problema è che per funzionare ha bisogno di tanta corrente, es. 84 mA. In corrente continua la corrente necessaria si fornice per tramite di un transistor.
- Il tranistor ha la funzione a sua volta di interruttore, si userà un transistor BJT bipolare NPN a saturazione.
- Una vantaggio del transistor è quella di fornire sufficientemente corrente al relè.
- E' composto da tre piedini: base, emettitore e collettore. La base riceve il comando mediante della corrente a pochi milliampere (es. 13mA) così si satura (si "riempie") e consentirà il passaggio di cariche negative dall'emettitore al collettore. Quando si "chiude" il circuito tra emettitore e collettore, il flusso che si crea sarà utile per azionare il relè (eccitando la sua bobbina interna che chiude o apre il circuito secondario di lavoro).
- al relè si aggiunge un diodo per evitare che, dopo aver azionato il relè, della corrente dalla bobbina vada in circolo per far danni ai componenti che lo circondano.
- per avere una indicazione visiva di quando il relè si attiverà si può aggiungere un led verde che consuma 2V, visto che la tensione di alimentazione è da 5V, la corrente sarà di 13mA gli applicheremo una resistenza di 380Ohm (5V = 380Ohm*0.013A)
Il progetto è il seguente implementato con Fritzing:
Saldatore, millefori e tanta pazienza ed esce fuori questo:
L'orrendo retro:
E ad 1.5€ si trova comodamente questo ma senz'anima:
RTC orologio
DS3232
- Basato sulla guida: makerguides.com
- Libreria: di Korneliusz Jarzębski
Usa il protocollo I2C quindi è possibile usarlo in parallelo con altri dispositivi che usano lo stesso protocollo come ad esempio il display (attraverso l'adattatore interfaccia seriale PCF8574).
- Tensione operativa: 3.3-5.5V.
- Consente la programmazione di due calendari di allarme.
- Integra un sensore di temperatura digitale, accessibile tramite l'interfaccia I2C.
- Ha un chip di memoria EEPROM: AT24C32 (con 32K byte di spazio disponibile).
- L'interfaccia di bus IIC con trasmissione massima a 400KHz (quando opera a 5V).
Può essere collegato a una batteria ricaricabile LIR2032 da 3,6 V. Nonostante possa funzionare sia con 3.3V che con 5V in realtà il modulo ha un circuito di carica molto semplice che danneggerebbe la batteria (se NON ricaricabile) se alimentata a 5V (per andar bene l'alimentazione deve esser di almeno 4.7V con ricaricabile). Si può intervenire interrompendo il circuito di ricarica (dare un'occhiata all'immagine sotto in alto a dx) se si precede di non usare batterie NON ricarciabili.
Pinout
Articolo di riferimento: makerguides.comI contatti in basso a dx, indirizzo I2C - A1, A2, A3, se saldati cambiano l'indirizzo di riferimento del dispositivo nel canale I2C; segue tabella di riferimento:
| A0 | A1 | A2 | Indirizzo |
|---|---|---|---|
| . | . | . | 0x57 |
| ! | . | . | 0x56 |
| . | ! | . | 0x55 |
| ! | ! | . | 0x54 |
| . | . | ! | 0x53 |
| ! | . | ! | 0x52 |
| . | ! | ! | 0x51 |
| ! | ! | ! | 0x50 |
- il pin 32K indica un'uscita del segnale dell'orologio a 32kHz.
- il pin SQW è un pin di interruzione che può essere utilizzato come segnale di allarme o come uscita "server programmabile ad onda quadara".
- sul chip c'è anche un pin RST di reset che però dalla scheda sembra inaccessibile.
- Notare che nel datasheet c'è scritto che i pin SCL e SDA hanno integrate resistenze di 4.7k Ω.
Semplice sketch
Nel seguente esempio utilizziamo un Arduino Nano 33 IoT ed un RTC DS3231, è un esempio in cui si condivide lo stesso canale I2C per i due dispositivi anzi considerando che si dispone di un sensore di temperatura interno questo lavorando sullo stesso canale I2C aumenta a tre i dispositivi connessi.NOTARE in questo esempio si alimentano entrambe a 5V.
Per il display si installa e si usa la libreria "LiquidCrystal_I2C.h" (installabile direttamente mediante PlatformIO) mentre per la libreria necessaria ad usare l'RTC si installa la "Arduino-DS3231" di Korneliusz Jarzębski (si scarica da GitHub si crea la cartella "DS3231" la cartella lib da VS Code e progetto PlatformIO).
Punti di attenzione:
-
m_rtc.setDateTime(__DATE__, __TIME__);inserisce data e ora MA del momento della compilazione... occorrerebbe farglielo fare solo la prima volta! Le due macro __xxxx__ sono due stringhe di caratteri, un esempio è:__DATE__= "Mar 13 2026"__TIME__= "20:19:09" - si deve trovare un metodo per evitare che ad ogni avvio prenda la data della compilazione ma, usando l'orologio interno con batteria, usi la data ed ora che si aggiorna autonomamente. Si usa la EEPROM ma in questo esempio l'Arduino Nano 33 IoT non ce l'ha e si simula usando la flash e la libreria "FlashStorag" di Cristian Maglie.
-
RTCDateTime dt = m_rtc.getDateTime();prende la data ed ora dell'istante corrente. -
m_rtc.dateFormat("d-m-Y H:i:s", dt)formatta l'aoutput stringa della data e ora estratta - In questo esempio mostreremo anche il valore della temperatura sfruttando il sensore incorporato, notare le istruzioni
m_rtc.forceConversion();efloat temperature = m_rtc.readTemperature();. NOTA non è il top di affidabilità, man mano che passa il tempo dall'accensione la temperatura aumenta
facendo pensare che si autoriscaldi almeno fino ad un certo punto.
La variabile di tipo RTCDateTime è una struttura così fatta:
struct RTCDateTime { uint16_t year; uint8_t month; uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; uint8_t dayOfWeek; uint32_t unixtime; };
Data questa premessa per inserire un allarme (rtc è l'oggetto dedicato all'orologio):
if ((rtc.minute==0) & (rec.second==0)) { RTCDateTime dt = rtc.getDateTime(); Serial.println(rtc.dateFormat("H:i:s", dt)); delay(1000); }
Implementazione
#include <Arduino.h> //Per ipotesi: Arduino Nano 33 IoT #include <Wire.h> //Per la comunicazione I2C #include <DS3231.h> #include <LiquidCrystal_I2C.h> #include <FlashStorage.h> // Libreria di Cristian Maglie e che sostituisce EEPROM.h LiquidCrystal_I2C m_lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display DS3231 m_rtc; // Definisce una variabile persistente di tipo byte e la chiama "g_isSetStorage" // in realtà punta ad una locazione di memoria flesh per cui ci scrive o legge meddiante // funzioni dedicate: // read() // write(0xAA) <-- Scrive nella locazione 0xAA FlashStorage(g_isSetStorage, byte); unsigned long m_previousMillis = millis(); unsigned long m_currentMillis = millis(); void setup() { Serial.begin(9600); Wire.begin(); m_rtc.begin(); while (!Serial && (m_currentMillis - m_previousMillis <= 2000)) { //timeout 2s per evitare di restare bloccati m_currentMillis = millis(); } m_lcd.init(); m_lcd.clear(); m_lcd.backlight(); // Make sure backlight is on // Legge il valore memorizzato nella Flash byte isSet = g_isSetStorage.read(); if (isSet != 0xAA) { Serial.println("Primo avvio dopo compilazione: imposto data e ora..."); m_rtc.setDateTime(__DATE__, __TIME__); //Inserisce la data ed ora al momento della compilazione // Salva il flag (0xAA) nella Flash g_isSetStorage.write(0xAA); } else { Serial.println("RTC già configurato."); } } void loop() { m_lcd.setCursor(0,0); m_lcd.print("Data e orario:"); m_previousMillis = millis(); m_currentMillis = millis(); while (!Serial && (m_currentMillis - m_previousMillis < 1000)) { m_currentMillis = millis(); } m_lcd.setCursor(0,3); RTCDateTime dt = m_rtc.getDateTime(); //Prende la data ed ora dell'istante corrente m_lcd.print(m_rtc.dateFormat("d-m-Y H:i:s", dt)); }
Allarmi
Il modulo DS3231 RTC ha due registri di allarme: Allarme 1 e Allarme 2. Questi allarmi possono essere associati ad eventi di ricorrenza che vanno dal giorno ai secondi, l'Allarme 1 ha un evento opzionale in più, quello basato sui secondi, l'Allarme 2 permettedi impostare dai minuti in poi. La tabella seguente ne definisce le opzioni disponibili:
Per l'Alalrme 1:
| DY/DT | A1M4 | A1M3 | A1M2 | A1M1 | Frequenza allarme |
|---|---|---|---|---|---|
| X | 1 | 1 | 1 | 1 | Una volta al secondo |
| X | 1 | 1 | 1 | 0 | In corrispondenza del secondo indicato |
| X | 1 | 1 | 0 | 0 | In corrispondenza del minuto e secondo indicati |
| X | 1 | 0 | 0 | 0 | In corrispondenza dell'ora, minuto e secondo indicati |
| 0 | 0 | 0 | 0 | 0 | In corrispondenza della data, ora, minuto e secondo indicati |
| 1 | 0 | 0 | 0 | 0 | In corrispondenza del giorno, ora, minuto e secondo indicati |
Per l'Alalrme 2:
| DY/DT | A2M4 | A2M3 | A2M2 | Frequenza allarme |
|---|---|---|---|---|
| X | 1 | 1 | 1 | Una volta al minuto (ovvero al secondo 00 di ogni minuto) |
| X | 1 | 1 | 0 | In corrispondenza del minuto indicato |
| X | 1 | 0 | 0 | In corrispondenza del'ora e minuto indicati |
| 0 | 0 | 0 | 0 | In corrispondenza della data, ora e minuto indicati |
| 1 | 0 | 0 | 0 | In corrispondenza del giorno, ora e minuto indicati |
Si possono impostare comunque degli allarmi senza usare Allarme 1 e 2 ma con i registri e gli eventi generati si ha una maggiore stabilità ed effcienza anche nello stile di programmazione.
Per impostare un allarme si usa il metodo setAlarm?(). Ecco come si invocano:
| Metodo | Descrizione | Esempio |
|---|---|---|
setAlarm1(uint8_t dydw, uint8_t hour, uint8_t minute, uint8_t second, DS3231_alarm1_t mode, bool armed)
|
rtc.setAlarm1(1, 10, 45, 30, DS3231_MATCH_DY_H_M_S); // Ogni lunedì (1=lunedì), alle 10:45:30 | |
setAlarm2(uint8_t dydw, uint8_t hour, uint8_t minute, DS3231_alarm2_t mode, bool armed)
|
rtc.setAlarm2(0, 0, 0, DS3231_MATCH_M); //Scatta quando i minuti son 0 quindi una volta ogni ora |
Per disattivare un allarme ad esempio si esegue: isAlarm2(false)
Per verificare se l'allarme è scattato, nel loop() dello sketch si inserisce:
if (rtc.isAlarm2())
I seguenti enumerativi sono delle maschere che indicano come interpretare i parametri passati ad Alarm1 o Alarm2.
Per Alarm1:
typedef enum { DS3231_EVERY_SECOND = 0b00001111, DS3231_MATCH_S = 0b00001110, DS3231_MATCH_M_S = 0b00001100, DS3231_MATCH_H_M_S = 0b00001000, DS3231_MATCH_DT_H_M_S = 0b00000000, DS3231_MATCH_DY_H_M_S = 0b00010000 } DS3231_alarm1_t
Per Alarm2:
typedef enum { DS3231_EVERY_MINUTE = 0b00001110, DS3231_MATCH_M = 0b00001100, DS3231_MATCH_H_M = 0b00001000, DS3231_MATCH_DT_H_M = 0b00000000, DS3231_MATCH_DY_H_M = 0b00010000 } DS3231_alarm2_t;
comunque si scelga di implementare l'allarme serve comunque un continuo polling che va benissimo nella funzione di loop() dello sketch.
Esempio di alalrme che fa suonare un buzer:
#include "Wire.h" #include "DS3231.h" const int buzzerPin = 3; DS3231 rtc; void setup() { rtc.begin(); rtc.setDateTime(__DATE__, __TIME__); rtc.setAlarm1(0, 0, 0, 0, DS3231_MATCH_S); // every minute rtc.setAlarm2(0, 0, 0, DS3231_MATCH_M); // every hour } void loop() { if (rtc.isAlarm1() && !rtc.isAlarm2()) { tone(buzzerPin, 1000, 200); } if (rtc.isAlarm2()) { tone(buzzerPin, 2000, 200); } }
Joystick
Servomotore
Un servomotore (anche chiamato "RC Servo") è un piccolo dispositivo elettronico per azionare parti meccaniche con precisione. La rotazione non è completa ma arriva ad un massimo di 180-270° a seconda del modello. I servomotori raggiungono una posizione impostata e la mantengono. Video di Paolo Aliverti qui
Componenti di un servomotore:
- motore in corrente continua;
- potenziometro, usato per rilevare la posizione del motore;
- gruppo di ingranaggi per aumentare la "potenza meccanica" del dispositivo demoltiplicando i giri del motore e collegare potenziometro al motore;
- piccolo circuito di pilotaggio che riceve il segnale di pilotaggio, aziona il motore e rileva la posizione mediante il potenziometro.
Dal servomotore fuoriescono tre fili:
- rosso per l'alimentazione, in funzione del motore possono esser sufficienti 5V ed è collegabile direttamente da Arduino altrimenti si collegherà ad opportuna alimentazione esterna;
- nero per la massa GND, si può collegare direttamente su quella disponibile su Arduino.
- giallo/marrone/arancione/bianco per l'ingresso del segnale di pilotaggio. Va benissimo un pin PWM digitale di Arduno.
La forza è misurata come "coppia" ed è espressa in kgm (chilogrammetri). Per capire il concetto di chilogrammetro: ad es. un servo con coppia di 2 kgm è in grado di sollevare 2 kg collegato ad un asta lunga 1 m collegata al suo perno. Se riducessimo la lunghezza dell'asta della metà raddopieremmo il peso sollevabile quindi da 2 a 4 kg.
Il segnale di pilotaggio è digitale quindi possiamo collegare direttamente il servomotore ad Arduino, si usano i pin PWM ed il motivo è legato alla natura del segnale richeisto in cui si devono rispettare dei tempi precisi per inviare l'angolo di apertura che dovrà assumere l'asta sul motore.
Per i servomotori occorre inviare ogni 20 ms un impulso positivo di ampiezza variabile che va da un minimo di 1 ms ad un massimo di 2 ms.
Variando l’ampiezza dell’impulso si possono ottenere tutti i valori di posizione che variano da 0° fino al massimo supportato dal servo. (nell’esempio 180°).
Qui, 1ms è chiamato “impulso minimo”, 2ms è chiamato “impulso massimo”, il periodo di 20ms è chiamato “frequenza di ripetizione” (50 HZ qui). Servomotori di marche diverse possono avere segnali PWM di controllo diversi.
Integrazione con Arduino
Come si vedrà dallo sketch l'uso di librerie specifiche evita la programmazione complessa nella taratura degli impulsi e frequenza.
Arduino IDE include già la libreria speciale per il pilotaggio dei servomotori, per le nuove schede potrebbe non essere disponibile e va installata, cercare ed usare la libreria "Servo" by Michael Margolis.
NOTARE che dopo la definizione dell'angolo che dovrà assumere l'asta del servomotore si usa un delay(20) è un ritardo introdotto per dare il tempo al servomotore di acquisire la posizione inviatagli.
#include <Arduino.h> #include <Servo.h> Servo rcServo; void setup() { Serial.begin(9600); while (!Serial) {} // Si configura il servo indicando il pin da usare rcServo.attach(9); } void loop() { // Movimento del servo da 0 a 180 gradi gradualmente for (int i = 0; i <= 180; i++) { rcServo.write(i); // Imposta l'angolo del servo Serial.print("Angolo: "); Serial.println(i); // Stampa l'angolo corrente sul monitor seriale delay(20); // Attende 20ms per permettere al servo di raggiungere la posizione } // Movimento del servo da 180 a 0 gradi gradualmente for (int i = 180; i >= 0; i--) { rcServo.write(i); // Imposta l'angolo del servo Serial.print("Angolo: "); Serial.println(i); // Stampa l'angolo corrente sul monitor seriale delay(20); // Attende 20ms per permettere al servo di raggiungere la posizione } }
Circuiti integrati digitali
Registri a scorrimento
Shift Register. In questo ambito la loro utilità è nell'aumentare il numero di ingressi\uscite di Arduino o ad esempio per realizzare degli effetti visivi con i LED.
Si classificano a seconda del tipo di ingresso e di uscita che posson essere seriali o paralleli.
- Una linea seriale è formata da un solo filo su cui trasmettere dati come sequenze di bit a tempo di clock;
- Una linea parallela usa più fili su cui si tramettono più bit contemporaneamente, sono più veloci delle linee seriali ma impegnano più fili per funzionare.
Nomenclatura in base alla tipologia di conversione in input e output:
- SISO: Serial Input -> Serial Output;
- SIPO: Serial Input -> Parallel Output; per moltiplicare gli output.
- PISO: Parallel Input -> Serial Output; per ridurre l'uscita ad una singola linea.
- PIPO: Parallel Input -> Parallel Output.
In sintesi, per aggiungere 8 uscite si useranno i chip SIPO mentre per aggiungere ingressi si useranno i PISO. L'organizzazione del flusso dati su seriale è effettuata grazie alla sincronizzazione del segnale di clock.
Ad es., i registri SIPO di un chip vanno collegati a tre pin digitali di Arduino:
- clock: segnale di temporizzazione per inviare una sequenza di bit al registro;
- dati: pin da cui invieremo i bit al registro;
- abilitazione: attiva le uscite del registro.
Per impostare le uscite, caricheremo lo stato desiderato con "otto copi" sul clock e presentando i dati sul pin dei dati; al termine del caricamento attiveremo i dati caricati agendo sul pin di attivazione del registro.
74HC164
Il chip 74HC164 (o 74LS164) è un shift register di tipo SIPO per cui con solo tre linee possiamo controllare otto segnali in uscita. Un ingresso è per il clock, uno è il reset ed uno è l'ingresso dati.
Altro
Traduttori BCD
Abbiamo già visto come integrare il circuito integrato SN7447 (o SN74LS47) usato come driver di pilotaggio per display a sette segmenti.
Funzionalità chiave e caratteristiche:
- BCD Input: Accepts 4-bit BCD data (e.g., 0011 for '3') on pins A, B, C, D.
- 7-Segment Output: Provides individual outputs (a, b, c, d, e, f, g) to control segments on a display.
- Lamp Test (LT): A dedicated pin to test all segments simultaneously.
- Blanking/Ripple Blanking: Includes pins (RB, BI/RBO) for suppressing leading zeros and blanking the display.
- Open-Collector Outputs: Can drive common-anode 7-segment displays and handle higher voltages (up to 15V) for brighter LEDs.
- Power: Operates on a 5V power supply (TTL logic family).
In parole povere:
It's the "translator" chip that takes digital numbers from a computer or microcontroller (in BCD format) and turns them into the specific "on/off" patterns required to draw that number on a 7-segment LED display.
Adattatori
Per I2C
Link interno: Adattatore I2C ese con Display
Protocolli per più dispositivi
I2C
Collegare più di un dispositivo I2C a un Arduino è semplice perché il protocollo I2C è progettato come un bus a cui si possono collegare decine di dispositivi (fino a 127) in parallelo utilizzando solo due pin condivisi: SDA (Dati) e SCL (Clock).
ATTENZIONE alcuni dispositivi Arduino funzionano con pin a 5V ed altri (come il Nano 33 IoT) a 3.3V, è importante assicurarsi che i dispositivi I2C siano compatibili ad es. con i 3.3V.
Tutti i dispositivi I2C devono essere collegati in parallelo ai pin I2C (supponiamo Arduino Nano 33 IoT):
- GND di tutti i dispositivi --> GND dell'Arduino.
- VCC (3.3V) di tutti i dispositivi --> 3.3V del Nano.
- SDA di tutti i dispositivi --> Pin A4 (o SDA) del Nano.
- SCL di tutti i dispositivi --> Pin A5 (o SCL) del Nano.
Resistenze di pull-up
Il bus I2C richiede resistenze di "pull-up" sulle linee SDA e SCL. Sebbene il Nano 33 IoT disponga di pull-up interni, spesso per più dispositivi è necessario aggiungerne di esterne (solitamente da 4.7kΩ o 10kΩ) tra SDA e 3.3V, e tra SCL e 3.3V, specialmente se i cavi sono lunghi.
Indirizzi I2C Unici
Ogni dispositivo sul bus deve avere un indirizzo I2C unico.
- Se i dispositivi sono diversi (es. un sensore di temperatura e un display), solitamente hanno indirizzi diversi predefiniti.
- Se colleghi dispositivi identici (es. due sensori uguali), potresti avere un conflitto di indirizzi. Controlla se il dispositivo ha dei ponticelli (jumper) o pin indirizzabili (A0, A1, A2) per modificare l'indirizzo hardware.
Risoluzione dei Conflitti di Indirizzo Se due dispositivi identici hanno lo stesso indirizzo e non puoi modificarlo, hai due opzioni:
- I2C Multiplexer (Es. TCA9548A): Un chip che permette di collegare più dispositivi con lo stesso indirizzo, attivando un solo canale alla volta via software.
- Software I2C (Bit-banging): Usare librerie che permettono di definire altri pin digitali come I2C, ma è più complesso e meno efficiente del multiplexer hardware.
(Mappa e Link)
Integrazioni tipiche | Arduino indice | Arduino | Arduino Progetti | Arduino C++
C++ Info fondamentali | Dizionario Elettronica | Dizionario
Parole chiave:

