Giuseppe Lo Presti
Published © CC BY

THDweeter

Yet another temperature-humidity sensor publishing to dweeter, with WiFi auto-disconnect and a push button to read daily max and min values.

IntermediateProtip2 hours867
THDweeter

Things used in this project

Hardware components

Photon
Particle Photon
×1
DHT22 Temperature Sensor
DHT22 Temperature Sensor
×1
Breadboard (generic)
Breadboard (generic)
Half-size is enough
×1
Resistor 1k ohm
Resistor 1k ohm
×1
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×1
Jumper wires (generic)
Jumper wires (generic)
×7

Software apps and online services

dweet.io

Story

Read more

Schematics

Breadboard schematic

This schematic takes all the space of a half+ breadboard to ease the understanding of the project. I preferred to realize the circuit in a rather more compact form, as shown in the cover picture.

The data posted to dweet.io

Time is simply in Unix format, but you can easily publish it in any other format thanks to the Time Particle API.

Code

THDweeter.ino

Arduino
****REMEMBER to import the DHT and HTTP Client libraries into the Particle Web IDE****

Upload this code to the particle web IDE. Specify the thing name and set the delay as appropriate for you. I did not need any real-time monitoring, that's why the interval is in minutes, but you can go for shorter cycles if you wish: just keep in mind that the whole WiFi connect - publish - disconnect cycle does take time (5-10 secs).
/*************************************************************************
 * Project THDweeter
 * Description: temperature & umidity dweeter
 * Author: Giuseppe Lo Presti, glopresti@gmail.com
 *
 * Changelog:
 * v1.0 - 1-05-2017: initial revision from https://www.hackster.io/shaiss
 * v2.0 - 6-05-2017: added wifi sleep + readout button, refactorization
 * v2.1 - 7-05-2017: dropped LED, minor changes
 * v2.2 - 8-05-2017: added daily max and min reports, use Time
 *************************************************************************/

// This #include statement was automatically added by the Particle IDE.
#include "HttpClient/HttpClient.h"

// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_DHT/Adafruit_DHT.h"

int dhtPin = 2;                        // DHT sensor pin
int pushButtonPin = D5;                // push button pin
int readoutTimeIntervalMins = 5;       // perform a readout every given minutes
String thingName = "glp_photon_vth";   // thing name for Dweeter

DHT dht(dhtPin, DHT22);
HttpClient http;
// Headers currently need to be set at init, useful for API keys etc.
http_header_t headers[] = {
  //  { "Content-Type", "application/json" },
  //  { "Accept" , "application/json" },
  { "Accept" , "*/*"},
  { NULL, NULL }  // NOTE: Always terminate headers will NULL
};
http_request_t request;
http_response_t response;
long lastReadoutTime = 0;       // timestamp of the last readout
float temp, tmax, tmin, hum, hmax, hmin;    // current and daily max and min values
int day = 0;

void setup() {
 	dht.begin();
  pinMode(pushButtonPin, INPUT_PULLUP);  // input with an internal pull-up resistor
}


int getAndStoreValues() {
  // reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a
  // very slow sensor). Also, the lib has a typo...
  temp = dht.getTempCelcius();
  hum = dht.getHumidity();
  //float hi = dht.getHeatIndex();
  //float dp = dht.getDewPoint();
  // Check if any reads failed and exit early
  if (isnan(hum) || isnan(temp)) {
    //Particle.publish("DEBUG", "Failed to read from DHT sensor!");
    return -1;
  }
  // reset every day the max and min values
  if(Time.day() != day) {
    tmin = tmax = temp;
    hmin = hmax = hum;
    day = Time.day();
  }
  // and update them at every readout
  if(temp < tmin) {
    tmin = temp;
  }
  else if(temp > tmax) {
    tmax = temp;
  }
  if(hum < hmin) {
    hmin = hum;
  }
  else if(hum > hmax) {
    hmax = hum;
  }
  return 0;
}


void readout(bool button) {
  // first wake up WiFi
  WiFi.on();
  WiFi.connect();
  // get and store current values
  if(getAndStoreValues()) {
    // failed to read out, try again right away
    lastReadoutTime = 0;
    return;
  }
  // cast floats to strings
  String st(temp, 1);
  String sh(hum, 1);
  // make sure WiFi is ready
  while(!WiFi.ready()) {
    delay(300);
  }
  String payload;
  if(button) {
    Particle.publish("STATE", "Button pressed, data readout");
    // also publish daily max and min values
    String stmin(tmin, 1);
    String stmax(tmax, 1);
    String shmin(hmin, 1);
    String shmax(hmax, 1);
    payload = "temp=" + st + "&humidity=" + sh + "&time=" + Time.now() +
        "&tmin=" + stmin + "&tmax=" + stmax +
        "&hmin=" + shmin + "&hmax=" + shmax;
  } else {
    Particle.publish("STATE", "Periodic data readout");
    payload = "temp=" + st + "&humidity=" + sh + "&time=" + Time.now();
  }
  // post to dweet: follow at http://dweet.io/follow/thingName
  request.hostname = "dweet.io";
  request.port = 80;
  request.path = "/dweet/for/" + thingName + "?" + payload;
  Particle.publish("DWEET", payload);
  http.get(request, response, headers);
  //Particle.publish("DEBUG",response.status);
  Particle.publish("DWEET", response.body);
}


void loop() {
  int pushButtonState = digitalRead(pushButtonPin);
  if(pushButtonState == LOW) {
    // button was pressed, readout
    readout(true);
    // and keep WiFi on for other Photon activities/upgrades
  }
  else {
    // force a readout after the given time interval
    if(Time.now() - lastReadoutTime >= readoutTimeIntervalMins*60) {
      // for regular readouts, record the time of this readout: this way,
      // we make the readings as evenly spread in time as possible
      lastReadoutTime = Time.now();
      readout(false);
      delay(1000);
      // turn off WiFi to spare power
      WiFi.off();
    }
  }
  // loop at 5 Hz to catch button press events
  delay(200);
}

Credits

Giuseppe Lo Presti

Giuseppe Lo Presti

0 projects • 1 follower
Software engineer starting to get dirty with IoT...
Thanks to Shai Perednik.

Comments