Skip to main content
All CollectionsConnect your Devices
Connect your SODAQ ONE V3 over LoRaWAN to Ubidots
Connect your SODAQ ONE V3 over LoRaWAN to Ubidots

Learn how to setup your SODAQ ONE V3 board to manage Uplink and Downlink messages with Ubidots using TTN as LoRaWAN network server.

Sergio M avatar
Written by Sergio M
Updated over 3 months ago

The ONE V3 is one of the hardware boards offered by SODAQ, a hardware company with a vision of enabling people and businesses by connecting their devices to the internet efficiently and off-grid. 

This amazing and easy-to-use board allows us to create several kinds of IoT applications such as Smart Agriculture, Fleet Tracking, Smart cities, and more. This board stands out thanks to its efficient use of battery life, achieved  through a well-managed interruptions logic.

Some hardware features include:

  • Arduino compatible

  • Deep Sleep Mode: 23uA

  • Highly integrated board files

  • Atmel SAMD21 32 bits ARM Cortex M0+ microcontroller

  • Microchip RN2903A LoRa module

  • uBlox EVA-8M GPS

  • LSM303AGR ultra-low-power 3D magnetometer and 3D accelerometer

  • Charge controller and on-board rechargeable coin cell battery

We highly recommend checking out the SODAQ official documentation to learn more about the ONE V3, such as sample codes that you can use later, hardware specifications for this flavor and also for other SODAQ boards’ family.

Now it’s time to start hacking! This guide is going to provide you all the basics to start managing uplink & downlink messages with the ONE V3, Ubidots and TTN.

IMPORTANT NOTE: The sample codes provided in this guide are not designed to manage battery as efficiently as possible. Their main purpose is to show the management of uplink & downlink message using The Things Network library

Requirements

 

Step-by-Step

  1. Setting up Arduino IDE

  2. TTN Device registration 

  3. Uplink messages management

  4. Sending messages to TTN

  5. Custom payload setup

  6. Ubidots integration setup

  7. Data verification

  8. Downlink messages management

  9. Variable creation

  10. Downlink Event creation in Ubidots

  11. Data verification

  12. Demo

  13. Summary

1. Setting up Arduino IDE

  1. To be able to work with the SODAQ ONE V3 in the Arduino IDE, you need to install the SODAQ Platform using the preconfigured Arduino Board Manager by assigning the following URL in the Preferences menu:

http://downloads.sodaq.net/package_sodaq_samd_index.json

2. With the SODAQ platform installed, select the SODAQ device you are working with. In this case, we are working with a “SODAQ ONE”. To select the board from your Arduino IDE, select Tools > Board > SODAQ ONE

3. Install “The Things Network” library.

NOTE: If you are not familiar with adding new boards or installing libraries within the Arduino IDE, refer to this article for additional guidance

2. TTN Device registration

To start managing the device's data with TTN LoRaWAN network server, you ought to register the SODAQ ONE V3 within an application. But, you will need the hardware EUI which is the unique identifier of your board. The steps below show how to get the credentials required, plus the device registration process. 

1. Upload the following code into the board to get the hardware EUI to register your device. Once the code is uploaded, open the serial monitor and write the command sys get hweui to obtain the device EUI. 

NOTE: The serial monitor configuration ought to be “Both NL & CR” 

/*
 * Compatible with:
 * SODAQ MBILI
 * SODAQ Autonomo
 * SODAQ ONE
 * SODAQ ONE BETA
 * SODAQ EXPLORER
 */

#include "Arduino.h"

#if defined(ARDUINO_AVR_SODAQ_MBILI)
#define debugSerial Serial
#define loraSerial Serial1

#elif defined(ARDUINO_SODAQ_AUTONOMO) || defined(ARDUINO_SODAQ_ONE) || defined(ARDUINO_SODAQ_ONE_BETA)
#define debugSerial SerialUSB
#define loraSerial Serial1

#elif defined(ARDUINO_SODAQ_EXPLORER)
#define debugSerial SerialUSB
#define loraSerial Serial2

#else
// please select a sodaq board
#endif

void setup() {
  // Enable LoRa module
  #if defined(ARDUINO_SODAQ_AUTONOMO)
  pinMode(BEE_VCC, OUTPUT);
  digitalWrite(BEE_VCC, HIGH); //set input power BEE high
  #elif defined(ARDUINO_AVR_SODAQ_MBILI)
  pinMode(20, OUTPUT);
  digitalWrite(20, HIGH); //set input power BEE high
  #endif

  // Hard reset the RN module
  #if defined(LORA_RESET)
  pinMode(LORA_RESET, OUTPUT);
  digitalWrite(LORA_RESET, LOW);
  delay(100);
  digitalWrite(LORA_RESET, HIGH);
  delay(100);
  #endif

  while ((!debugSerial) && (millis() < 10000)){
    // wait 10 seconds for serial monitor
  }
 
  debugSerial.begin(57600);
  loraSerial.begin(57600);
 
  debugSerial.println("Please send command");
}

void loop() {  

    //send and receive data with serial
     if (debugSerial.available()){
      //debugSerial.print("SEND:    ");
      while (debugSerial.available()) {
        uint8_t inChar = debugSerial.read();
        //debugSerial.write(inChar);
        loraSerial.write(inChar);
      }
     }

     if (loraSerial.available()){
      //debugSerial.print("RECEIVE: ");
      while (loraSerial.available()) {
        uint8_t inChar = loraSerial.read();
        debugSerial.write(inChar);
      }
     }
}

Once the code is uploaded into the board, you should receive the following result after requesting the hardware EUI: 

Now with the hardware EUI obtained, it’s time to register a device within an application on TTN.

2. First, go to the TTN console and enter to the application section to add a new application. To create the application, just press “add application”:

 

Then, in the following page assign the parameters below:

  • Application ID: The unique identifier of your application on the network.

  • Description (optional): a human readable description.

  • Handler registration: handler where you want to register the application. 

Once the application is created, you will be redirected to the application overview. 

3. To register a device, go to the device tab. Then press “Register Device

 

Then, in the following page assign the parameters below:

  • Device ID: the unique identifier for the device in the application. The device ID will be immutable.

  • Device EUI: the unique identifier for the device on the network.

The rest of parameters (App Key, and App EUI) are automatically assigned by TTN.

Once the device’s registration its done, you will be redirected to the device overview. At this point, the device’s status is “never seen” because we are not sending any message yet. 

3. Uplink messages management

To start sending data (uplink messages) to Ubidots, you need to establish some configurations in the TTN side. Please follow the steps below carefully to establish the proper communication between your device, TTN, and Ubidots. 

  • Sending messages to TTN

  1. Copy the following code and place it in the Arduino IDE. Once the code is pasted, you need to assign the parameters App EUI, App Key, and freqPlan.

The App EUI and App Key can be found in the device’s overview. The freqPlan is the zone where your device is going to be deployed. 

PRO TIP: At the bottom of the device’s overview an “example code” can be found ready to replace it into the code. 

#include <TheThingsNetwork.h>

// Define inputs/outputs pins
#define relay 10
#define potentiometer A11

// Set your AppEUI and AppKey
const char *appEui = "0000000000000000";
const char *appKey = "00000000000000000000000000000000";

#define loraSerial Serial1
#define debugSerial SerialUSB

// Replace REPLACE_ME with TTN_FP_EU868 or TTN_FP_US915
#define freqPlan REPLACE_ME // assign your freq. zone

TheThingsNetwork ttn(loraSerial, debugSerial, freqPlan);

void setup()
{
  loraSerial.begin(57600);
  debugSerial.begin(9600);

  // Wait a maximum of 10s for Serial Monitor
  while (!debugSerial && millis() < 10000)
    ;

  // status & join requests
  debugSerial.println("-- STATUS");
  ttn.showStatus();

  debugSerial.println("-- JOIN");  
  ttn.join(appEui, appKey);

  // Handle downlink data
  ttn.onMessage(message);

  pinMode(relay, OUTPUT);
  pinMode(potentiometer, INPUT);
}

void loop()
{
  debugSerial.println("-- LOOP");

  uint32_t potentiometer_value = analogRead(potentiometer);
  debugSerial.println(potentiometer_value);

  // Prepare payload of 2 byte to report potentiometer values
  byte payload[2];
  payload[0] = highByte(potentiometer_value);
  payload[1] = lowByte(potentiometer_value);

  // Send potentiometer value
  ttn.sendBytes(payload, sizeof(payload));

  delay(10000);
}

/*
 * Declaration for the downlink message received
 */
void message(const uint8_t *payload, size_t size, port_t port)
{
  debugSerial.println("-- MESSAGE");
  debugSerial.print("Received " + String(size) + " bytes on port " + String(port) + ":");

  if (payload[0] == 1) {
    digitalWrite(relay, HIGH);
  } else {
    digitalWrite(relay, LOW);
  }

  debugSerial.println();
}

2. Once the parameters have been assigned properly, upload the code into the board by pressing the upload button located at the left-upper side of the Arduino IDE interface. 

3. Open the Serial Monitor to debug the code; check once the join request is accepted, and every time a new value is being sent to TTN. Now, you'll see the device's status activated.

4. Verify if the data which have been sent are being received properly at TTN. To do this, refer to the “Data” tab: 

  • Custom payload setup

1. Go to the Application overview, and refer to the “Payload Formats” tab. Then, assign the following code into the decoder section to format the payload in one allowed by Ubidots, which a JSON object. 

function Decoder(bytes, port) {
  // Decode an uplink message from a buffer
  var potentiometer = (bytes[0] << 8) | bytes[1];

  return {
    potentiometer: potentiometer
  };
}

2. [OPTIONAL] Once you have the decoder code defined in TTN, you can test the payload which is being sent from the device to verify if the decoded value is the right one. 

As you can see the value sent from my device is equal to: 03 FF 

Then, assign the same payload sent and the result should be the initial integer printed in the serial monitor: 

3. To finish, press the “Save payload functions” button. At this point, if you refer to the data section you will notice how the data is being automatically decoded after saving the decoder function. 

  • Ubidots integration setup

1. Go to the “Integration” tab to add a new integration. To create a new integration, just press “add integration

Then, select Ubidots as integration: 

In the next window, assign the following parameters: 

With all the parameters assigned, your integration should look like the one below:

 

To finish, press “Add integration”. You’ll be redirected to the integration overview:

At this point, once a new value is received in TTN from the device, a new device is going to be automatically created into your Ubidots account. 

  • Data verification

1. Go to the device section of your Ubidots account (Devices > Devices) to verify the new device created identified with the device EUI.

Select the device created to verify the variable in charge of receiving the analog inputs of the board, which in this case is the variable called “Potentiometer”:

2. [ OPTIONAL - PRO TIP]: If you are using multiple devices to transmit data, we recommend editing the device name, assigning a friendly and readable name for easier identification:

4. Downlink messages management

To manage downlink messages with Ubidots & TTN, you need to create a new Ubidots Event conditioning a specific variable to trigger the TTN Downlink event. For a detailed explanation about the integration, please refer to this guide

  • Variable creation

1. Create a new raw variable called “relay” into the device automatically created after the integration setup. Having as result an empty variable, like the one shown below:

  • Downlink Event creation in Ubidots

  1. Go to the Event section (Data > Events) of your Ubidots account, press the plus orange icon located at the right upper corner to create a new event.

2. For the trigger logic select the variable previously created “Relay” with the following condition: If the variable’s value (relay activated) is equal to 1, then trigger the action.

Reference to the image below for a better understanding. 

NOTE: To learn more about the Ubidots Event Logic, refer to this guide.

To continue, press the right arrow icon located at the bottom-left side of the page. 

3. Select “TTN Downlink” as action.

4. Assign all the parameters required based on your application. To learn more about where to find the parameters needed in TTN, please refer to their official documentation.

IMPORTANT NOTE: The downlink event requires a new generic HTTP integration in TTN, different than the uplink one previously created using the Ubidots integration to allow the incoming messages from Ubidots. 

5. Taking as reference the use case of a relay, the expected behavior is to schedule a downlink message every time the relay change its status. Then, once a new uplink message is received the scheduled message is sent to the device to change the relay's status.

To do this, in the “Active trigger” section, assign the raw value desired to be sent once the variable’s value relay is activated (equal to 1). It’s important to highlight that the raw value needs to be encoded in base64

  • Activation trigger - Payload Raw: 1 - “AQ==”

Similarly, in the “Back to normal” section, assign the raw value desired to be sent once the variable’s value relay is deactivated (equal to 0).

  • Back to normal - Payload Raw: 0 - “AA==”

To finish, press the green check icon to save the changes. Then, press the right arrow to finish the event creation. 

  • Data verification

Now with the downlink integration finished, create a switch widget related to the relay variable to change its status, and verify how the message is being received in TTN data section. Also, you'll notice how the message is being received in the device too. 

5. Demo

Final behavior using TTN & Ubidots to manage uplink/downlink messages:

6. Summary

LPWAN applications are having a huge impact on the IoT ecosystem, and much more if the integrations required are rapidly to set up, just by using a few clicks. All of these makes the management of “things” easier for the IoT community, empowering more IoT engineers to grow their deployments fast and reliably

Did this answer your question?