[TUTORIAL] 1 – Interfacciare NodeMCU (esp8266) con un BOT Telegram – Domotica con Telegram
–Qui Trovate la guida per poterlo programmare con L’IDE di Arduino
–Qui Trovate la guida per interfacciarlo con Telegram
Ma non divaghiamo troppo! Uno dei punti che ho trovato più difficili nella realizzazione del termostato è la scelta del sensore di temperatura. Lo scenario dei sensori di temperatura supportati dalle librerie di Arduino è tutto sommato abbastanza ampio, andiamo però ad analizzare effettivamente la precisione, l’accuratezza a la precisione (parametri con i quali spesso facciamo confusione).
Iscriviti al nostro canale YouTube per saperne di più! 🙂
Facciamo innanzitutto brevemente chiarezza su questi tre parametri che caratterizzano un sensore. Non utilizzerò termini troppo complicati, proverò invece a spiegare in maniera molto grossolana i significati in modo da rendere l’idea.
La PRECISIONE quantifica quanto, ripetendo con lo stesso sensore la stessa misura più volte, i risultati saranno gli stessi. Più i risultati saranno differenti, meno il sensore si può ritenere preciso. Effettuado più misure i valori avranno quindi una dispersione legata alla precisione del sensore, e una media. Da qui partiamo per parlare di ACCURATEZZA.
L’ACCURATEZZA rappresenta, in pochissime parole, quanto la media dei valori misurati si discosta dal VALORE VERO o VALORE DI RIFERIMENTO. Ecco una figura che rappresenta, secondo me chiaramente, il concetto.Per quanto invece riguarda la RISOLUZIONE, è la capacità, nella misura di una grandezza fisica, di rilevare piccole variazioni della grandezza fisica in esame. Penso che con un esempio tutto questo si chiarifichi molto meglio. Supponiamo di pesare 1kg di sale con una bilancia con risoluzione 0,1kg. Mettiamo sulla bilancia 1kg esatto sulla bilancia, il display ci indicherà 1kg. Aggiungendo 40g di sale la bilancia continuerà a indicare 1,0kg. Continuando ad aggiungere sale fino ad arrivare a 1,050kg la bilancia continuerà a indicare 1,0kg. Possiamo quindi dire che una bilancia con una RISOLUZIONE di 0,1kg, segnerà 1,0kg se sopra di essa metteremo una quantità che va da da 0,950kg a 1,050kg, non riuscendo a rilevare quindi le variazioni di peso all’interno di questo “GAP”.
Dopo aver divagato un po’, arriviamo al sodo! Avevamo iniziato a parlare di sensori….
I sensori che ho avuto modo di provare sono:
MPU6050 (I2C) – Datasheet (oltre a essere Accelerometro e Giroscopio è anche sensore di temperatura)
Senza stare a fare troppi discorsi vi riporto in una tabella le caratteristiche principali di questi sensori.
Sensore | Alimeentazione [V] | Range T [°C] | Precisione [°C] | Accuratezza [°C] | Risoluz. | ||
---|---|---|---|---|---|---|---|
DHT11 | 3.3 - 5.5 | 0/+50 | ±0.5 | ±2 | ±1 | ||
DHT22 | 3.3 - 5.5 | -40/+80 | ±0.2 | ±0.5 | ±0.1 | ||
DS18B20 | 3.3 - 6 | -10/+85 | ±0.1 | ±0.5 | ±0.0625 (configurabile) | ||
MPU-6050 | 2.375 - 3.46 | -40/+85 | ±0.2 | ±1 | ±0.5 |
#include <dht11.h> dht11 DHT; #define DHT11_PIN 4 void setup(){ Serial.begin(9600); Serial.println("DHT TEST PROGRAM "); Serial.print("LIBRARY VERSION: "); Serial.println(DHT11LIB_VERSION); Serial.println(); Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)"); } void loop(){ int chk; Serial.print("DHT11, \t"); chk = DHT.read(DHT11_PIN); // READ DATA switch (chk){ case DHTLIB_OK: Serial.print("OK,\t"); break; case DHTLIB_ERROR_CHECKSUM: Serial.print("Checksum error,\t"); break; case DHTLIB_ERROR_TIMEOUT: Serial.print("Time out error,\t"); break; default: Serial.print("Unknown error,\t"); break; } // DISPLAT DATA Serial.print(DHT.humidity,1); Serial.print(",\t"); Serial.println(DHT.temperature,1); delay(1000); }
DHT22
#include <dht.h> dht DHT; #define DHT11_PIN 4 #define DHT21_PIN 5 #define DHT22_PIN 6 void setup() { Serial.begin(115200); Serial.println("DHT TEST PROGRAM "); Serial.print("LIBRARY VERSION: "); Serial.println(DHT_LIB_VERSION); Serial.println(); Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)"); } void loop() { // READ DATA Serial.print("DHT22, \t"); int chk = DHT.read22(DHT22_PIN); switch (chk) { case DHTLIB_OK: Serial.print("OK,\t"); break; case DHTLIB_ERROR_CHECKSUM: Serial.print("Checksum error,\t"); break; case DHTLIB_ERROR_TIMEOUT: Serial.print("Time out error,\t"); break; default: Serial.print("Unknown error,\t"); break; } // DISPLAY DATA Serial.print(DHT.humidity, 1); Serial.print(",\t"); Serial.println(DHT.temperature, 1); delay(1000); // READ DATA Serial.print("DHT21, \t"); chk = DHT.read21(DHT21_PIN); switch (chk) { case DHTLIB_OK: Serial.print("OK,\t"); break; case DHTLIB_ERROR_CHECKSUM: Serial.print("Checksum error,\t"); break; case DHTLIB_ERROR_TIMEOUT: Serial.print("Time out error,\t"); break; default: Serial.print("Unknown error,\t"); break; } // DISPLAY DATA Serial.print(DHT.humidity, 1); Serial.print(",\t"); Serial.println(DHT.temperature, 1); delay(1000); // READ DATA Serial.print("DHT11, \t"); chk = DHT.read11(DHT11_PIN); switch (chk) { case DHTLIB_OK: Serial.print("OK,\t"); break; case DHTLIB_ERROR_CHECKSUM: Serial.print("Checksum error,\t"); break; case DHTLIB_ERROR_TIMEOUT: Serial.print("Time out error,\t"); break; default: Serial.print("Unknown error,\t"); break; } // DISPLAY DATA Serial.print(DHT.humidity,1); Serial.print(",\t"); Serial.println(DHT.temperature,1); delay(1000); }
MPU6050
#include<Wire.h> const int MPU_addr=0x68; // I2C address of the MPU-6050 int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; void setup(){ Wire.begin(); Wire.beginTransmission(MPU_addr); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) Wire.endTransmission(true); Serial.begin(9600); } void loop(){ Wire.beginTransmission(MPU_addr); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) Serial.print("AcX = "); Serial.print(AcX); Serial.print(" | AcY = "); Serial.print(AcY); Serial.print(" | AcZ = "); Serial.print(AcZ); Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53); //equation for temperature in degrees C from datasheet Serial.print(" | GyX = "); Serial.print(GyX); Serial.print(" | GyY = "); Serial.print(GyY); Serial.print(" | GyZ = "); Serial.println(GyZ); delay(333); }
DS18B20
#include <OneWire.h> #include <LiquidCrystal.h> #define BUTTON A0 int DS18B20_Pin = 2; OneWire ds(DS18B20_Pin); LiquidCrystal lcd(8,9,4,5,6,7); void setup(void) { Serial.begin(9600); lcd.begin(16, 2); lcd.setCursor(0,0); lcd.print(" DS18B20 LCD "); lcd.setCursor(0,1); lcd.print("mauroalfieri.it"); delay( 3000 ); } void loop(void) { float temperature = getTemp(); Serial.println(temperature); lcd.clear(); lcd.setCursor(0,0); lcd.print("Temperatura: "); lcd.setCursor(0,1); lcd.print(temperature); delay(1000); //just here to slow down the output so it is easier to read } float getTemp(){ //returns the temperature from one DS18B20 in DEG Celsius byte data[12]; byte addr[8]; if ( !ds.search(addr)) { //no more sensors on chain, reset search ds.reset_search(); return -1000; } if ( OneWire::crc8( addr, 7) != addr[7]) { Serial.println("CRC is not valid!"); return -1000; } if ( addr[0] != 0x10 && addr[0] != 0x28) { Serial.print("Device is not recognized"); return -1000; } ds.reset(); ds.select(addr); ds.write(0x44,1); // start conversion, with parasite power on at the end byte present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for (int i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } ds.reset_search(); byte MSB = data[1]; byte LSB = data[0]; float tempRead = ((MSB << 8) | LSB); //using two's compliment float TemperatureSum = tempRead / 16; return TemperatureSum; }
Ecco un video dove illustro l’utilizzo del DHT11