Demo of DHT11->mDot->TTN

Dependencies:   DHT22 DS18B20_1wire SHTx TSL2561_I2C libmDot mbed-rtos mbed

Fork of mDot_TTN_DHT11 by Chris Merck

Revision:
18:5b57c3cb4554
Parent:
17:3dc30f4a8da2
Child:
19:a2c9c4cc4863
--- a/main.cpp	Tue Nov 29 15:59:18 2016 +0000
+++ b/main.cpp	Sat Dec 03 22:05:59 2016 +0000
@@ -1,32 +1,56 @@
-/** mDot_TTN_DHT11 -- The Things Network Temperature & Humidity Sensor
+/** mDot_TTN_Raingarden -- Rain Garden Sensor by The Things Network New York
  * 
- *  This is a rough demo of mDot+DHT11 on The Things Network.
- *  This code is not indended as a reference design.
- *  In particular, it lacks:
- *   (1) power management
- *   (2) reasonable transmission period 
- *   (3) adaptive data rate
+ *  This firmware runs an mDot dev board, with the following sensors:
+ *   - DHT22 - air temp & humidity
+ *   - TSL2561 - ambient light
+ *   - SHT10 - soil temp & humidity
+ *   - DS18B20 - water temp
  * 
  * Uses MultiTech mDot developer board http://www.multitech.com/models/94558010LF
  * Requires a MultiTech MultiConnect Conduit http://www.multitech.com/models/94557203LF
  * http://www.multitech.net/developer/software/lora/conduit-mlinux-convert-to-basic-packet-forwarder/
  * http://forum.thethingsnetwork.org/t/setting-up-multitech-conduit-gateway-for-ttn/216/35
  *
- * To receive and visualize this data,
- *  consider using InitialState and the bridge code here:
- * https://github.com/things-nyc/initial-state-example
+ * To receive and visualize this data:
+ *
  */
 
 #include "mbed.h"
-#include "DHT11.h"
 #include "mDot.h"
 #include "MTSLog.h"
 #include "MTSText.h"
+#include "DHT22.h"
+#include "TSL2561_I2C.h"
+#include "sht15.hpp"
+#include "DS18B20.h"
 #include <string>
 #include <vector>
 
 using namespace mts;
 
+/* Pin definitions */
+
+// air temp/humid sensor
+#define DHT_PIN PA_1
+DHT22 dht(DHT_PIN);
+
+// water temp sensor
+#define DS_PIN PA_11
+DS18B20 thermom(DS_PIN, DS18B20::RES_12_BIT); 
+
+// soil temp/humid sensor
+#define SHT_DATA_PIN PA_4
+#define SHT_SCK_PIN PC_13
+SHTx::SHT15 sht(SHT_DATA_PIN, SHT_SCK_PIN);
+
+// light sensor
+#define TSL_DATA_PIN PC_9
+#define TSL_SCK_PIN PA_8
+TSL2561_I2C tsl(TSL_DATA_PIN, TSL_SCK_PIN);
+
+// LEDs
+#define STATUS PB_1
+
 #define MIN(a,b) (((a)<(b))?(a):(b))
 #define MAX(a,b) (((a)>(b))?(a):(b))
 
@@ -35,10 +59,16 @@
  * Register your device and update these values:
  * https://account.thethingsnetwork.org/
  */
-uint8_t AppSKey[16]= { 0x11, 0x6F, 0xA9, 0x2A, 0x46, 0xDE, 0xE6, 0x1D, 0x11, 0xE3, 0x71, 0x37, 0x24, 0xBC, 0x44, 0x1A };
-uint8_t NwkSKey[16]= { 0xF1, 0xA4, 0x78, 0x09, 0x75, 0xE2, 0x3C, 0x2B, 0x76, 0x8F, 0x9F, 0x8D, 0xE0, 0x5E, 0xAA, 0x64 };
-uint8_t NetworkAddr[4]= { 0x68, 0x8E, 0x64, 0xE5 };
 
+#if 1
+uint8_t AppSKey[16] = { 0x11, 0x6F, 0xA9, 0x2A, 0x46, 0xDE, 0xE6, 0x1D, 0x11, 0xE3, 0x71, 0x37, 0x24, 0xBC, 0x44, 0x1A };
+uint8_t NwkSKey[16] = { 0xF1, 0xA4, 0x78, 0x09, 0x75, 0xE2, 0x3C, 0x2B, 0x76, 0x8F, 0x9F, 0x8D, 0xE0, 0x5E, 0xAA, 0x64 };
+uint8_t NetworkAddr[4] = { 0x68, 0x8E, 0x64, 0xE5 };
+#else
+uint8_t AppSKey[16] = { 0x60, 0xA5, 0xFF, 0xAA, 0x5E, 0xBA, 0x23, 0xD7, 0x20, 0xCF, 0xE0, 0x48, 0xBA, 0x63, 0x9C, 0x93 };
+uint8_t NwkSKey[16] = { 0xE6, 0x86, 0x87, 0x2C, 0x4D, 0x77, 0x12, 0x18, 0xAF, 0xE2, 0xDC, 0x54, 0xB6, 0x2F, 0x46, 0x16 };
+uint8_t NetworkAddr[4] = { 0xBD, 0x07, 0x3E, 0x3C };
+#endif
 
 // Some defines for the LoRa configuration
 #define LORA_SF mDot::SF_7
@@ -218,9 +248,6 @@
         };
 
 
-// Temperature sensor object
-#define DHT_PIN PB_1
-DHT11 dht(DHT_PIN);
 
 // Serial via USB for debugging only
 Serial pc(USBTX,USBRX);
@@ -240,8 +267,11 @@
 
     float temperature = 0.0;
 
+    DigitalInOut status_led(STATUS);
+    status_led.output();
+
     pc.baud(115200);
-    pc.printf("TTN mDot LoRa Temperature  & Humidity Sensor\n\r");
+    pc.printf("TTN mDot LoRa Temperature & Humidity Sensor\n\r");
 
     // get a mDot handle
     dot = mDot::getInstance();
@@ -365,13 +395,45 @@
     pc.printf("Ack: %s\r\n", (dot->getAck() ? "Y" : "N")  );
 
     logInfo("Joining Network");
-
     while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
         logError("failed to join network [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
         wait_ms(dot->getNextTxMs() + 1);
     }
+    logInfo("Joined Network");
+    wait_ms(500);
+    
+    /* Setup Sensors */
+ 
+    logInfo("Configure Soil Sensor (SHT)");
+/*    DigitalInOut sht_data(SHT_DATA_PIN);
+    DigitalInOut sht_sck(SHT_SCK_PIN);
+    sht_data.output();
+    sht_sck.output();
+    while (1) {
+        sht_data.write(1);
+        wait_ms(1);
+        sht_data.write(0);
+        wait_ms(1);
+    }*/
+ 
+    //logInfo("Configure Air Sensor (DHT)");
+    // no config needed for DHT
+    logInfo("Configure Water Sensor (DS)");
+    wait_ms(500);
+    DS18B20::ROM_Code_t ROM_Code;
+    wait_ms(500);
+    thermom.ReadROM(&ROM_Code);
+    logInfo("Family code: 0x%X\n\r", ROM_Code.BYTES.familyCode);
+    wait_ms(500);
+    logInfo("Serial Number: ");
+    for (unsigned i = 6; i != 0; --i) {
+        logInfo("%02X%s", ROM_Code.BYTES.serialNo[i-1], (i != 1)?":":"\r\n");
+    }
+    logInfo("CRC: 0x%X\r\n", ROM_Code.BYTES.VTV);
 
-    logInfo("Joined Network");
+    wait_ms(500);    
+    logInfo("Configure Light Sensor (TSL)");
+    tsl.enablePower();
 
     char dataBuf[50];
     uint16_t seq = 0;
@@ -380,6 +442,7 @@
         
         /* cycle through spreading factors */
         uint8_t sf;
+        seq = 0; /* force SF7 */
         switch (seq % 4) {
             case 0:
                 sf = mDot::SF_7;
@@ -409,23 +472,6 @@
         int temp = 0;
         int humid = -1;
         
-        /* read from sensor */
-        int r = dht.readData();
-        switch (r) {
-            case DHT11::OK:
-            {
-                temp = dht.readTemperature();
-                humid = dht.readHumidity();
-                pc.printf("[DHT] T %d degC   H %d %%\r\n",temp,humid);
-                break;
-            }
-            default:
-            {
-                pc.printf("[DHT] ERROR %d\r\n",r);
-                break;
-            }
-        };
-        
         /* build packet */
         b.begin();
         uint8_t flag = 0;
@@ -437,23 +483,54 @@
         b.putV(13.8);
         flag |= FlagVbat;
         
-        // TODO: read from Bme280 sensor:
-        b.putT(27.0); // air temp
+        // read from Bme280 sensor:
+        float air_temp=0, air_humid=0;
+        bool dht_success = dht.sample();    
+        wait_ms(100);
+        logInfo("Air Sensor Status: %s", dht_success?"OK":"ERROR");
+        wait_ms(100);
+        air_temp = (float)dht.getTemperature()/10.0;
+        air_humid = (float)dht.getHumidity()/10.0;
+        logInfo("Air Temp: %1.01fC  Air Humid: %1.01f%%", air_temp, air_humid);
+        
+        
+        b.putT(air_temp); // air temp
         b.putP(1010.0); // air pressure
-        b.putRH(66.0); // air humidity
+        b.putRH(air_humid); // air humidity
         flag |= FlagTPH;
         
-        // TODO: read from light sensor
-        b.putLux(1234); // ambient light
+        wait_ms(100);
+        // read from light sensor
+        float lux = tsl.getLux();
+        logInfo("Ambient Light: %.4f", lux);
+        wait_ms(100);
+        b.putLux(lux*100); // ambient light
         flag |= FlagLux;
         
-        // TODO: read water temperature
-        b.putT(22.0); // water temperature
+        // read water temperature
+        wait_ms(100);
+        logInfo("Running temperature conversion...");
+        float water_temp = thermom.GetTemperature();
+        logInfo("Water Temperature: %.4fC", water_temp);         
+        wait_ms(100);
+        b.putT(water_temp); // water temperature
         flag |= FlagWater;
         
-        // TODO: read soil sensor
-        b.putT(25.2); // soil temperature
-        b.putRH(82.0); // soil humidity
+        // read soil sensor
+        wait_ms(100);
+        logInfo("sht.ready = %s", sht.ready?"true":"false");
+        sht.ready = true; // override error... 
+        sht.reset();
+        wait_ms(50);
+        bool sht_success = sht.update();
+        logInfo("Soil Sensor Status: %s", sht_success?"OK":"ERROR");
+        float soil_temp = (float)sht.getTemperature();  
+        float soil_humid = (float)(sht.humidity)/(float)35.0;
+        logInfo("sht->humid = %d",sht.humidity);
+        logInfo("Soil Temp: %1.01fC  Soil Humid: %1.01f%%", soil_temp, soil_humid);
+        b.putT(soil_temp); // soil temperature
+        b.putRH(soil_humid); // soil humidityupdate
+        
         flag |= FlagSoilTH;
         
         // write flag byte
@@ -468,6 +545,7 @@
             send_data.push_back( c );
         }
 
+        wait_ms(100);
         /* send packet */
         if ((ret = dot->send(send_data)) != mDot::MDOT_OK) {
             logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
@@ -478,7 +556,11 @@
         /* sleep */
         uint32_t sleep_time = MAX((dot->getNextTxMs() / 1000), 10 /* use 6000 for 10min */);
         logInfo("going to sleep for %d seconds", sleep_time);
-        wait_ms(10*1000);
+        
+        status_led.write(1);
+        wait_ms(1*1000);
+        status_led.write(0);
+        wait_ms(4*1000);
         
         seq++;
     }