diff --git a/README.md b/README.md index 4481e91..1ec1add 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@ -# Prototype with Orange using Live Objects and Arduino MKR Boards +# Quickly prototype IoT solutions with Orange using Live Objects and Arduino compatible boards -### Discover Orange [**Live Objects**](https://liveobjects.orange-business.com) using dedicated SDK for [**Arduino MKR family boards**](https://store.arduino.cc/arduino-genuino/arduino-genuino-mkr-family). +### Discover [**Live Objects**](https://liveobjects.orange-business.com), the IoT platform from Orange using this dedicated SDK for [**Arduino**](https://store.arduino.cc/arduino-genuino/arduino-genuino-mkr-family) and compatible boards. -This code wraps all the functions necessary to make your object work with Live Objects. +This dedicated SDK simplifies connecting your MKR board to the Live Objects platform. It manages LTE-M, GSM, and WiFi connections (depending on your board) and handle MQTT(S) and SMS communication behind the scenes. Easily define parameters you can update remotely and create commands to trigger actions on your device. -You can declare parameters, which you can later update OTA from Live objects. You can also create commands to trigger actions remotely. - -The code will manage the LTE-M, GSM and WiFi connection (depending on currently used board), as well MQTT(S) and SMS exchanges with Live objects under the hood to keep your parameters up to date or execute the commands received without you having to take care of them (apart from writing the code of these commands, of course). +Focus on your application logic – this library handles the communication with the Live Objects platform, keeping your parameters synchronized and executing received commands. ## Compatibility ## | Board | MQTT | MQTTS | SMS | @@ -36,7 +34,8 @@ This code needs external libraries to run, that you can install using the built- - [PubSubClient](https://pubsubclient.knolleary.net/) library provides a client for doing simple publish/subscribe messaging with a server that supports MQTT #### Library developed by Benoît Blanchon (mandatory for both Arduino, ESP and Adafruit boards) -- [ArduinoJson](https://arduinojson.org/), a powerful library used to parse, store and handle JSON easily +- [ArduinoJson](https://arduinojson.org/), a powerful library used to parse, store and handle JSON easily. +The default installation includes ArduinoJSON v6.21.5, optimized for the architectures supported by this SDK. While later versions of ArduinoJSON are compatible, they will consume more flash memory (see [here](https://arduinojson.org/news/2024/01/03/arduinojson-7/)). #### SAMD21 Arduino core - You also need to install the Arduino core for Atmel SAMD21 processor, used on the boards of the MKR family. Open the [Boards Manager](https://www.arduino.cc/en/guide/cores) and install the package called "Arduino SAMD Boards (32-bit ARM Cortex-M0+)". @@ -47,7 +46,7 @@ This code needs external libraries to run, that you can install using the built- 2. Create an [API key](https://liveobjects.orange-business.com/#/administration/apikeys) for your device. Give it a name, select the *Device access* role and validate. Copy the key. 3. Clone or download the directory from Github. 4. In the **'src/arduino_secrets.h'** file : - - Paste it as initialization value for the `SECRET_LIVEOBJECTS_API_KEY` variable in the 'arduino_secrets.h' file -keep the double quotes! + - Paste it as initialization value for the `SECRET_LIVEOBJECTS_API_KEY` variable in the 'arduino_secrets.h' file — keep the double quotes! - In case of feather 32u4 you have to change type of this variable to *char** from *String*. - Fill in the connection(WIFI or GSM) credentials if needed (pin code, APN information, etc). In case of GSM connection, most of the time, APN will set up automatically. Your SIM card may have a default pin code (like "0000"), unless you deactivated it using the [Pin management](https://github.com/arduino-libraries/MKRNB/blob/master/examples/Tools/PinManagement/PinManagement.ino) sketch, provided with the MKRNB library. diff --git a/keywords.txt b/keywords.txt index 5331e65..e3d4411 100644 --- a/keywords.txt +++ b/keywords.txt @@ -14,32 +14,33 @@ enableDebug KEYWORD2 setClientID KEYWORD2 setDecoder KEYWORD2 setModel KEYWORD2 -debugEnabled KEYWORD2 +debugEnabled KEYWORD2 addTimestamp KEYWORD2 addLocation KEYWORD2 addNetworkInfo KEYWORD2 +addTags KEYWORD2 addPowerStatus KEYWORD2 clearPayload KEYWORD2 publishMessage KEYWORD2 networkCheck KEYWORD2 addCommand KEYWORD2 -addParameter KEYWORD2 -addToPayload KEYWORD2 -addObjectToPayload KEYWORD2 -connect KEYWORD2 +addParameter KEYWORD2 +addToPayload KEYWORD2 +addObjectToPayload KEYWORD2 +connect KEYWORD2 disconnect KEYWORD2 sendData KEYWORD2 -loop KEYWORD2 -begin KEYWORD2 -changeConfiguration KEYWORD2 +loop KEYWORD2 +begin KEYWORD2 +changeConfiguration KEYWORD2 ###################################### # Constants (LITERAL1) ###################################### -NONE LITERAL1 -TLS LITERAL1 -SMS LITERAL1 -MQTT LITERAL1 -BINARY LITERAL1 -TEXT LITERAL1 \ No newline at end of file +NONE LITERAL1 +TLS LITERAL1 +SMS LITERAL1 +MQTT LITERAL1 +BINARY LITERAL1 +TEXT LITERAL1 \ No newline at end of file diff --git a/library.properties b/library.properties index d6dc2e1..a603852 100644 --- a/library.properties +++ b/library.properties @@ -1,11 +1,11 @@ name=LiveObjectsSDK -version=2.1.1 +version=2.1.2 author=Orange maintainer=Marc Delain , Krzysztof Krzeslak , Tomasz Malek -sentence=A library that makes connection with Orange LiveObjects platform a breeze. -paragraph=Supports connection with LiveObjects platform in device mode, with the use of LTE, GSM or WifI connectivity. +sentence=A library that simplifies the integration of Arduino boards with Live Objects, the IoT platform from Orange. +paragraph=Upgrade your Arduino projects to IoT with this library, which allows you to easily connect your board to the Live Objects platform: send data, remotely modify execution parameters, or send commands to interact with your board. category=Communication url=https://github.com/DatavenueLiveObjects/LiveObjects_SDK_for_Arduino architectures=* includes=LiveObjects.h -depends=WiFiNINA,MKRNB,ArduinoJson,MKRGSM,WiFi101,PubSubClient,ArduinoMqttClient,SparkFun VL6180 Sensor +depends=WiFiNINA,MKRNB,ArduinoJson(=6.21.5),MKRGSM,WiFi101,PubSubClient,ArduinoMqttClient,SparkFun VL6180 Sensor diff --git a/src/LiveObjectsBase.cpp b/src/LiveObjectsBase.cpp index 874c9df..11f15b1 100644 --- a/src/LiveObjectsBase.cpp +++ b/src/LiveObjectsBase.cpp @@ -11,7 +11,7 @@ LiveObjectsBase::LiveObjectsBase() lastKeepAliveNetwork(5000) ,m_sPayload() ,m_sDecoder() - ,m_sModel("Orange") + ,m_sModel(F(SW_MODEL)) ,m_Security(NONE) ,m_bDebug(false) ,m_bInitialized(false) @@ -31,12 +31,12 @@ void LiveObjectsBase::paramTyper(const String& name, bool* variable, LiveObjects else addTypedParam(name, variable, type, T_BOOL, callback); } -void LiveObjectsBase::paramTyper(const String& name, char* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback) { +/*void LiveObjectsBase::paramTyper(const String& name, char* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback) { if (type == IMPLICIT) addTypedParam(name, variable, INTEGER, T_CHAR, callback); else addTypedParam(name, variable, type, T_CHAR, callback); -} +}*/ #if not defined ESP8266 && not defined ESP32 && not defined ARDUINO_AVR_FEATHER32U4 void LiveObjectsBase::paramTyper(const String& name, int* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback) { if (type == IMPLICIT) @@ -111,9 +111,9 @@ void LiveObjectsBase::ptrTyper(const LiveObjects_parameter param, const JsonDocu case T_BOOL: updateParameter(param, (bool*)param.value, configIn, configOut); break; - case T_CHAR: +/* case T_CHAR: updateParameter(param, (char*)param.value, configIn, configOut); - break; + break;*/ #ifndef ESP8266 case T_INT: updateParameter(param, (int*)param.value, configIn, configOut); @@ -301,7 +301,7 @@ void LiveObjectsBase::sendData(const String customPayload) { { StaticJsonDocument payload; deserializeJson(payload, customPayload); - if (!payload.containsKey(JSONMODEL)) payload[JSONMODEL] = m_sModel; + if (!payload[JSONMODEL].is()) payload[JSONMODEL] = m_sModel; publishMessage(m_sTopic, payload); } else publishMessage(m_sTopic, const_cast(customPayload)); @@ -425,6 +425,13 @@ void LiveObjectsBase::addLocation(double lat, double lon, double alt) else addToStringPayload(lat,lon,alt); } +void LiveObjectsBase::addTag(const char* tag) +{ + if (!easyDataPayload[JSONTAGS].is()) + tags = easyDataPayload.createNestedArray(JSONTAGS); + tags.add(tag); +} + void LiveObjectsBase::clearPayload() { easyDataPayload.clear(); diff --git a/src/LiveObjectsBase.h b/src/LiveObjectsBase.h index 6619ea4..394598f 100644 --- a/src/LiveObjectsBase.h +++ b/src/LiveObjectsBase.h @@ -12,8 +12,8 @@ ******************************************************************************/ #define PAYLOAD_DATA_SIZE 1024 #define KEEP_ALIVE_NETWORK 1000 -#define SW_REVISION "2.1.1" - +#define SW_MODEL "LO_SDK_Arduino" +#define SW_REVISION "2.1.2" /****************************************************************************** LiveObjects MQTT constants @@ -24,7 +24,7 @@ #else #define MQTT_BROKER "liveobjects.orange-business.com" #endif -#define SDK_PREFIX "urn:lo:nsid:Arduino:" +#define SDK_PREFIX SW_MODEL ":" #define MQTT_USER "json+device" #define MQTT_PUBDATA "dev/data" #define MQTT_PUBDATA_BINARY "dev/v1/data/binary" @@ -42,6 +42,8 @@ #define JSONCFGTYPE "t" #define JSONMODEL "model" #define JSONVALUE "value" +#define JSONTAGS "tags" + /****************************************************************************** INCLUDES ******************************************************************************/ @@ -176,6 +178,7 @@ class LiveObjectsBase public: void addTimestamp(time_t timestamp); void addLocation(double lat, double lon, double alt); + void addTag(const char* tag); virtual void addPowerStatus()=0; virtual void addNetworkInfo()=0; void clearPayload(); @@ -215,7 +218,6 @@ class LiveObjectsBase virtual void sendMQTT(String& topic, String& doc)=0; virtual void deserializeMessage(JsonDocument& doc)=0; - protected: /****************************************************************************** CONFIGURATION MANAGER @@ -260,6 +262,8 @@ class LiveObjectsBase LinkedList parameters; LiveObjects_networkStatus networkStatus = DISCONNECTED; StaticJsonDocument easyDataPayload; + JsonArray tags; + /****************************************************************************** VARIABLES ******************************************************************************/ @@ -285,12 +289,12 @@ class LiveObjectsBase PARAM TYPERS ******************************************************************************/ void paramTyper(const String& name, bool* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); - void paramTyper(const String& name, char* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); + // void paramTyper(const String& name, char* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); #if not defined ESP8266 && not defined ESP32 && not defined ARDUINO_AVR_FEATHER32U4 void paramTyper(const String& name, int* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); void paramTyper(const String& name, unsigned int* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); #endif - void paramTyper(const String& name, int8_t*variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); + void paramTyper(const String& name, int8_t* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); void paramTyper(const String& name, int32_t* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); void paramTyper(const String& name, int16_t* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); void paramTyper(const String& name, uint8_t* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback); diff --git a/src/LiveObjectsCellular.cpp b/src/LiveObjectsCellular.cpp index 18cd490..5cb9e52 100644 --- a/src/LiveObjectsCellular.cpp +++ b/src/LiveObjectsCellular.cpp @@ -102,7 +102,7 @@ void LiveObjectsCellular::connectNetwork() #endif if(modem.begin()) { - String imei=""; + String imei="imei:"; for(int i=1;i<=3;i++) { imei=modem.getIMEI(); diff --git a/src/LiveObjectsWiFi.cpp b/src/LiveObjectsWiFi.cpp index 3641037..dce7015 100644 --- a/src/LiveObjectsWiFi.cpp +++ b/src/LiveObjectsWiFi.cpp @@ -53,7 +53,7 @@ void LiveObjectsWiFi::begin(Protocol p, Encoding s, bool bDebug) void LiveObjectsWiFi::connectNetwork() { #ifdef ADAFRUIT_FEATHER_M0 - WiFi.setPins(8,7,4,2); + WiFi.setPins(8,7,4,2); #endif if(!m_bInitialized) { @@ -81,7 +81,7 @@ void LiveObjectsWiFi::connectNetwork() outputDebug(TXT,"."); delay(1000); } - outputDebug(); + outputDebug(); IPAddress ip = WiFi.localIP(); for(int i=0;i<4;++i) { @@ -89,7 +89,9 @@ void LiveObjectsWiFi::connectNetwork() if(i!=3) m_sIP+='.'; } - uint8_t mac[6]; + m_sMqttid+= "mac:"; + + uint8_t mac[6]; char buff[10]; WiFi.macAddress(mac); @@ -107,37 +109,35 @@ void LiveObjectsWiFi::connectNetwork() m_sMac += (char)toupper(buff[j]); m_sMqttid += (char)toupper(buff[j]); } - if(i!=0) m_sMac += ':'; + if(i!=0) m_sMac += ':'; } - m_sModel = m_sMqttid; } + void LiveObjectsWiFi::checkNetwork() { if(WiFi.status()== WL_DISCONNECTED) connectNetwork(); } + void LiveObjectsWiFi::disconnectNetwork() { outputDebug(INFO,"Disconnecting WiFi"); WiFi.disconnect(); } + void LiveObjectsWiFi::messageCallback(int msg) { LiveObjects::get().onMQTTmessage(msg); } - - - - - - void LiveObjectsWiFi::addNetworkInfo() { String tmp; - tmp = WiFi.RSSI(); + tmp = String(WiFi.RSSI()); tmp += " dbm"; - if(m_Protocol == MQTT && m_Encoding==TEXT) addToPayload(easyDataPayload[JSONVALUE].createNestedObject("networkInfo"),"mac",m_sMac,"ssid",SECRET_SSID,"ip",m_sIP,"strength",tmp); - else addToPayload(m_sMac,SECRET_SSID,m_sIP,tmp); + if(m_Protocol == MQTT && m_Encoding==TEXT) + addToPayload(easyDataPayload[JSONVALUE].createNestedObject("networkInfo"),"mac",m_sMac,"ssid",SECRET_SSID,"ip",m_sIP,"rssi",tmp); + else + addToPayload(m_sMac,SECRET_SSID,m_sIP,tmp); } #endif \ No newline at end of file diff --git a/src/examples/1_send_data/1_send_data.ino b/src/examples/1_send_data/1_send_data.ino new file mode 100644 index 0000000..8bd97cd --- /dev/null +++ b/src/examples/1_send_data/1_send_data.ino @@ -0,0 +1,38 @@ +/****************************************************************************** + INCLUDES + ******************************************************************************/ +#include "arduino_secrets.h" +#include +/****************************************************************************** + USER VARIABLES + ******************************************************************************/ +uint32_t messageRate = 15000; // stores the current data message rate in Milliseconds +unsigned long uptime; // stores the device uptime (sent as fake sensor data) +unsigned long lastMessageTime = 0; // stores the time when last data message was sent + +/****************************************************************************** + USER PROGRAM + ******************************************************************************/ +void setup() { + delay(2000); + Serial.begin(9600); + Serial.print("\n*** Live Objects SDK for Arduino, revision "); + Serial.print(SW_REVISION); + Serial.println(" ***\n"); + lo.setSecurity(TLS); + lo.begin(MQTT, TEXT, true); + lo.connect(); // connects to the network + Live Objects +} + +void loop() { + if (millis() - lastMessageTime > messageRate) { + // collect data periodically + Serial.println("Sampling data"); + uptime = millis(); + lo.addToPayload("uptime", uptime); // adding 'uptime' value to the current payload + Serial.println("Sending data to Live Objects"); + lo.sendData(); // send the data to Live Objects + lastMessageTime = millis(); + } + lo.loop(); // don't forget to keep this in your main loop +} diff --git a/src/examples/1_send_data/README.md b/src/examples/1_send_data/README.md new file mode 100644 index 0000000..43c9266 --- /dev/null +++ b/src/examples/1_send_data/README.md @@ -0,0 +1,23 @@ +# Send data to Live Objects + +This example shows how to send some sample data (device uptime) to Live Objects using Arduino MKR NB 1500. +![diagram](img/send_data_diagram.png) + +## Running +First of all, be sure that you installed the required libraries and generated an API key mentioned in the main README file, then: +1. Open "1_send_data.ino" sketch using Arduino IDE +2. Replace ```const char SECRET_LIVEOBJECTS_API_KEY[]="";``` in arduino_secrets.h with API key you generated +3. In ```lo.setSecurity()``` select security mode using ```TLS``` or ```NONE``` according to board abilities shown in **Compatibility** point in main **README.md** +4. Upload *1_send_data.ino* sketch to your Arduino MKR NB 1500 board + + +## Verify +**Is device online:**
+If all went fine under **devices** tab on Live Live Objects portal you should see online your device identified by its modem IMEI: + +![device_online](img/device_online.png) + +**Is device sending data:**
+Under data tab on Live Objects portal you should see messages sent by your device, along with values *{ "uptime": xxxxx }* + +![data_portal](img/data_portal.png) diff --git a/src/examples/1_send_data/arduino_secrets.h b/src/examples/1_send_data/arduino_secrets.h new file mode 100644 index 0000000..b846511 --- /dev/null +++ b/src/examples/1_send_data/arduino_secrets.h @@ -0,0 +1,16 @@ + // Cellular connection cerdentials, used only for GSM boards +extern const String SECRET_PINNUMBER = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_APN = ""; // specify the APN name (if needed) +extern const String SECRET_APN_USER = ""; // specify the username for your APN (if needed) +extern const String SECRET_APN_PASS = ""; // specify the password for your APN (if needed) +extern const String SECRET_SERVER_MSISDN = ""; // specify the number of server(gate) + +// WIFI connection credentials, used only for WiFi boards +extern const String SECRET_SSID = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_WIFI_PASS = ""; // specify the APN name (if needed) + + // Live Objects credential: paste below your API key (see Configuration > API keys on the portal). + // You API key must have at least the predefined 'MQTT Device' rights profile + // (alternatively: 'Device Access' read + write rights if need to customise the rights). + // Please note that you *must* use a TLS connection (MQTTS) if you grant more rights to the API key. +extern const String SECRET_LIVEOBJECTS_API_KEY = ""; diff --git a/src/examples/1_send_data/img/data_portal.png b/src/examples/1_send_data/img/data_portal.png new file mode 100644 index 0000000..490c8dd Binary files /dev/null and b/src/examples/1_send_data/img/data_portal.png differ diff --git a/src/examples/1_send_data/img/device_online.png b/src/examples/1_send_data/img/device_online.png new file mode 100644 index 0000000..e44e6ce Binary files /dev/null and b/src/examples/1_send_data/img/device_online.png differ diff --git a/src/examples/1_send_data/img/send_data_diagram.png b/src/examples/1_send_data/img/send_data_diagram.png new file mode 100644 index 0000000..418e6d6 Binary files /dev/null and b/src/examples/1_send_data/img/send_data_diagram.png differ diff --git a/src/examples/2_simple_parameters/2_simple_parameters.ino b/src/examples/2_simple_parameters/2_simple_parameters.ino new file mode 100644 index 0000000..a52f04a --- /dev/null +++ b/src/examples/2_simple_parameters/2_simple_parameters.ino @@ -0,0 +1,50 @@ + +/****************************************************************************** + INCLUDES + ******************************************************************************/ +#include "arduino_secrets.h" +#include + +/****************************************************************************** + USER VARIABLES + ******************************************************************************/ + +uint32_t messageRate = 60000; // stores the current data message rate in Milliseconds +unsigned long uptime; // stores the device uptime (sent as fake sensor data) +unsigned long lastMessageTime = 0; // stores the time when last data message was sent + + +/****************************************************************************** + USER PROGRAM + ******************************************************************************/ + +void setup() { + delay(2000); + Serial.begin(9600); + Serial.print("\n*** Live Objects SDK for Arduino, revision "); + Serial.print(SW_REVISION); + Serial.println(" ***\n"); + + // Declaring a simple parameter stored in the variable 'messageRate'. + // This parameter will become available for modification over the air from Live Objects + // upon the first connection: go to Devices > your device > Parameters + // Note that parameters are reset upon restart. + lo.addParameter("message rate (milliseconds)", messageRate); + lo.setSecurity(TLS); + lo.begin(MQTT, TEXT, true); + lo.connect(); // connects to the network + Live Objects +} + +void loop() { + if (millis() - lastMessageTime > messageRate) { + // collect data periodically + Serial.println("Sampling data"); + uptime = millis(); + lo.addToPayload("uptime", uptime); // adding 'uptime' value to the current payload + Serial.println("Sending data to Live Objects"); + lo.sendData(); // send the data to Live Objects + lastMessageTime = millis(); + } + + lo.loop(); // don't forget to keep this in your main loop +} diff --git a/src/examples/2_simple_parameters/README.md b/src/examples/2_simple_parameters/README.md new file mode 100644 index 0000000..91c3df5 --- /dev/null +++ b/src/examples/2_simple_parameters/README.md @@ -0,0 +1,27 @@ +# Live Objects parameters + +Parameters give you ability to configure your device over the air from Live Objects. In this example we will use a parameter to adjust time rate on which messages from device are sent. + +![diagram](img/parameter_diagram.png) + +## Running +First of all, be sure that you installed the required libraries and generated an API key mentioned in the main README file, then: +1. Open "2_simple_parameters.ino" sketch using Arduino IDE +2. Replace ```const char SECRET_LIVEOBJECTS_API_KEY[]="";``` in arduino_secrets.h with API key you generated +3. In ```lo.setSecurity()``` select security mode using ```TLS``` or ```NONE``` according to board abilities shown in **Compatibility** point in main **README.md** +4. Upload *2_simple_parameters.ino* sketch to your Arduino MKR NB 1500 board + + +## Verify +**Is device online:**
+If all went fine under **devices** tab on Live Live Objects portal you should see online your device identified by its modem IMEI: + +**Is device sending data:**
+Under data tab on Live Objects portal you should see messages sent by your device, along with values *{ "uptime": xxxxx }* + +## Update parameter +Now you can adjust the rate on which messages are sent from Live Objects (default is 60000ms). To do this navigate to:
+**Devices->urn:lo:nsid:mqtt:[your_device_imei]->Parameters**
+You should see a parameter named "message rate (miliseconds)" there. Feel free to modify the parameter: click on the parameter's name, modify the value and hit **Update**. Don't forget to click on the **Send changes** button to send the new value to your device. + +![parameter](img/parameter.png) diff --git a/src/examples/2_simple_parameters/arduino_secrets.h b/src/examples/2_simple_parameters/arduino_secrets.h new file mode 100644 index 0000000..b846511 --- /dev/null +++ b/src/examples/2_simple_parameters/arduino_secrets.h @@ -0,0 +1,16 @@ + // Cellular connection cerdentials, used only for GSM boards +extern const String SECRET_PINNUMBER = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_APN = ""; // specify the APN name (if needed) +extern const String SECRET_APN_USER = ""; // specify the username for your APN (if needed) +extern const String SECRET_APN_PASS = ""; // specify the password for your APN (if needed) +extern const String SECRET_SERVER_MSISDN = ""; // specify the number of server(gate) + +// WIFI connection credentials, used only for WiFi boards +extern const String SECRET_SSID = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_WIFI_PASS = ""; // specify the APN name (if needed) + + // Live Objects credential: paste below your API key (see Configuration > API keys on the portal). + // You API key must have at least the predefined 'MQTT Device' rights profile + // (alternatively: 'Device Access' read + write rights if need to customise the rights). + // Please note that you *must* use a TLS connection (MQTTS) if you grant more rights to the API key. +extern const String SECRET_LIVEOBJECTS_API_KEY = ""; diff --git a/src/examples/2_simple_parameters/img/parameter.png b/src/examples/2_simple_parameters/img/parameter.png new file mode 100644 index 0000000..6ede46d Binary files /dev/null and b/src/examples/2_simple_parameters/img/parameter.png differ diff --git a/src/examples/2_simple_parameters/img/parameter_diagram.png b/src/examples/2_simple_parameters/img/parameter_diagram.png new file mode 100644 index 0000000..db49f6a Binary files /dev/null and b/src/examples/2_simple_parameters/img/parameter_diagram.png differ diff --git a/src/examples/3_Parameter_with_callback/3_Parameter_with_callback.ino b/src/examples/3_Parameter_with_callback/3_Parameter_with_callback.ino new file mode 100644 index 0000000..fffdcb8 --- /dev/null +++ b/src/examples/3_Parameter_with_callback/3_Parameter_with_callback.ino @@ -0,0 +1,59 @@ +/****************************************************************************** + INCLUDES + ******************************************************************************/ +#include "arduino_secrets.h" +#include + +/****************************************************************************** + USER VARIABLES + ******************************************************************************/ + +uint32_t messageRate = 60; // stores the current data message rate in Seconds +uint32_t messageRateInMs = messageRate * 1000; // stores the current data message rate in Milliseconds +unsigned long uptime; // stores the device uptime (sent as fake sensor data) +unsigned long lastMessageTime = 0; // stores the time when last data message was sent + + +/****************************************************************************** + USER PROGRAM + ******************************************************************************/ + + // an example of simple parameter callback function: + // this function is called after the messageRate parameter has been updated over the air + // and transforms the message rate from Seconds to Milliseconds, which is the native time measurement on Arduino +void processMsgRate() { + messageRateInMs = messageRate * 1000; +} + + +void setup() { + delay(2000); + Serial.begin(9600); + Serial.print("\n*** Live Objects SDK for Arduino, revision "); + Serial.print(SW_REVISION); + Serial.println(" ***\n"); + + // Declaring a parameter with a callback function 'processMsgRate'. + // This function will be called after the update of the variable 'messageRate'. + // This parameter will become available for modification over the air from Live Objects + // upon the first connection: go to Devices > your device > Parameters + // Note that parameters are reset upon restart. + lo.addParameter("message rate (seconds)", messageRate, processMsgRate); // connects to the network + Live Objects + lo.setSecurity(TLS); + lo.begin(MQTT, TEXT, true); + lo.connect(); +} + +void loop() { + if (millis() - lastMessageTime > messageRateInMs) { + // collect data periodically + Serial.println("Sampling data"); + uptime = millis(); + lo.addToPayload("uptime", uptime); // adding 'uptime' value to the current payload + Serial.println("Sending data to Live Objects"); + lo.sendData(); // send the data to Live Objects + lastMessageTime = millis(); + } + + lo.loop(); // don't forget to keep this in your main loop +} diff --git a/src/examples/3_Parameter_with_callback/README.md b/src/examples/3_Parameter_with_callback/README.md new file mode 100644 index 0000000..6788a44 --- /dev/null +++ b/src/examples/3_Parameter_with_callback/README.md @@ -0,0 +1,35 @@ +# Live Objects parameters with callbacks + +Parameters give you ability to configure your device over the air from Live Objects. In this example we will use a parameter to adjust time rate on which messages from device are sent.
+ +![diagram](img/parameter_diagram.png) + +Additionally in this example we will use a "callback" function which will convert the rate value received as parameter (in seconds) to Arduino-native milliseconds. + +This is how callback function will look like:
+``void processMsgRate() { + messageRateInMs = messageRate * 1000; +}`` + + +## Running +First of all, be sure that you installed the required libraries and generated an API key mentioned in the main README file, then: +1. Open "3_parameter_with_callback.ino" sketch using Arduino IDE +2. Replace ```const char SECRET_LIVEOBJECTS_API_KEY[]="";``` in arduino_secrets.h with API key you generated +3. In ```lo.setSecurity()``` select security mode using ```TLS``` or ```NONE``` according to board abilities shown in **Compatibility** point in main **README.md** +4. Upload *3_parameter_with_callback.ino* sketch to your Arduino MKR NB 1500 board + + +## Verify +**Is device online:**
+If all went fine under **devices** tab on Live Live Objects portal you should see online your device identified by its modem IMEI + +**Is device sending data:**
+Under data tab on Live Objects portal you should see messages sent by your device, along with values *{ "uptime": xxxxx }* + +## Send parameter +Now you can adjust the rate on which messages are sent from Live Objects (default is 60s). To do this navigate to:
+**Devices->urn:lo:nsid:mqtt:[your_device_imei]->Parameters**
+You should see a parameter named "message rate (seconds)" there. Feel free to modify the parameter: click on the parameter's name, modify the value and hit **Update**. Don't forget to click on the **Send changes** button to send the new value to your device. + +![diagram](img/parameter_seconds.png) diff --git a/src/examples/3_Parameter_with_callback/arduino_secrets.h b/src/examples/3_Parameter_with_callback/arduino_secrets.h new file mode 100644 index 0000000..b846511 --- /dev/null +++ b/src/examples/3_Parameter_with_callback/arduino_secrets.h @@ -0,0 +1,16 @@ + // Cellular connection cerdentials, used only for GSM boards +extern const String SECRET_PINNUMBER = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_APN = ""; // specify the APN name (if needed) +extern const String SECRET_APN_USER = ""; // specify the username for your APN (if needed) +extern const String SECRET_APN_PASS = ""; // specify the password for your APN (if needed) +extern const String SECRET_SERVER_MSISDN = ""; // specify the number of server(gate) + +// WIFI connection credentials, used only for WiFi boards +extern const String SECRET_SSID = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_WIFI_PASS = ""; // specify the APN name (if needed) + + // Live Objects credential: paste below your API key (see Configuration > API keys on the portal). + // You API key must have at least the predefined 'MQTT Device' rights profile + // (alternatively: 'Device Access' read + write rights if need to customise the rights). + // Please note that you *must* use a TLS connection (MQTTS) if you grant more rights to the API key. +extern const String SECRET_LIVEOBJECTS_API_KEY = ""; diff --git a/src/examples/3_Parameter_with_callback/img/parameter_diagram.png b/src/examples/3_Parameter_with_callback/img/parameter_diagram.png new file mode 100644 index 0000000..db49f6a Binary files /dev/null and b/src/examples/3_Parameter_with_callback/img/parameter_diagram.png differ diff --git a/src/examples/3_Parameter_with_callback/img/parameter_seconds.png b/src/examples/3_Parameter_with_callback/img/parameter_seconds.png new file mode 100644 index 0000000..c33eaa1 Binary files /dev/null and b/src/examples/3_Parameter_with_callback/img/parameter_seconds.png differ diff --git a/src/examples/4_Simple_command/4_Simple_command.ino b/src/examples/4_Simple_command/4_Simple_command.ino new file mode 100644 index 0000000..7e2f194 --- /dev/null +++ b/src/examples/4_Simple_command/4_Simple_command.ino @@ -0,0 +1,60 @@ +/****************************************************************************** + INCLUDES + ******************************************************************************/ +#include "arduino_secrets.h" +#include + +/****************************************************************************** + USER VARIABLES + ******************************************************************************/ + +uint32_t messageRate = 60000; // stores the current data message rate in Milliseconds +unsigned long uptime; // stores the device uptime (sent as fake sensor data) +unsigned long lastMessageTime = 0; // stores the time when last data message was sent + + +/****************************************************************************** + USER PROGRAM + ******************************************************************************/ + + // An example of a simple command callback function +void blinkLED5times(const String arguments, String &response) { + pinMode(LED_BUILTIN, OUTPUT); + for (byte i = 0; i < 5; i++) { + digitalWrite(LED_BUILTIN, LOW); + delay(250); + digitalWrite(LED_BUILTIN, HIGH); + delay(250); + } + response = "{\"blinked\":\"5 times\"}"; +} + + +void setup() { + delay(2000); + Serial.begin(9600); + Serial.print("\n*** Live Objects SDK for Arduino, revision "); + Serial.print(SW_REVISION); + Serial.println(" ***\n"); + + // Declaring a simple commands hadled by the function 'blinkLED5times'. + lo.addCommand("blink", blinkLED5times); + lo.setSecurity(TLS); + lo.begin(MQTT, TEXT, true); + lo.connect(); // connects to the network + Live Objects +} + +void loop() { + if (millis() - lastMessageTime > messageRate) { + // collect data periodically + Serial.println("Sampling data"); + uptime = millis(); + lo.addToPayload("uptime", uptime); // adding 'uptime' value to the current payload + + Serial.println("Sending data to Live Objects"); + lo.sendData(); // send the data to Live Objects + lastMessageTime = millis(); + } + + lo.loop(); // don't forget to keep this in your main loop +} diff --git a/src/examples/4_Simple_command/README.md b/src/examples/4_Simple_command/README.md new file mode 100644 index 0000000..ceaa33e --- /dev/null +++ b/src/examples/4_Simple_command/README.md @@ -0,0 +1,32 @@ +# Live Objects device commands + +Commands can be used to trigger actions on the device. + +![diagram](img/command_diagram.png) + +In this example we will use command to make Arduino onboard LED blink. + + +## Running +First of all, be sure that you installed the required libraries and generated an API key mentioned in the main README file, then: +1. Open "4_simple_command.ino" sketch using Arduino IDE +2. Replace ```const char SECRET_LIVEOBJECTS_API_KEY[]="";``` in arduino_secrets.h with API key you generated +3. In ```lo.setSecurity()``` select security mode using ```TLS``` or ```NONE``` according to board abilities shown in **Compatibility** point in main **README.md** +4. Upload *4_simple_command.ino* sketch to your Arduino MKR NB 1500 board + +## Verify +**Is device online:**
+If all went fine under **devices** tab on Live Live Objects portal you should see online your device identified by its modem IMEI + +## Send command +Now navigate to:
+**Devices->urn:lo:nsid:mqtt:[your_device_imei]->Commands**
+And click **"Add command"**
+ +Finally define your command like this: + +![diagram](img/command_send.png) + +After clicking "Validate" your command should be sent to the device and as an effect you should see the onboard LED blinking 5 times: + +![blink](img/blinkCommand.gif) diff --git a/src/examples/4_Simple_command/arduino_secrets.h b/src/examples/4_Simple_command/arduino_secrets.h new file mode 100644 index 0000000..b846511 --- /dev/null +++ b/src/examples/4_Simple_command/arduino_secrets.h @@ -0,0 +1,16 @@ + // Cellular connection cerdentials, used only for GSM boards +extern const String SECRET_PINNUMBER = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_APN = ""; // specify the APN name (if needed) +extern const String SECRET_APN_USER = ""; // specify the username for your APN (if needed) +extern const String SECRET_APN_PASS = ""; // specify the password for your APN (if needed) +extern const String SECRET_SERVER_MSISDN = ""; // specify the number of server(gate) + +// WIFI connection credentials, used only for WiFi boards +extern const String SECRET_SSID = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_WIFI_PASS = ""; // specify the APN name (if needed) + + // Live Objects credential: paste below your API key (see Configuration > API keys on the portal). + // You API key must have at least the predefined 'MQTT Device' rights profile + // (alternatively: 'Device Access' read + write rights if need to customise the rights). + // Please note that you *must* use a TLS connection (MQTTS) if you grant more rights to the API key. +extern const String SECRET_LIVEOBJECTS_API_KEY = ""; diff --git a/src/examples/4_Simple_command/img/blinkCommand.gif b/src/examples/4_Simple_command/img/blinkCommand.gif new file mode 100644 index 0000000..6f250e4 Binary files /dev/null and b/src/examples/4_Simple_command/img/blinkCommand.gif differ diff --git a/src/examples/4_Simple_command/img/command_diagram.png b/src/examples/4_Simple_command/img/command_diagram.png new file mode 100644 index 0000000..fca1caf Binary files /dev/null and b/src/examples/4_Simple_command/img/command_diagram.png differ diff --git a/src/examples/4_Simple_command/img/command_send.png b/src/examples/4_Simple_command/img/command_send.png new file mode 100644 index 0000000..3b4b29d Binary files /dev/null and b/src/examples/4_Simple_command/img/command_send.png differ diff --git a/src/examples/5_Command_with_arguments/5_Command_with_arguments.ino b/src/examples/5_Command_with_arguments/5_Command_with_arguments.ino new file mode 100644 index 0000000..ce10603 --- /dev/null +++ b/src/examples/5_Command_with_arguments/5_Command_with_arguments.ino @@ -0,0 +1,80 @@ +/****************************************************************************** + INCLUDES + ******************************************************************************/ +#include "arduino_secrets.h" +#include + +/****************************************************************************** + USER VARIABLES + ******************************************************************************/ + +uint32_t messageRate = 60000; // stores the current data message rate in Milliseconds +unsigned long uptime; // stores the device uptime (sent as fake sensor data) +unsigned long lastMessageTime = 0; // stores the time when last data message was sent + + +/****************************************************************************** + USER PROGRAM + ******************************************************************************/ + + // An example of a command callback function handling 3 arguments: + // 'time ON' holds the LED ON time in milliseconds, + // 'time OFF' holds the LED OFF time in milliseconds, + // 'repetitions' holds the number of blinks. + // The command will respond with the total duration of the animation. + +void blinkLED(const String arguments, String &response) { + // example of 'arguments' content: "{\"time ON\":250,\"time OFF\":750,\"repetitions\":5}" + StaticJsonDocument<128> incomingArguments; // creation of a JSON document called "incomingArguments" that will holds the arguments + deserializeJson(incomingArguments, arguments); // extraction of JSON data + + int timeOn = incomingArguments["time ON"]; // arguments are now accessible using their name + int timeOff = incomingArguments["time OFF"]; + int reps = incomingArguments["repetitions"]; + unsigned long elapsedTime = millis(); // will keep track of time in order to compute the animation duration + + pinMode(LED_BUILTIN, OUTPUT); + for (byte i = 0; i < reps; i++) { + digitalWrite(LED_BUILTIN, LOW); + delay(timeOn); + digitalWrite(LED_BUILTIN, HIGH); + delay(timeOff); + } + + elapsedTime = millis() - elapsedTime; + + StaticJsonDocument<128> outgoingResponse; // creation of a JSON document that will hold the response + outgoingResponse["animation duration (milliseconds)"] = elapsedTime; // adding reponse item (you can add several by repeating the line): + serializeJson(outgoingResponse, response); // exporting JSON in 'reponse' String + // example of 'response' content: "{\"animation duration (milliseconds)\":5000}" +} + + +void setup() { + delay(2000); + Serial.begin(9600); + Serial.print("\n*** Live Objects SDK for Arduino, revision "); + Serial.print(SW_REVISION); + Serial.println(" ***\n"); + + // Declaring a simple commands hadled by the function 'blinkLED'. + lo.addCommand("blink", blinkLED); + lo.setSecurity(TLS); + lo.begin(MQTT, TEXT, true); + lo.connect(); // connects to the network + Live Objects +} + +void loop() { + if (millis() - lastMessageTime > messageRate) { + // collect data periodically + Serial.println("Sampling data"); + uptime = millis(); + lo.addToPayload("uptime", uptime); // adding 'uptime' value to the current payload + + Serial.println("Sending data to Live Objects"); + lo.sendData(); // send the data to Live Objects + lastMessageTime = millis(); + } + + lo.loop(); // don't forget to keep this in your main loop +} diff --git a/src/examples/5_Command_with_arguments/README.md b/src/examples/5_Command_with_arguments/README.md new file mode 100644 index 0000000..e623497 --- /dev/null +++ b/src/examples/5_Command_with_arguments/README.md @@ -0,0 +1,30 @@ +# Live Objects device commands with arguments + +Commands can be used to trigger actions on the device. Additionally when creating the command on Live Objects, you can add some arguments which will be handled by device. + +![diagram](img/command_with_args.png) + +In this example we will use command to make Arduino onboard LED blink. Unlike in previous example where blink time and count was fixed, this time the on/off time of the LED and the repetitions will be passed as arguments in the command sent from Live Objects. + + +## Running +First of all, be sure that you installed the required libraries and generated an API key mentioned in the main README file, then: +1. Open "5_simple_command.ino" sketch using Arduino IDE +2. Replace ```const char SECRET_LIVEOBJECTS_API_KEY[]="";``` in arduino_secrets.h with API key you generated +3. In ```lo.setSecurity()``` select security mode using ```TLS``` or ```NONE``` according to board abilities shown in **Compatibility** point in main **README.md** +4. Upload *5_simple_command.ino* sketch to your Arduino MKR NB 1500 board + +## Verify +**Is device online:**
+If all went fine under **devices** tab on Live Live Objects portal you should see online your device identified by its modem IMEI + +## Send command +Now navigate to:
+**Devices->urn:lo:nsid:mqtt:[your_device_imei]->Commands**
+And click **"Add command"**
+ +Define command like this: + +![diagram](img/define_command.png) + +After clicking "Validate" your command should be sent to the device and as an effect you should see the onboard LED blinking according to the parameters provided diff --git a/src/examples/5_Command_with_arguments/arduino_secrets.h b/src/examples/5_Command_with_arguments/arduino_secrets.h new file mode 100644 index 0000000..b846511 --- /dev/null +++ b/src/examples/5_Command_with_arguments/arduino_secrets.h @@ -0,0 +1,16 @@ + // Cellular connection cerdentials, used only for GSM boards +extern const String SECRET_PINNUMBER = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_APN = ""; // specify the APN name (if needed) +extern const String SECRET_APN_USER = ""; // specify the username for your APN (if needed) +extern const String SECRET_APN_PASS = ""; // specify the password for your APN (if needed) +extern const String SECRET_SERVER_MSISDN = ""; // specify the number of server(gate) + +// WIFI connection credentials, used only for WiFi boards +extern const String SECRET_SSID = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_WIFI_PASS = ""; // specify the APN name (if needed) + + // Live Objects credential: paste below your API key (see Configuration > API keys on the portal). + // You API key must have at least the predefined 'MQTT Device' rights profile + // (alternatively: 'Device Access' read + write rights if need to customise the rights). + // Please note that you *must* use a TLS connection (MQTTS) if you grant more rights to the API key. +extern const String SECRET_LIVEOBJECTS_API_KEY = ""; diff --git a/src/examples/5_Command_with_arguments/img/command_with_args.png b/src/examples/5_Command_with_arguments/img/command_with_args.png new file mode 100644 index 0000000..06c8934 Binary files /dev/null and b/src/examples/5_Command_with_arguments/img/command_with_args.png differ diff --git a/src/examples/5_Command_with_arguments/img/define_command.png b/src/examples/5_Command_with_arguments/img/define_command.png new file mode 100644 index 0000000..f26183d Binary files /dev/null and b/src/examples/5_Command_with_arguments/img/define_command.png differ diff --git a/src/examples/6_sms_send_data/6_sms_send_data.ino b/src/examples/6_sms_send_data/6_sms_send_data.ino new file mode 100644 index 0000000..c97c70c --- /dev/null +++ b/src/examples/6_sms_send_data/6_sms_send_data.ino @@ -0,0 +1,38 @@ +/****************************************************************************** + INCLUDES + ******************************************************************************/ +#include "arduino_secrets.h" +#include +/****************************************************************************** + USER VARIABLES + ******************************************************************************/ +uint32_t messageRate = 5000; // stores the current data message rate in Milliseconds +unsigned long uptime; // stores the device uptime (sent as fake sensor data) +unsigned long lastMessageTime = 0; // stores the time when last data message was sent + +/****************************************************************************** + USER PROGRAM + ******************************************************************************/ +void setup() { + delay(2000); + Serial.begin(9600); + Serial.print("\n*** Live Objects SDK for Arduino, revision "); + Serial.print(SW_REVISION); + Serial.println(" ***\n"); + lo.begin(SMS, TEXT, true); + lo.connect(); // connects to the network + Live Objects +} + +void loop() { + if (millis() - lastMessageTime > messageRate) { + // collect data periodically + Serial.println("Sampling data"); + uptime = millis(); + lo.addToPayload("uptime", uptime); // adding 'uptime' value to the current payload + lo.addTimestamp(1596283200); // adding timestamp to the current payload + Serial.println("Sending data to Live Objects"); + lo.sendData(); // send the data to Live Objects + lastMessageTime = millis(); + } + lo.loop(); // don't forget to keep this in your main loop +} \ No newline at end of file diff --git a/src/examples/6_sms_send_data/README.md b/src/examples/6_sms_send_data/README.md new file mode 100644 index 0000000..d6ae8d1 --- /dev/null +++ b/src/examples/6_sms_send_data/README.md @@ -0,0 +1,74 @@ +# Live Objects using SMS protocol + +SMS protocol can be used the same as MQTT protocol, but in addition you have to create device interface manualy. + +This protocol has 2 modes, text and binary. You can specify which u want to use in function `lo.begin(SMS, mode, true)`. Simply replace mode with `TXT` or `BINARY` + +![diagram](img/sms_protocol.png) + +In this example we will sent uptime and timestamp to LiveObjects in `TXT` mode. + +## Preparations +You have to create a device interface. Go to Devices->Add device. Select SMS tab then complete necessary fields like MSISDN (phone number) and select Server phone number. + +**:warning: yours MSISDN have to be preceeded by area code** + +Next click Create. + +![Live Object screenshot](img/add_interface.png) +## Running +First of all, be sure that you installed the required libraries and generated an API key mentioned in the main README file, then: +1. Open "6_sms_protocol.ino" sketch using Arduino IDE +2. Replace ```extern const String SECRET_LIVEOBJECTS_API_KEY="";``` in arduino_secrets.h with API key you generated +3. Replace ```extern const String SECRET_SERVER_MSISDN="";``` with number you have choosen while creating device interface. +4. Upload *5_simple_command.ino* sketch to your Arduino MKR board + +## Verify +**Is device sending data:**
+Under data tab on Live Objects portal you should see messages sent by your device. The data doesn't look preety especialy if you are using binary mode. + +## Parse incoming data using decoders + +Go to Data->Decoders then click +Add. Fill the name and model fields then choose type of the decoder. + +**CSV Example** + +Column description + +```Json: +[ + {"name":"Example_string","jsonType":"STRING"}, + {"name":"Example_number","jsonType":"NUMERIC"}, + {"name":"Example_bool","jsonType":"BOOLEAN"} +] +``` + +Parser options: + +```Json +{ + "columnSeparator":";" +} +``` + +Template: + +``` +{ + String : {{Example_string}}, + Number : {{Example_number}}, + Bool : {{Example_bool}} +} +``` + +Result should look like this: + +![Live Object screenshot](img/decoder_csv.png) + +**Binary Example** + +Binary payload description +```C++ +int uptime; utf8[20] timestamp; +``` +![Live Object screenshot](img/decoder_binary.png) \ No newline at end of file diff --git a/src/examples/6_sms_send_data/arduino_secrets.h b/src/examples/6_sms_send_data/arduino_secrets.h new file mode 100644 index 0000000..836b0ff --- /dev/null +++ b/src/examples/6_sms_send_data/arduino_secrets.h @@ -0,0 +1,16 @@ + // Cellular connection cerdentials, used only for GSM boards +extern const String SECRET_PINNUMBER = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_APN = ""; // specify the APN name (if needed) +extern const String SECRET_APN_USER = ""; // specify the username for your APN (if needed) +extern const String SECRET_APN_PASS = ""; // specify the password for your APN (if needed) +extern const String SECRET_SERVER_MSISDN = ""; // specify the number of server(gate) + +// WIFI connection credentials, used only for WiFi boards +extern const String SECRET_SSID = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_WIFI_PASS = ""; // specify the APN name (if needed) + + // Live Objects credential: paste below your API key (see Configuration > API keys on the portal). + // You API key must have at least the predefined 'MQTT Device' rights profile + // (alternatively: 'Device Access' read + write rights if need to customise the rights). + // Please note that you *must* use a TLS connection (MQTTS) if you grant more rights to the API key. +extern const String SECRET_LIVEOBJECTS_API_KEY = ""; diff --git a/src/examples/6_sms_send_data/img/add_interface.png b/src/examples/6_sms_send_data/img/add_interface.png new file mode 100644 index 0000000..6086c03 Binary files /dev/null and b/src/examples/6_sms_send_data/img/add_interface.png differ diff --git a/src/examples/6_sms_send_data/img/decoder_binary.png b/src/examples/6_sms_send_data/img/decoder_binary.png new file mode 100644 index 0000000..090fb71 Binary files /dev/null and b/src/examples/6_sms_send_data/img/decoder_binary.png differ diff --git a/src/examples/6_sms_send_data/img/decoder_csv.png b/src/examples/6_sms_send_data/img/decoder_csv.png new file mode 100644 index 0000000..d941408 Binary files /dev/null and b/src/examples/6_sms_send_data/img/decoder_csv.png differ diff --git a/src/examples/6_sms_send_data/img/sms_protocol.png b/src/examples/6_sms_send_data/img/sms_protocol.png new file mode 100644 index 0000000..5ceea9e Binary files /dev/null and b/src/examples/6_sms_send_data/img/sms_protocol.png differ diff --git a/src/examples/7_distance_and_light_sensor/7_distance_and_light_sensor.ino b/src/examples/7_distance_and_light_sensor/7_distance_and_light_sensor.ino new file mode 100644 index 0000000..452e8ff --- /dev/null +++ b/src/examples/7_distance_and_light_sensor/7_distance_and_light_sensor.ino @@ -0,0 +1,51 @@ +/****************************************************************************** + INCLUDES + ******************************************************************************/ +#include "arduino_secrets.h" +#include +#include "ExtDevices.h" + +/****************************************************************************** + USER VARIABLES + ******************************************************************************/ +uint32_t messageRate = 5000; // stores the current data message rate in Milliseconds +unsigned long lastMessageTime = 0; // stores the time when last data message was sent + +VL6180x sensor(VL6180X_ADDRESS); +u_int8_t distance; // distance from obstruction [mm] +float ambient_light; // ambient light [lx] + +/****************************************************************************** + USER PROGRAM + ******************************************************************************/ +void setup() { + delay(2000); + + VL6180XInit(); // initialization of VL6180X sensor + + Serial.begin(9600); + Serial.print("\n*** Live Objects SDK for Arduino, revision "); + Serial.print(SW_REVISION); + Serial.println(" ***\n"); + lo.setSecurity(NONE); + lo.begin(MQTT, BINARY, true); + lo.connect(); // connects to the network + Live Objects +} + +void loop() { + if (millis() - lastMessageTime > messageRate) { + // collect data periodically + Serial.println("Sampling data"); + + distance = sensor.getDistance(); + lo.addToPayload(distance); // adding 'distance' value to the current payload + // limiting value to 2 decimal places + ambient_light = (static_cast(sensor.getAmbientLight(GAIN_1) * 100.0)) / 100.0; + lo.addToPayload(ambient_light); + + Serial.println("Sending data to Live Objects"); + lo.sendData(); // send the data to Live Objects + lastMessageTime = millis(); + } + lo.loop(); // don't forget to keep this in your main loop +} diff --git a/src/examples/7_distance_and_light_sensor/README.md b/src/examples/7_distance_and_light_sensor/README.md new file mode 100644 index 0000000..77baff6 --- /dev/null +++ b/src/examples/7_distance_and_light_sensor/README.md @@ -0,0 +1,181 @@ +# Sending data from VL6180 sensor to Live Objects + +This example shows how to send real data from sensor [VL6180X](https://www.st.com/resource/en/datasheet/vl6180x.pdf). Sensor delivers two useful values: +- ambient light [[lx](https://en.wikipedia.org/wiki/Lux)], +- distance from disturbance [mm]. + +In this use-case [an example of board using sensor](https://kamami.pl/en/kamod-kamami-peripheral-modules/559362-kamodvl6180x-a-module-with-distance-gesture-and-als-sensor.html) was being used. + +![sensor](img/KAmodVL6180X_module.png) + +## Our Setup view: + +![setup_view](img/setup_view.jpg) + +## Preparations +### Installation VL6180X library +Using **Library Manager** from Arduino IDE (*Tools -> Manage Libraries...*) you need to install library: + +![library_installation](img/VL6180X_libr.png) + +### Diagram of connection +Module is controlled via I2C and accepts power and signal levels 3.3V. +MKR1010 WiFi setup diagram: + +![setup_diagram](img/setup_diagram.png) + +For your board you need to connect power lines (**+3.3V, GND**) and I2C lines (**SDA, SCL**) to corresponding VL6180X lines. + +### Decoder's preparation for MQTT devices +If you want to limit amount of data which are being sent from board to Live Objects portal you can use **BINARY** mode which is defined in ```lo.begin()``` in *7_distance_and_light_sensor.ino*: ```lo.begin(MQTT, BINARY, true);```. In this case both values: ambient light (1 byte) and distance (4 bytes) will be sent as only five bytes (see terminal output in point 6). + +To achieve this goal, you need to create **private binary decoder** in Live Objects portal. Use: *Data -> Decoders -> +Add*. You an enter data as below and click **Save**. + +![binary_decoder](img/binary_decoder.png) +|Field |Value | +|--------------------------|-----------------------------------------------------------| +|Name |VL6180Xbin | +|Model |VL6180Xbin100 | +|Type |Parameterized (Binary) | +|Binary payload description|ubyte distance; float amblight; | +|Template |{\\"distance\\":{{distance}}, "amblight\\":{{amblight}}\\"}| +
+ +### MQTT interface modification + +You need to select your device for which you want to activate previously created **private binary decoder**. Click selected device from the list uder tab **Devices**. + +![select_dev](img/select_device_1.png) + +
+ +Then click **Identity** and next click icon in red circle. After that in field **Decoder** you can select your decoder. Clicking **Save** finishes this step and activates our private decoder **VL6180Xbin** for MQTT interface for selected device. + +![mod_interface](img/mod_interface_1.png) + +## Running +To use a software you need to: +1. Log in to [Live Objects](https://liveobjects.orange-business.com) or request a [trial account](https://liveobjects.orange-business.com/#/request_account) (up to 10 devices for 1 year) if you don't have one, +2. Create an [API key](https://liveobjects.orange-business.com/#/administration/apikeys) for your device. Give it a name, select the *Device access* role and validate. Copy the key, +3. Clone or download the directory from Github, +4. Open *7_distance_and_light_sensor.ino* sketch using Arduino IDE, +5. Replace ```const char SECRET_LIVEOBJECTS_API_KEY[]="";``` in *[arduino_secrets.h](arduino_secrets.h)* with API key you generated, +6. Define necessary credentials for your board in *arduino_secrets.h*: +- for WiFi boards: + - ```extern const String SECRET_SSID = "";``` + - ```extern const String SECRET_WIFI_PASS = "";``` +- for cellular boards: + - ```extern const String SECRET_PINNUMBER = "";``` (if needed), + - ```extern const String SECRET_APN = "";``` (if needed), + - ```extern const String SECRET_APN_USER = "";``` (if needed), + - ```extern const String SECRET_APN_PASS = "";``` (if needed), +7. In ```lo.setSecurity()``` select security mode using ```TLS``` or ```NONE``` according to board abilities shown in **Compatibility** point in main **README.md**, +8. Upload *7_distance_and_light_sensor.ino* sketch to your board. +9. In your terminal window you should see similiar output: + +``` +15:31:22.732 -> +15:31:22.732 -> VL6180X sensor +15:31:22.732 -> Model ID = 180 +15:31:22.732 -> Model Rev = 13 +15:31:22.732 -> Module Rev = 12 +15:31:22.732 -> Manufacture Date = 16/11/14 Phase: 1 +15:31:22.732 -> +15:31:23.762 -> +15:31:23.762 -> *** Live Objects for Arduino MKR boards, revision 2.1.0 *** +15:31:24.526 -> [INFO] WiFi firmware version 1.2.4 +15:31:24.526 -> [INFO] Attempting to connect to SSID: EdekAD57BA +15:31:28.279 -> +15:31:28.279 -> [INFO] Connecting to MQTT broker mqtt.liveobjects.orange-business.com:1883 +15:31:30.439 -> [INFO] You're connected to the MQTT broker +15:31:30.439 -> Sampling data +15:31:30.572 -> Sending data to Live Objects +15:31:30.572 -> [INFO] Publishing message on topic: dev/v1/data/binary +15:31:30.572 -> [INFO] 4041A9C28F +15:31:35.554 -> Sampling data +15:31:35.687 -> Sending data to Live Objects +15:31:35.687 -> [INFO] Publishing message on topic: dev/v1/data/binary +15:31:35.687 -> [INFO] 4841AEE148 +... +``` + +## Verify +**Is device online:** +If all went fine under **Devices** tab on Live Live Objects portal you should see online your device identified by its modem IMEI or WiFi MAC address: + +![device_online](img/device_online.png) + +**Is device sending data:** +Under **Data** tab on Live Objects portal you should see messages sent by your device, along with values eg. *{ "distance": 110, "amblight": 192.63 }* + +![data_portal](img/data_portal.png) + +

+ +*** +## SMS (cellular boards) + +## Preparations + +### SMS device creation +You need to manually add your cellular device as it is described in [this point](../6_sms_send_data/README.md). + +### Decoder's preparation for SMS devices +If you want to limit amount of data which are being sent from board to Live Objects portal you can use pure **TEXT** mode which is defined in ```lo.begin()``` in *7_distance_and_light_sensor.ino*: ```lo.begin(SMS, TEXT, true);```. In this case both values: ambient light and distance will be transmitted as raw text. + +To achieve this goal, you need to create **private sms decoder** in Live Objects portal. Use: *Data -> Decoders -> +Add*. You an enter data as below and click **Save**. + +![sms_decoder](img/sms_decoder.png) +|Field |Value | +|-------------------|-----------------------------------------------------------| +|Name |VL6180Xsms | +|Model |VL6180Xs | +|Type |Parameterized (CSV) | +|Columns description|[{"name": "distance","jsonType": "NUMERIC"},{"name": "amblight","jsonType": "NUMERIC"}]| +|Parser options |{"columnSeparator": ";","quoteChar": "\"","useEscapeChar": false,"escapeChar": "\\","skipWhiteSpace": false,"lineFeedSeparator": "\n"}| +|Template |{distance:{{distance}}, amblight:{{amblight}}}| +
+### SMS interface modification + +You need to modify SMS interface for you device in similar way as for MQTT device selecting **VL6180Xsms** decoder. + +## Running +To use a software you need to: +1. Log in to [Live Objects](https://liveobjects.orange-business.com) or request a [trial account](https://liveobjects.orange-business.com/#/request_account) (up to 10 devices for 1 year) if you don't have one, +2. Create an [API key](https://liveobjects.orange-business.com/#/administration/apikeys) for your device. Give it a name, select the *Device access* role and validate. Copy the key, +3. Clone or download the directory from Github, +4. Open *7_distance_and_light_sensor.ino* sketch using Arduino IDE, +5. Replace ```const char SECRET_LIVEOBJECTS_API_KEY[]="...";``` in *[arduino_secrets.h](arduino_secrets.h)* with API key you generated, +6. Specify the number of sever (gate): + - ```extern const String SECRET_SERVER_MSISDN = "...";``` - the same number needs to be used in interface of sms device. **Every Orange operator has its individual number.** + ![sms_int](img/sms_int2.png) +7. In ```lo.setSecurity()``` select security mode ```NONE``` +8. Upload *7_distance_and_light_sensor.ino* sketch to your board. +9. In your terminal window you should see similiar output: + +``` +13:00:46.470 -> VL6180X sensor +13:00:46.470 -> Model ID = 180 +13:00:46.470 -> Model Rev = 13 +13:00:46.470 -> Module Rev = 12 +13:00:46.470 -> Manufacture Date = 16/11/14 Phase: 1 +13:00:46.470 -> +13:00:47.467 -> +13:00:47.467 -> *** Live Objects for Arduino MKR boards, revision 2.1.0 *** +13:00:52.151 -> [INFO] Connecting to cellular network +13:01:00.558 -> +13:01:00.758 -> [INFO] You're connected to the network +13:01:00.758 -> Sampling data +13:01:00.891 -> Sending data to Live Objects +13:01:00.891 -> [INFO] Publishing message: 122;310.17; +13:01:06.740 -> Sampling data +13:01:06.840 -> Sending data to Live Objects +13:01:06.840 -> [INFO] Publishing message: 255;300.67; +... +``` + +## Verify + +You can verify if device is online and data are delivered in the same way as it is described for MQTT device. You need to take into account that SMS devices are always **Online**. + +![sms_dev](img/sms_dev.png) diff --git a/src/examples/7_distance_and_light_sensor/arduino_secrets.h b/src/examples/7_distance_and_light_sensor/arduino_secrets.h new file mode 100644 index 0000000..b846511 --- /dev/null +++ b/src/examples/7_distance_and_light_sensor/arduino_secrets.h @@ -0,0 +1,16 @@ + // Cellular connection cerdentials, used only for GSM boards +extern const String SECRET_PINNUMBER = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_APN = ""; // specify the APN name (if needed) +extern const String SECRET_APN_USER = ""; // specify the username for your APN (if needed) +extern const String SECRET_APN_PASS = ""; // specify the password for your APN (if needed) +extern const String SECRET_SERVER_MSISDN = ""; // specify the number of server(gate) + +// WIFI connection credentials, used only for WiFi boards +extern const String SECRET_SSID = ""; // unless PIN is deactivated, specify your SIM card PIN number +extern const String SECRET_WIFI_PASS = ""; // specify the APN name (if needed) + + // Live Objects credential: paste below your API key (see Configuration > API keys on the portal). + // You API key must have at least the predefined 'MQTT Device' rights profile + // (alternatively: 'Device Access' read + write rights if need to customise the rights). + // Please note that you *must* use a TLS connection (MQTTS) if you grant more rights to the API key. +extern const String SECRET_LIVEOBJECTS_API_KEY = ""; diff --git a/src/examples/7_distance_and_light_sensor/img/KAmodVL6180X_module.png b/src/examples/7_distance_and_light_sensor/img/KAmodVL6180X_module.png new file mode 100644 index 0000000..4677e25 Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/KAmodVL6180X_module.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/VL6180X_libr.png b/src/examples/7_distance_and_light_sensor/img/VL6180X_libr.png new file mode 100644 index 0000000..1e18272 Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/VL6180X_libr.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/binary_decoder.png b/src/examples/7_distance_and_light_sensor/img/binary_decoder.png new file mode 100644 index 0000000..617c8e8 Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/binary_decoder.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/data_portal.png b/src/examples/7_distance_and_light_sensor/img/data_portal.png new file mode 100644 index 0000000..b6c8552 Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/data_portal.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/device_online.png b/src/examples/7_distance_and_light_sensor/img/device_online.png new file mode 100644 index 0000000..c89d8d1 Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/device_online.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/mod_interface_1.png b/src/examples/7_distance_and_light_sensor/img/mod_interface_1.png new file mode 100644 index 0000000..4d7ffcf Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/mod_interface_1.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/select_device_1.png b/src/examples/7_distance_and_light_sensor/img/select_device_1.png new file mode 100644 index 0000000..11198a1 Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/select_device_1.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/setup_diagram.png b/src/examples/7_distance_and_light_sensor/img/setup_diagram.png new file mode 100644 index 0000000..cc19eba Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/setup_diagram.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/setup_view.jpg b/src/examples/7_distance_and_light_sensor/img/setup_view.jpg new file mode 100644 index 0000000..18e7053 Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/setup_view.jpg differ diff --git a/src/examples/7_distance_and_light_sensor/img/sms_decoder.png b/src/examples/7_distance_and_light_sensor/img/sms_decoder.png new file mode 100644 index 0000000..9559802 Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/sms_decoder.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/sms_dev.png b/src/examples/7_distance_and_light_sensor/img/sms_dev.png new file mode 100644 index 0000000..0dcf40d Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/sms_dev.png differ diff --git a/src/examples/7_distance_and_light_sensor/img/sms_int2.png b/src/examples/7_distance_and_light_sensor/img/sms_int2.png new file mode 100644 index 0000000..7fba3c4 Binary files /dev/null and b/src/examples/7_distance_and_light_sensor/img/sms_int2.png differ