O objetivo deste BLOG é demonstrar como é possível utilizar o Zephyr para programação do WISOL LSM110A. Foi utilizado o Starter Kit LSM110A para o teste. O exemplo permitirá via linha de comandos o acesso à rede LoRaWAN e então será enviado um texto "HELLO" via OTA, AU915 (FSB1), ao servidor LoRaWAN CHIRPSTACK.
BETA - EM TESTES - APENAS PARA PROGRAMADORES COM ZEPHYR
Baseado no nucleo_wl55jc
Compilação no WSL2 e VirtualBox (Ubuntu)
O que é TTN
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 (utilizado nesse trabalho), 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 GoA 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.
ZEPHYR
O que é Zephyr
O sistema operacional Zephyr é baseado em um kernel de pequena dimensão projetado para uso em sistemas com recursos restritos e embarcados: de sensores ambientais incorporados simples e wearables de LED a sofisticados controladores embarcados, relógios inteligentes e aplicativos sem fio IoT.
O Projeto Zephyr RTOS é um esforço recente da Fundação Linux para fornecer ao mundo embarcado um Sistema Operacional em Tempo Real gratuito, seguro e completo. Ele foi projetado desde o início para ser um RTOS moderno, escalável, seguro e responsivo com um foco claro em protocolos e fundações de IoT. Este RTOS de código aberto é licenciado pelo Apache 2.0 e possui um modelo de desenvolvimento totalmente aberto
LSM110A e o Zephyr
Como o módulo LSM110A é baseado no chip STM32WL55 (CPU), será possível rodar o Zephyr sem problemas.
C:\msys64\home\Usuario\loramac-node\src\boards
O link abaixo, é roteiro Básico para que você possa preparar o ambiente para programar o LSM110A, sobre o WSL2
$source ~/zephyrproject/.venv/bin/activate
Cmake muito antigo
cd ~
wget https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1-Linux-x86_64.sh
chmod +x cmake-3.21.1-Linux-x86_64.sh
sudo ./cmake-3.21.1-Linux-x86_64.sh --skip-license --prefix=/usr/local
hash -r
Compile Blynk para verificar instalação OK
west build -p always -b nucleo_wl55jc samples/basic/blinky
Compilacao
cd /home/osboxes/zephyrproject/zephyr
west build -p always -b nucleo_wl55jc samples/subsys/lorawan/class_a -p
.
.
-- The C compiler identification is GNU 12.1.0 -- The CXX compiler identification is GNU 12.1.0 -- The ASM compiler identification is GNU -- Found assembler: /home/osboxes/zephyr-sdk-0.15.1/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc -- Configuring done -- Generating done -- Build files have been written to: /home/osboxes/zephyrproject/zephyr/build -- west build: building application [1/171] Preparing syscall dependency handling [2/171] Generating include/generated/version.h -- Zephyr version: 3.2.99 (/home/osboxes/zephyrproject/zephyr), build: zephyr-v3.2.0-1267-g278120acb600 [161/171] Linking C executable zephyr/zephyr_pre0.elf [165/171] Linking C executable zephyr/zephyr_pre1.elf [171/171] Linking C executable zephyr/zephyr.elf Memory region Used Size Region Size %age Used FLASH: 74484 B 192 KB 37.88% RAM: 13944 B 20 KB 68.09% IDT_LIST: 0 GB 2 KB 0.00% (.venv) osboxes@osboxes:~/zephyrproject/zephyr$
Configuração do aplicativo do LSM110A
Antes de criar o aplicativo e ingressar em uma rede LoRaWAN, você precisa de uma conta em um provedor de back-end LoRaWAN. Em seguida, crie um aplicativo LoRaWAN e registre seu dispositivo. Como este aplicativo foi fortemente testado com o backend fornecido pelo CHIRPSTACK. Assim que seu aplicativo e dispositivo forem criados e registrados, você terá várias informações (fornecidas pelo provedor LoRaWAN).
Assim que seu aplicativo e dispositivo forem criados e registrados, você terá várias informações fornecidas pelo provedor LoRaWAN:
- O tipo de procedimento de JOIN: ABP (Ativação por personalização) ou OTAA (Ativação Over The Air)
- O dispositivo EUI: uma matriz de 8 bytes
- A aplicação EUI: uma matriz de 8 bytes
- A chave do aplicativo: uma matriz de 16 bytes
- O endereço do dispositivo: uma matriz de 4 bytes, necessária apenas com o procedimento de junção ABP
- A chave de sessão do aplicativo: uma matriz de 16 bytes, necessária apenas com o procedimento de junção ABP
- A chave de sessão de rede: uma matriz de 16 bytes, necessária apenas com o procedimento de junção ABP
- Depois de obter essas informações, edite o Makefile adequadamente ou use os comandos set/get no shell do aplicativo de teste.
Editando arquivos para gerar o APP
Em
/home/osboxes/zephyrproject/zephyr/samples/subsys/lorawan/class_a/src
Altere main.c para as credenciais OTAA
* Customize based on network configuration */ #define LORAWAN_DEV_EUI { 0xDD, 0xEE, 0xAA, 0xDD, 0xBB, 0xEE,\ 0xEE, 0xFF } #define LORAWAN_JOIN_EUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ 0x00, 0x00 } #define LORAWAN_APP_KEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE,\ 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88,\ 0x09, 0xCF, 0x4F, 0x3C }Menuconfig (opcional)
/home/osboxes/zephyrproject/zephyr
west build -t menuconfig
(Top) Zephyr Kernel Configuration Devicetree Info ---- Modules ---> Board Selection (STMicroelectronics nucleo_wl55jc Discovery kit) ---> Board Options ---- SoC/CPU/Configuration Selection (LSM110A Series MCU) ---> Hardware Configuration ---> ARM Options ---> General Architecture Options ---> -*- MPU features ---> -*- Assign appropriate permissions to kernel areas in SRAM [ ] Support code/data section relocation Floating Point Options ---- Cache Options ---- General Kernel Options ---> Device Options ---- Virtual Memory Support ---- Device Drivers ---> C Library ---> Additional libraries ---> Sub Systems and OS Services ---> Build and Link Features ---> Boot Options ---> Compatibility ---> [ ] Allow for the legacy include paths (without the zephyr/ prefix) (DEPRECATED) [Space/Enter] Toggle/enter [ESC] Leave menu [S] Save [O] Load [?] Symbol info [/] Jump to symbol [F] Toggle show-help mode [C] Toggle show-name mode [A] Toggle show-all mode [Q] Quit (prompts for save) [D] Save minimal config (advanced)
Em RegionAU915.c
/home/osboxes/zephyrproject/modules/lib/loramac-node/src/mac/region
void RegionAU915InitDefaults( InitDefaultsParams_t* params ) { Band_t bands[AU915_MAX_NB_BANDS] = { AU915_BAND0 }; switch( params->Type ) { case INIT_TYPE_DEFAULTS: { if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) { return; } RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; RegionBands = (Band_t*) params->Bands; // Initialize 8 bit channel groups index RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0; // Initialize the join trials counter RegionNvmGroup1->JoinTrialsCounter = 0; // Default bands memcpy1( ( uint8_t* )RegionBands, ( uint8_t* )bands, sizeof( Band_t ) * AU915_MAX_NB_BANDS ); // Channels for( uint8_t i = 0; i < AU915_MAX_NB_CHANNELS - 8; i++ ) { // 125 kHz channels RegionNvmGroup2->Channels[i].Frequency = 915200000 + i * 200000; RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; RegionNvmGroup2->Channels[i].Band = 0; } for( uint8_t i = AU915_MAX_NB_CHANNELS - 8; i < AU915_MAX_NB_CHANNELS; i++ ) { // 500 kHz channels RegionNvmGroup2->Channels[i].Frequency = 915900000 + ( i - ( AU915_MAX_NB_CHANNELS - 8 ) ) * 1600000; RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_6 << 4 ) | DR_6; RegionNvmGroup2->Channels[i].Band = 0; } // Initialize channels default mask RegionNvmGroup2->ChannelsDefaultMask[0] = 0xFF00; RegionNvmGroup2->ChannelsDefaultMask[1] = 0x0000; RegionNvmGroup2->ChannelsDefaultMask[2] = 0x0000; RegionNvmGroup2->ChannelsDefaultMask[3] = 0x0000; RegionNvmGroup2->ChannelsDefaultMask[4] = 0x0000; RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; // Copy channels default mask RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); // Copy into channels mask remaining RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Intentional fallthrough } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Copy channels default mask RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ ) { // Copy-And the channels mask RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i]; } break; } default: { break; } } }
Em
/home/osboxes/zephyrproject/zephyr/samples/subsys/lorawan/class_a
Altere prj.conf
CONFIG_LOG=y
CONFIG_SPI=y
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_LORA=y
CONFIG_LORA_SX12XX=y
CONFIG_LORA_LOG_LEVEL_DBG=y
#CONFIG_LORA_SX127X=y
CONFIG_HAS_SEMTECH_RADIO_DRIVERS=y
CONFIG_HAS_SEMTECH_LORAMAC=y
CONFIG_LORAWAN=y
CONFIG_LORAMAC_REGION_AU915=y
CONFIG_LORAWAN_LOG_LEVEL_DBG=y
CONFIG_LORAWAN_NVM_NONE=y
#CONFIG_LORAWAN_NVM_SETTINGS=y
CONFIG_LORAWAN_SYSTEM_MAX_RX_ERROR=90
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_TEST_RANDOM_GENERATOR=y
UART
&usart1 { pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; pinctrl-names = "default"; current-speed = <115200>; status = "okay"; }; &usart2 { pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; pinctrl-names = "default"; current-speed = <115200>; status = "okay"; };
Enviando um TEXTO
Abra o Emulador de Terminal
PA2 e PA3 do LSM110A (USB DO KIT)
Starting up Lora node...
Starting Lorawan stack...
Joining TTN network over OTTA
1m--- 28 messages dropped ---
[00:00:00.110,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: RX (5)
--- 10 messages dropped ---
[00:00:00.117,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: STDBY_RC (1)
--- 20 messages dropped ---
[00:00:00.138,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x86 w. 4 bytes of data
[00:00:00.139,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x80 w. 1 bytes of data
[00:00:00.140,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: STDBY_RC (1)
[00:00:00.140,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8a w. 1 bytes of data
[00:00:00.142,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8b w. 4 bytes of data
[00:00:00.143,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:00.144,000] <dbg> sx126x: SX126xReadRegisters: Reading 1 registers @ 0x889
[00:00:00.144,000] <dbg> sx126x: SX126xReadRegisters: register_value
24 |$
[00:00:00.144,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x889: 0x24 , ...
[00:00:00.144,000] <dbg> sx126x: SX126xSetRfTxPower: power: 27
[00:00:00.144,000] <dbg> sx126x: SX126xReadRegisters: Reading 1 registers @ 0x8d8
[00:00:00.144,000] <dbg> sx126x: SX126xReadRegisters: register_value
fe |.
[00:00:00.144,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x8d8: 0xfe , ...
[00:00:00.144,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x95 w. 4 bytes of data
[00:00:00.145,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8e w. 2 bytes of data
[00:00:00.147,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:00.149,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8 w. 8 bytes of data
[00:00:00.149,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:00.150,000] <dbg> sx126x: SX126xWriteBuffer: Writing buffers @ 0x0 (23 bytes)
[00:00:00.150,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: TX (4)
[00:00:00.150,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x83 w. 3 bytes of data
[00:00:00.156,000] <dbg> lorawan: lorawan_join: Network join request sent!
[00:00:00.526,000] <dbg> sx126x: sx126x_dio1_irq_work_handler: Processing DIO1 interrupt
[00:00:00.526,000] <dbg> sx126x: SX126xReadCommand: Issuing opcode 0x12 (data size: 2)
[00:00:00.526,000] <dbg> sx126x: SX126xReadCommand: -> status: 0xac
[00:00:00.526,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x2 w. 2 bytes of data
[00:00:00.526,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: STDBY_RC (1)
[00:00:00.526,000] <dbg> sx126x: SX126xAntSwOff: No antenna switch configured
[00:00:00.526,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x84 w. 1 bytes of data
[00:00:00.526,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: SLEEP (0)
[00:00:05.434,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x80 w. 1 bytes of data
[00:00:05.434,000] <dbg> sx126x: SX126xWakeup: Sending GET_STATUS
[00:00:05.435,000] <dbg> sx126x: SX126xWakeup: Waiting for device...
[00:00:05.436,000] <dbg> sx126x: SX126xWakeup: Device ready
[00:00:05.436,000] <dbg> sx126x: SX126xAntSwOn: No antenna switch configured
[00:00:05.437,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: STDBY_RC (1)
[00:00:05.437,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x86 w. 4 bytes of data
[00:00:05.438,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x9f w. 1 bytes of data
[00:00:05.439,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x80 w. 1 bytes of data
[00:00:05.440,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: STDBY_RC (1)
[00:00:05.440,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8a w. 1 bytes of data
[00:00:05.441,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8b w. 4 bytes of data
[00:00:05.443,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:05.444,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0xa0 w. 1 bytes of data
[00:00:05.445,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x706: 0x61 , ...
[00:00:05.445,000] <dbg> sx126x: SX126xReadRegisters: Reading 1 registers @ 0x736
[00:00:05.445,000] <dbg> sx126x: SX126xReadRegisters: register_value
09 |.
[00:00:05.445,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x736: 0x9 , ...
[00:00:05.445,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:05.446,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8 w. 8 bytesSending data...
of data
--- 11 messages dropped ---
[00:00:05.610,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x902: 0x0 , ...
--- 21 messages dropped ---
[00:00:05.620,000] <dbg> sx126x: SX126xWakeup: Sending GET_STATUS
[00:00:05.620,000] <dbg> sx126x: SX126xWakeup: Waiting for device...
[00:00:05.621,000] <dbg> sx126x: SX126xWakeup: Device ready
[00:00:05.621,000] <dbg> sx126x: SX126xAntSwOn: No antenna switch configured
[00:00:05.622,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x80 w. 1 bytes of data
[00:00:05.623,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: STDBY_RC (1)
[00:00:05.623,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8a w. 1 bytes of data
[00:00:05.624,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8b w. 4 bytes of data
[00:00:05.626,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:05.627,000] <dbg> sx126x: SX126xReadRegisters: Reading 1 registers @ 0x889
[00:00:05.627,000] <dbg> sx126x: SX126xReadRegisters: register_value
24 |$
[00:00:05.627,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x889: 0x24 , ...
[00:00:05.627,000] <dbg> sx126x: SX126xSetRfTxPower: power: 27
[00:00:05.627,000] <dbg> sx126x: SX126xReadRegisters: Reading 1 registers @ 0x8d8
[00:00:05.627,000] <dbg> sx126x: SX126xReadRegisters: register_value
fe |.
[00:00:05.627,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x8d8: 0xfe , ...
[00:00:05.627,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x95 w. 4 bytes of data
[00:00:05.628,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8e w. 2 bytes of data
[00:00:05.629,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:05.631,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8 w. 8 bytes of data
[00:00:05.631,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:05.633,000] <dbg> sx126x: SX126xWriteBuffer: Writing buffers @ 0x0 (18 bytes)
[00:00:05.633,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: TX (4)
[00:00:05.633,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x83 w. 3 bytes of data
[00:00:05.968,000] <dbg> sx126x: sx126x_dio1_irq_work_handler: Processing DIO1 interrupt
[00:00:05.968,000] <dbg> sx126x: SX126xReadCommand: Issuing opcode 0x12 (data size: 2)
[00:00:05.968,000] <dbg> sx126x: SX126xReadCommand: -> status: 0xac
[00:00:05.968,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x2 w. 2 bytes of data
[00:00:05.968,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: STDBY_RC (1)
[00:00:05.968,000] <dbg> sx126x: SX126xAntSwOff: No antenna switch configured
[00:00:05.968,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x84 w. 1 bytes of data
[00:00:05.968,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: SLEEP (0)
[00:00:10.876,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x80 w. 1 bytes of data
[00:00:10.876,000] <dbg> sx126x: SX126xWakeup: Sending GET_STATUS
[00:00:10.876,000] <dbg> sx126x: SX126xWakeup: Waiting for device...
[00:00:10.877,000] <dbg> sx126x: SX126xWakeup: Device ready
[00:00:10.877,000] <dbg> sx126x: SX126xAntSwOn: No antenna switch configured
[00:00:10.879,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: STDBY_RC (1)
[00:00:10.879,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x86 w. 4 bytes of data
[00:00:10.880,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x9f w. 1 bytes of data
[00:00:10.881,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x80 w. 1 bytes of data
[00:00:10.882,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: STDBY_RC (1)
[00:00:10.882,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8a w. 1 bytes of data
[00:00:10.883,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8b w. 4 bytes of data
[00:00:10.884,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:10.885,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0xa0 w. 1 bytes of data
[00:00:10.887,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x706: 0x61 , ...
[00:00:10.887,000] <dbg> sx126x: SX126xReadRegisters: Reading 1 registers @ 0x736
[00:00:10.887,000] <dbg> sx126x: SX126xReadRegisters: register_value
09 |.
[00:00:10.887,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x736: 0x9 , ...
[00:00:10.887,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8c w. 6 bytes of data
[00:00:10.888,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x8 w. 8 bytes of data
[00:00:10.888,000] <dbg> sx126x: SX126xSetOperatingMode: SetOperatingMode: RX (5)
[00:00:10.888,000] <dbg> sx126x: SX126xWriteRegisters: Writing 1 registers @ 0x8ac: 0x94 , ...
[00:00:10.888,000] <dbg> sx126x: SX126xWriteCommand: Issuing opcode 0x82 w. 3 bytes of data
[00:00:10.975,000] <dbg> sx126x: sx126x_dio1_irq_work_handler: Processing DIO1 interrupt
[00:00:10.975,000] <dbg> sx126x: SX126xReadCommand: Issu
Downlink data received:
Data size: 0
Data Port: 0
RSSI: -38
SNR: 9
Data pend: 0
Data sent!
DOWNLINK
CÓDIGO FONTE
#define OTAA //#define ABP #include <zephyr/lorawan/lorawan.h> #include <zephyr/drivers/uart.h> #include <zephyr/drivers/gpio.h> #include <zephyr/random/rand32.h> #define DEFAULT_RADIO_NODE DT_ALIAS(lora0) BUILD_ASSERT(DT_NODE_HAS_STATUS(DEFAULT_RADIO_NODE, okay), "No default LoRa radio specified in DT"); #define DEFAULT_RADIO DT_LABEL(DEFAULT_RADIO_NODE) #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL #include <zephyr/logging/log.h> LOG_MODULE_REGISTER(lorawan_node); /* Customize based on network configuration */ // OTAA #ifdef OTAA #define LORAWAN_DEV_EUI { 0xXX, 0xXX, 0xXX, 0xFF, 0xXX, 0xEE, 0x8C, 0xXX } // MSB Format! #define LORAWAN_JOIN_EUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // MSB Format! #define LORAWAN_APP_KEY { 0xF1, 0xD1, 0x1D, 0x78, 0xDA, 0x2A, 0xEF, 0xB2, 0x7C, 0x70, 0x35, 0x08, 0x25, 0xB8, 0xB6, 0x3B } #endif // ABP #ifdef ABP #define LORAWAN_DEV_ADDR { 0x00, 0x00, 0x00, 0x00 } #define LORAWAN_NWK_SKEY { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } #define LORAWAN_APP_SKEY { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } #define LORAWAN_APP_EUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } #endif #define DELAY K_MSEC(10000) char data[] = {'H', 'E', 'L', 'L', 'O'}; /* size of stack area used by each thread */ #define STACKSIZE 1024 /* scheduling priority used by each thread */ #define PRIORITY 7 // Call back functions: // Downlink callback static void dl_callback(uint8_t port, bool data_pending, int16_t rssi, int8_t snr, uint8_t len, const uint8_t *data) { printk("\nDownlink data received: \n"); for(int i=0; i < len; i++ ) printk("%02X ", data[i]); printk("\n"); printk("Data size: %d\n" , len ); printk("Data Port: %d\n" , port ); printk("RSSI: %d\n" , (int16_t)rssi ); printk("SNR: %d\n" , (int16_t)snr ); printk("Data pend: %d\n" , data_pending ); printk("\n\n"); } // ADR change callback static void lorwan_datarate_changed(enum lorawan_datarate dr) { uint8_t unused, max_size; lorawan_get_payload_sizes(&unused, &max_size); LOG_INF("New Datarate: DR_%d, Max Payload %d", dr, max_size); } /* Main program. */ void main(void) { const struct device *lora_dev; struct lorawan_join_config join_cfg; #ifdef OTAA uint8_t dev_eui[] = LORAWAN_DEV_EUI; uint8_t join_eui[] = LORAWAN_JOIN_EUI; uint8_t app_key[] = LORAWAN_APP_KEY; #endif #ifdef ABP uint8_t dev_addr[] = LORAWAN_DEV_ADDR; uint8_t nwk_skey[] = LORAWAN_NWK_SKEY; uint8_t app_skey[] = LORAWAN_APP_SKEY; uint8_t app_eui[] = LORAWAN_APP_EUI; #endif int ret; printk("Starting up Lora node...\n\n"); lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0)); if (!lora_dev) { printk("Lora default radio not found.\nExiting program.\n"); return; } printk("Starting Lorawan stack...\n"); ret = lorawan_start(); if (ret < 0) { printk("lorawan_start failed: %d\n\n", ret); return; } // Enable ADR lorawan_enable_adr( true ); // Enable callbacks struct lorawan_downlink_cb downlink_cb = { .port = LW_RECV_PORT_ANY, .cb = dl_callback }; lorawan_register_downlink_callback( &downlink_cb ); lorawan_register_dr_changed_callback( lorwan_datarate_changed ); uint32_t random = sys_rand32_get(); uint16_t dev_nonce = random & 0x0000FFFF; #ifdef OTAA join_cfg.mode = LORAWAN_CLASS_A; join_cfg.dev_eui = dev_eui; join_cfg.otaa.join_eui = join_eui; join_cfg.otaa.app_key = app_key; join_cfg.otaa.nwk_key = app_key; join_cfg.otaa.dev_nonce = dev_nonce; #endif #ifdef ABP join_cfg.mode = LORAWAN_ACT_ABP; join_cfg.dev_eui = dev_addr; join_cfg.abp.dev_addr = dev_addr; join_cfg.abp.app_skey = app_skey; join_cfg.abp.nwk_skey = nwk_skey; join_cfg.abp.app_eui = app_eui; #endif printk("Joining TTN network over"); #ifdef OTAA printk(" OTTA\n\n\n"); #else printk(" ABP\n\n\n"); #endif // Loop until we connect do { ret = lorawan_join(&join_cfg); if (ret < 0) { printk("lorawan_join_network failed: %d\n\n", ret); printk("Sleeping for 10s to try again to join network.\n\n"); k_sleep(K_MSEC(10000)); } } while ( ret < 0 ); printk("Sending data...\n\n"); while (1) { ret = lorawan_send(2, data, sizeof(data), LORAWAN_MSG_CONFIRMED); if (ret == -EAGAIN) { k_sleep(DELAY); continue; } if (ret < 0) { k_sleep(DELAY); continue; } printk("Data sent!\n\n"); k_sleep(DELAY); } }
DOWNLINK
DÚVIDAS
FORUMS ZEPHYR
THANKS TO
Benjamin Lindqvist <benjamin@eub.se>
REFERÊNCIAS
zephyrproject-rtos/loramac-node: Zephyr repository tracking https://github.com/Lora-net/LoRaMac-node
Sobre a SMARTCORE
A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portifó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