Tuesday, May 24, 2016

SHT11 + Particle Photon (running matrixSSL) + InitialState.com


Now days microcontroller platform for IoT devices are becoming more and more powerful so much so that they can now sport an HTTPS stack and hence send telemetry to an HTTPS capable data broker like initialstate.com. Which means no need for any linux based gateway/hub - you can do away with your Raspberry Pi as a go between your microcontroller node and the internet.

You ask why would some one want to do that? Simple - lesser the number of components in your system, lesser the points of failure.

So, I wanted to explore if it was possible to use a Particle Photon to send data directly to initialstate.com and recently it just became possible when a few good folks ported an SSL library to Spark Photon.
My Particle Photon with SHT11



Steps:
  1. Get a Particle Photon and connect it to SHT11. SHT11 is a digital temperature and humidity sensor. It works at 3.3V logic levels and can be powered by the photon itself. The photon will draw power from any nearby device (computer, smartphone charger or router) which has a spare USB port. Here are the connections:
    Connection schematic
  2. Install the Particle app on your android phone and use it to create an account for yourself and link your particle photon to your home WiFi network.
  3. Get an initialstate.com account and create a bucket. Make sure to note down the two API keys (Access key and Bucket Key)
    Noting down your initialstate.com access keys
  4. Now open https://build.particle.io and login with your particle account. Create a new App. add two libraries to it: HTTPSCLIENT-PARTICLE and SHT1X
  5. Write the following code into the .ino file that has been created by default. Make sure to modify the code so that it has your own initialstate.com access keys.

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    #include "SHT1x/SHT1x.h"
    #include "httpsclient-particle/httpsclient-particle.h"
    
    
    
    //Initial State.com and HTTPS configuration START---------------->
    #define INITIALSTATE_ACCESS_KEY "243434gdfsgt43f43rfwp3"
    #define INITIALSTATE_BUCKET_KEY "GHDER34RF3NE"
    
    const bool g_https_trace = false;  // This controls debug info print to Serial
    const char host [] = "groker.initialstate.com";
    //const char ad_endpoint [] = "/api/events";
    const char se_endpoint [] = "/api/events";
    const int g_port = 443; // Don't change this, unless you know what you are doing
    static unsigned int freemem;
    bool g_https_complete;
    uint32 g_bytes_received;
    
    TCPClient client;
    
    // Replace XXXX...XXX with base64 encoding if your gf username:password
    // If you don't know how to generate the base64 encoding go here:
    //    http://www.tuxgraphics.org/toolbox/base64-javascript.html
    // CAUTION: Do NOT remove/replace the word Basic from the string above,
    //          it's part of http standard.
    unsigned char httpRequestContent[] = "POST %s HTTP/1.0\r\n"
     // "User-Agent: curl/7.38.0 \r\n"
      "User-Agent: MatrixSSL/" MATRIXSSL_VERSION "\r\n"
      "Host: groker.initialstate.com\r\n"
      "Accept: */*\r\n"
      "Content-Type: application/json\r\n"
      "X-IS-AccessKey: " INITIALSTATE_ACCESS_KEY "\r\n"
      "X-IS-BucketKey: " INITIALSTATE_BUCKET_KEY "\r\n"
      "Accept-Version: 0.0.4\r\n"
      "Content-Length: %d\r\n\r\n%s";
    
    //<----------------Initial State.com and HTTPS configuration END
    
    
    //SHT11 Temperature and Humidity Sensor START---------------->
    // Channel 1 is Temperature (deg C)
    // Channel 2 is Humidity (%)
    
    #define dataPin  D0
    #define clockPin D1
    
    SHT1x sht1x(dataPin, clockPin);
    //<----------------SHT11 Temperature and Humidity Sensor END
    
    
    void setup() {
      if (g_https_trace) {
        Serial.begin(9600);
      }
      httpsclientSetup(host, se_endpoint);
    }
    
    
    unsigned int nextTime = 0;    // Next time to contact the server
    int g_connected;
    char jsonBufARR[300] = {0};
        
    void loop() {
        String jsonBuf;
        unsigned int t = millis();
        if (nextTime > t) return;
    
        float temperature = sht1x.readTemperatureC();
        float humidity = sht1x.readHumidity();
        jsonBuf = "[";
        jsonBuf += "{";
        jsonBuf += " \"key\": \"Inside_Temperature\",";
        String Temperature_C(temperature, 4);
        jsonBuf += " \"value\": \"" + Temperature_C + "\"";
        jsonBuf += " },";
        jsonBuf += " {";
        jsonBuf += "\"key\": \"Inside_Humidity\",";
        String Humidity_Percent(humidity, 4);
        jsonBuf += " \"value\": \"" + Humidity_Percent + "\"";
        jsonBuf += " }";
        jsonBuf += "]";
        jsonBuf.toCharArray(jsonBufARR, 300);
        
    
        g_connected = client.connect(host, g_port);
        if (!g_connected) {
            client.stop();
            // If TCP Client can't connect to host, exit here.
            return;
        }
        g_https_complete = false;
        g_bytes_received = 0;
        int rc;
        httpsclientSetPath(se_endpoint);
        if ((rc = httpsClientConnection(httpRequestContent, jsonBuf.length(), jsonBufARR)) < 0) {
            // Failure
            if (g_https_trace) {
                Serial.print("httpsClientConnection Returned:\n");
                Serial.println(rc);
            }
            httpsclientCleanUp();
            return;
        } else {
            if (g_https_trace) {
                Serial.println("HTTPS Transaction Successful");
            }
            
        }
        
        client.stop();
        if (g_https_trace) {
            Serial.println("<<<<----------------------------------------New HTTPS Transaction ENDS\n\n");
        }
        nextTime = millis() + 40000;
    }
    

    This is how your Web IDE should look like.
    Note the place where you need to add your own initialstate.com Access keys.

  6. Download the firmware (using the Web IDE - over the air) into your photon and wait for a few seconds then open your initialstate.com tiles view, you note the data being uploaded every 40 seconds.
Here is what my lines app view on initialstate.com looks like, the "Inside_Temperature" and "Inside_Humidity" show the data sent by my Particle Photon to my Home bucket which also includes streams from various other IoT devices that I have installed in my home.


My Particle Photon and SHT11 is installed inside my house.
This is the lines app view showing temperature and humidity data graphed over the past two month

This lines app view shows only the "Inside_Temperature" stream.
I have been out on vacation and my house has been unoccupied since 5/7/2016.
Note how the temperature curve over latest 2 weeks is a smooth wave with
no dips and downward spike - probably a dynamic state of equilibrium established since
there is no one entering or leaving the house and the doors and windows are closed!


Notes:
  1. For background on how hubs are used to do HTTPS/TLS, read Your Very Own Raspberry Pi Smart Home Hub
  2. Webhooks when used with your Particle devices can bypass the use of Raspberry Pi kinda gateway/hub as well - AND THAT WOULD DEFINITELY BE A BETTER WAY to send data to initialstate.com than the one I have specified above because of one main reason - HTTPS stack uses up precious code space on your particle microcontroller which is not ideal, you need that re
  3. Arduino Yun has a microcontroller and a microprocessor (running Linux) on it. You can use that to send DHT11 readings to initialstate.com as well.
  4. I tested the above code on Particle Cores - The web IDE threw compilation errors. In case of Particle Core, you can use webhooks like so.
  5. Forum post regarding matrixSSL ported to Particle Photon by glowfi.sh team is here
  6. Github repository for https library for Particle Photon is here.

0 comments:

Post a Comment