#include <OneWire.h>
#include <DallasTemperature.h>
// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
// il tipo dati DeviceAddress è un array dui byte definito cosi:
// typedef uint8_t DeviceAddress[8];
typedef struct RdTemp
{
uint8_t busIndex;
DeviceAddress deviceId;
float temperature;
uint32_t lastReadTime; // Non viene usata in questo sketch, ma potrebbe servire??
};
#define NUM_DEVICE 3
RdTemp tempSensors[NUM_DEVICE];
const uint32_t readInterval = 2000;
void setup()
{
Serial.begin(9600);
sensors.begin();
// locate devices on the bus
Serial.print("Locating devices...");
Serial.print("Found ");
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" devices.");
for (int i = 0; i < NUM_DEVICE; i++)
{
// Ottieni l'id del devix i
DeviceAddress addr;
sensors.getAddress(tempSensors[i].deviceId, i);
// Salvo l'indice del dispositivo nella struct
tempSensors[i].busIndex = i;
// Visto che siamo su ESP32, possiamo usare printf e risparmiare qualche riga di codice
Serial.printf("\nBus index=%d; Device address=", i);
pintDeviceId(i);
}
Serial.println();
}
void loop()
{
static uint32_t printTime;
if (millis() - printTime > readInterval)
{
printTime = millis();
sensors.requestTemperatures();
Serial.println();
// Ciclo for classico (usa il bus index)
// for (int i = 0; i < NUM_DEVICE; i++)
// {
// if (readTempByIndex(i)) {
// outputTemp(i);
// }
// else {
// Serial.printf("Il dispositivo %d non ha risposto correttamente\n", i);
// }
// }
// Ciclo for "range based" (usa la struct passata per riferimento alla funzione)
for (RdTemp & device : tempSensors)
{
if (readTempByStructPointer(device)) {
outputTemp(device.busIndex);
}
else {
Serial.printf("Il dispositivo %d non ha risposto correttamente\n", device.busIndex);
}
}
}
}
// Lettura temperatura usando l'indice bus
bool readTempByIndex(uint8_t index)
{
float tempC = sensors.getTempCByIndex(tempSensors[index].busIndex);
// Se c'è un errore di comunicazione, la libreria restituisce -127.0
if (tempC != -127.0) {
tempSensors[index].temperature = tempC;
tempSensors[index].lastReadTime = millis();
return true;
}
return false;
}
// Lettura temperatura usando il riferimento al tipo dati RdTemp
bool readTempByStructPointer(RdTemp &device)
{
float tempC = sensors.getTempC(device.deviceId);
// Se c'è un errore di comunicazione, la libreria restituisce -127.0
if (tempC != -127.0) {
device.temperature = tempC;
device.lastReadTime = millis();
return true;
}
return false;
}
void pintDeviceId(uint8_t index)
{
RdTemp device = tempSensors[index];
for (int i = 0; i < 8; i++) {
Serial.printf("%02X ", device.deviceId[i]);
}
}
void outputTemp(uint8_t index)
{
pintDeviceId(index);
Serial.printf("-> %3.1f °C\n", tempSensors[index].temperature);
}