Demonstration connecting an xDot to Telit Devicewise using the libxDot-mbed5 library.

Dependencies:   ISL29011 libxDot-mbed5

Files at this revision

API Documentation at this revision

Comitter:
pferland
Date:
Tue Aug 01 21:37:30 2017 +0000
Commit message:
Initial Commit

Changed in this revision

ISL29011.lib Show annotated file Show diff for this revision Revisions of this file
libxDot-mbed5.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISL29011.lib	Tue Aug 01 21:37:30 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/Multi-Hackers/code/ISL29011/#c1d5f4999b9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libxDot-mbed5.lib	Tue Aug 01 21:37:30 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/MultiTech/code/libxDot-mbed5/#fc3817b65dca
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Aug 01 21:37:30 2017 +0000
@@ -0,0 +1,531 @@
+/*================================================================================
+ *
+ * CLASIFICATION:     **** PUBLIC RELEASE AS-IS APPLICATION EXAMPLE ****
+ *
+ * SOURCE FILE NAME:  main.cpp
+ *
+ * DESCRIPTIVE NAME:  MBED Source for MultiTech mDot, EVB, and MDOT-BOX Devices
+ *
+ * COPYRIGHT:         Copyright 2014-2017, Telit
+ *
+** WEB SITE:          www.telit.com
+ *
+ * WRITTEN BY:        John Keever
+ *
+ * DATE:              27 July, 2017
+ *
+ * VERSION:           1.00
+ *
+ * FUNCTION:          Provide working example for LoRa 'Sensor-to-Cloud'
+ *                    Demonstration using MultiTech LoRa Starter Kit and
+ *                    Telit Data and Cloud Platform Services Offerings
+ *
+ * SOURCE FILE TYPE:  MBED C++
+ *
+ * FUNCTIONS/ENTRY POINTS:  main
+ *
+ * INPUT  = None.
+ * OUTPUT = None.
+ *
+ * EXIT-NORMAL = N/A
+ * EXIT-ERROR  = N/A
+ *
+ * EXTERNAL REFERENCES = None.
+ *
+ * EXTERNAL FUNCTIONS = None.
+ *
+ * CONTROL BLOCKS = None.
+ *
+ *================================================================================*/
+/*                              LEGAL DISCLAIMER                                  */
+/*================================================================================
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    Neither the name of ILS Technology nor Telit nor the names of its
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ *================================================================================*/
+/*                                 CHANGE LOG                                     */
+/*================================================================================*/
+/*          |Changed |          |                                                 */
+/*  Date    |   by   |Version ID| Comments                                        */
+/*----------+--------+----------+-------------------------------------------------*/
+/*07-27-2017|JEK     |V1.00     |Original Version - xDot (Light Sensor, S2 Button)*/
+/*          |        |          |                                                 */
+/*================================================================================*/
+/*NOTE:  Please keep the change log up to date!!!                                 */
+/*================================================================================*/
+
+#include "mbed.h"
+#include "mDot.h"
+#include "rtos.h"
+#include "ChannelPlans.h"
+
+#include "ISL29011.h"
+
+#include <cmath>
+#include <string>
+#include <vector>
+#include <ctime>
+
+#ifndef CHANNEL_PLAN
+#define CHANNEL_PLAN CP_US915
+#endif
+
+static volatile bool timer_irq_triggered = false;
+static volatile bool ff_irq_triggered = false;
+
+//static std::string config_network_name = "MTCDT-19186797";
+//static std::string config_network_pass = "MTCDT-19186797";
+//static uint8_t config_frequency_sub_band = 1;
+
+static std::string config_network_name = "MTCDT-19186799";
+static std::string config_network_pass = "MTCDT-19186799";
+static uint8_t config_frequency_sub_band = 1;
+
+uint8_t result;
+uint8_t data;
+uint8_t sf_val = mDot::DR2;
+uint8_t pwr_val = 11; // dBm
+uint8_t swp_pwr;
+uint8_t swp_sf;
+
+int32_t mdot_ret;
+int32_t join_delay;
+
+osThreadId mainThreadID;
+
+// Physical I/O Instantiation
+DigitalOut led(LED1);
+DigitalIn s2(PA_0);
+
+I2C i2c(I2C_SDA, I2C_SCL);
+ISL29011 lux(i2c);
+// InterruptIn btn(PA_0); /* S2 - button */
+
+// flags for push button debounce code
+bool pb1_low = false;
+bool pb2_low = false;
+bool toggle_text = false;
+bool sw1_state = false;
+bool sw2_state = false;
+
+uint32_t num_whole;
+uint16_t num_frac;
+
+uint32_t pressure;
+double current;
+
+bool exit_program = false;
+
+mDot* mdot_radio;
+Mutex mdot_mutex;
+
+static Ticker ticker;
+
+void pb1ISR(void);
+void pb2ISR(void);
+void pb1_debounce(void const *args);
+void pb2_debounce(void const *args);
+
+//MPL3115A2* resetBaro(const MPL3115A2* oldBaro);
+void log_error(mDot* dot, const char* msg, int32_t retval);
+int32_t sendString(const std::string text);
+bool writeValueOrError();
+
+const int FAIL_MAX=15;
+int failtime=FAIL_MAX;
+int cycle_cnt = 0;
+
+char sensor_text[64];
+char lora_temp_string[16];
+char lora_alt_string[16];
+char lora_press_string[16];
+char lora_light_string[16];
+char lora_current_string[16];
+char lora_humid_string[16];
+
+bool bHasGPS = false;
+bool bHasACC = false;
+bool bHasLCD = false;
+
+//Helper Functions... Interrupt Handlers
+
+void rise() 
+{
+    printf("\r\nS2 Button Interrupt... RISE (on)\r\n");
+    //led.write(true);
+    led = 1;
+}
+
+void fall() 
+{
+    printf("\r\nS2 Button Interrupt... FALL (off)\r\n");
+    //led.write(false);
+    led = 0;
+}
+
+int xmitDataPayload( int, int, int );
+
+/*===================================================================================
+Main Program Logic - Entry
+===================================================================================*/
+int main()
+{
+    std::vector<uint8_t> mdot_data;
+    std::vector<uint8_t> mdot_EUI;
+    uint16_t i = 0;
+    
+    printf ("\r\nStarting xDot Demonstration Application...\r\n");
+
+    mainThreadID = osThreadGetId();
+
+    printf("Begin I2C/SPI Device Initialization...\r\n");
+
+    printf("Initializing Light Sensor...\r\n");
+
+    lux.setMode(ISL29011::ALS_CONT);
+    lux.setResolution(ISL29011::ADC_16BIT);
+    lux.setRange(ISL29011::RNG_64000);    
+
+    printf("I2C/SPI Device Initialization Complete...\r\n");
+
+    printf("Setup PushButton Interface Handlers...\r\n");
+
+    //btn.rise(&rise);
+    //btn.fall(&fall);
+
+    printf("S2 IRQs Set...\r\n");
+
+    printf("PushButton Interface Handlers Setup...\r\n");
+ 
+    printf("\r\nSetup xDot Radio Communications...\r\n");
+    
+    #if CHANNEL_PLAN == CP_AS923
+        lora::ChannelPlan* plan = new lora::ChannelPlan_AS923();
+    #elif CHANNEL_PLAN == CP_US915
+        lora::ChannelPlan* plan = new lora::ChannelPlan_US915();
+    #elif CHANNEL_PLAN == CP_AU915
+        lora::ChannelPlan* plan = new lora::ChannelPlan_AU915();
+    #elif CHANNEL_PLAN == CP_EU868
+        lora::ChannelPlan* plan = new lora::ChannelPlan_EU868();
+    #elif CHANNEL_PLAN == CP_KR920
+        lora::ChannelPlan* plan = new lora::ChannelPlan_KR920();
+    #elif CHANNEL_PLAN == CP_IN865
+        lora::ChannelPlan* plan = new lora::ChannelPlan_IN865();
+    #elif CHANNEL_PLAN == CP_AS923_JAPAN
+        lora::ChannelPlan* plan = new lora::ChannelPlan_AS923_Japan();
+    #endif
+
+    printf("xDot getInstance()...\r\n");
+
+    // get an xDot handle
+    mdot_radio = mDot::getInstance( plan ); 
+    
+    if (mdot_radio)
+    {
+        printf("xDot getInstance()... Successful!\r\n");  
+
+        // reset to default config so we know what state we're in
+        mdot_mutex.lock();  // lock mdot before setting configuration
+        mdot_radio->resetConfig();
+
+        // Setting up LED1 as activity LED
+        mdot_radio->setActivityLedPin(LED1);
+        mdot_radio->setActivityLedEnable(true);
+
+        // Read node ID
+        mdot_EUI = mdot_radio->getDeviceId();
+        printf("mDot EUI = ");
+
+        for(i=0; i<mdot_EUI.size(); i++) 
+        {
+            printf("%02x ", mdot_EUI[i]);
+        }
+        printf("\r\n");
+
+        // Setting up the mDot with network information.
+
+        // This call sets up private or public mode on the MTDOT. Set the function to true if
+        // connecting to a public network
+        printf("Setting Private Network Mode...\r\n");
+        if ((mdot_ret = mdot_radio->setPublicNetwork(false)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Public Network Mode", mdot_ret);
+        }
+
+        // Frequency sub-band is valid for NAM only and for Private networks should be set to a value
+        // between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only.
+        // This function can be commented out for EU networks
+        printf("Setting Frequency Sub-Band...\r\n");
+        if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Frequency Sub-Band", mdot_ret);
+        }
+
+        // Setting TX power for radio. Max allowed is +14dBm for EU and +20 dBm for NAM. Default is +11 dBm
+        printf("Setting TX Power Level to %2d dBm...\r\n", pwr_val);
+        if ((mdot_ret = mdot_radio->setTxPower(pwr_val)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set TX Power Level", mdot_ret);
+        }
+
+        // Turning ADR off for the purposes of demonstrating TX data rates
+        printf("Setting ADR to Off...\r\n");
+        if((mdot_ret = mdot_radio->setAdr(false)) != mDot::MDOT_OK){
+            log_error(mdot_radio, "ERROR: Failed to set ADR", mdot_ret);
+        }
+        
+        // Setting TX data rate for radio. Max allowed is SF_12 for EU and SF10 dBm for NAM. Default is SF_10
+        printf("Setting TX data rate to SF_7...\r\n");
+        if ((mdot_ret = mdot_radio->setTxDataRate(sf_val)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set TX Data Rate", mdot_ret);
+        }
+
+        // Setting Packet ACK to 1 try.
+        printf("Setting Packet Retry to 1...\r\n");
+        if ((mdot_ret = mdot_radio->setAck(1)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Packet Retry\r\n", mdot_ret);
+        }
+
+        // setNetworkName is used for private networks.
+        // Use setNetworkID(AppID) for public networks
+        // config_app_id.assign(app_id,app_id+7);
+
+        printf("Setting Network Name...\r\n");
+        if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) {
+        // if ((mdot_ret = mdot_radio->setNetworkID(config_app_id)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Network Name", mdot_ret);
+        }
+
+        // setNetworkPassphrase is used for private networks
+        // Use setNetworkKey for public networks
+        // config_app_key.assign(app_key,app_key+15);
+
+        printf("Setting Network Password...\r\n");
+        if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) {
+        // if ((mdot_ret = mdot_radio->setNetworkKey(config_app_key)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Network Password", mdot_ret);
+        }
+
+        mdot_mutex.unlock();        // unlock mdot mutex before join attempt so SW1 can work
+
+        // attempt to join the network
+        printf("Joining LoRa Network...\r\n");
+        do {
+            mdot_mutex.lock();      // lock mdot mutex before join attempt
+            mdot_ret = mdot_radio->joinNetwork();
+            mdot_mutex.unlock();        // unlock mdot mutex after join attempt so SW1 can work
+
+            if (mdot_ret != mDot::MDOT_OK)
+            {
+                log_error(mdot_radio,"ERROR: Failed to Join Network:", mdot_ret);
+
+                join_delay = 100;
+
+                printf("Join Delay = %lu\r\n",join_delay);
+                osDelay(join_delay + 1);
+                toggle_text = !toggle_text;
+            }
+
+            /*
+             * Setting TX power and Data Rate for radio just in case user requested by SW2
+             */
+            mdot_mutex.lock();      // lock mdot mutex before setting change
+            mdot_radio->setTxPower(pwr_val);
+            mdot_radio->setTxDataRate(sf_val);
+            mdot_mutex.unlock();        // unlock mdot mutex after settings change so SW1 can work
+
+        } while (mdot_ret != mDot::MDOT_OK);
+
+        printf("Successfully Joined LoRa Network...\r\n");
+    }
+    else
+    {
+        printf("ERROR:  Unable to Join LoRa Network...\r\n");
+        printf("getInstance... Radio Initialization Failed!\r\n");
+
+        exit(1);
+    }
+
+    printf("Initialization/Configuration Completed...\r\n");
+
+    osDelay(1500);
+
+    // Enter Main Data Acquisition Loop...
+    printf("Processing Data Acquisition Scan Loop...\r\n");
+
+    i = 0;
+    cycle_cnt = 100;
+
+    bool s2_last = 0;
+    int  lum_last = 0;
+    int  lum_delta = 0;
+
+    do
+    {
+            // Read Pushbutton #2 (S2) State...
+            if( s2 > 0 )
+            {
+                printf("S2 Pressed... State: %d\r\n", (int) s2);
+            }         
+
+            int delta = rand()%16;
+            int temperature = 20 + delta;
+            int luminosity = lux.getData();
+            int current = s2;
+
+            printf("Scan... Temperature: %d degC (delta=%d), Light: %d lux, Button: %d\r\n", temperature, delta, luminosity, current );
+
+            lum_delta = abs( luminosity - lum_last );
+
+            if( s2 != s2_last || lum_delta > 20 )
+            {
+                printf("Data Change Event...\r\n");
+
+                xmitDataPayload( temperature, luminosity, current );
+                
+                cycle_cnt = 0;
+            } 
+           
+            if( cycle_cnt > 30 )
+            {   
+                printf("Transmitting Data... \r\n");
+
+                sprintf(sensor_text, "t:%d,l:%d,c:%d",
+                    temperature,
+                    luminosity,
+                    current );
+
+                if((mdot_ret = sendString((const std::string)sensor_text)) != mDot::MDOT_OK) 
+                {
+                    log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret);
+                } 
+                else 
+                {
+                    printf("Ok, Successfully Sent Data to Gateway...\r\n");
+                }
+
+                /*
+                //---------------------------------------------------------------------------
+                // Binary Encoded Format:  Most Data Payload, Not Human Readible
+                //---------------------------------------------------------------------------
+                mdot_data.clear();
+                mdot_data.push_back(0x0E);              // key for Current Acceleration 3-Axis Value
+                converts.f_s = accel_data._x *4;        // shift data 2 bits while retaining sign
+                mdot_data.push_back(converts.t_u[1]);   // get 8 MSB of 14 bit value
+                converts.f_s = accel_data._y * 4;       // shift data 2 bits while retaining sign
+                mdot_data.push_back(converts.t_u[1]);   // get 8 MSB of 14 bit value
+                converts.f_s = accel_data._z * 4;       // shift data 2 bits while retaining sign
+                mdot_data.push_back(converts.t_u[1]);   // get 8 MSB of 14 bit value
+                mdot_data.push_back(0x08);              // key for Current Pressure Value
+                convertl.f_u = pressure;                // pressure data is 20 bits unsigned
+                mdot_data.push_back(convertl.t_u[2]);
+                mdot_data.push_back(convertl.t_u[1]);
+                mdot_data.push_back(convertl.t_u[0]);
+                mdot_data.push_back(0x05);              // key for Current Ambient Light Value
+                converts.f_u = lux_data;                // data is 16 bits unsigned
+                mdot_data.push_back(converts.t_u[1]);
+                mdot_data.push_back(converts.t_u[0]);
+                mdot_data.push_back(0x0B);              // key for Current Temperature Value
+                converts.f_s = baro_data._temp;         // temperature is signed 12 bit
+                mdot_data.push_back(converts.t_u[1]);
+                mdot_data.push_back(converts.t_u[0]);
+
+                if ((mdot_ret = mdot_radio->send(mdot_data)) != mDot::MDOT_OK) 
+                {
+                    log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret);
+                } 
+                else 
+                {
+                    printf("Ok, Successfully Sent Data to Gateway...\r\n");
+                }
+                */
+            
+                osDelay(500);
+
+                printf("Scanning...     \r\n");
+                cycle_cnt = 0;
+            }
+
+        s2_last = s2;
+        lum_last = luminosity;
+
+        osDelay(1000);
+        cycle_cnt++;
+                
+        // Put Thread to Sleep for 30 Seconds...
+        // osDelay(30000);
+
+    } while(i < 86400);
+
+    printf("End of Data Collection Cycle (24 Hours) - Ending Application, GoodBye...\r\n");
+}
+
+/*===================================================================================
+Send String Payload to Conduit Gateway
+===================================================================================*/
+int32_t sendString(const std::string text)
+{
+    int32_t ret;
+    if (mdot_radio->getNextTxMs() != 0)
+    {
+        printf("Sending in %lu ms...\r\n", mdot_radio->getNextTxMs());
+        return false;
+    }
+
+    printf("Sending: '%s'\r\n", text.c_str());
+    std::vector<uint8_t> data(text.begin(), text.end());
+    if ((ret = mdot_radio->send(data, 1)) != mDot::MDOT_OK)
+    {
+        log_error(mdot_radio, "ERROR: Failed to Send Data", ret);
+    }
+
+    led = 0;
+
+    return ret;
+}
+
+/*===================================================================================
+Transmit Data Payload to Cloud Platform
+===================================================================================*/
+int32_t xmitDataPayload( int temperature, int luminosity, int current )
+{
+    int32_t mdot_ret;
+
+    printf("Transmitting Data... \r\n");
+
+    sprintf(sensor_text, "t:%d,l:%d,c:%d", temperature, luminosity, current );
+
+    if((mdot_ret = sendString((const std::string)sensor_text)) != mDot::MDOT_OK) 
+    {
+        log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret);
+    } 
+    else 
+    {
+        printf("Ok, Successfully Sent Data to Gateway...\r\n");
+    }
+
+    return mdot_ret;
+}
+
+/*===================================================================================
+Print clear text verion of mDot/EVB errors
+===================================================================================*/
+void log_error(mDot* dot, const char* msg, int32_t retval)
+{
+    printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Tue Aug 01 21:37:30 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#fc1836545dcc2fc86f03b01292b62bf2089f67c3