Demonstration connecting an xDot to Telit Devicewise using the libxDot-mbed5 library.
Dependencies: ISL29011 libxDot-mbed5
Revision 0:dd2c9d4723e7, committed 2017-08-01
- Comitter:
- pferland
- Date:
- Tue Aug 01 21:37:30 2017 +0000
- Commit message:
- Initial Commit
Changed in this revision
diff -r 000000000000 -r dd2c9d4723e7 ISL29011.lib --- /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
diff -r 000000000000 -r dd2c9d4723e7 libxDot-mbed5.lib --- /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
diff -r 000000000000 -r dd2c9d4723e7 main.cpp --- /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()); +}
diff -r 000000000000 -r dd2c9d4723e7 mbed-os.lib --- /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