Arduino example: Simple dallas sensor webserver.

Cellie
Posts: 45
Joined: Sat Feb 27, 2016 9:47 pm

Arduino example: Simple dallas sensor webserver.

Postby Cellie » Fri Oct 27, 2017 1:47 pm

Uses ESPAsyncWebServer as webserver.

Code available at dallas-webserver on GitHub

The example:

Code: Select all

/*************************************************************************************************
 * 
 *     Simple DS18B20 Dallas sensor webserver.
 *     
 *     For ESP32 by CelliesProjects 2017.
 *     
 *     Code adapted from https://www.pjrc.com/teensy/td_libs_OneWire.html
 * 
 ************************************************************************************************/
//#define SHOW_DALLAS_ERROR        // uncomment to show Dallas ( CRC ) errors on Serial.
#define ONEWIRE_PIN           5    // OneWire Dallas sensors are connected to this pin
#define MAX_NUMBER_OF_SENSORS 3    // maximum number of Dallas sensors

#include "OneWire.h"
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

const char* ssid = "----------";
const char* password = "-----------";

AsyncWebServer server(80);

OneWire  ds( ONEWIRE_PIN );        // (a 4.7K pull-up resistor is necessary)

struct sensorStruct
{
  byte    addr[8];
  float   tempCelcius;
  char    name[8];
} sensor[MAX_NUMBER_OF_SENSORS];

byte numberOfFoundSensors;

void setup()
{
  Serial.begin( 115200 );
  Serial.println( "\n\nSimple DS18B20 Dallas sensor webserver example.\n" );
  
  xTaskCreatePinnedToCore(
    tempTask,                       /* Function to implement the task */
    "tempTask ",                    /* Name of the task */
    4000,                           /* Stack size in words */
    NULL,                           /* Task input parameter */
    5,                              /* Priority of the task */
    NULL,                           /* Task handle. */
    1);                             /* Core where the task should run */
    
  Serial.printf( "Connecting to '%s' with password '%s'\n", ssid,  password );
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while ( WiFi.status() != WL_CONNECTED )
  {
    vTaskDelay( 250 /portTICK_PERIOD_MS );
    Serial.print( "." );
  } 
  Serial.println();

  server.on( "/", HTTP_GET, []( AsyncWebServerRequest * request )
  {
    if ( !numberOfFoundSensors )
    {
      return request->send( 501, "text/plain", "No sensors." );
    }

    char content[200];
    uint8_t usedChars = 0;

    for ( uint8_t sensorNumber = 0; sensorNumber < numberOfFoundSensors; sensorNumber ++ )
    {
      usedChars += snprintf( content + usedChars, sizeof( content ) - usedChars, "%s %.2f\n", 
                             sensor[sensorNumber].name, sensor[sensorNumber].tempCelcius );
    }
    request->send( 200 , "text/plain", content );
  });

  server.onNotFound( []( AsyncWebServerRequest * request )
  {
    request->send( 404 , "text/plain", "Not found" );
  });
  
  server.begin();
  
  Serial.print( "\n\nBrowse to http://");
  Serial.print( WiFi.localIP().toString() );
  Serial.println( "/ to get temperature readings.\n" );
}

void loop()
{
  /* show the temperatures in a loop */
  if ( numberOfFoundSensors )
  {
    Serial.printf( "%.1f sec\n", millis() / 1000.0 );
    for ( byte thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++ )
    {
      Serial.printf( "%s %.2f\n", sensor[thisSensor].name,sensor[thisSensor].tempCelcius );
    }
  }
  else
  {
    Serial.println( "No Dallas sensors." );
  }
  vTaskDelay( 5000 / portTICK_PERIOD_MS );
}

void tempTask( void * pvParameters )
{
  numberOfFoundSensors = 0;
  byte currentAddr[8];
  while ( ds.search( currentAddr ) && numberOfFoundSensors < MAX_NUMBER_OF_SENSORS )
  {
    Serial.write( "Sensor "); Serial.print( numberOfFoundSensors ); Serial.print( ":" );
    for ( byte i = 0; i < 8; i++)
    {
      Serial.write(' ');
      Serial.print( currentAddr[i], HEX );
      sensor[numberOfFoundSensors].addr[i] = currentAddr[i];
    }
    snprintf( sensor[numberOfFoundSensors].name, sizeof( sensor[numberOfFoundSensors].name ), "temp %i", numberOfFoundSensors );
    numberOfFoundSensors++;
    Serial.println();
  }
  Serial.printf( "%i Dallas sensors found.\n", numberOfFoundSensors );

  if ( !numberOfFoundSensors )
  {
    vTaskDelete( NULL );
  }

  /* main temptask loop */

  while (1)
  {
    for ( byte thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++)
    {
      ds.reset();
      ds.select( sensor[thisSensor].addr );
      ds.write( 0x44, 0);        // start conversion, with parasite power off at the end
    }

    vTaskDelay( 750 / portTICK_PERIOD_MS); //wait for conversion ready

    for ( byte thisSensor = 0; thisSensor < numberOfFoundSensors; thisSensor++)
    {
      byte data[12];
      ds.reset();
      ds.select( sensor[thisSensor].addr );
      ds.write( 0xBE );         // Read Scratchpad

      //Serial.print( "Sensor " );Serial.print( thisSensor ); Serial.print("  Data = ");
      //Serial.println( present, HEX );
      //Serial.print(" ");
      for ( byte i = 0; i < 9; i++)
      { // we need 9 bytes
        data[i] = ds.read(  );
        //Serial.print(data[i], HEX);
        //Serial.print(" ");
      }
      //Serial.println();

      byte type_s;
      // the first ROM byte indicates which chip
      switch ( sensor[thisSensor].addr[0] )
      {
        case 0x10:
          //Serial.println("  Chip = DS18S20");  // or old DS1820
          type_s = 1;
          break;
        case 0x28:
          //Serial.println("  Chip = DS18B20");
          type_s = 0;
          break;
        case 0x22:
          //Serial.println("  Chip = DS1822");
          type_s = 0;
          break;
        default:
#ifdef SHOW_DALLAS_ERROR
          Serial.println("Device is not a DS18x20 family device.");
#endif
          return;
      }

      int16_t raw;
      if ( OneWire::crc8(data, 8) != data[8])
      {
#ifdef SHOW_DALLAS_ERROR
        // CRC of temperature reading indicates an error, so we print a error message and discard this reading
        Serial.print( millis() / 1000.0 ); Serial.print( " - CRC error from device " ); Serial.println( thisSensor );
#endif
      }
      else
      {
        raw = (data[1] << 8) | data[0];
        if (type_s)
        {
          raw = raw << 3; // 9 bit resolution default
          if (data[7] == 0x10)
          {
            // "count remain" gives full 12 bit resolution
            raw = (raw & 0xFFF0) + 12 - data[6];
          }
        }
        else
        {
          byte cfg = (data[4] & 0x60);
          // at lower res, the low bits are undefined, so let's zero them
          if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
          else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
          else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
          //// default is 12 bit resolution, 750 ms conversion time
        }
        sensor[thisSensor].tempCelcius = raw / 16.0;
      }
    }
  }
}

hml9083@hotmail.com
Posts: 17
Joined: Mon Nov 30, 2015 12:58 pm

Re: Arduino example: Simple dallas sensor webserver.

Postby hml9083@hotmail.com » Thu Jan 18, 2018 1:26 pm

What is the longest period your device has responded successfully to Web requests, IE: number of days ?

Cellie
Posts: 45
Joined: Sat Feb 27, 2016 9:47 pm

Re: Arduino example: Simple dallas sensor webserver.

Postby Cellie » Thu Jan 25, 2018 5:19 pm

hml9083@hotmail.com wrote:What is the longest period your device has responded successfully to Web requests, IE: number of days ?
Atm my fish tanks run 12 days with Dallas sensor code comparable to the example.
http://vissen.wasietsmet.nl/
http://salamanders.wasietsmet.nl/

I had uptimes on several ESP32 devices (and responding webservers) of over three months.
Would have been longer, but I reflashed the ESP.

Who is online

Users browsing this forum: No registered users and 53 guests