Demo program for LoRaWan with data formated for cayenne interface on mydevices.com Check on https://goo.gl/fTUDNc

Dependencies:   Cayenne-LPP

Demonstration d'un node LoRaWan sur carte : Discovery IOT STmicro : B-L072Z-LRWAN1 https://www.st.com/en/evaluation-tools/b-l072z-lrwan1.html

L e code original MBED-ARM : https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-lorawan/ est une application de l'API LoRAWan https://os.mbed.com/docs/v5.9/reference/lorawan.html

Le code original a été adapté pour une carte B-L072Z-LRWAN1 équipée d'un capteur de température LM35 connecté en 3.3v sur le port PA_0 (port analogique AN0) Les données sont formatées "cayenne" et visualisables sur mydevices.com ( https://goo.gl/fTUDNc ) Documentation cayenne : https://mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload

Les essais ont été réalisés avec une passerelle TTN https://www.thethingsnetwork.org/ le "Payload Format" ayant été configuré pour "Cayenne LPP"

Des capteurs virtuels on été également ajoutés (humidité, température, lumière, etc...) pour les essais au format cayenne.

Données physiques transmises (downlink)

- Température sur capteur LM35 - Tension sur PA_1 (AN1) est transmise entre 0% et 100% - Etat du bouton bleu

Données physiques reçues (uplink) Un actionneur permet d'allumer/eteindre à distance la led verte de la carte B-L072Z-LRWAN1

L'interface mydevice.com proposé permet de visualiser :

- Les capteurs virtuels - La température réelle sur LM35 - L'état du bouton bleu

/media/uploads/cdupaty/cayenne_mydevice.jpg

/media/uploads/cdupaty/ex_terminal-lorawan.jpg

Revision:
43:74226f6ca42c
Parent:
26:f07f5febf97f
--- a/main.cpp	Wed Oct 24 18:45:20 2018 +0100
+++ b/main.cpp	Thu Nov 29 07:48:18 2018 +0000
@@ -13,12 +13,23 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- */
+ *
+ * Adaptation for Discovery IOT STmicro B-L072Z-LRWAN1, TTN and  CAYENNE (mydevices.com)
+ * Christian Dupaty Lycee Fourcade 13120 Gardanne France
+ * 11-2018
+ * Peripherals on B-L072Z-LRWAN1
+    LED1        = PB_5, // Green
+    LED2        = PA_5, // Red
+    LED3        = PB_6, // Blue
+    LED4        = PB_7, // Red
+    USER_BUTTON = PB_2,
+  */
 #include <stdio.h>
 
 #include "lorawan/LoRaWANInterface.h"
 #include "lorawan/system/lorawan_data_structures.h"
 #include "events/EventQueue.h"
+#include "CayenneLPP.h"
 
 // Application helpers
 #include "DummySensor.h"
@@ -60,6 +71,15 @@
  */
 DS1820  ds1820(PC_9);
 
+// added by C.Dupaty
+
+CayenneLPP cayenne(100);   // data to cayenne format
+AnalogIn lm35(A0);  // for test we have connect a 
+                    //LM35 temperature captor on A0 Arduino analog port
+AnalogIn ana(A1);
+DigitalIn bp(USER_BUTTON);
+DigitalOut ledTest(LED1);
+
 /**
 * This event queue is the global event queue for both the
 * application and stack. To conserve memory, the stack is designed to run
@@ -100,11 +120,12 @@
 
     // Initialize LoRaWAN stack
     if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) {
-        printf("\r\n LoRa initialization failed! \r\n");
+        printf("LoRa initialization failed! \r\n");
         return -1;
     }
-
-    printf("\r\n Mbed LoRaWANStack initialized \r\n");
+    printf("\r\nTEST LORAWAN Lycee Fourcade \r\n");
+    printf("--------------------------- \r\n");
+    printf("\r\nMbed LoRaWANStack initialized \r\n");
 
     // prepare application callbacks
     callbacks.events = mbed::callback(lora_event_handler);
@@ -113,31 +134,32 @@
     // Set number of retries in case of CONFIRMED messages
     if (lorawan.set_confirmed_msg_retries(CONFIRMED_MSG_RETRY_COUNTER)
                                           != LORAWAN_STATUS_OK) {
-        printf("\r\n set_confirmed_msg_retries failed! \r\n\r\n");
+        printf("set_confirmed_msg_retries failed! \r\n\r\n");
         return -1;
     }
 
-    printf("\r\n CONFIRMED message retries : %d \r\n",
+    printf("CONFIRMED message retries : %d \r\n",
            CONFIRMED_MSG_RETRY_COUNTER);
 
     // Enable adaptive data rate
     if (lorawan.enable_adaptive_datarate() != LORAWAN_STATUS_OK) {
-        printf("\r\n enable_adaptive_datarate failed! \r\n");
+        printf("enable_adaptive_datarate failed! \r\n");
         return -1;
     }
 
-    printf("\r\n Adaptive data  rate (ADR) - Enabled \r\n");
+    printf("Adaptive data  rate (ADR) - Enabled \r\n");
 
     retcode = lorawan.connect();
 
     if (retcode == LORAWAN_STATUS_OK ||
         retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) {
     } else {
-        printf("\r\n Connection error, code = %d \r\n", retcode);
+        printf("Connection error, code = %d \r\n", retcode);
         return -1;
     }
 
-    printf("\r\n Connection - In Progress ...\r\n");
+    printf("Connection - In Progress ...\r\n");
+    printf("it may take a while\r\n");
 
     // make your event queue dispatching events forever
     ev_queue.dispatch_forever();
@@ -152,27 +174,68 @@
 {
     uint16_t packet_len;
     int16_t retcode;
-    float sensor_value;
+    float sensor_value; // dummy
+    float lum=0.0;      // dummy
+    float hum;         // dummy
+    float temp;         // dummy
+    float an;           // AN1 on Arduino connectors
+    int btBleu;         // The bleu button on Nucleo board
+    
+    float tempLM35;
+    static int cpt=0;
 
+    printf("\n\rEmission : %d\r\n",++cpt);
+        printf("-------------\r\n");
+    // Dummy sensors are used for test only
     if (ds1820.begin()) {
         ds1820.startConversion();
         sensor_value = ds1820.read();
-        printf("\r\n Dummy Sensor Value = %3.1f \r\n", sensor_value);
+        printf("Dummy Sensor Value = %3.1f \r\n", sensor_value);
         ds1820.startConversion();
     } else {
-        printf("\r\n No sensor found \r\n");
+        printf("No sensor found \r\n");
         return;
     }
+    lum+=111.0;
+    if (lum>9999.0) lum=0.0;
+    hum+=2.5;
+    if (temp>100.0) temp=1.1;
+    an=ana.read()*100.0;
+    btBleu=bp.read();
+    
+    // LM35 must be connected on A0 analog port
+    tempLM35=lm35.read()*330.0;
+    printf("Capteur LM35 : %3.2f C\r\n", tempLM35);
+    
 
-    packet_len = sprintf((char*) tx_buffer, "Dummy Sensor Value is %3.1f",
-                    sensor_value);
+    // mise en forme format CAYENNE LPP
+    // doc ici https://mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload
+    // doc logiciel : CayenneLPP.h
+    cayenne.reset();
+    cayenne.addLuminosity(1, lum);
+    cayenne.addPresence(2,1);
+    cayenne.addTemperature(3, temp);
+    cayenne.addRelativeHumidity(4, hum);
+    cayenne.addDigitalInput(5, btBleu);
+    cayenne.addAnalogInput(6, an);
+    cayenne.addDigitalOutput(7,0);
+    cayenne.addTemperature(8, tempLM35);   
+    cayenne.addTemperature(9, sensor_value);
+
+    cayenne.copy(tx_buffer);
+    
+    packet_len=cayenne.getSize();
+    printf("Emission du packet : \n\r");
+    for (int i=0;i<packet_len;i++) printf("%02X ",tx_buffer[i]);
+    printf("\n\r");
+  //  packet_len = sprintf((char*) tx_buffer, "Dummy Sensor Value is %3.1f",          sensor_value);
 
     retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, tx_buffer, packet_len,
                            MSG_CONFIRMED_FLAG);
 
     if (retcode < 0) {
         retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - WOULD BLOCK\r\n")
-                : printf("\r\n send() - Error code %d \r\n", retcode);
+                : printf("send() - Error code %d \r\n", retcode);
 
         if (retcode == LORAWAN_STATUS_WOULD_BLOCK) {
             //retry in 3 seconds
@@ -183,7 +246,7 @@
         return;
     }
 
-    printf("\r\n %d bytes scheduled for transmission \r\n", retcode);
+    printf("%d bytes scheduled for transmission \r\n", retcode);
     memset(tx_buffer, 0, sizeof(tx_buffer));
 }
 
@@ -193,22 +256,28 @@
 static void receive_message()
 {
     int16_t retcode;
-    retcode = lorawan.receive(MBED_CONF_LORA_APP_PORT, rx_buffer,
-                              sizeof(rx_buffer),
-                              MSG_CONFIRMED_FLAG|MSG_UNCONFIRMED_FLAG);
-
+    uint8_t port; // var to store port number provided by the stack
+    int flags; // var to store flags provided by the stack
+    retcode = lorawan.receive( rx_buffer,sizeof(rx_buffer), port, flags);
+    printf("\x1B[1m");  // yellow text
     if (retcode < 0) {
-        printf("\r\n receive() - Error code %d \r\n", retcode);
+        printf("receive() - Error code %d \r\n", retcode);
         return;
     }
-
-    printf(" Data:");
+    printf(" Reception on port : %d \n",port);
+    printf(" Flags are : %d \n",flags);
+    printf(" Data: ");
 
     for (uint8_t i = 0; i < retcode; i++) {
-        printf("%x", rx_buffer[i]);
+        printf("%02X ", rx_buffer[i]);
     }
 
-    printf("\r\n Data Length: %d\r\n", retcode);
+    printf("\n\r Data Length: %d\r\n", retcode);
+    printf("\x1B[0m");  // white text
+    printf("End reception\n\r");
+
+    if (rx_buffer[2]==0x64) ledTest=1;
+    if (rx_buffer[2]==0x00) ledTest=0;
 
     memset(rx_buffer, 0, sizeof(rx_buffer));
 }
@@ -220,7 +289,7 @@
 {
     switch (event) {
         case CONNECTED:
-            printf("\r\n Connection - Successful \r\n");
+            printf("Connection - Successful \r\n");
             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
                 send_message();
             } else {
@@ -230,10 +299,10 @@
             break;
         case DISCONNECTED:
             ev_queue.break_dispatch();
-            printf("\r\n Disconnected Successfully \r\n");
+            printf("Disconnected Successfully \r\n");
             break;
         case TX_DONE:
-            printf("\r\n Message Sent to Network Server \r\n");
+            printf("Message Sent to Network Server \r\n");
             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
                 send_message();
             }
@@ -242,25 +311,25 @@
         case TX_ERROR:
         case TX_CRYPTO_ERROR:
         case TX_SCHEDULING_ERROR:
-            printf("\r\n Transmission Error - EventCode = %d \r\n", event);
+            printf("Transmission Error - EventCode = %d \r\n", event);
             // try again
             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
                 send_message();
             }
             break;
         case RX_DONE:
-            printf("\r\n Received message from Network Server \r\n");
+            printf("Received message from Network Server \r\n");
             receive_message();
             break;
         case RX_TIMEOUT:
         case RX_ERROR:
-            printf("\r\n Error in reception - Code = %d \r\n", event);
+            printf("Error in reception - Code = %d \r\n", event);
             break;
         case JOIN_FAILURE:
-            printf("\r\n OTAA Failed - Check Keys \r\n");
+            printf("OTAA Failed - Check Keys \r\n");
             break;
         case UPLINK_REQUIRED:
-            printf("\r\n Uplink required by NS \r\n");
+            printf("Uplink required by NS \r\n");
             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
                 send_message();
             }