NodeMUC Sensore di temperatura Seconda Parte

NodeMUC Sensore di temperatura Seconda Parte

In questo articolo ho già descritto quali sono i vari stati a basso consumo di ESP e il codice di questo progetto si ispira a quello realizzato in quella serie di articoli poichè il NodeMUC è dotato di un ESP 12F.

Per quel che riguarda la gestione del Wi Fi in funzione del risparmio della batteria, il codice di questo e altri progetti è ispirato a questo articolo.

L’obiettivo è quello di tenere spento il Wi Fi il più a lungo possibile. Per questo motivo, non appena il codice  entra nel setup il Wi fi viene spento mediante le istruzioni:

WiFi.mode( WIFI_OFF );
WiFi.forceSleepBegin();
delay( 1 );

Il WiFi viene riattivato solo dopo aver effettuato la lettura del sensore e le operazioni che coinvolgono la EEprom per elaborare una rudimentale previsione del tempo.

Le istruzioni per la riaccensione del WIFI sono:

WiFi.forceSleepWake();
delay( 1 );
WiFi.mode( WIFI_STA );

subito dopo vengono impostati i parametri di rete dichiarati all’inizio.

WiFi.config(staticIP, gateway, subnet);
WiFi.begin(ssid, password);

Dopo aver inviato i dati mediante una chiamata Http a Domoticz e alla stazione meteo viene chiamata la funzione sleepWell().

In essa ESP  viene messo in deep sleep. In particolare la funzione ESP.deepSleep(7440000000,WAKE_RF_DISABLED);

Mette in deep Sleeep ESP per  un numero di microsecondi pari al numero riportato nel primo parametro (nel nostro caso poco più di  due ore). Dopo questo tempo GPIO16 mette a low il pin RST a cui è collegato e riavvia ESP

Il secondo parametro WAKE_RF_DISABLED è un flag che impone a ESP di tenere il Wi Fi spento fino a che non viene esplicitamente chiesto di riaccenderlo. In quest modo si manterrà spento al risveglio di ESP.

Infine la classe WiFiClient   permette di inizializzare una connessione TCP e di inviare un richiesta http (una GET in questo caso) che contiene la stringa JSON necessaria a passare su domoticz i parametri di temperatura e pressione.

Inoltre è possibile impostare un IP statico e altri parametri di rete.

IPAddress staticIP(192, 168, 1, 44); //ESP static ip 
IPAddress gateway(192, 168, 1, 1); //IP Address of your WiFi Router (Gateway) 
IPAddress subnet(255, 255, 255, 0); //Subnet mask

Tutti gli accorgimenti presi via software, insieme a quelli di ridurre a zero il numero dei led accessi durante il funzionamento semplicemente dissaldandoli, fanno ridurre al minimo il consumo richiesto richiedendo la ricarica della batteria solo dopo diversi mesi.

La gestione e la lettura del sensore DS18B20 avvengono mediante le due librerie Onewire.h e DallasTemperature.h

La ditta Dallas Semiconductor (adessp Maxim) produce una famiglia di dispositivi che sono controllati attraverso il protocollo 1-wire.

Qui il reference della libreria OneWire.h che gestisce tale protocollo

Con questa libreria è possibile collegare una serie di sensori DS18B20 e di collegare il pin dati sullo stesso cavetto in modo da far viaggiare i dati in serie su di esso. La libreria permetta la lettura solo “interrogandoli”, in modo da non far accavallare i dati provenienti dai vari sensori. Nel progetto che viene illustrato il sensore utilizzato è uno solo e il software è già predisposto per la lettura di un solo sensore. Qualora si volesse aggiungere altri sensore il software può essere facilmente modificato seguendo questo esempio.

Il software funziona in questo modo:

Anzitutto viene inizializzata la comunicazione con i sensori sensors.begin();

Di seguito viene recuperato l’indirizzo del primo sensore (nel nostro caso l’unico).

sensors.getAddress(insideThermometer, 0)

se l’indirizzo può essere recuperato allora si setta la risoluzione del sensore.

La funzione setResolution() setta la risoluzione interna del convertitore insterno Analogico-Digitale del sensore DS18B20 a 9, 10, 11, o 12-bits, correspondenti ad incrementi di 0.5°C, 0.25°C, 0.125°C, and 0.0625°C, rispettivamente.

Di seguito viene richiesta la lettura del dato al primo sensore

sensors.requestTemperatures(); // Send the command to get temperatures Serial.println("DONE"); 
float tempC = sensors.getTempCByIndex(0);

la temperatura entra  nella costruzione dell’URL che costituirà la chiamata a Domoticz (con un pattern specifico JSON).

Di seguito il codice completo e qui il datasheet del sensore.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

//#define SERIAL_DEBUG
#define IDX_DOMOTICZ 41

/**
   An example showing how to put ESP8266 into Deep-sleep mode
   GPI00 to ground during flashing (without VCC)
   GPI00 free and vcc during execution
   flashing phase:
              1- OFF VCC ESP
              2- GP00 to ground
              3- plug USB adaptor
              4- FLash
   execution PHASE
              1- OFF VCC ESP
              2- GP00 Free
              3- ON VCC ESP
              4- PLUG ESP Adaptor
  cut the voltage regulator and the led to save power;
  After the cut the flasing mode doesn't work with the button
  You must connect D3 (Gp00) to ground
  NB: this is a program for NodeMCU 1.0

*/

//Wi Fi
const char* ssid     = "SSIDName";  
const char* password = "pwd"; // The SSID (password) of the Wi-Fi network you want to connect to

//DomoticZ
const char* host = "192.168.1.112"; //Domoticz, i'm calling you
const int httpPort1 = 8080;

//Static IP address configuration
IPAddress staticIP(192, 168, 1, 44); //ESP static ip
IPAddress gateway(192, 168, 1, 1);   //IP Address of your WiFi Router (Gateway)
IPAddress subnet(255, 255, 255, 0);  //Subnet mask


// Data wire is plugged into port 2 on the ESP
#define ONE_WIRE_BUS 2

// 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;
boolean test;

void setup() {
  //Force WiFi Sleep
  WiFi.mode( WIFI_OFF );
  WiFi.forceSleepBegin();
  delay(200);


#ifdef SERIAL_DEBUG
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");
#endif

}

void loop() {

  // locate devices on the bus
  Serial.print("Locating devices...");

  sensors.begin();

  if (!sensors.getAddress(insideThermometer, 0)) {
    test = true; //not okay
    Serial.println("Unable to find address for Device 0");
  } else
  {
    test = false;
    // set the resolution to 10 bit (Each Dallas/Maxim device is capable of several different resolutions)
    sensors.setResolution(insideThermometer, 10);
  }

  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");

  float tempC = sensors.getTempCByIndex(0);
  if (tempC == DEVICE_DISCONNECTED_C)
  {
    Serial.println("Error: Could not read temperature data");
  }
  if (test) {
    //Temperatura improbabile per segnalare che qualcosa va storto nella lettura
    tempC = -200;
  }
  Serial.print("Temp C: ");
  Serial.print(tempC, 1);


  // Bring up the WiFi connection
  WiFi.forceSleepWake();
  delay( 1 );
  WiFi.persistent( false );
  WiFi.mode( WIFI_STA );
  WiFi.config(staticIP, gateway, subnet);
  WiFi.begin(ssid, password);             // Connect to the network

  int i = 0;
  while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
    delay(1000);
    Serial.print(++i); Serial.print(' ');
  }

  // Use WiFiClient class to create TCP connections
  WiFiClient client;

  if (!client.connect(host, httpPort1)) {
    Serial.println("connection failed");
    //MI metto a nanna se non riesco a contattare il Web Server
    sleepWell();
  }

  // We now create a URI for the request for Domoticz
  String url = "/json.htm?type=command&param=udevice&idx=41&nvalue=0&svalue=";
  url += String(tempC);
  url += ";";

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }


#ifdef SERIAL_DEBUG
  //If client is opened,Read all the lines of the reply from server and print them to Serial
  while (client.available()) {
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
#endif

  //Sleep for a while
  sleepWell();

}


void sleepWell() {
  Serial.println("Going into deep sleep");
  WiFi.disconnect( true );
  delay(100);
  WiFi.mode( WIFI_OFF );
  delay(100);
  //sleep 2h
  ESP.deepSleep(7440000000, WAKE_RF_DISABLED ); //
}

 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.