segunda-feira, 24 de julho de 2023

LSM110A - CONSUMO SLEEP (LORAWAN - OTA) - RAK LIB

       

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

Será testado o modo SLEEP para avaliar consumo de bateria, muito importante quando sua aplicação requer baixo consumo, com LoRaWAN OTA.


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




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 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


Transferindo


Executando

Uma vez gravado o Software, o LSM110A entrará em Sleep por 60 segundos.



Segue código final

/*** * This example shows LoRaWan protocol joining the network in OTAA mode, class A, region EU868. * Device will send uplink every 20 seconds. ***/ uint16_t maskBuff = 0x0002; #define OTAA_PERIOD (15000) /************************************* 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, 0xXX, 0x1F, 0xXX, 0x0A} #define OTAA_APPEUI {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99} #define OTAA_APPKEY {0xA6, 0x14, 0xD5, 0x99, 0xXX, 0xA0, 0x86, 0x1E, 0xDF, 0x27, 0x02, 0xAE, 0x6F, 0x0E, 0x1A, 0xD6} /** 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); } /************************************* * enum type for LoRa Event RAK_LORAMAC_STATUS_OK = 0, RAK_LORAMAC_STATUS_ERROR, RAK_LORAMAC_STATUS_TX_TIMEOUT, RAK_LORAMAC_STATUS_RX1_TIMEOUT, RAK_LORAMAC_STATUS_RX2_TIMEOUT, RAK_LORAMAC_STATUS_RX1_ERROR, RAK_LORAMAC_STATUS_RX2_ERROR, RAK_LORAMAC_STATUS_JOIN_FAIL, RAK_LORAMAC_STATUS_DOWNLINK_REPEATED, RAK_LORAMAC_STATUS_TX_DR_PAYLOAD_SIZE_ERROR, RAK_LORAMAC_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS, RAK_LORAMAC_STATUS_ADDRESS_FAIL, RAK_LORAMAC_STATUS_MIC_FAIL, RAK_LORAMAC_STATUS_MULTICAST_FAIL, RAK_LORAMAC_STATUS_BEACON_LOCKED, RAK_LORAMAC_STATUS_BEACON_LOST, RAK_LORAMAC_STATUS_BEACON_NOT_FOUND, *************************************/ void sendCallback(int32_t status) { if (status == RAK_LORAMAC_STATUS_OK) { Serial.println("Successfully sent"); } else { Serial.println("Sending failed"); } } void setup() { Serial.begin(115200, RAK_AT_MODE); delay(2000); Serial.println("RAKwireless LoRaWan OTAA Example"); Serial.println("------------------------------------------------------"); if(api.lorawan.nwm.get() != 1) { Serial.printf("Set Node device work mode %s\r\n", api.lorawan.nwm.set(1) ? "Success" : "Fail"); api.system.reboot(); } // 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; } Serial.printf("Set channel mask %s\r\n", api.lorawan.mask.set(&maskBuff) ? "Success" : "Fail"); 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(""); Serial.printf("Set channel mask %s\r\n", api.lorawan.mask.set(&maskBuff) ? "Success" : "Fail"); /** 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.."); }

Execução


Ao medir com o multímetro,  durante a execução do comando api.system.sleep.all(OTAA_PERIOD)acusou 4uA





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