Demo of DHT11->mDot->TTN
Dependencies: DHT22 DS18B20_1wire SHTx TSL2561_I2C libmDot mbed-rtos mbed
Fork of mDot_TTN_DHT11 by
Diff: main.cpp
- 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++; }