Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-rtos by
Revision 124:e39e0bd6eec5, committed 2017-02-11
- Comitter:
- DanL
- Date:
- Sat Feb 11 17:38:44 2017 +0000
- Parent:
- 96:6d90423c236e
- Commit message:
- working code for analog temp sensor
Changed in this revision
| working_code_before_cleanup.txt | Show annotated file Show diff for this revision Revisions of this file |
diff -r 6d90423c236e -r e39e0bd6eec5 working_code_before_cleanup.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/working_code_before_cleanup.txt Sat Feb 11 17:38:44 2017 +0000
@@ -0,0 +1,630 @@
+/** mDot_TTN_DL1
+*
+ * Demo of use of an analog sensor
+ * Based on is a rough demo of mDot+DHT11 on The Things Network.
+ *
+ * As with the original, this code is not indended as a reference design.
+ * In particular, it lacks:
+ * (1) power management
+ * (2) reasonable transmission period
+ * (3) adaptive data rate
+ *
+ * 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
+ */
+
+//DL variation -- code compiles before DL work
+
+//DL addition
+#define RBUFFER_LEN 8 //number of stored readings
+#define INIT_BYTE 250; //first byte of payload
+#define PAYLOAD_LEN (RBUFFER_LEN + 2)
+//end addition
+
+
+#include "mbed.h"
+#include "mDot.h"
+#include "MTSLog.h"
+#include "MTSText.h"
+#include <string>
+#include <vector>
+
+using namespace mts;
+
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+
+/** ABP
+ * Register your device and update these values: --done dl-mdot-001
+ * https://account.thethingsnetwork.org/
+ */
+uint8_t AppSKey[16]= { 0x98, 0x29, 0xC2, 0xF2, 0xA9, 0x95, 0xD7, 0x6B, 0x3A, 0xDD, 0x66, 0xBB, 0x5C, 0x1C, 0x65, 0xFD };
+uint8_t NwkSKey[16]= { 0xCB, 0xDC, 0x14, 0xE0, 0x79, 0xF4, 0x83, 0x10, 0x09, 0x99, 0x2D, 0x87, 0xCF, 0x1D, 0x9A, 0xD9 };
+uint8_t NetworkAddr[4]= { 0x26, 0x02, 0x19, 0x70 };
+
+//DL additions to globals
+uint8_t readings[RBUFFER_LEN]; // storage for readings
+uint8_t head = 0; //next place to store a reading (better code possible)
+uint8_t payload[PAYLOAD_LEN]; // this will eventually be mydata[]
+//end of additions
+
+
+// Serial via USB for debugging only DL relocated here from just before main()
+Serial pc(USBTX,USBRX);
+
+//DL additions to functions
+
+AnalogIn pot_val(PB_1);
+
+char readTemp(void)
+{
+ unsigned short int reading;
+ reading = pot_val.read_u16(); // returns 0 - 0xFFFF in decimal 16 bit read
+ reading /= 69; // now in range 0 - 237
+ return reading;
+}
+
+void dataToBuffer (uint8_t newdata) {
+ uint8_t index;
+ readings[head] = newdata;
+
+ //data is now in readings buffer in order received
+ //insert data in payload current byte first
+ index = head;
+ for (uint8_t i = 0 ; i < RBUFFER_LEN ; i++) { // do once for each entry in readings
+ payload[i + 1] = readings[index]; //start insert with second byte
+ if (index == 0) index = RBUFFER_LEN ;
+ index--;
+ }
+ head++; //set up for next data byte
+ if (head > (RBUFFER_LEN - 1)) head = 0;
+ //insert battery condition byte here -- payload[PAYLOAD_LEN -1] = batt cond last byte
+ payload[PAYLOAD_LEN -1] = 100;
+ }
+
+
+
+float decodeTempC(uint8_t c4) { //input is celsius
+ float output;
+ float input = c4;
+ if (c4 <= 240) output = (float(input / 4) - 10); //temperature in range
+ if (c4 == 241) {
+ pc.printf("below range\n");
+ output = 255;
+ }
+ if (c4 == 242) {
+ pc.printf("above range\n");
+ output = 255;
+ }
+ if (c4 == 243) {
+ pc.printf("no sensor\n");
+ output = 255;
+ }
+ if (c4 == 244) {
+ pc.printf("bad CRC\n");
+ output = 255;
+ }
+ if (c4 >= 245) {
+ pc.printf("unknown code\n");
+ output = 255;
+ }
+ return output;
+}
+
+float decodeTempF(uint8_t c4) { //input is farenheight
+ float output;
+ float input = c4;
+ if (c4 <= 240) output = (((input / 4) - 10) * 1.8 + 32); //temperature in range
+ if (c4 == 241) {
+ pc.printf("below range\n");
+ output = 255;
+ }
+ if (c4 == 242) {
+ pc.printf("above range\n");
+ output = 255;
+ }
+ if (c4 == 243) {
+ pc.printf("no sensor\n");
+ output = 255;
+ }
+ if (c4 == 244) {
+ pc.printf("bad CRC\n");
+ output = 255;
+ }
+ if (c4 >= 245) {
+ pc.printf("unknown code\n");
+ output = 255;
+ }
+ return output;
+}
+
+//end of DL additions to functions
+
+
+// Some defines for the LoRa configuration
+#define LORA_SF mDot::SF_7
+#define LORA_ACK 0
+#define LORA_TXPOWER 20
+static uint8_t config_frequency_sub_band = 2;
+
+// functions for ensuring network endianness (little-endian)
+uint16_t hton16(const uint16_t x)
+{
+ uint16_t t = x;
+ uint8_t * a = (uint8_t*)&t;
+ a[0] = x>>(8*1);
+ a[1] = x>>(8*0);
+ return t;
+}
+void hton16(uint16_t * x)
+{
+ *x = hton16(*x);
+}
+
+
+/*
+// build a transmit buffer (from https://raw.githubusercontent.com/mcci-catena/Catena4410-Sketches/master/catena4410_sensor1/catena4410_sensor1.ino)
+class TxBuffer_t
+ {
+public:
+ uint8_t buf[32]; // this sets the largest buffer size
+ uint8_t *p;
+
+ TxBuffer_t() : p(buf) {};
+ void begin()
+ {
+ p = buf;
+ }
+ void put(uint8_t c)
+ {
+ if (p < buf + sizeof(buf))
+ *p++ = c;
+ }
+ void put1u(int32_t v)
+ {
+ if (v > 0xFF)
+ v = 0xFF;
+ else if (v < 0)
+ v = 0;
+ put((uint8_t) v);
+ }
+ void put2(uint32_t v)
+ {
+ if (v > 0xFFFF)
+ v = 0xFFFF;
+
+ put((uint8_t) (v >> 8));
+ put((uint8_t) v);
+ }
+ void put2(int32_t v)
+ {
+ if (v < -0x8000)
+ v = -0x8000;
+ else if (v > 0x7FFF)
+ v = 0x7FFF;
+
+ put2((uint32_t) v);
+ }
+ void put3(uint32_t v)
+ {
+ if (v > 0xFFFFFF)
+ v = 0xFFFFFF;
+
+ put((uint8_t) (v >> 16));
+ put((uint8_t) (v >> 8));
+ put((uint8_t) v);
+ }
+ void put2u(int32_t v)
+ {
+ if (v < 0)
+ v = 0;
+ else if (v > 0xFFFF)
+ v = 0xFFFF;
+ put2((uint32_t) v);
+ }
+ void put3(int32_t v)
+ {
+ if (v < -0x800000)
+ v = -0x800000;
+ else if (v > 0x7FFFFF)
+ v = 0x7FFFFF;
+ put3((uint32_t) v);
+ }
+ uint8_t *getp(void)
+ {
+ return p;
+ }
+ size_t getn(void)
+ {
+ return p - buf;
+ }
+ uint8_t *getbase(void)
+ {
+ return buf;
+ }
+ void put2sf(float v)
+ {
+ int32_t iv;
+
+ if (v > 32766.5f)
+ iv = 0x7fff;
+ else if (v < -32767.5f)
+ iv = -0x8000;
+ else
+ iv = (int32_t)(v + 0.5f);
+
+ put2(iv);
+ }
+ void put2uf(float v)
+ {
+ uint32_t iv;
+
+ if (v > 65535.5f)
+ iv = 0xffff;
+ else if (v < 0.5f)
+ iv = 0;
+ else
+ iv = (uint32_t)(v + 0.5f);
+
+ put2(iv);
+ }
+ void put1uf(float v)
+ {
+ uint8_t c;
+
+ if (v > 254.5)
+ c = 0xFF;
+ else if (v < 0.5)
+ c = 0;
+ else
+ c = (uint8_t) v;
+
+ put(c);
+ }
+ void putT(float T)
+ {
+ put2sf(T * 256.0f + 0.5f);
+ }
+ void putRH(float RH)
+ {
+ put1uf((RH / 0.390625f) + 0.5f);
+ }
+ void putV(float V)
+ {
+ put2sf(V * 4096.0f + 0.5f);
+ }
+ void putP(float P)
+ {
+ put2uf(P / 4.0f + 0.5f);
+ }
+ void putLux(float Lux)
+ {
+ put2uf(Lux);
+ }
+ }; */
+
+/* the magic byte at the front of the buffer */
+enum {
+ FormatSensor1 = 0x11,
+ };
+
+/* the flags for the second byte of the buffer */
+enum {
+ FlagVbat = 1 << 0,
+ FlagVcc = 1 << 1,
+ FlagTPH = 1 << 2,
+ FlagLux = 1 << 3,
+ FlagWater = 1 << 4,
+ FlagSoilTH = 1 << 5,
+ };
+
+
+// Temperature sensor object
+//#define DHT_PIN PB_1
+//DHT11 dht(DHT_PIN);
+
+
+int main()
+{
+ // TxBuffer_t b;
+
+ int32_t ret;
+ mDot* dot;
+ std::vector<uint8_t> send_data;
+ std::vector<uint8_t> recv_data;
+ std::vector<uint8_t> nwkSKey;
+ std::vector<uint8_t> appSKey;
+ std::vector<uint8_t> nodeAddr;
+ std::vector<uint8_t> networkAddr;
+
+ // float temperature = 0.0;
+ uint8_t currentTemp; //DP
+ payload[0] = INIT_BYTE; // DL set up initial byte
+
+ pc.baud(115200);
+ pc.printf("TTN mDot LoRa Temperature & Humidity Sensor\n\r");
+
+ // get a mDot handle
+ dot = mDot::getInstance();
+
+// dot->setLogLevel(MTSLog::WARNING_LEVEL);
+ dot->setLogLevel(MTSLog::TRACE_LEVEL);
+
+ logInfo("Checking Config");
+
+ // Test if we've already saved the config
+ std::string configNetworkName = dot->getNetworkName();
+
+ uint8_t *it = NwkSKey;
+ for (uint8_t i = 0; i<16; i++)
+ nwkSKey.push_back((uint8_t) *it++);
+
+ it = AppSKey;
+ for (uint8_t i = 0; i<16; i++)
+ appSKey.push_back((uint8_t) *it++);
+
+ it = NetworkAddr;
+ for (uint8_t i = 0; i<4; i++)
+ networkAddr.push_back((uint8_t) *it++);
+
+ logInfo("Resetting Config");
+ // reset to default config so we know what state we're in
+ dot->resetConfig();
+
+ // Set byte order - AEP less than 1.0.30
+// dot->setJoinByteOrder(mDot::LSB);
+ dot->setJoinByteOrder(mDot::MSB); // This is default for > 1.0.30 Conduit
+
+
+
+ logInfo("Set TxPower");
+ if((ret = dot->setTxPower( LORA_TXPOWER )) != mDot::MDOT_OK) {
+ logError("Failed to set Tx Power %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+ }
+
+ logInfo("Set Public mode");
+ if((ret = dot->setPublicNetwork(true)) != mDot::MDOT_OK) {
+ logError("failed to set Public Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+ }
+
+ logInfo("Set MANUAL Join mode");
+ if((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) {
+ logError("Failed to set MANUAL Join Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+ }
+
+ logInfo("Set Ack");
+ // 1 retries on Ack, 0 to disable
+ if((ret = dot->setAck( LORA_ACK)) != mDot::MDOT_OK) {
+ logError("Failed to set Ack %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+ }
+
+ //Not applicable for 868MHz in EU
+ if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
+ logError("failed to set frequency sub band", ret);
+ }
+
+ logInfo("Set Network Address");
+ if ((ret = dot->setNetworkAddress(networkAddr)) != mDot::MDOT_OK) {
+ logError("Failed to set Network Address %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+ }
+
+ logInfo("Set Data Session Key");
+ if ((ret = dot->setDataSessionKey(appSKey)) != mDot::MDOT_OK) {
+ logError("Failed to set Data Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+ }
+
+ logInfo("Set Network Session Key");
+ if ((ret = dot->setNetworkSessionKey(nwkSKey)) != mDot::MDOT_OK) {
+ logError("Failed to set Network Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+ }
+
+ logInfo("Saving Config");
+ // Save config
+ if (! dot->saveConfig()) {
+ logError("failed to save configuration");
+ }
+
+ // Display what is set
+ std::vector<uint8_t> tmp = dot->getNetworkSessionKey();
+ pc.printf("Network Session Key: ");
+ pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
+
+ tmp = dot->getDataSessionKey();
+ pc.printf("Data Session Key: ");
+ pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
+
+ pc.printf("Device ID ");
+ std::vector<uint8_t> deviceId;
+ deviceId = dot->getDeviceId();
+ for (std::vector<uint8_t>::iterator it = deviceId.begin() ; it != deviceId.end(); ++it)
+ pc.printf("%2.2x",*it );
+ pc.printf("\r\n");
+
+ std::vector<uint8_t> netAddress;
+
+ pc.printf("Network Address ");
+ netAddress = dot->getNetworkAddress();
+ for (std::vector<uint8_t>::iterator it = netAddress.begin() ; it != netAddress.end(); ++it)
+ pc.printf("%2.2x",*it );
+
+ pc.printf("\r\n");
+
+ // Display LoRa parameters
+ // Display label and values in different colours, show pretty values not numeric values where applicable
+ pc.printf("Public Network: %s\r\n", (char*)(dot->getPublicNetwork() ? "Yes" : "No") );
+ pc.printf("Frequency: %s\r\n", (char*)mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str() );
+ pc.printf("Sub Band: %s\r\n", (char*)mDot::FrequencySubBandStr(dot->getFrequencySubBand()).c_str() );
+ pc.printf("Join Mode: %s\r\n", (char*)mDot::JoinModeStr(dot->getJoinMode()).c_str() );
+ pc.printf("Join Retries: %d\r\n", dot->getJoinRetries() );
+ pc.printf("Join Byte Order: %s\r\n", (char*)(dot->getJoinByteOrder() == 0 ? "LSB" : "MSB") );
+ pc.printf("Link Check Count: %d\r\n", dot->getLinkCheckCount() );
+ pc.printf("Link Check Thold: %d\r\n", dot->getLinkCheckThreshold() );
+ pc.printf("Tx Data Rate: %s\r\n", (char*)mDot::DataRateStr(dot->getTxDataRate()).c_str() );
+ pc.printf("Tx Power: %d\r\n", dot->getTxPower() );
+ pc.printf("TxWait: %s, ", (dot->getTxWait() ? "Y" : "N" ));
+ pc.printf("CRC: %s, ", (dot->getCrc() ? "Y" : "N") );
+ 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");
+
+ // char dataBuf[50];
+ uint16_t seq = 0;
+ char * sf_str;
+ while( 1 ) {
+
+ /* cycle through spreading factors */
+ uint8_t sf;
+ switch (seq % 4) {
+ case 0:
+ sf = mDot::SF_7;
+ sf_str = "SF7";
+ break;
+ case 1:
+ sf = mDot::SF_8;
+ sf_str = "SF8";
+ break;
+ case 2:
+ sf = mDot::SF_9;
+ sf_str = "SF9";
+ break;
+ case 3:
+ sf = mDot::SF_10;
+ sf_str = "SF10";
+ break;
+ }
+ // Set Spreading Factor, higher is lower data rate, smaller packets but longer range
+ // Lower is higher data rate, larger packets and shorter range.
+ logInfo("Set SF: %s",sf_str);
+ if((ret = dot->setTxDataRate( sf )) != mDot::MDOT_OK) {
+ logError("Failed to set SF %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+ }
+
+ /* set default data values */
+ // 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;
+ b.put(FormatSensor1);
+ uint8_t * const pFlag = b.getp(); // save pointer to flag location
+ b.put(0x00); // placeholder for flags
+ */
+ /* // TODO: read battery voltage
+ b.putV(13.8);
+ flag |= FlagVbat;
+
+ // TODO: read from Bme280 sensor:
+ b.putT(27.0); // air temp
+ b.putP(1010.0); // air pressure
+ b.putRH(66.0); // air humidity
+ flag |= FlagTPH;
+
+ // TODO: read from light sensor
+ b.putLux(1234); // ambient light
+ flag |= FlagLux;
+
+ // TODO: read water temperature
+ b.putT(22.0); // water temperature
+ flag |= FlagWater;
+
+ // TODO: read soil sensor
+ b.putT(25.2); // soil temperature
+ b.putRH(82.0); // soil humidity
+ flag |= FlagSoilTH;
+
+ // write flag byte
+ *pFlag = flag;
+
+ */
+ //DL stuff added
+
+ //DL additions
+
+ currentTemp = readTemp();
+ pc.printf(" %.2f \n", decodeTempC(currentTemp)); //for debugging- returns degrees celsius as a float
+ pc.printf(" %.2f \n", decodeTempF(currentTemp)); //for debugging- returns degrees farenheight as a float
+ //put recent readings into a buffer with most recent data first
+ dataToBuffer (currentTemp); //adds data to buffer and payload
+
+ //print payload for debugging
+ pc.printf(" %d \n", currentTemp);
+ pc.printf("Payload ");
+ for (uint8_t i = 0 ; i < PAYLOAD_LEN ; i++){
+ pc.printf("%d ",payload[i]);
+ pc.printf(" ");
+ }
+ pc.printf("\n");
+//end of payload printout
+
+ //wait_ms(1500);
+
+ //end of DL adds
+
+
+ /* load vector */
+ /* send_data.clear();
+ / uint8_t c;
+ int n = b.getn();
+ for( int i=0; i< n; i++ ) {
+ c = b.buf[i];
+ send_data.push_back( c );
+ }*/
+
+
+ //DL Load Veector from HS Payload
+ send_data.clear();
+ uint8_t c;
+ for( int i=0; i< PAYLOAD_LEN ; i++ ) {
+ c = payload[i];
+ send_data.push_back( c );
+ }
+
+ /* send packet */
+ if ((ret = dot->send(send_data)) != mDot::MDOT_OK) {
+ logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
+ } else {
+ logInfo("data len: %d, send data: %s", PAYLOAD_LEN, Text::bin2hexString(send_data).c_str()); //PAYLOAD_LEN constant instead of b length variable
+ }
+
+ /* 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);
+
+ seq++;
+ }
+
+ return 0;
+}
