segunda-feira, 27 de fevereiro de 2023

PROGRAMANDO WISOL LSM110A ( LoRaWAN CLASS A - OTAA) COM ARDUINO E ACESSANDO LoRaWAN TTN - RAK LIB - BME680

    

BETA BETA BETA BETA BETA BETA BETA BETA 

O objetivo deste BLOG é demonstrar como é possível programar o módulo WISOL LSM110A via ARDUINO e assim utilizá-lo como OPENCPU.

Será publicada a temperatura obtida pelo sensor BME680 na rede LoRaWAN TTN (CLASS A, OTAA) a cada 60 segundos.

Temp xx.xx

BETA BETA BETA BETA BETA BETA BETA BETA


LSM110A Starter KIT
Módulo

O LSM110A é um módulo de última geração que integra o STMicroelectronics STM32WL. É muito menos consumo atual para o dispositivo IoT para estender a vida útil da bateria. E, também suporta ambas as tecnologias – Sigfox e LoRa – com o próprio módulo LSM110A.

Você pode trocar Sigfox ou LoRa com ele para que você também possa reduzir o custo. É altamente otimizado para solução de IoT (Alto Consumo de Energia, Baixo Custo)

BREAKOUT para testes


Esquema Elétrico - últimas correções





PLACA MONTADA



CONEXÃO COM ST-LINK V2 E UART



BME680

O BME680 é o primeiro sensor de gás que integra sensores de gás, pressão, umidade e temperatura de alta linearidade e alta precisão. É especialmente desenvolvido para aplicações móveis e wearables, onde o tamanho e o baixo consumo de energia são requisitos críticos. O BME680 garante - dependendo do modo de operação específico - um consumo otimizado, estabilidade a longo prazo e alta robustez EMC. 

TTN
The Thing Network

A Rede de Coisas (TTN) é uma iniciativa iniciada pela sociedade civil holandesa. O objetivo é ter redes LoRaWAN instaladas em todas as cidades do mundo. Ao interconectar essas redes locais, a TTN quer construir uma infra-estrutura mundial para facilitar uma Internet das Coisas (IoT) pública.

A The Things Network (TTN) é o servidor IoT na nuvem utilizado nesse projeto. É um dos servidores gratuitos para LoRaWAN mais utilizados, com mais de 90 mil desenvolvedores, mais de 9 mil gateways de usuários conectados à rede ao redor do mundo e mais de 50 mil aplicações em funcionamento.

A TTN comercializa nós e gateways LoRa e provê treinamento individual e coletivo para empresas e desenvolvedores que desejam utilizar o LoRa. Possui uma comunidade bem ativa nos fóruns, sempre colaborando e ajudando a resolver problemas, além de prover diversos meios de integrar a TTN com a aplicação que se deseja usar. Possui integração nativa com diversas aplicações como: Cayenne, Hypertext Transfer Protocol (HTTP), permitindo ao usuário realizar uplink para um gateway e receber downlink por HTTP, OpenSensors e EVRYTHNG . Caso o usuário queira criar sua própria aplicação, a TTN disponibiliza Application Programming Interface (API) para uso com Message Queuing Telemetry Transport (MQTT) e diversos Software Developer Kits (SDK) para uso com as linguagens Python, Java , Node.Js , NODE-RED e Go

A rede TTN utiliza o protocolo LoRaWAN objetivando uma cobertura em longo alcance para os dispositivos da rede, caracterizando-a assim com uma Wide Area Network (WAN). Devido ao baixo consumo de energia e ao uso da tecnologia LoRa, é chamada de LPWAN (Low Power Wide Area Network). O grande diferencial da TTN é seu estabelecimento como uma rede aberta (open-source) e colaborativa (crowd-sourced), onde qualquer usuário pode contribuir instalando um gateway em sua residência.

Os elementos da TTN são classificados como: 

• Endpoints (nós): Os dispositivos responsáveis pela camada de sensoriamento da rede, o endpoint LoRaWAN. Podem coletar informações através de sensores e também acionar dispositivos/máquinas via atuadores. São configurados através de uma das três classes distintas do protocolo LaRaWAN; 

• Gateways: Elementos responsáveis por concentrar e processar as informações enviadas pelos endpoints. Os gateways em geral estão conectados a internet, seja por WiFi/Ethernet ou 3G/4G em locais remotos. Mesmo que uma mesma rede LoRaWAN tenha diferentes objetivos, baseados em aplicações distintas, os gateways possuem o objetivo comum de fornecer a maior área de cobertura possível; 

• Aplicações: Conectar e interligar os diferentes dispositivos da rede TTN para o fornecimento de informações gerais sobre a coleta de dados dos dispositivos.

BME680 LIB

LSM110A e ARDUINO (RAKWIRELESS)

LSM110A é baseado em STM32WL55.  No Arduino RAKWIRELESS existe o core similar, o qual deve ser modificado para ser compatível com LSM110A

Baixar RAKWIRELESS Arduino

Versão: 3.5.1
https://raw.githubusercontent.com/RAKWireless/RAKwireless-Arduino-BSP-Index/main/package_rakwireless.com_rui_index.json

Pronto

Altere radio_board_if.c para

int32_t RBI_ConfigRFSwitch(RBI_Switch_TypeDef Config) { switch (Config) { case RBI_SWITCH_OFF: { /* Turn off switch */ HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET); break; } case RBI_SWITCH_RX: { /*Turns On in Rx Mode the RF Switch */ HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET); break; } case RBI_SWITCH_RFO_LP: { /*Turns On in Tx Low Power the RF Switch */ HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET); break; } case RBI_SWITCH_RFO_HP: { /*Turns On in Tx High Power the RF Switch */ HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET); break; } default: break; } return 0; }

































Altere radio_board_if.h para

#define RF_SW_CTRL1_PIN GPIO_PIN_12 #define RF_SW_CTRL1_GPIO_PORT GPIOB #define RF_SW_CTRL1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define RF_SW_CTRL1_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() /* official version */ #define RF_SW_CTRL2_PIN GPIO_PIN_13 #define RF_SW_CTRL2_GPIO_PORT GPIOC #define RF_SW_CTRL2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define RF_SW_CTRL2_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()

Altere Cristal para uso de frequênciais (BAND) mais altas (board.c)

uint8_t BoardGetHardwareFreq(void)
{
    uint8_t hardwareFreq = 0;
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /*Configure GPIO pin : PB12 */
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    hardwareFreq  = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12);
hardwareFreq = 1;

    HAL_GPIO_DeInit(GPIOB,GPIO_PIN_12);
    return hardwareFreq;
}

Altere Placa para RAK3272-SIP, compile


Grave com o STM32 Programmer o BOOTLOADER no LSM110A 

Assim, pode-se transferir o programa via Serial, através dos pinos PA2 e PA3 do LSM110A.


RAK3272-SiP_latest_final.hex


Ok, o ambiente de desenvolvimento está pronto. Abra Projeto Arduino LORAWAN_OTA.INOconfigure 3 parâmetros para LoRaWAN_OTAA os quais deve ser obtidos no servidor TTN.

#define OTAA_BAND     RAK_REGION_AU915
#define OTAA_DEVEUI   {0x00, 0x80, 0xE1, 0xXX, 0x05, 0xXX, 0xXX, 0x0A}
#define OTAA_APPEUI   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99}
#define OTAA_APPKEY   {0xFF, 0x9F, 0x13, 0x8B, 0x40, 0x18, 0x0A, 0xA4, 0x5D, 0x68, 0x46, 0xE0, 0xA0, 0x14, 0x69, 0x54}

Transferindo


Executando

Uma vez gravado o Software, o LSM110A fará o JOIN na LoRaWAN enviará o pacote Test a cada 60 segundos.


TTN




Neste exemplo, será transmitido para LoRaWAN (TTN) os dados

Segue código final

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

#define OTAA_PERIOD   (20000)
/*************************************

   LoRaWAN band setting:
     RAK_REGION_EU433
     RAK_REGION_CN470
     RAK_REGION_RU864
     RAK_REGION_IN865
     RAK_REGION_EU868
     RAK_REGION_US915
     RAK_REGION_AU915
     RAK_REGION_KR920
     RAK_REGION_AS923

 *************************************/
#define OTAA_BAND     RAK_REGION_AU915
#define OTAA_DEVEUI   {0x88, 0x57, 0xXX, 0xFF, 0xXX, 0xEE, 0x8C, 0xXX}
#define OTAA_APPEUI   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
#define OTAA_APPKEY   {0x46, 0x28, 0xCB, 0xXX, 0x4F, 0xF9, 0x4B, 0xA5, 0xB0, 0x04, 0xE2, 0xDC, 0x01, 0xXX, 0x89, 0xA2}

/** Packet buffer for sending */
char collected_data[64] = { 0 };

void recvCallback(SERVICE_LORA_RECEIVE_T * data)
{
  if (data->BufferSize > 0) {
    Serial.println("Something received!");
    for (int i = 0; i < data->BufferSize; i++) {
      Serial.printf("%x", data->Buffer[i]);
    }
    Serial.print("\r\n");
  }
}

void joinCallback(int32_t status)
{
  Serial.printf("Join status: %d\r\n", status);
}

void sendCallback(int32_t status)
{
  if (status == 0) {
    Serial.println("Successfully sent");
  } else {
    Serial.println("Sending failed");
  }
}

void setup()
{
 unsigned status;
  
  Serial.begin(115200, RAK_AT_MODE);

  Serial.println("BME680 LoRaWAN");

  if (!bme.begin()) {
    Serial.println("Could not find a valid BME680 sensor, check wiring!");
    while (1);
  }

  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms
  
  // OTAA Device EUI MSB first
  uint8_t node_device_eui[8] = OTAA_DEVEUI;
  // OTAA Application EUI MSB first
  uint8_t node_app_eui[8] = OTAA_APPEUI;
  // OTAA Application Key MSB first
  uint8_t node_app_key[16] = OTAA_APPKEY;

  if (!api.lorawan.appeui.set(node_app_eui, 8)) {
    Serial.printf("LoRaWan OTAA - set application EUI is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.appkey.set(node_app_key, 16)) {
    Serial.printf("LoRaWan OTAA - set application key is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.deui.set(node_device_eui, 8)) {
    Serial.printf("LoRaWan OTAA - set device EUI is incorrect! \r\n");
    return;
  }

  if (!api.lorawan.band.set(OTAA_BAND)) {
    Serial.printf("LoRaWan OTAA - set band is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {
    Serial.printf("LoRaWan OTAA - set device class is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.njm.set(RAK_LORA_OTAA))  // Set the network join mode to OTAA
  {
    Serial.
  printf("LoRaWan OTAA - set network join mode is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.join())  // Join to Gateway
  {
    Serial.printf("LoRaWan OTAA - join fail! \r\n");
    return;
  }

  /** Wait for Join success */
  while (api.lorawan.njs.get() == 0) {
    Serial.print("Wait for LoRaWAN join...");
    api.lorawan.join();
    delay(10000);
  }

  if (!api.lorawan.adr.set(true)) {
    Serial.printf
  ("LoRaWan OTAA - set adaptive data rate is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.rety.set(1)) {
    Serial.printf("LoRaWan OTAA - set retry times is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.cfm.set(1)) {
    Serial.printf("LoRaWan OTAA - set confirm mode is incorrect! \r\n");
    return;
  }

  /** Check LoRaWan Status*/
  Serial.printf("Duty cycle is %s\r\n", api.lorawan.dcs.get()? "ON" : "OFF"); // Check Duty Cycle status
  Serial.printf("Packet is %s\r\n", api.lorawan.cfm.get()? "CONFIRMED" : "UNCONFIRMED");  // Check Confirm status
  uint8_t assigned_dev_addr[4] = { 0 };
  api.lorawan.daddr.get(assigned_dev_addr, 4);
  Serial.printf("Device Address is %02X%02X%02X%02X\r\n", assigned_dev_addr[0], assigned_dev_addr[1], assigned_dev_addr[2], assigned_dev_addr[3]);  // Check Device Address
  Serial.printf("Uplink period is %ums\r\n", OTAA_PERIOD);
  Serial.println("");
  api.lorawan.registerRecvCallback(recvCallback);
  api.lorawan.registerJoinCallback(joinCallback);
  api.lorawan.registerSendCallback(sendCallback);
}

void uplink_routine()
{
  /** Payload of Uplink */
  uint8_t data_len = 0;

  String s = String(collected_data);
  data_len = s.length();

  Serial.println("Data Packet:");
  for (int i = 0; i < data_len; i++) {
    Serial.printf("0x%02X ", collected_data[i]);
  }
  Serial.println("");

  /** Send the data package */
  if (api.lorawan.send(data_len, (uint8_t *) & collected_data, 2, true, 1)) {
    Serial.println("Sending is requested");
  } else {
    Serial.println("Sending failed");
  }
}

void loop()
{
  static uint64_t last = 0;
  static uint64_t elapsed;

  if (! bme.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }
  Serial.print("Temperature = ");
  Serial.print(bme.temperature);
  Serial.println(" *C");

  sprintf(collected_data,"Temp %f",bme.temperature);

  Serial.print("Pressure = ");
  Serial.print(bme.pressure / 100.0);
  Serial.println(" hPa");

  Serial.print("Humidity = ");
  Serial.print(bme.humidity);
  Serial.println(" %");

  Serial.print("Gas = ");
  Serial.print(bme.gas_resistance / 1000.0);
  Serial.println(" KOhms");

  Serial.print("Approx. Altitude = ");
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  if ((elapsed = millis() - last) > OTAA_PERIOD) {
    if(api.lorawan.njs.get() == 1)
        uplink_routine();
    last = millis();
  }
  //Serial.printf("Try sleep %ums..", OTAA_PERIOD);
  api.system.sleep.all(OTAA_PERIOD);
  //Serial.println("Wakeup..");
}

Execução


Gateway


Montagem


DOWNLINK message




Fontes:

Dúvidas

FORUM

Atenção:

Com a nova versão da LIB da RAK, a 4.0.0,  LIB BME680 da Adafruit gerou estouro de memória ROM.

Sobre a SMARTCORE

A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portfólio inclui modem 2G/3G/4G/NB-IoT/Cat.M, satelital, módulos WiFi, Bluetooth, GNSS / GPS, Sigfox, LoRa, leitor de cartão, leitor QR code, mecanismo de impressão, mini-board PC, antena, pigtail, LCD, bateria, repetidor GPS e sensores.

Mais detalhes em www.smartcore.com.br

sábado, 25 de fevereiro de 2023

PROGRAMMING WISOL LSM110A ( LoRaWAN CLASS A - OTAA) WITH ARDUINO AND ACCESSING LoRaWAN TTN - RAKWIRELLES LIB (PORT)

 

The purpose of this BLOG is to demonstrate how it is possible to program the WISOL LSM110A module via ARDUINO and thus use it as OPENCPU.

"Test" will be published on the LoRaWAN TTN network (CLASS A, OTAA) every 60 seconds (FPU).

LSM110A Starter KIT
Module

The purpose of this LSM110A is a state-of-the-art module that integrates the STMicroelectronics STM32WL. It is much less current consumption for the IoT device to extend battery life. And it also supports both technologies – Sigfox and LoRa – with the LSM110A module itself.

You can trade Sigfox or LoRa with it so you can also reduce the cost. It is highly optimized for IoT (High Energy Consumption, Low Cost)BLOG solution is to demonstrate how it is possible to program the WISOL LSM110A module via ARDUINO and thus use it as OPENCPU.

Test will be published on the LoRaWAN TTN network (CLASS A, OTAA) every 60 seconds.

BREAKOUT


|Schematic - updated





Assembled



ST-LINK V2 CONNECTION 



TTN
The Thing Network

The Things Network (TTN) is the IoT server in the cloud used in this project. It is one of the most widely used free LoRaWAN servers, with more than 90,000 developers, more than 9,000 gateways of network-connected users around the world and more than 50,000 applications in operation.


LSM110A AND ARDUINO (RAKWIRELESS)

LSM110A is based on STM32WL55.  In Arduino RAKWIRELESS there is the similar core, which must be modified to be compatible with LSM110A

Download RAKWIRELESS Arduino
https://raw.githubusercontent.com/RAKWireless/RAKwireless-Arduino-BSP-Index/main/package_rakwireless.com_rui_index.json

Ready

Change radio_board_if.c to

int32_t RBI_ConfigRFSwitch(RBI_Switch_TypeDef Config) { switch (Config) { case RBI_SWITCH_OFF: { /* Turn off switch */ HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET); break; } case RBI_SWITCH_RX: { /*Turns On in Rx Mode the RF Switch */ HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET); break; } case RBI_SWITCH_RFO_LP: { /*Turns On in Tx Low Power the RF Switch */ HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET); break; } case RBI_SWITCH_RFO_HP: { /*Turns On in Tx High Power the RF Switch */ HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET); break; } default: break; } return 0; }



































Change radio_board_if.h to

#define RF_SW_CTRL1_PIN GPIO_PIN_12 #define RF_SW_CTRL1_GPIO_PORT GPIOB #define RF_SW_CTRL1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define RF_SW_CTRL1_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() /* official version */ #define RF_SW_CTRL2_PIN GPIO_PIN_13 #define RF_SW_CTRL2_GPIO_PORT GPIOC #define RF_SW_CTRL2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define RF_SW_CTRL2_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()

Change Crystal to use higher frequencies (BAND) (board.c)

uint8_t BoardGetHardwareFreq(void)
{
    uint8_t hardwareFreq = 0;
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /*Configure GPIO pin : PB12 */
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    hardwareFreq  = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12);
hardwareFreq = 1;

    HAL_GPIO_DeInit(GPIOB,GPIO_PIN_12);
    return hardwareFreq;
}

Change Arduino config to RAK3272-SIP and compile


Burn with the STM32 Programmer the BOOTLOADER on the LSM110A 

Thus, you can transfer the program via Serial via the PA2 and PA3 pins of the LSM110A.


RAK3272-SiP_latest_final


Okay, the development environment is ready. Open Arduino project LORAWAN_OTA. INO, configure 3 parameters for LoRaWAN_OTAA must be obtained on the TTN server.

#define OTAA_BAND     RAK_REGION_AU915
#define OTAA_DEVEUI   {0x00, 0x80, 0xE1, 0xXX, 0x05, 0xXX, 0xXX, 0x0A}
#define OTAA_APPEUI   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99}
#define OTAA_APPKEY   {0xFF, 0x9F, 0x13, 0x8B, 0x40, 0x18, 0x0A, 0xA4, 0x5D, 0x68, 0x46, 0xE0, 0xA0, 0x14, 0x69, 0x54}

Transfer


Executing

Once the Software is burned, the LSM110A will join lorawan will send the Test package every 60 seconds.


TTN



In this example, the data will be transmitted to LoRaWAN (TTN)

Follow final code

#define OTAA_PERIOD   (60000)
/*************************************

   LoRaWAN band setting:
     RAK_REGION_EU433
     RAK_REGION_CN470
     RAK_REGION_RU864
     RAK_REGION_IN865
     RAK_REGION_EU868
     RAK_REGION_US915
     RAK_REGION_AU915
     RAK_REGION_KR920
     RAK_REGION_AS923

 *************************************/
#define OTAA_BAND     RAK_REGION_AU915
#define OTAA_DEVEUI   {0x00, 0xXX, 0xXX, 0x15, 0x05, 0xXX, 0xXX, 0x0A}
#define OTAA_APPEUI   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99}
#define OTAA_APPKEY   {0xFF, 0x9F, 0x13, 0x8B, 0x40, 0x18, 0x0A, 0xA4, 0x5D, 0x68, 0x46, 0xE0, 0xA0, 0x14, 0x69, 0x54}

/** Packet buffer for sending */
uint8_t collected_data[64] = { 0 };

void recvCallback(SERVICE_LORA_RECEIVE_T * data)
{
  if (data->BufferSize > 0) {
    Serial.println("Something received!");
    for (int i = 0; i < data->BufferSize; i++) {
      Serial.printf("%x", data->Buffer[i]);
    }
    Serial.print("\r\n");
  }
}

void joinCallback(int32_t status)
{
  Serial.printf("Join status: %d\r\n", status);
}

void sendCallback(int32_t status)
{
  if (status == 0) {
    Serial.println("Successfully sent");
  } else {
    Serial.println("Sending failed");
  }
}

void setup()
{
  Serial.begin(115200, RAK_AT_MODE);

  Serial.println("RAKwireless LoRaWan OTAA Example");
  Serial.println("------------------------------------------------------");

  // OTAA Device EUI MSB first
  uint8_t node_device_eui[8] = OTAA_DEVEUI;
  // OTAA Application EUI MSB first
  uint8_t node_app_eui[8] = OTAA_APPEUI;
  // OTAA Application Key MSB first
  uint8_t node_app_key[16] = OTAA_APPKEY;

  if (!api.lorawan.appeui.set(node_app_eui, 8)) {
    Serial.printf("LoRaWan OTAA - set application EUI is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.appkey.set(node_app_key, 16)) {
    Serial.printf("LoRaWan OTAA - set application key is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.deui.set(node_device_eui, 8)) {
    Serial.printf("LoRaWan OTAA - set device EUI is incorrect! \r\n");
    return;
  }

  if (!api.lorawan.band.set(OTAA_BAND)) {
    Serial.printf("LoRaWan OTAA - set band is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {
    Serial.printf("LoRaWan OTAA - set device class is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.njm.set(RAK_LORA_OTAA)) // Set the network join mode to OTAA
  {
    Serial.
printf("LoRaWan OTAA - set network join mode is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.join()) // Join to Gateway
  {
    Serial.printf("LoRaWan OTAA - join fail! \r\n");
    return;
  }

  /** Wait for Join success */
  while (api.lorawan.njs.get() == 0) {
    Serial.print("Wait for LoRaWAN join...");
    api.lorawan.join();
    delay(10000);
  }

  if (!api.lorawan.adr.set(true)) {
    Serial.printf
("LoRaWan OTAA - set adaptive data rate is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.rety.set(1)) {
    Serial.printf("LoRaWan OTAA - set retry times is incorrect! \r\n");
    return;
  }
  if (!api.lorawan.cfm.set(1)) {
    Serial.printf("LoRaWan OTAA - set confirm mode is incorrect! \r\n");
    return;
  }

  /** Check LoRaWan Status*/
  Serial.printf("Duty cycle is %s\r\n", api.lorawan.dcs.get()? "ON" : "OFF"); // Check Duty Cycle status
  Serial.printf("Packet is %s\r\n", api.lorawan.cfm.get()? "CONFIRMED" : "UNCONFIRMED"); // Check Confirm status
  uint8_t assigned_dev_addr[4] = { 0 };
  api.lorawan.daddr.get(assigned_dev_addr, 4);
  Serial.printf("Device Address is %02X%02X%02X%02X\r\n", assigned_dev_addr[0], assigned_dev_addr[1], assigned_dev_addr[2], assigned_dev_addr[3]); // Check Device Address
  Serial.printf("Uplink period is %ums\r\n", OTAA_PERIOD);
  Serial.println("");
  api.lorawan.registerRecvCallback(recvCallback);
  api.lorawan.registerJoinCallback(joinCallback);
  api.lorawan.registerSendCallback(sendCallback);
}

void uplink_routine()
{
  /** Payload of Uplink */
  uint8_t data_len = 0;
  collected_data[data_len++] = (uint8_t) 't';
  collected_data[data_len++] = (uint8_t) 'e';
  collected_data[data_len++] = (uint8_t) 's';
  collected_data[data_len++] = (uint8_t) 't';

  Serial.println("Data Packet:");
  for (int i = 0; i < data_len; i++) {
    Serial.printf("0x%02X ", collected_data[i]);
  }
  Serial.println("");

  /** Send the data package */
  if (api.lorawan.send(data_len, (uint8_t *) & collected_data, 2, true, 1)) {
    Serial.println("Sending is requested");
  } else {
    Serial.println("Sending failed");
  }
}

void loop()
{
  static uint64_t last = 0;
  static uint64_t elapsed;

  if ((elapsed = millis() - last) > OTAA_PERIOD) {
    uplink_routine();

    last = millis();
  }
  //Serial.printf("Try sleep %ums..", OTAA_PERIOD);
  api.system.sleep.all(OTAA_PERIOD);
  //Serial.println("Wakeup..");
}

Gateway


Mounting


DOWNLINK message


References:

Questions

FORUM

About  SMARTCORE

SmartCore provides modules for wireless communication, biometrics, connectivity, tracking and automation.
Our portfolio includes 2G/3G/4G/4G/NB-IoT/Cat.M modem, satellite, WiFi modules, Bluetooth, GNSS/GPS, Sigfox, LoRa, card reader, QR code reader, printing engine, mini-board PC, antenna, pigtail, LCD, battery, GPS repeater and sensors.

More details in www.smartcore.com.br