Sensor de temperatura DS18B20 con ESP32 o ESP8266 para Alexa (también MAX31820, DS1822)

En esta sección te guiamos para crear un sensor de temperatura con ESP32 y ESP8266, y después ver la temperatura a través de Alexa, Google Home o SmartThings.

Requisitos previos :

  1. ESP32, ESP8266 x 1.
  2. DS18B20 o DS1822, DS1820, MAX31820, MAX31850 x 1.
  3. Resistencia de 4.7k Ohm x 1
  4. Cables jumper.

Introducción rápida al sensor de temperatura

El DS18B20 es un sensor de temperatura digital que se comunica mediante un bus 1-Wire. Es una opción muy usada en numerosas aplicaciones, como la domótica, el monitoreo ambiental y la automatización industrial. El DS18B20 funciona midiendo la resistencia de un termistor. El termistor es un dispositivo semiconductor cuya resistencia cambia con la temperatura. El DS18B20 cuenta con un ADC de 12 bits integrado que convierte la resistencia del termistor en un valor digital.

MAX31820, DS1822, DS1820 y MAX31850: ¿son compatibles con el DS18B20?

Sí. Todos estos sensores usan el mismo protocolo 1-Wire y la misma librería DallasTemperature, por lo que el cableado y el código de este tutorial funcionan sin cambios. La librería detecta el modelo del sensor a partir de su código de familia 1-Wire.

Sensor Código de familia Resolución Tensión de alimentación Notas
DS18B20 0x28 9 a 12 bits 3.0 V a 5.5 V ±0.5 °C de −10 °C a +85 °C
MAX31820 0x28 9 a 12 bits 3.0 V a 3.7 V ±0.5 °C de +10 °C a +45 °C. Mismo código de familia que el DS18B20
DS1822 0x22 9 a 12 bits 3.0 V a 5.5 V Versión de menor costo, ±2 °C
DS1820 / DS18S20 0x10 9 bits 3.0 V a 5.5 V Resolución fija
MAX31850 0x3B 14 bits 3.0 V a 3.7 V Conversor de termopar (tipo K) con interfaz 1-Wire

MAX31820 y MAX31850: usa solo 3.3V. Su tensión de alimentación máxima es de 3.7 V, así que conecta VDD al pin de 3.3V del ESP32 o ESP8266, no a 5V.

Cableado

Sinric Pro esp8266 DS18B20 wiring

Si usas el DS18B20, conecta a tierra los pines 1 y 3. El pin central es la línea de datos ‘1-wire’.

MCU Pin GPIO
ESP32 16
ESP8266 14 (D5)

Comprobemos que la temperatura está bien cableada y funciona.

#if defined(ESP8266)
  #define DS18B20_PIN    D5
#elif defined(ESP32)
  #define DS18B20_PIN    16
#endif

#include <OneWire.h>
#include <DallasTemperature.h> // Supports DS18B20 or DS1822, DS1820, MAX31820, MAX31850
 
OneWire oneWire(DS18B20_PIN);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(115200);
  
  Serial.print("DallasTemperature Library version: ");
  Serial.println(DALLASTEMPLIBVERSION);

  sensors.begin();
}

void loop() {
  sensors.requestTemperatures(); 
  float temperatureC = sensors.getTempCByIndex(0);
  float temperatureF = sensors.getTempFByIndex(0);
  Serial.print(temperatureC);
  Serial.println("C");
  Serial.print(temperatureF);
  Serial.println("F");
  delay(2000);
}

Ver este código en GitHub Gist

El monitor serial del Arduino IDE mostrará la temperatura actual así

Sinric Pro DS18B20 Temperature Sensor

Paso 1 : Crea un nuevo dispositivo en Sinric Pro

Sinric Pro create device alexa

Sinric Pro temperature sensor device notifications

Aquí puedes configurar el umbral para recibir una notificación push a través de la app de Sinric Pro cuando la temperatura baje por debajo o suba por encima de un valor determinado. Usa el Retrigger Time para establecer el retraso entre notificaciones.

Sinric Pro copy device id

Paso 2 : Conéctate a Sinric Pro

Paso 2.1 Instala la librería Sinric Pro

Sinric Pro install SinricPro library

Puedes generar el código con la función Zero Code o escribirlo tú mismo. Si no tienes experiencia en programación, te recomendamos usar la función Zero Code del Portal para generar el código, descargarlo y grabarlo en la placa.

2.2 Código completo

#ifdef ENABLE_DEBUG
  #define DEBUG_ESP_PORT Serial
  #define NODEBUG_WEBSOCKETS
  #define NDEBUG
#endif 

#include <Arduino.h>
#if defined(ESP8266)
  #include <ESP8266WiFi.h>
#elif defined(ESP32)
  #include <WiFi.h>
#endif

#if defined(ESP8266)
  #define DS18B20_PIN    D5
#elif defined(ESP32)
  #define DS18B20_PIN    16
#endif

#include "SinricPro.h"
#include "SinricProTemperaturesensor.h"
#include <OneWire.h>
#include <DallasTemperature.h> // https://github.com/milesburton/Arduino-Temperature-Control-Library

#define WIFI_SSID         ""   // Your WiFI SSID name 
#define WIFI_PASS         ""   // Your WiFi Password.
#define APP_KEY           ""   // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx" (Get it from Portal -> Secrets)
#define APP_SECRET        ""   // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx" (Get it from Portal -> Secrets)
#define TEMP_SENSOR_ID    ""   // Should look like "5dc1564130xxxxxxxxxxxxxx" (Get it from Portal -> Devices)
#define BAUD_RATE         115200              // Change baudrate to your need (used for serial monitor)
#define EVENT_WAIT_TIME   60000               // send event every 60 seconds

OneWire oneWire(DS18B20_PIN);
DallasTemperature sensors(&oneWire);

float temperature;                            // actual temperature
float humidity;                               // actual humidity
float lastTemperature;                        // last known temperature (for compare)
   
void handleTemperaturesensor() {
  if (SinricPro.isConnected() == false) {
    Serial.printf("Not connected to Sinric Pro...!\r\n");
    return; 
  }

  static unsigned long last_millis;
  unsigned long        current_millis = millis();
  if (last_millis && current_millis - last_millis < EVENT_WAIT_TIME) return;
  last_millis = current_millis;
  
  sensors.requestTemperatures(); 
  temperature = sensors.getTempCByIndex(0);
  //temperature = sensors.getTempFByIndex(0); // in °F

  Serial.printf("Temperature: %2.1f °C\r\n", temperature);

  if (isnan(temperature)) { // reading failed... 
    Serial.printf("DS18B20 reading failed!\r\n");  // print error message
    return;                                    // try again next time
  } 

  if (temperature == lastTemperature) {
    Serial.printf("Temperature did not changed. do nothing...!\r\n");
    return; 
  }

  SinricProTemperaturesensor &mySensor = SinricPro[TEMP_SENSOR_ID];  // get temperaturesensor device
  bool success = mySensor.sendTemperatureEvent(temperature, -1); // send event
  if (success) {  
    Serial.printf("Sent!\r\n");
  } else {
    Serial.printf("Something went wrong...could not send Event to server!\r\n"); // Enable ENABLE_DEBUG to see why
  }

  lastTemperature = temperature;  // save actual temperature for next compare  
}


// setup function for WiFi connection
void setupWiFi() {
  Serial.printf("\r\n[Wifi]: Connecting");

  #if defined(ESP8266)
    WiFi.setSleepMode(WIFI_NONE_SLEEP); 
    WiFi.setAutoReconnect(true);
  #elif defined(ESP32)
    WiFi.setSleep(false); 
    WiFi.setAutoReconnect(true);
  #endif

  WiFi.begin(WIFI_SSID, WIFI_PASS); 

  while (WiFi.status() != WL_CONNECTED) {
    Serial.printf(".");
    delay(250);
  }
  IPAddress localIP = WiFi.localIP();
  Serial.printf("connected!\r\n[WiFi]: IP-Address is %d.%d.%d.%d\r\n", localIP[0], localIP[1], localIP[2], localIP[3]);
}

bool onPowerState(const String &deviceId, bool &state) {
  return true; // request handled properly
}

// setup function for SinricPro
void setupSinricPro() {
  // add device to SinricPro
  SinricProTemperaturesensor &mySensor = SinricPro[TEMP_SENSOR_ID];
  mySensor.onPowerState(onPowerState);
  
  // setup SinricPro
  SinricPro.onConnected([](){ Serial.printf("Connected to SinricPro\r\n"); }); 
  SinricPro.onDisconnected([](){ Serial.printf("Disconnected from SinricPro\r\n"); });
  //SinricPro.restoreDeviceStates(true); // Uncomment to restore the last known state from the server.
  SinricPro.begin(APP_KEY, APP_SECRET);  
}

// main setup function
void setup() {
  Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
  
  Serial.print("DallasTemperature Library version: ");
  Serial.println(DALLASTEMPLIBVERSION);
  sensors.begin();

  setupWiFi();
  setupSinricPro();
}

void loop() {
  SinricPro.handle();
  handleTemperaturesensor();
}

Ver este código en GitHub Gist

Ahora deberías poder ver la temperatura a través de la app de Sinric Pro

Sinric Pro App Temperature Sensor

Ten en cuenta que la app de Google Home muestra el sensor de temperatura como un termostato debido a las limitaciones de Google Home.

Solución de problemas

  1. error: DallasTemperature.h: No such file or directory

    Solución: Asegúrate de tener instalada la librería de temperatura correcta. https://github.com/milesburton/Arduino-Temperature-Control-Library

  2. Lecturas de valores inválidos como -127.00C, -196.60F, -127.00C, -196.60F

    Solución: Asegúrate de haberlo cableado correctamente o de que no haya una conexión floja.

    -127 es el valor de DEVICE_DISCONNECTED_C en la librería DallasTemperature. getTempCByIndex() lo devuelve cuando ningún sensor responde en el bus 1-Wire. Comprueba que:

    • la resistencia pull-up de 4.7k Ohm está conectada entre la línea de datos y 3.3V
    • la línea de datos está en el GPIO definido en el sketch
    • VDD y GND no están invertidos
    • un MAX31820 o MAX31850 se alimenta desde 3.3V, no desde 5V

Sinric Pro App Temperature Sensor

  1. Consulta nuestra página de Solución de problemas para más detalles.

Tutoriales relacionados

Este documento es de código abierto. ¿Ves un error? Por favor, crea una incidencia