Guida n. 84
Il modulo Adafruit 935 dà alla FireBeetle 2 ESP32-E, o ad Arduino UNO, un'uscita analogica vera: 4096 livelli comandati in I²C, da misurare con il tester e da guardare sul Plotter seriale.
A cura di Ada Intelisano · redazione tecnica di informaticait.it
- L'MCP4725 di Microchip trasforma un numero da 0 a 4095 in una tensione ferma, non a impulsi come il PWM.
- Il riferimento è l'alimentazione: VOUT = VDD × codice ÷ 4096. A 3,3 V un passo vale circa 0,8 mV.
- Si comanda in I²C all'indirizzo 0x62 con la libreria Adafruit MCP4725; con l'ESP32 il modulo va al 3V3.
- Con
setVoltage(codice, true)il valore resta nella EEPROM e il chip lo ritrova a ogni accensione.
Per leggere una tensione le schede hanno l'ADC; per produrne una, quasi sempre no. Il PWM della guida n. 37 accende e spegne il pin molto in fretta e il tester ci vede una media, ma la tensione vera salta sempre tra zero e il massimo. Un DAC invece tiene ferma sull'uscita la tensione che gli chiedi. L'MCP4725 di Microchip lo fa con 4096 livelli, riceve gli ordini in I²C e si ricorda l'ultimo valore salvato anche da spento.
1Il materiale
- il modulo Adafruit 935 con l'MCP4725: ha un pettine a sei pin sciolto, da saldare. Adafruit avverte che appoggiarlo nei fori senza saldatura non funziona (guida n. 70);
- la FireBeetle 2 ESP32-E con i pin già saldati, cinque cavetti femmina-femmina;
- un tester (guida n. 8). In alternativa alla FireBeetle va bene Arduino UNO, passo 8.
2Il modulo
- VIN e GND: alimentazione, da 2,7 a 5,5 V per il chip. Adafruit consiglia la stessa tensione della scheda che lo comanda: le resistenze di pull-up da 10 kΩ portano SDA e SCL proprio a VIN. Con l'ESP32 quindi 3,3 V.
- SCL e SDA: il bus I²C (guida n. 22). L'indirizzo è 0x62; diventa 0x63 portando A0 a VIN o chiudendo il ponticello «Addr» sul retro. Così sullo stesso bus ci stanno due moduli.
- VOUT: l'uscita. Gli stessi segnali, VOUT escluso, passano anche dai due connettori STEMMA QT.
3Quanto vale un passo
Il chip non ha un riferimento suo: usa l'alimentazione. La formula del datasheet è VOUT = VDD × codice ÷ 4096, con il codice da 0 a 4095. Se VDD cambia, cambia anche l'uscita.
- A 5 V un passo vale 1,22 mV (tabella del datasheet); a 3,3 V circa 0,8 mV (calcolo nostro).
- Con 4095 l'uscita arriva a un passo sotto VDD, non a VDD.
- Vicino agli estremi la precisione cala: Microchip misura la linearità tra i codici 100 e 4000 e l'errore di zero non è tarato in fabbrica.
4Collega e misura
- Cinque fili dritti: 3V3 → VIN, GND → GND, 22 → SCL, 21 → SDA, 35 → VOUT. Il 35 è anche A3, un ingresso analogico: così la FireBeetle rilegge la tensione che ha chiesto.
- VIN al 3V3, mai al VCC: lì arrivano i circa 5 V dell'USB, le pull-up porterebbero a 5 V anche SDA e SCL, e i pin dell'ESP32 non li reggono (guida n. 21).
- Tester su V⎓: puntale nero nel foro − e rosso nel foro + del morsetto opzionale (sono GND e VOUT), oppure direttamente sui pin GND e VOUT.
5Quattro tensioni
// Il DAC MCP4725: quattro tensioni, una ogni 4 secondi. Misurale con il tester // tra VOUT e GND; A3 le rilegge. Libreria: Adafruit MCP4725. #include <Arduino.h> #include <Adafruit_MCP4725.h> const byte INDIRIZZO = 0x62; // Adafruit 935: 0x62 (0x63 con il ponticello chiuso) #ifdef ESP32 const float VDD = 3.3; // FireBeetle 2 ESP32-E: modulo al 3V3 #else const float VDD = 5.0; // Arduino UNO: modulo al 5V #endif const int CODICI[] = {0, 1024, 2048, 4095}; // da 0 a 4095: 12 bit Adafruit_MCP4725 dac; void setup() { Serial.begin(115200); if (!dac.begin(INDIRIZZO)) { Serial.println(F("MCP4725 non risponde: controlla i fili e l'indirizzo")); while (true) delay(1000); } } void loop() { for (int codice : CODICI) { dac.setVoltage(codice, false); // false: la EEPROM non si tocca delay(50); Serial.print(F("codice ")); Serial.print(codice); Serial.print(F(" circa ")); Serial.print(codice * VDD / 4096, 2); // la formula del datasheet Serial.print(F(" V A3: ")); #ifdef ESP32 Serial.print(analogReadMilliVolts(A3)); // millivolt Serial.println(F(" mV")); #else Serial.println(analogRead(A3)); // da 0 a 1023: circa codice / 4 #endif delay(4000); } }
Installa la libreria Adafruit MCP4725. dac.begin(0x62) risponde false se il chip non si fa sentire;
setVoltage(codice, false) cambia l'uscita senza toccare la EEPROM. Apri il Monitor seriale a 115200 baud: per ogni codice
c'è la tensione attesa e quella letta da A3.
- «MCP4725 non risponde»: SDA e SCL scambiati, VIN non collegato, oppure l'indirizzo è 0x63 perché il ponticello «Addr» è chiuso.
- Il tester segna un po' meno del previsto: misura il 3V3 della scheda e rifai il conto con quel valore al posto di 3,3.
- A3 e il tester non coincidono: l'ADC dell'ESP32 è meno preciso di un tester (guida n. 14). Fidati del tester.
6Un'onda sul Plotter
// Un'onda dal DAC MCP4725 e quello che rilegge A3, insieme sul Plotter seriale. #include <Arduino.h> #include <Adafruit_MCP4725.h> const byte INDIRIZZO = 0x62; // Adafruit 935 const bool SENO = false; // true: onda sinusoidale; false: triangolare const int PUNTI = 32; // punti in ogni periodo Adafruit_MCP4725 dac; int punto = 0; void setup() { Serial.begin(115200); if (!dac.begin(INDIRIZZO)) { Serial.println(F("MCP4725 non risponde: controlla i fili e l'indirizzo")); while (true) delay(1000); } } void loop() { int codice; if (SENO) { codice = 2048 + 2047 * sin(TWO_PI * punto / PUNTI); } else { // sale per metà periodo, poi scende int meta = PUNTI / 2; int salita = punto < meta ? punto : PUNTI - punto; codice = salita * 4095L / meta; } dac.setVoltage(codice, false); delay(2); #ifdef ESP32 Serial.print(F("Inviato_mV:")); Serial.print(codice * 3300L / 4096); // modulo al 3V3 Serial.print(F(",A3_mV:")); Serial.println(analogReadMilliVolts(A3)); #else Serial.print(F("Inviato:")); Serial.print(codice / 4); // in punti di A3: 1023 = 5 V Serial.print(F(",A3:")); Serial.println(analogRead(A3)); #endif punto = (punto + 1) % PUNTI; delay(40); }
Ogni 40 millesimi di secondo circa il DAC fa un passo: 32 punti per salire e scendere. Apri il Plotter seriale a 115200 baud. Con
SENO = true l'onda diventa una sinusoide, centrata su metà alimentazione. Il Plotter dell'IDE 2 mostra le ultime 50
righe, poco più di un'onda e mezza.
Inviato_mV è la tensione chiesta, A3_mV quella letta. Il tester, che è lento, segue l'onda a fatica: è normale.7Un valore per l'accensione
Con dac.setVoltage(2048, true) il codice va anche nella
EEPROM, e il chip lo ricarica a ogni accensione: l'uscita parte subito da quel valore, prima ancora che lo sketch giri. Comodo
per una tensione di riferimento che deve esserci sempre.
- Una scrittura nella EEPROM dura fino a 50 ms (datasheet) e le scritture non sono infinite: falla una volta, nel
setupo alla pressione di un pulsante, mai nelloop.
8Con Arduino UNO
- VIN al 5V, GND al GND, SCL e SDA ai pin SCL e SDA accanto ad AREF, VOUT ad A3. L'uscita va da 0 a 5 V.
- Lo sketch è lo stesso: si compila per l'UNO e stampa la lettura di A3 da 0 a 1023. DAC e ADC dell'UNO prendono come riferimento gli stessi 5 V, quindi la lettura vale circa codice ÷ 4 anche se la porta USB dà un po' meno di 5 V (calcolo nostro).
- Senza cavetti: il cavo STEMMA QT porta alimentazione e I²C, con spinotti maschio per l'UNO e con prese femmina per la FireBeetle. Rosso V+, nero GND, blu SDA, giallo SCL; VOUT resta sul pettine.
- Una rampa lenta, da 0 a 4095 in dieci secondi, da seguire con il tester.
- Leggi un potenziometro (guida n. 36) e copia la sua posizione sul DAC.
- Misura l'uscita con 0 e con 4095: quanto manca da 0 V e da VDD?
- un DAC dà una tensione ferma, non a impulsi;
- VOUT = VDD × codice ÷ 4096: il riferimento è l'alimentazione;
- con
trueil valore resta nella EEPROM, ma va scritto di rado.
Prodotti utili
Altre guide
- Codice colori delle resistenze e tolleranze
- MOSFET a canale N e a canale P
- Transistor bipolare (BJT) o MOSFET?
- Il relè: come comandarlo e quanto assorbe
- Componenti THT e SMD/SMT
- Pinout delle schede XIAO
- LED: tensione diretta e resistenza in serie
- Il multimetro: misurare tensione e corrente
- Wemos D1 mini: primi passi
- Modulo MOSFET con Arduino ed ESP32
- Modulo relè con Arduino ed ESP32
- Filamenti per stampa 3D: PLA, PETG e versioni con fibre
- Analogico e digitale: le differenze
- ADS1115: convertitore a 16 bit con Arduino ed ESP32
- Da bit a valore reale: convertire le letture dei sensori
- Orologio RTC DS3231 con Arduino ed ESP32
- Regolatore lineare o switching: quale scegliere
- Step-down, step-up e buck-boost: scegliere il modulo giusto
- Partitore di tensione: leggere tensioni più alte di 5 V o 3,3 V
- Pull-up, pull-down e rimbalzo: collegare un pulsante come si deve
- Livelli logici 3,3 V e 5 V: far parlare ESP32 e Arduino
- Il bus I²C: indirizzi, pull-up e lo scanner
- Batterie al litio: tensioni, carica e protezione
- Consumi e deep sleep dell'ESP32: quanto dura la batteria
- Sensori di temperatura a confronto
- ESP32: quali pin usare e quali evitare
- Primi passi con l'ESP32 in Arduino IDE 2 e PlatformIO
- Display OLED SSD1306 e LCD 16×2 I²C con Arduino ed ESP32
- Sensore di movimento PIR e sensore a ultrasuoni HC-SR04
- Data e ora da Internet con l'ESP32: NTP, fuso italiano e ora legale
- Data logger su microSD: salvare le misure in CSV
- ESP32 a pannello solare: pannello, caricatore e conti per l'Italia
- Web server sull'ESP32: comandare un relè dal telefono
- Il tuo primo LED: collegarlo e farlo lampeggiare
- Il pulsante: far decidere ad Arduino
- Il potenziometro: girare una manopola e leggerne il valore
- Luce morbida: regolare la luminosità di un LED
- Il cicalino: suonare note e melodie
- Il semaforo: tre LED in sequenza
- Il termometro: leggere la temperatura con il TMP36
- Il servomotore: muovere un braccetto con Arduino
- La luce notturna: la fotoresistenza e la prima decisione
- Il relè: accendere una lampadina con Arduino
- Il display LCD: far scrivere Arduino
- Il dado elettronico: il primo progetto completo
- Il LED RGB: tutti i colori con tre luci
- Il joystick: comandi a due assi con uno shield
- L'anello di LED: dodici colori con un solo pin
- Il motore DC: farlo girare con un MOSFET
- L'umidità del terreno: la pianta che chiede acqua
- Il motore passo-passo: girare di quanto vuoi tu
- Il sensore di parcheggio: bip sempre più veloci
- Il display a 7 segmenti: numeri grandi e luminosi
- L'irrigazione automatica: la pianta si annaffia da sola
- Il tastierino: la serratura con il codice segreto
- Stazione meteo in rete: valori e grafico sul telefono
- Un bot Telegram sull'ESP32: casa tua dal telefono
- MQTT con l'ESP32: la lingua degli oggetti connessi
- Aggiornare l'ESP32 via Wi-Fi (OTA)
- ESP-NOW: due ESP32 che si parlano senza router
- WebSocket con l'ESP32: il LED che segue il cursore
- Le letture su un foglio Google, con il deep sleep
- WiFiManager: il Wi-Fi si sceglie dal telefono
- Bluetooth LE con l'ESP32: il telefono senza rete
- La fotocamera nel browser con l'ESP32-S3
- Una cassa Bluetooth portatile, fatta da te
- Diffusori Bluetooth da scrivania, 2 × 20 W
- Lettore MP3 stereo con due pulsanti
- La mensola che suona: un exciter Visaton
- Come si salda bene
- Quanto consuma? Corrente e potenza con l'INA219
- Bilancia con cella di carico e HX711
- Semaforo della CO2: quando aprire le finestre
- Apriporta con tessera RFID
- GPS: registratore di percorso su microSD
- LoRa: fin dove arriva? Prova di portata con due schede
- Cartello meteo a batteria con display e-paper
- Radio web con ESP32 e amplificatore I2S
- Primi passi con il Raspberry Pi Pico 2 in MicroPython
- Il primo amplificatore: LM386 e un altoparlante
- Arduino che parla: il modulo di sintesi vocale DFR0760
- Lo spettro della musica su una matrice di LED
- Disegnare con 64 LED: la matrice 8×8 con il MAX7219
- Il battito del cuore su Arduino: ECG con l'AD8232