Sending several bytes with LoRa

Hello everyone,
I’m working on a project using Lorawan in which I need to send 7 bytes over Lora. I’m using the LoraAPI example and I only can send data byte to byte. Therefore I modified the code by using the send function 7 times to send my data to the gateway. By the way, I’m using TTN console to see the data I sent. It seems to send properly (I’m looking at the serial transmission if the board sends the send confirmation message. And I check with LEDs too.

Here is my code (sorry it’s not very clean)

/**
  • Copyright (c) 2017, Arm Limited and affiliates.
  • SPDX-License-Identifier: Apache-2.0
  • Licensed under the Apache License, Version 2.0 (the “License”);
  • you may not use this file except in compliance with the License.
  • You may obtain a copy of the License at
  • http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an “AS IS” BASIS,
  • 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.
    */
    #include <stdio.h>
    #include “mbed.h”
    #include “lorawan/LoRaWANInterface.h”
    #include “lorawan/system/lorawan_data_structures.h”
    #include “events/EventQueue.h”

// Application helpers

#include “trace_helper.h”
#include “lora_radio_helper.h”

using namespace events;

// Max payload size can be LORAMAC_PHY_MAXPAYLOAD.
// This example only communicates with much shorter messages (<30 bytes).
// If longer messages are used, these buffers must be changed accordingly.
uint8_t tx_buffer[30];
uint8_t rx_buffer[30];

/*

  • Sets up an application dependent transmission timer in ms. Used only when Duty Cycling is off for testing
    */
    #define TX_TIMER 10000

/**

  • Maximum number of events for the event queue.
  • 10 is the safe number for the stack events, however, if application
  • also uses the queue for whatever purposes, this number should be increased.
    */
    #define MAX_NUMBER_OF_EVENTS 10

/**

  • Maximum number of retries for CONFIRMED messages before giving up
    */
    #define CONFIRMED_MSG_RETRY_COUNTER 3

/**

  • This event queue is the global event queue for both the
  • application and stack. To conserve memory, the stack is designed to run
  • in the same thread as the application and the application is responsible for
  • providing an event queue to the stack that will be used for ISR deferment as
  • well as application information event queuing.
    */
    static EventQueue ev_queue(MAX_NUMBER_OF_EVENTS *EVENTS_EVENT_SIZE);

/**

  • Event handler.
  • This will be passed to the LoRaWAN stack to queue events for the
  • application which in turn drive the application.
    */
    static void lora_event_handler(lorawan_event_t event);

/**

  • Constructing Mbed LoRaWANInterface and passing it the radio object from lora_radio_helper.
    */
    static LoRaWANInterface lorawan(radio);

/**

  • Application specific callbacks
    */
    static lorawan_app_callbacks_t callbacks;

/**

  • Entry point for application
    */
    int main(void)
    {

    // setup tracing
    setup_trace();

    // stores the status of a call to LoRaWAN protocol
    lorawan_status_t retcode;

    // Initialize LoRaWAN stack
    if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) {
    printf(“\r\n LoRa initialization failed! \r\n”);
    return -1;
    }

    printf(“\r\n Mbed LoRaWANStack initialized \r\n”);

    // prepare application callbacks
    callbacks.events = mbed::callback(lora_event_handler);
    lorawan.add_app_callbacks(&callbacks);

    // 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”);
    return -1;
    }

    printf(“\r\n 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”);
    return -1;
    }

    printf(“\r\n 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);
    return -1;
    }

    printf(“\r\n Connection - In Progress …\r\n”);

    // make your event queue dispatching events forever
    ev_queue.dispatch_forever();

    return 0;
    }

/**

  • Sends a message to the Network Server
    */
    static void send_message(uint8_t Octet_envoye) {

    static DigitalOut led(LED1, 0);

    // create a one-byte payload which contains whether the PIR sensor is high or low

    uint8_t buffer1 = {Octet_envoye};
    int16_t retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, buffer1, sizeof(buffer1), MSG_CONFIRMED_FLAG);

    led =1;
    ThisThread::sleep_for(500);
    led=0;

    if (retcode != 0) {
    printf(“Sent message over LoRaWAN successfully!\n”);

    }
    else {
    printf(“Failed to send message (duty-cycle violation?) (%d)\n”, retcode);
    }
    }

/**

  • Receive a message from the Network Server
    */
    static void receive_message() {

    int16_t retcode = lorawan.receive(MBED_CONF_LORA_APP_PORT, rx_buffer,
    LORAMAC_PHY_MAXPAYLOAD,
    MSG_CONFIRMED_FLAG|MSG_UNCONFIRMED_FLAG);

    // ignore errors while retrieving
    if (retcode < 0) return;

    printf(“Received %d bytes: “, retcode);
    for (uint8_t i = 0; i < retcode; i++) {
    printf(”%x”, rx_buffer[i]);
    }
    printf(“\n”);
    }

/**

  • Event handler
    */
    static void lora_event_handler(lorawan_event_t event)
    {
    static DigitalOut led2(LED3, 0);
    static DigitalOut led3(LED4, 0);
    switch (event) {
    case CONNECTED:
    printf(“\r\n Connection - Successful \r\n”);
    if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
    send_message(1);

         } else {
             ev_queue.call_every(TX_TIMER, send_message,1);
         }
    
         break;
     case DISCONNECTED:
         ev_queue.break_dispatch();
         printf("\r\n Disconnected Successfully \r\n");
         break;
     case TX_DONE:
         printf("\r\n Message Sent to Network Server \r\n");
         if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
             send_message(5);
             ThisThread::sleep_for(5000);
             send_message(4);
             ThisThread::sleep_for(5000);
             send_message(2);
             ThisThread::sleep_for(5000);
             send_message(8);
             ThisThread::sleep_for(5000);
             send_message(11);
             ThisThread::sleep_for(5000);
             send_message(143);
             ThisThread::sleep_for(5000);
             send_message(60);
             led3=1;
             ThisThread::sleep_for(500);
             led3=0;
         }
         break;
     case TX_TIMEOUT:
     case TX_ERROR:
     case TX_CRYPTO_ERROR:
     case TX_SCHEDULING_ERROR:
         printf("\r\n Transmission Error - EventCode = %d \r\n", event);
         // try again
         if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
             send_message(1);
         }
         break;
     case RX_DONE:
         printf("\r\n 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);
         break;
     case JOIN_FAILURE:
         printf("\r\n OTAA Failed - Check Keys \r\n");
         break;
     case UPLINK_REQUIRED:
         printf("\r\n Uplink required by NS \r\n");
         if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
             send_message(1);
         }
         break;
     default:
         MBED_ASSERT("Unknown Event");
    

    }
    }

// EOF

The code is compiling well, and the 5 seconds was to see if it was a syncro problem with TTN.

Thanks in advance,

Natan