segunda-feira, 15 de julho de 2024

PROGRAMANDO WISOL LSM110A ( LoRaWAN CLASS A - OTAA) COM STM32DUINO LoRaWAN E ACESSANDO LoRaWAN - EVERYNET - ASSYNC

   

Baseado no canais de uplink, downlink, dwell, etc

LA915 · Everynet Network Server Máscara de canais (Join, Uplink, Downlink)

Foram alterados os arquivos RegionAU915.h e RegionAU915.c para serem compatíveis somente com EVERYNET.

Entre em contato para testes.

LORAMAC VERSION 1.0.3

O objetivo deste BLOG é demonstrar como é possível programar o módulo WISOL LSM110A via Arduino Framework (STMDUINO32 com LoRaWAN) e assim utilizá-lo como OPENCPU.

Será publicada uma sequência de bytes {0xde, 0xad, 0xbe, 0xef} a cada 20 segundos na rede LoRaWAN EVERYNET (CLASS A, OTAA).

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


ATENÇÃO: PARA UTILIZAR SERVIÇOS DA EVERYNET, CONTATE E PEÇA OS BROKERS.

A American Tower é uma multi nacional presente em mais de 16 países, com de 160.000 sites no mundo onde ela aluga espaço para as operadoras colocarem suas torres celulares e rádios. No Brasil ela possui mais de 19.000 sites, tendo uma ampla presença geográfica. Ela decidiu de forma pioneira no Brasil lançar uma rede LoRaWAN junto com a EveryNet, de forma a permitir o avanço do IoT.

O cliente que tem um produto que siga o padrão LoRaWAN pode contratar o serviço de dados da American Tower / EveyNet de forma a se preocupar somente com seus devices e aplicação, sem ter que se focar na infra-estrutura e gateways.





OTAA

• Vantagem: a rede gera e envia as chaves de criptografia; isto torna mais seguro. Devido ao maior nível de segurança, o OTAA é o método mais utilizado em IoT / LoRaWAN. 

• AppEUI: Este é um identificador de aplicativo exclusivo usado para agrupar objetos. este
endereço, 64 bits, é usado para classificar os dispositivos periféricos por aplicação. Essa configuração pode seja ajustado. 

• DevEUI: Este identificador, configurado de fábrica, torna cada objeto único. Em princípio, esta
configuração não pode ser ajustada. 

• AppKey: esta é uma chave secreta compartilhada entre o dispositivo periférico e a rede. É usado para determinar as chaves da sessão. Essa configuração pode ser ajustada.

Concentre-se na OTAA 

O Servido de Rede é o componente de software encarregado de estabelecer uma conexão com os objetos e gerenciando o núcleo da rede. Durante a conexão OTAA, e supondo que o dispositivo esteja autorizado a conectar-se a rede, a rede troca chaves de criptografia específicas da sessão com o núcleo da rede. O Servidor de Rede então aloca informações específicas para a sessão e as envia para o aparelho periférico:

DevAddr: Endereço lógico (equivalente a um endereço IP) que será usado para todos comunicação subseqüente.

 NetSKey (chave de sessão de rede): chave de criptografia entre o objeto e o operador usado para transmissões e para validar a integridade das mensagens. 

•   AppSKey (chave de sessão do aplicativo): chave de criptografia entre o objeto e operador (através da aplicação) utilizado para as transmissões e para validar a integridade das mensagens

1.1 Entrando na EveryNet

Passo 1: Cadastre-se uma conta de usuário no servidor EveryNet, em https://ns.atc.everynet.io




1.2 Adicionar um dispositivo EndDevice LoRaWan




Esta seção mostra como adicionar um dispositivo EndDevice LoRaWAN à rede LoRaWAN e ver os dados pelo web site da EveryNet. Usamos o LSM110A como um dispositivo de referência - a configuração para outros dispositivos LoRaWAN será semelhante.

Passo 1​: Criar uma definição de dispositivos no EveryNet

Três códigos são necessários para definir o dispositivo no EveryNet: 

Device EUI - código de identificação único para um dispositivo em particular. 
Application EUI - código de identificação para um aplicativo definido no Everynet. 
Application key - Chave exclusiva para proteger as comunicações com um dispositivo em particular.

Para o servidor EveryNet, você pode usar os códigos estabelecidos por você ou criados pelo servidor.

Pressione o sinal de + para abrir a tela abaixo e adicionar device!





Mude para Activation para OTAA e Encryption para NS

LA915-928


Dicas

Device EUI –  deixe o sistema gerar
Application EUI – deixe o sistema gerar
Application key – deixe o sistema gerar

Nota-se que há uma APP EUI já criado por EveryNet, mas esta não é a definida no dispositivo. Para adicionar o APP EUI do dispositivo LSM110A, utilize comandos AT.

Introduzir os códigos ApplicationEUI ApplicationKey obtidos do site da EveryNet e SET para cada um.




Passo 2: Ligar dispositivo LSM110A e vai juntar-se automaticamente a rede EveryNet. 


Depois de ingressar com sucesso, ele vai começar a fazer upload de mensagens para a EveryNet. Selecione a guia Dados e você vai ver os dados que aparecem no painel.

Note que isso pode levar algum tempo para que os dados do dispositivo para aparecer no visor EveryNet.

Dados são mostrados no final da página

Configuração no Servidor final.

Não esquecer de especificar "LoRaWAN protocol version" que você está utilizando em seu EndDevice (LoRaWAN protocol version)



ARDUINO

O que é Arduino? Se você sabe pouco sobre Arduino, por favor dê uma olhada abaixo:

Você conhece Arduino. Instale o IDE primeiro:
https://www.arduino.cc/en/Main/Software

LSM110A e Arduino (STM32DUINO)

LSM110A é baseado em STM32WL55.  No Arduino STM32 existe este core.

Como instalar Arduino STM32? adicionar em Arquivo-->Preferências-->URLs adicionais

https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json


BSP

2.4.0 (última versão na presente data)

LIB STM32LoRaWAN

No github


Baixe em formato ZIP


Adicione ao Arduino IDE:


Pronto


Altere Placa para STM32WL series


Modelo Generic WLE5CCUX


Baseado no canais de uplink, downlink, dwell, etc

LA915 · Everynet Network Server Máscara de canais (Join, Uplink, Downlink)

Foram alterados os arquivos RegionAU915.h e RegionAU915.c para serem compatíveis somente com EVERYNET.

Altere em radio_board_if.c 
em
C:\Users\Usuario\Documents\Arduino\libraries\STM32LoRaWAN-main\src\BSP

// Supported TX modes (LP/HP or both) #if !defined(LORAWAN_TX_CONFIG) #define LORAWAN_TX_CONFIG RBI_CONF_RFO_HP //MIGUEL#define LORAWAN_TX_CONFIG RBI_CONF_RFO_LP_HP #endif #if !defined(LORAWAN_RFSWITCH_PINS) #define LORAWAN_RFSWITCH_PINS PB12,PC13 #define LORAWAN_RFSWITCH_PIN_COUNT 2 #define LORAWAN_RFSWITCH_OFF_VALUES LOW,LOW #define LORAWAN_RFSWITCH_RX_VALUES HIGH,LOW #define LORAWAN_RFSWITCH_RFO_LP_VALUES HIGH,HIGH #define LORAWAN_RFSWITCH_RFO_HP_VALUES HIGH,HIGH #endif










Ok, o ambiente de desenvolvimento está pronto. Abra o  ScheduleAsync.ino  e configure 3 parâmetros para LoRaWAN_OTAA os quais deve ser obtidos no servidor EVERYNET.

bool connected = modem.joinOTAA(/* AppEui */ "0000000000000099", /* AppKey */ "FF9F138B40180AA45D6846E0A0146954", /* DevEui */ "0080E115051FD80A");



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

Segue código final (alterado)

/** * This is a more complex asynchronous sketch that shows how the * asynchronous code could be used in a sketch that uses a scheduler of * some sort to decide what code to run when. * * This sketch defines its own very, very simple scheduler that is not * suggested to be used directly, but just serves to show how a sketch * that uses some scheduling mechanism can be used with the * asynchronous STM32LoRaWAN API and the MaintainNeeded callback. * * The behavior of the sketch is simple, it just blinks a LED * (asynchronously) and at the same time joins the network and transmit * a packet periodically. * * Revised BSD License - https://spdx.org/licenses/BSD-3-Clause.html */ #include <STM32LoRaWAN.h> #include <IWatchdog.h> STM32LoRaWAN modem; char STAT[128]; /********************************************************************* * This part of the sketch defines a very simple scheduler and defines * two tasks that handle the actual work. *********************************************************************/ struct Task { unsigned long time; /* When to run, 0 == never */ void (*callback)(); }; enum Tasks { BLINK_TASK, LORA_WORK_TASK, LORA_MAINTAIN_TASK, NUM_TASKS, }; void do_blink(); void do_lora_maintain(); void do_lora_work(); void maintain_needed_callback(); Task tasks[NUM_TASKS] = { [BLINK_TASK] = {0, do_blink}, [LORA_WORK_TASK] = {0, do_lora_work}, [LORA_MAINTAIN_TASK] = {0, do_lora_maintain}, }; void run_scheduler() { // Super-simple scheduler that just checks all tasks and runs // any that are due. for (size_t i = 0; i < NUM_TASKS; ++i) { if (tasks[i].time != 0 && (int)(millis() - tasks[i].time) >= 0) { tasks[i].time = 0; tasks[i].callback(); } } } /********************************************************************* * This part of the sketch defines the blink task, which just toggles * a LED whenever it is called. * And this is the entry points of the sketch. *********************************************************************/ static const unsigned long BLINK_TASK_TIME = 1000; /* ms */ void do_blink() { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); tasks[BLINK_TASK].time = millis() + BLINK_TASK_TIME; } /********************************************************************* * This part of the sketch defines the lora work task, which initiates * new work and the lora_done() function that processes the results. *********************************************************************/ static const unsigned long TX_INTERVAL = 10000; /* ms */ static const unsigned long RETRY_JOIN_INTERVAL = 5000; /* ms */ enum LoraState { IDLE, JOINING, TRANSMITTING, }; LoraState lora_state; void start_join() { // Configure join method by (un)commenting the right method // call, and fill in credentials in that method call. modem.setAppEui("534ae9677ffc1c41"); modem.setAppKey("708ce3cfacf88f24eb88da478ce56fca"); modem.setDevEui("0080e115051fcc25"); modem.joinOTAAAsync(); //modem.setDevAddr("00000000"); //modem.setNwkSKey("00000000000000000000000000000000"); //modem.setAppSKey("00000000000000000000000000000000"); //modem.joinABP(); lora_state = JOINING; } void send_packet() { uint8_t payload[] = {0xde, 0xad, 0xbe, 0xef}; modem.setPort(1); modem.setADR(true); modem.beginPacket(); modem.write(payload, sizeof(payload)); if (modem.endPacketAsync(true) == sizeof(payload)) { Serial.println("Queued packet"); } else { Serial.println("Failed to queue packet"); } lora_state = TRANSMITTING; } void process_rx() { if (modem.available()) { Serial.print("Received packet on port "); Serial.print(modem.getDownlinkPort()); Serial.print(":"); while (modem.available()) { uint8_t b = modem.read(); Serial.print(" "); Serial.print(b >> 4, HEX); Serial.print(b & 0xF, HEX); } Serial.println(); } } void do_lora_work() { // Time to start new work if (!modem.connected()) { start_join(); } else { send_packet(); } } void lora_done() { // If, after calling maintain() the library is no longer // busy, then the asynchronous operation has completed, // so check its results. String STAT_R = String(STAT); //Serial.println("++++++++++++++++++++++++++++++++++++++++"); //Serial.println(STAT_R); //Serial.println("++++++++++++++++++++++++++++++++++++++++"); if (lora_state == TRANSMITTING) { if (STAT_R == "LORAMAC_EVENT_INFO_STATUS_OK") Serial.println("Sent packet"); else Serial.println("Fail sent packet"); // Done transmitting process_rx(); lora_state = IDLE; // Schedule transmission of next packet tasks[LORA_WORK_TASK].time = millis() + TX_INTERVAL; } else if (lora_state == JOINING) { if (modem.connected()) { Serial.println("Joined"); send_packet(); } else { Serial.println("Join failed"); lora_state = IDLE; tasks[LORA_WORK_TASK].time = millis() + RETRY_JOIN_INTERVAL; } } } /********************************************************************* * This part of the sketch defines the lora maintain task, which calls * maintain() to let the lora library do any background work that it * needs to do. It is called whenever request by the callback. *********************************************************************/ void do_lora_maintain() { modem.maintain(); // If, after calling maintain() the library is no longer // busy, then the asynchronous operation has completed, // so check its results. if (!modem.busy()) { lora_done(); } } void maintain_needed_callback() { // This is called from interrupt context, so this must *not* // call maintain() directly and return as fast as possible. // So just schedule the maintain task to run ASAP. tasks[LORA_MAINTAIN_TASK].time = millis(); } /********************************************************************* * And this is the entry points of the sketch. *********************************************************************/ void setup() { Serial.begin(115200); Serial.println("Start"); modem.begin(AU915); modem.setPort(1); modem.setADR(true); modem.power(14); //wdt IWatchdog.begin(32000000); modem.setMaintainNeededCallback(maintain_needed_callback); //pinMode(LED_BUILTIN, OUTPUT); //do_blink(); do_lora_work(); } void loop() { run_scheduler(); //WDT WAKE UP IWatchdog.reload(); }














Alterado também STM32LoRaWAN.cpp

extern char STAT[128];

void STM32LoRaWAN::MacMcpsConfirm(McpsConfirm_t* c) {
  // Called after an Mcps request (data TX) when the stack becomes idle again (so after RX windows)
  strcpy(STAT, toString(c->Status));
  core_debug(
    "McpsConfirm: req=%s, status=%s, datarate=%u, power=%d, ack=%u, %s=%u, airtime=%u, upcnt=%u, channel=%u\r\n",
     toString(c->McpsRequest), toString(c->Status), c->Datarate, c->TxPower,
     c->AckReceived,
    #if (defined( LORAMAC_VERSION ) && ( LORAMAC_VERSION == 0x01000300 ))
      "retries", c->NbRetries,
    #elif (defined( LORAMAC_VERSION ) && ( LORAMAC_VERSION == 0x01000400 ))
      "trans", c->NbTrans,
    #endif /* LORAMAC_VERSION */
    (unsigned)c->TxTimeOnAir, (unsigned)c->UpLinkCounter, (unsigned)c->Channel);
  instance->last_tx_acked = c->AckReceived;
  instance->fcnt_up = c->UpLinkCounter;
}

Montagem


Compilando

Gravador

"Instale" o STM32 Cube Programmer, o Arduino (STM32 PACKAGE) irá reconhecê-lo e então utilizá-lo para programar o LSM110A. O Kit LSM110A possui um "gravador" ST-LINK embarcado.

Neste blog foi utilizado o BREAKOUT e um ST-LINK-V2.



Uma vez gravado o Software, o LSM110A fará o JOIN na LoRaWAN enviará o pacote a cada 10 segundos.
UPLINK message
PA2 - TXD / PA3- RXD

DOWNLINK message




Fontes:


Dúvidas

FORUM

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

Nenhum comentário:

Postar um comentário