Dallas DS18B20 con ESP32 ed ESP8266: introduzione e modalità parassita
Il Dallas DS18B20 è un sensore di temperatura digitale che comunica tramite un’interfaccia a 1 filo (1-Wire). È una scelta popolare per la misurazione della temperatura grazie alla sua elevata precisione e al basso costo.
L’ESP32 e l’ESP8266 sono entrambi microcontrollori che possono essere utilizzati per interfacciarsi con il sensore DS18B20. Entrambi i microcontrollori supportano nativamente il protocollo 1-Wire, il che semplifica la connessione al DS18B20.
Il DS18B20 ha due modalità operative: modalità normale e modalità parasita. Nella modalità normale, il sensore richiede un’alimentazione esterna, che fornisce sia alimentazione che comunicazione tramite l’interfaccia 1-Wire. Nella modalità parasita, il sensore trae l’alimentazione direttamente dalla linea dati dell’interfaccia 1-Wire. Ciò consente al sensore di funzionare utilizzando solo due fili: la linea dati e la massa (GND).
Ho già mostrato alcuni sensori di temperatura e umidità in questa serie di articoli: “Sensori di temperatura e umidità: guida all’uso e confronto“, ma ora vorrei spiegare meglio il Dallas DS18B20. Questo sensore a un filo può essere gestito in serie senza limiti significativi.
In particolare, ha una buona precisione (±0.5°) e un notevole intervallo (-55°C a +125°C o -67°F a +257°F), ma puoi aggiungere su un singolo filo molti dispositivi. Supporta inoltre la modalità di alimentazione parasita che consente di utilizzare solo due fili per la connessione.
Ora aggiungerò la spiegazione tratta dal datasheet per una migliore comprensione.
Il termometro digitale DS18B20 fornisce misurazioni di temperatura Celsius a 9-12 bit e ha una funzione di allarme con punti di attivazione superiori e inferiori programmabili dall’utente. Il DS18B20 comunica tramite un bus a 1 filo che richiede solo una linea dati (e GND) per la comunicazione con un microprocessore centrale. Inoltre, il DS18B20 può ottenere l’alimentazione direttamente dalla linea dati (“alimentazione parasita”), eliminando la necessità di un’alimentazione esterna.
Datasheet
Ogni DS18B20 ha un codice seriale univoco a 64 bit, che consente a più DS18B20 di funzionare sullo stesso bus a 1 filo. Pertanto, utilizzare un microprocessore per controllare molti DS18B20 distribuiti su un’ampia area è semplice. Le applicazioni che possono beneficiare di questa funzionalità includono controlli ambientali HVAC, sistemi di monitoraggio della temperatura all’interno di edifici, apparecchiature o macchinari e sistemi di monitoraggio e controllo dei processi.
Caratteristiche
- Interfaccia 1-Wire® univoca: richiede solo un pin per la comunicazione
- Riduce il numero di componenti con sensore di temperatura integrato ed EEPROM
- Misura temperature da -55°C a +125°C (-67°F a +257°F)
- Precisione di ±0.5°C da -10°C a +85°C
- Risoluzione programmabile da 9 a 12 bit
- Non richiede componenti esterni
- Modalità di alimentazione parasita: richiede solo 2 pin per il funzionamento (DQ e GND)
- Semplifica le applicazioni di monitoraggio della temperatura distribuita con capacità multidrop
- Ogni dispositivo ha un codice seriale univoco a 64 bit memorizzato nella ROM integrata
- Impostazioni flessibili di allarme non volatili definite dall’utente con comando di ricerca allarmi per identificare dispositivi con temperature fuori dai limiti programmati
- Disponibile nei pacchetti 8-Pin SO (150 mils), 8-Pin µSOP e 3-Pin TO-92
Datasheet
Pinout
Il sensore presenta diverse varianti, ma il cablaggio rimane invariato.
GND: collegare a GND.
DATA: bus dati One-Wire.
VCC: alimentazione (3,3 – 5 V), ma in modalità parasita puoi collegarlo a GND.
Ecco il sensore AliExpress
Collegamenti
La libreria One-Wire è uno standard per tutti i microcontrollori, quindi il dispositivo può essere utilizzato con molti microcontrollori.
ESP32
Ecco il pinout di una delle schede di sviluppo ESP32 più comuni.
Ecco la mia selezione di ESP32 ESP32 Dev Kit v1 - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 - WeMos Lolin32 mini - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S
Modalità normale
In modalità normale, useremo una linea di alimentazione a 3,3 V, quindi il collegamento sarà così.
Il collegamento è molto semplice.
ESP32 | DS18B20 |
---|---|
GND | GND |
3.3V | VCC |
D22 con pull-up | DATA |
Schema
Ecco lo schema semplice.
Modalità parasita
In modalità parasita, collegherai anche il GND alla linea VCC del sensore, e otterrà l’alimentazione dalla linea dati.
ESP32 | DS18B20 |
---|---|
GND | GND |
GND | VCC |
D22 con pull-up | DATA |
In seguito analizzeremo questa modalità più in dettaglio, ma per ora non serve sapere altro.
Schema
Ecco lo schema.
ESP8266
Modalità normale
ESP8266 | DS18B20 |
---|---|
GND | GND |
3.3V | VCC |
D2 con pull-up | DATA |
Modalità parasita
ESP8266 | DS18B20 |
---|---|
GND | GND |
GND | VCC |
D2 con pull-up | DATA |
Libreria
Prima di tutto, ricorda che questo sensore utilizza il protocollo One-Wire, quindi devi aggiungere la libreria OneWire.
Ogni piattaforma lo supporta; spiegheremo meglio questo protocollo successivamente quando introdurremo l’uso di più sensori.
Dopo aver installato questa libreria, devi aggiungere una libreria che implementa le funzionalità del sensore.
Ho scelto la libreria DallasTemperature, una delle più utilizzate (precedentemente nota come Dallas, ora Maxim).
Dispositivi supportati
Come descritto nel repository, questa libreria supporta i seguenti dispositivi:
- DS18B20
- DS18S20 (alcuni problemi su questo dispositivo)
- DS1822
- DS1820
- MAX31820
- MAX31850
Avrai bisogno di una resistenza pull-up di circa 4.7kOhm tra la linea dati 1-Wire e VCC. Se utilizzi il DS18B20, puoi sfruttare la modalità parasita e collegare VCC a GND come descritto.
Risoluzione dei problemi
In caso di problemi con la conversione della temperatura (il risultato restituisce -85
), potrebbe essere necessaria una configurazione con strong pull-up. Consulta la sezione Alimentazione del DS18B20 nel datasheet del DS18B20 (pagina 7) e utilizza il costruttore DallasTemperature(OneWire*, uint8_t)
.
Alimentazione del DS18B20 (normale/parasita)
Il DS18B20 può essere alimentato con un’alimentazione esterna tramite il pin VDD oppure può funzionare in modalità parasita. In questa modalità, VDD viene collegato a GND e il DS18B20 si alimenta tramite la linea dati 1-Wire (DQ). La carica sottratta dalla linea dati viene immagazzinata nel condensatore di alimentazione parasita (CPP), che fornisce energia durante i momenti in cui la linea dati è bassa.
Tuttavia, durante la conversione della temperatura o il trasferimento di dati nella memoria EEPROM, la corrente richiesta può arrivare fino a 1.5mA. Questa corrente potrebbe causare un calo di tensione inaccettabile sulla resistenza pull-up, e il condensatore CPP potrebbe non riuscire a sostenere il funzionamento.
Pull-up forte per la modalità parasita
Per garantire che il DS18B20 riceva corrente sufficiente, è necessario utilizzare un pull-up forte sulla linea dati durante la conversione della temperatura o il trasferimento di dati. Questo si può ottenere utilizzando un MOSFET per portare direttamente la linea dati al livello di alimentazione.
La linea dati deve essere portata al livello pull-up entro 10µs dopo l’inizio della conversione della temperatura e mantenuta a livello alto fino al completamento della conversione. Durante questo tempo, nessuna altra attività può avvenire sulla linea 1-Wire.
Un’alternativa consiste nell’alimentare il DS18B20 con il metodo convenzionale, collegando un’alimentazione esterna al pin VDD, come mostrato nello schema sottostante. Questo metodo elimina la necessità di un pull-up forte e consente di utilizzare la linea 1-Wire per altre attività durante la conversione della temperatura.
L’uso della modalità parasita non è consigliato per temperature superiori a +100°C, poiché il DS18B20 potrebbe non riuscire a mantenere la comunicazione a causa delle correnti di perdita più elevate che possono verificarsi a tali temperature.
Ridurre le dimensioni della libreria
Abbiamo incluso le definizioni REQUIRESNEW
e REQUIRESALARMS
. Se desideri ridurre le dimensioni del codice, puoi utilizzare una di queste definizioni aggiungendole all’inizio del file DallasTemperature.h
:
#define REQUIRESNEW
oppure:
#define REQUIRESALARMS
Codice
Ora possiamo iniziare con alcuni esempi pratici.
Per ESP8266, devi semplicemente cambiare il pin da 22 a D2 o direttamente a 4.
Ottenere la temperatura dal sensore
Per prima cosa, il modo più veloce per far funzionare il sensore.
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 22
#define ONE_WIRE_BUS 22
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
/*
* The setup function. We only start the sensors here
*/
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
// Start up the library
sensors.begin();
}
/*
* Main function, get and show the temperature
*/
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
// After we got the temperatures, we can print them here.
// We use the function ByIndex, and as an example get the temperature from the first sensor only.
float tempC = sensors.getTempCByIndex(0);
// Check if reading was successful
if(tempC != DEVICE_DISCONNECTED_C)
{
Serial.print("Temperature for the device 1 (index 0) is: ");
Serial.println(tempC);
}
else
{
Serial.println("Error: Could not read temperature data");
}
delay(2000);
}
L’output seriale è molto semplice:
Dallas Temperature IC Control Library Demo
Requesting temperatures...DONE
Temperature for the device 1 (index 0) is: 21.12
Requesting temperatures...DONE
Temperature for the device 1 (index 0) is: 21.12
Requesting temperatures...DONE
Temperature for the device 1 (index 0) is: 21.12
Ottenere informazioni e temperatura (tramite indice)
Ora possiamo ottenere l’indirizzo, le informazioni sulla connessione (normale o parasita) e la temperatura.
/**
* Retrieve information about a single sensor
* minor change by Renzo Mischianti <www.mischianti.org>
*
* www.mischianti.org
*/
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 22
#define ONE_WIRE_BUS 22
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// arrays to hold device address
DeviceAddress insideThermometer;
/*
* Setup function. Here we do the basics
*/
void setup(void)
{
// start serial port
Serial.begin(112500);
Serial.println("Dallas Temperature IC Control Library Demo");
// locate devices on the bus
Serial.print("Locating devices...");
sensors.begin();
Serial.print("Found ");
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" devices.");
// report parasite power requirements
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
// Assign address manually. The addresses below will beed to be changed
// to valid device addresses on your bus. Device address can be retrieved
// by using either oneWire.search(deviceAddress) or individually via
// sensors.getAddress(deviceAddress, index)
// Note that you will need to use your specific address here
// insideThermometer = { 0x28, 0xFF, 0x64, 0x0E, 0x79, 0x69, 0x3A, 0x1A };
// we can check if the address is correct and if It's all ok
// if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
// Search for devices on the bus and assign based on an index. Ideally,
// you would do this to initially discover addresses on the bus and then
// use those addresses and manually assign them (see above) once you know
// the devices on your bus (and assuming they don't change).
if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
// show the addresses we found on the bus
Serial.print("Device 0 Address: ");
printAddress(insideThermometer);
Serial.println();
Serial.print("Device 0 HEX Address: ");
printHEXAddress(insideThermometer);
Serial.println();
// set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
sensors.setResolution(insideThermometer, 9);
Serial.print("Device 0 Resolution: ");
Serial.print(sensors.getResolution(insideThermometer), DEC);
Serial.println();
}
/*
* Main function. It will request the tempC from the sensors and display on Serial.
*/
void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
// It responds almost immediately. Let's print out the data
printTemperature(insideThermometer); // Use a simple function to print out the data
delay(4000);
}
// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
void printHEXAddress(DeviceAddress deviceAddress)
{
Serial.print(" { ");
for (uint8_t i = 0; i < 8; i++)
{
Serial.print("0x");
if (deviceAddress[i] < 0x10) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
if (i < 7) Serial.print(", ");
}
Serial.println(" }");
}
// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
// method 1 - slower
//Serial.print("Temp C: ");
//Serial.print(sensors.getTempC(deviceAddress));
//Serial.print(" Temp F: ");
//Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit
// method 2 - faster
float tempC = sensors.getTempC(deviceAddress);
if(tempC == DEVICE_DISCONNECTED_C)
{
Serial.println("Error: Could not read temperature data");
return;
}
Serial.print("Temp C: ");
Serial.print(tempC);
Serial.print(" Temp F: ");
Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}
L’output sulla console seriale apparirà così:
Dallas Temperature IC Control Library Demo
Locating devices...Found 1 devices.
Parasite power is: OFF
Device 0 Address: 28FF640E79693A1A
Device 0 HEX Address: { 0x28, 0xFF, 0x64, 0x0E, 0x79, 0x69, 0x3A, 0x1A }
Device 0 Resolution: 9
Requesting temperatures...DONE
Temp C: 22.50 Temp F: 72.50
Requesting temperatures...DONE
Temp C: 22.50 Temp F: 72.50
Come puoi vedere, ho impostato il pin OneWire a 22:
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 22
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
Controlliamo quanti sensori sono rilevati sulla linea:
// locate devices on the bus
Serial.print("Locating devices...");
sensors.begin();
Serial.print("Found ");
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" devices.");
Verifica se stiamo utilizzando una connessione in modalità parasita:
// report parasite power requirements
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
Assegna all’indirizzo insideThermometer
il sensore 0:
// Search for devices on the bus and assign based on an index. Ideally,
// you would do this to initially discover addresses on the bus and then
// use those addresses and manually assign them (see above) once you know
// the devices on your bus (and assuming they don't change).
if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
Ora possiamo leggere la temperatura (in gradi Celsius):
float tempC = sensors.getTempC(deviceAddress);
Converti poi in Fahrenheit:
Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converte tempC in Fahrenheit
È possibile leggere direttamente in Fahrenheit, ma internamente viene comunque effettuata una conversione:
Serial.print(sensors.getTempF(deviceAddress)); // Effettua una seconda chiamata a getTempC e converte in Fahrenheit
Grazie
- ESP32: piedinatura, specifiche e configurazione dell’Arduino IDE
- ESP32: fileSystem integrato SPIFFS
- ESP32: gestire più seriali e logging per il debug
- ESP32 risparmio energetico pratico
- ESP32 risparmio energetico pratico: gestire WiFi e CPU
- ESP32 risparmio energetico pratico: modem e light sleep
- ESP32 risparmio energetico pratico: deep sleep e ibernazione
- ESP32 risparmio energetico pratico: preservare dati al riavvio, sveglia a tempo e tramite tocco
- ESP32 risparmio energetico pratico: sveglia esterna e da ULP
- ESP32 risparmio energetico pratico: sveglia da UART e GPIO
- ESP32: filesystem integrato LittleFS
- ESP32: filesystem integrato FFat (Fat/exFAT)
- ESP32-wroom-32
- ESP32-CAM
- ESP32: ethernet w5500 con chiamate standard (HTTP) e SSL (HTTPS)
- ESP32: ethernet enc28j60 con chiamate standard (HTTP) e SSL (HTTPS)
- Come usare la scheda SD con l’esp32
- esp32 e esp8266: file system FAT su memoria SPI flash esterna
- Gestione aggiornamenti firmware e OTA
- Gestione del firmware
- Aggiornamento OTA con Arduino IDE
- Aggiornamento OTA con browser web
- Aggiornamenti automatici OTA da un server HTTP
- Aggiornamento del firmware non standard
- Integrare LAN8720 con ESP32 per la connettività Ethernet con plain (HTTP) e SSL (HTTPS)
- Collegare l’EByte E70 (CC1310) ai dispositivi ESP32 c3/s3 ed un semplice sketch di esempio
- ESP32-C3: piedinatura, specifiche e configurazione dell’IDE Arduino
- Integrazione del modulo W5500 su ESP32 con Core 3: supporto nativo ai protocolli Ethernet con SSL e altre funzionalità
- Integrazione del modulo LAN8720 su ESP32 con Core 3: supporto nativo del protocollo Ethernet con SSL e altre funzionalità.
- Dallas DS18B20
- Dallas DS18B20 con ESP32 ed ESP8266: introduzione e modalità parasita
- Dallas DS18B20 con ESP32 ed ESP8266: gate P-MOSFET pull-up e allarmi
- Dallas DS18B20 con ESP32 ed ESP8266: tutte le topologie OneWire, lunghe derivazioni e più dispositivi