![]() | ![]() | ![]() | ![]() | ![]() |
|---|
Segmentando o baixo consumo de energia, esta biblioteca Arduino para módulos de núcleo de Wisblock Rakwireless cuida de toda a funcionalidade Lora P2P, Lorawan, BLE, AT. Você pode se concentrar no seu aplicativo e deixar o restante na API. É feito como um companheiro para a biblioteca SX126X-Aduino Lorawan
Requer repensar os aplicativos Arduino, porque você não possui a função setup() ou loop() . Em vez disso, tudo é orientado a eventos. O MCU está dormindo até que precise tomar ações. Este pode ser um evento de Lorawan, um comando recebido pela porta USB ou um evento de aplicativo, por exemplo, uma interrupção proveniente de um sensor.
Essa abordagem facilita a criação de aplicativos projetados para baixo uso de energia. Durante o sono, a base do Wisblock + Wisblock Core Rak4631 consome apenas 40ua.
Além disso, a API oferece duas opções para configurar as configurações Lora P2P / Lorawan sem a necessidade de codificá-las nos códigos de origem.
V2 da biblioteca alterou o formato de comando AT para ser compatível com os comandos Rui3. Por favor, verifique o manual de comando no Rui3 para obter diferenças.
A versão V2 suporta apenas o módulo Core Rakwireless Wisblock RAK4631
O suporte para o RAK11310 e RAK1200 pode ser adicionado no futuro
A API está lidando com tudo, desde setup() , loop() , inicialização de Lorawan, manuseio de eventos de Lorawan, inicialização BLE, manuseio de eventos BL para a interface de comando AT.
OBSERVAÇÃO!
O aplicativo do usuário não deve ter as funções setup() e loop() !
O aplicativo do usuário possui duas funções de inicialização, uma é chamada no início do setup() , a outra no final. As outras funções são retornos de chamada de evento chamados de loop() . É possível definir eventos personalizados (como interrupções de um sensor) também.
A leitura do sensor, o controle do atuador ou outras tarefas de aplicativo são tratadas no app_event_handler() . app_event_handler() é chamado com frequência, o tempo entre as chamadas é definido pelo aplicativo. Além disso, app_event_handler() é chamado em eventos personalizados.
ble_data_handler() é chamado em eventos ble (eventos ble uart rx por enquanto) de loop() . Pode ser usado para implementar a comunicação personalizada sobre o BLE UART.
OBSERVAÇÃO!
Esta função não é necessária no RAK11310!
lora_data_handler() é chamado em diferentes eventos de Lorawan
Gráfico TD
A [bota] -> | Startup | B (configuração)
B -> | 1 | D (setup_app)
D -> B (Configuração)
B -> | 2 | E [Inicialize Lora e Ble]
E -> B (Configuração)
B -> | 3 | G (init_app)
G -> K (configuração terminada)
K -> | Start Loop | Eu (loop)
Q [Evento Lora] -> | Acorde | J
O [Evento do sensor] -> | Acorde | JP [evento ble] -> | Acorde | Jr [AT COMMAND] -> | Acorde | JT [Timer] -> | Acorde | Ji -> j (dormindo)
K -> | Timer de início | T
J -> L (APP_EVENT_HANDLER)
J -> m (lora_data_handler)
J -> n (ble_data_handler)
J -> s (manipulador de comando)
L -> U (Sensores de leitura)
M -> V (Junt -se, eventos TX e RX)
N -> w (manuseio com comandos ble)
S -> AA (Usuário at comandos)
U -> l
V -> m
W -> n
Aa -> s
L -> J.
M -> j
N -> j
S -> j

Todos os comandos AT podem ser encontrados no manual de comando no comando, nem todos os comandos Rui3 são suportados. Uma lista de comandos disponíveis no AT pode ser recuperada? do dispositivo
Dois comandos personalizados foram adicionados ao conjunto de comandos Rui3 padrão:
Descrição: Defina o intervalo de transmissão automática
Este comando permite definir o intervalo em segundos entre as transmissões automáticas de pacotes. Se definido como 0, a transmissão automática de pacotes está desativada.
| Comando | Parâmetro de entrada | Valor de retorno | Código de retorno |
|---|---|---|---|
| ATC+sendint? | - | ATC+SENDINT: "Get or Set the automatic send interval | OK |
| ATC+sendint =? | - | <interval in seconds> | OK |
ATC+sendint = <Input Parameter> | <interval in seconds> | - | OK ou AT_PARAM_ERROR |
Exemplos :
ATC+SENDINT?
ATC+SENDINT: Get or Set the automatic send interval
OK
ATC+SENDINT=?
ATC+SENDINT:60
OK
ATC+SENDINT=60
OK
Descrição: Mostrar status do dispositivo
Este comando permite que o usuário obtenha o status atual do dispositivo.
| Comando | Parâmetro de entrada | Valor de retorno | Código de retorno |
|---|---|---|---|
| Status ATC+? | - | ATC+STATUS: Show LoRaWAN status | OK |
| Status ATC+=? | - | <Status> | OK |
Exemplos :
ATC+STATUS?
ATC+STATUS: Show LoRaWAN status
OK
// When in LoRaWAN mode:
ATC+STATUS=?
Device status:
RAK4631
Mode LPWAN
Auto join enabled
Network joined
LPWAN status:
Dev EUI AC1F09FFFE09016C
App EUI 70B3D57ED00201E1
App Key 2B84E0B09B68E5CB42176FE753DCEE79
Dev Addr 26021FB4
NWS Key 323D155A000DF335307A16DA0C9DF53F
Apps Key 3F6A66459D5EDCA63CBC4619CD61A11E
OTAA enabled
ADR disabled
Public Network
Dutycycle disabled
Join trials 5
TX Power 0
DR 3
Class 0
Subband 1
Fport 2
Unconfirmed Message
Region AS923-3
Send Frequency 300
// When in LoRa P2P mode:
ATC+STATUS=?
Device status:
RAK4631
Mode P2P
P2P frequency 916000000
P2P TX Power 22
P2P BW 125
P2P SF 7
P2P CR 0
P2P Preamble length 8
P2P Symbol Timeout 0
Send Frequency 300
Descrição: Configurações da porta
Este comando permite ao usuário acessar e configurar as configurações da porta.
| Comando | Parâmetro de entrada | Valor de retorno | Código de retorno |
|---|---|---|---|
| Porta ATC+? | - | AT+PORT=<Port><CR>. Get or Set the Port | OK |
| ATC+PORT =? | - | 1-223 | OK |
ATC+PORT = <Input Parameter> | 1-223 | - | Ok ou at_param_error |
Exemplos :
ATC+PORT?
ATC+PORT: Get or Set the Port=[1..223]
OK
ATC+PORT=?
ATC+PORT:2
OK
ATC+PORT=2
OK
Voltar
Começando com o Wisblock API v1.1.2 Os comandos AT podem ser estendidos pelos comandos definidos pelo usuário. Esta nova implementação usa a função do analisador da API WISBLOCK AT FUNCIMENTO. Além disso, os comandos personalizados serão listados se o AT? é usado.
OBSERVAÇÃO! No Rui3, os comandos personalizados são chamados com ATC em vez de !
Para estender os comandos AT, são necessárias três etapas:
Os comandos AT personalizados estão listados em uma matriz com o formato STRUT ATCMD_T. Cada entrada consiste no comando AT, o texto de explicação é mostrado quando o comando é chamado com A? e ponteiros para as funções para consulta, execute com parâmetros e execute sem parâmetros. Aqui está um exemplo para dois comandos personalizados:
atcmd_t g_user_at_cmd_list_example[] = {
/* | CMD | AT+CMD? | AT+CMD=? | AT+CMD=value | AT+CMD | Permissions | */
// GNSS commands
{ " +SETVAL " , " Get/Set custom variable " , at_query_value, at_exec_value, NULL , " RW " },
{ " +LIST " , " Show last packet content " , at_query_packet, NULL , NULL , " R " },
};
atcmd_t *g_user_at_cmd_list = g_user_at_cmd_list_example; Observação 1
A estrutura para comandos AT personalizados é estendida para a compatibilidade do RUI3. O código mais antigo escrito para o Wisblock-API v1.x precisa ser ajustado para esta nova estrutura.
Observação 2
Para funções que não são suportadas pelo comando AT, um NULL deve ser colocado na matriz.
Observação 3
O nome g_user_at_cmd_list é corrigido e não pode ser alterado ou os comandos personalizados não são detectados.
Observação 4
As permissões são dadas como uma string. Entradas válidas são "R" (somente leitura), "W" (apenas escreva), "RW" (Leia e escreva)
Uma variável com o número de comandos personalizados deve ser fornecida:
/* * Number of user defined AT commands */
uint8_t g_user_at_cmd_num = sizeof (g_user_at_cmd_list_example) / sizeof ( atcmd_t ); OBSERVAÇÃO
O nome g_user_at_cmd_num é corrigido e não pode ser alterado ou os comandos personalizados não são detectados.
Para cada comando personalizado, os comandos de consulta e execução devem ser gravados. Os nomes dessas funções devem corresponder aos nomes de funções usados na matriz de comandos AT personalizados. O comando Execute recebe como parâmetro o valor do comando AT após o = do valor.
As funções de consulta ( =? ) Não recebem e parâmetros e devem sempre retornar com 0. As funções de consulta salvam o resultado da consulta na matriz Global CHAR g_at_query_buffer , a matriz tem um tamanho máximo de ATQUERY_SIZE , que tem 128 caracteres.
Execute as funções com parâmetros ( =<value> ) recebem valores ou configurações como um ponteiro para uma matriz de char. Esta matriz inclui apenas o valor ou parâmetro sem o próprio comando AT. Por exemplo, o manuseio de funções executivas ATC+SETDEV=12000 receberia apenas o 120000 . O valor ou parâmetro recebido deve ser verificado quanto à validade e, se o valor do formato não estiver correspondendo, um AT_ERRNO_PARA_VAL deverá ser retornado. Se o valor ou parâmetro estiver correto, a função deverá retornar 0 .
Executar funções sem parâmetros são usadas para executar uma ação e retornar o sucesso da ação como 0 se bem -sucedido ou AT_ERRNO_EXEC_FAIL se a execução falhar.
Esses exemplos são usados para definir uma variável no aplicativo.
/* ******************************************************************* */
// Example AT command to change the value of the variable new_val:
// Query the value AT+SETVAL=?
// Set the value AT+SETVAL=120000
// Second AT command to show last packet content
// Query with AT+LIST=?
/* ******************************************************************* */
int32_t new_val = 3000 ;
/* *
* @brief Returns the current value of the custom variable
*
* @return int always 0
*/
static int at_query_value ()
{
snprintf (g_at_query_buf, ATQUERY_SIZE, " Custom Value: %d " , new_val);
return 0 ;
}
/* *
* @brief Command to set the custom variable
*
* @param str the new value for the variable without the AT part
* @return int 0 if the command was succesfull, 5 if the parameter was wrong
*/
static int at_exec_value ( char *str)
{
new_val = strtol (str, NULL , 0 );
MYLOG ( " APP " , " Value number >>%ld<< " , new_val);
return 0 ;
}
/* *
* @brief Example how to show the last LoRa packet content
*
* @return int always 0
*/
static int at_query_packet ()
{
snprintf (g_at_query_buf, ATQUERY_SIZE, " Packet: %02X%02X%02X%02X " ,
g_lpwan_data. data_flag1 ,
g_lpwan_data. data_flag2 ,
g_lpwan_data. batt_1 ,
g_lpwan_data. batt_2 );
return 0 ;
}
/* *
* @brief List of all available commands with short help and pointer to functions
*
*/
atcmd_t g_user_at_cmd_list_example[] = {
/* | CMD | AT+CMD? | AT+CMD=? | AT+CMD=value | AT+CMD | Permission | */
// GNSS commands
{ " +SETVAL " , " Get/Set custom variable " , at_query_value, at_exec_value, NULL , " RW " },
{ " +LIST " , " Show last packet content " , at_query_packet, NULL , NULL , " R " },
};
atcmd_t *g_user_at_cmd_list = g_user_at_cmd_list_example;
/* * Number of user defined AT commands */
uint8_t g_user_at_cmd_num = sizeof (g_user_at_cmd_list_example) / sizeof ( atcmd_t );Esses cinco exemplos explicam o uso da API. Em todos os exemplos, os retornos de chamada da API e as funções adicionais (leituras de sensores, manuseio de IRQ, serviço de localização do GNSS) são separados em seus próprios esboços.
O WisBlock-Api-V2 também foi usado nos seguintes projetos de plataforma:
Quando usado com o RAK4631, a atualização do firmware sobre o BLE já está incluída na biblioteca. As atualizações de firmware para o RAK4631 podem ser feitas usando a caixa de ferramentas Nordic NRF (disponível para Android e iOS) ou com a caixa de ferramentas Wisblock (meu aplicativo Android).
Para a atualização, copie o arquivo de atualização criado (geralmente chamado de firmware.zip) da pasta .pio/build/{device}, copie -o para seu telefone e use um dos aplicativos para atualizar o firmware.
Se a atualização do firmware via BLE falhar, atualize o dispositivo para o mais recente carregador de inicialização para o RAK4631 com a versão v0.4.3. Você pode encontrar o mais recente carregador de inicialização no repo Wisblock
A API fornece algumas chamadas para a gerência, para enviar pacotes de Lorawan, enviar dados BLE UART e desencadear eventos.
void api_set_version(uint16_t sw_1 = 1, uint16_t sw_2 = 0, uint16_t sw_3 = 0);
Esta função pode ser chamada para definir a versão do aplicativo. A versão do aplicativo pode ser solicitada pelos comandos AT. O número da versão é construído a partir de três dígitos:
sw_1 ==> Aumento da versão principal na mudança de API / não compatível com versões anteriores
sw_2 ==> Aumento da versão menor na mudança de API / compatível com versões anteriores
sw_3 ==> Aumente a versão do patch no bug, sem efeito na API
Se api_set_version não for chamado, a versão do aplicativo padronizará para 1.0.0 .
void api_reset(void);
Executa uma redefinição do módulo Wisblock Core
void api_wake_loop(uint16_t reason);
Isso é usado para acordar o loop com um evento. O reason deve ser definido no app.h Depois que o loop acordou o aplicativo, ele chamará o app_event_handler() com o valor da reason em g_task_event_type .
Como exemplo, isso pode ser usado para acordar o dispositivo a partir da interrupção de um sensor de acelerômetro. Aqui como exemplo, um extrato do código de exemplo do accelerometer .
No accelerometer.ino o evento é definido. A primeira definição é definir o sinal, o segundo é limpar o evento depois que ele foi tratado.
/* * Define additional events */
# define ACC_TRIGGER 0b1000000000000000
# define N_ACC_TRIGGER 0b0111111111111111 Então, em lis3dh_acc.ino , na função de retorno de chamada interrompida void acc_int_handler(void) o loop é acordado com o sinal ACC_TRIGGER
void acc_int_handler ( void )
{
// Wake up the task to handle it
api_wake_loop (ACC_TRIGGER);
} E finalmente no accelerometer.ino , o evento é tratado em app_event_handler()
// ACC triggered event
if ((g_task_event_type & ACC_TRIGGER) == ACC_TRIGGER)
{
g_task_event_type &= N_ACC_TRIGGER;
MYLOG ( " APP " , " ACC IRQ wakeup " );
// Reset ACC IRQ register
get_acc_int ();
// Set Status flag, it will trigger sending a packet
g_task_event_type = STATUS;
} void api_log_settings(void);
Esta função pode ser chamada para listar as configurações completas do dispositivo Wisblock sobre USB. A saída se parece:
Device status:
RAK11310
Auto join enabled
Mode LPWAN
Network joined
Send Frequency 120
LPWAN status:
Dev EUI AC1F09FFFE0142C8
App EUI 70B3D57ED00201E1
App Key 2B84E0B09B68E5CB42176FE753DCEE79
Dev Addr 26021FB4
NWS Key 323D155A000DF335307A16DA0C9DF53F
Apps Key 3F6A66459D5EDCA63CBC4619CD61A11E
OTAA enabled
ADR disabled
Public Network
Dutycycle disabled
Join trials 30
TX Power 0
DR 3
Class 0
Subband 1
Fport 2
Unconfirmed Message
Region AS923-3
LoRa P2P status:
P2P frequency 916000000
P2P TX Power 22
P2P BW 125
P2P SF 7
P2P CR 1
P2P Preamble length 8
P2P Symbol Timeout 0 void api_timer_stop(void)
Pare o temporizador que acorda o MCU com frequência.
void api_timer_restart(uint32_t new_time)
Reinicia o temporizador com um novo valor. O valor está em milissegundos
void api_read_credentials(void);
void api_set_credentials(void); Se as configurações de Lora P2P precisarem ser codificadas (por exemplo, a frequência, largura de banda, ...), isso pode ser feito em setup_app() . Primeiro, as configurações salvas devem ser lidas no flash com api_read_credentials(); , as configurações podem ser alteradas. Depois de alterar as configurações, deve ser salvo com api_set_credentials() . À medida que a API do Wisblock verifica se alguma alteração precisar ser salva, os valores alterados serão salvos apenas na primeira inicialização após piscar o aplicativo.
Exemplo:
// Read credentials from Flash
api_read_credentials ();
// Make changes to the credentials
g_lorawan_settings.p2p_frequency = 916000000 ; // Use 916 MHz to send and receive
g_lorawan_settings.p2p_bandwidth = 0 ; // Bandwidth 125 kHz
g_lorawan_settings.p2p_sf = 7 ; // Spreading Factor 7
g_lorawan_settings.p2p_cr = 1 ; // Coding Rate 4/5
g_lorawan_settings.p2p_preamble_len = 8 ; // Preample Length 8
g_lorawan_settings.p2p_tx_power = 22 ; // TX power 22 dBi
// Save hard coded LoRaWAN settings
api_set_credentials (); Observação 1
As configurações de codificação dura devem ser definidas em void setup_app(void) !
Observação 2
Lembre -se de que os parâmetros que são alterados com esse método podem ser alterados no comando ou ble ble , mas serão redefinidos após uma reinicialização !
api_ble_printf() pode ser usado para enviar dados sobre o UART ble. print , println e printf são suportados.
OBSERVAÇÃO
Este comando não está disponível no RAK11310!
Por padrão, a publicidade BLE está ativa apenas por 30 segundos após a inicialização/redefinição para diminuir o consumo de energia. Chamando void restart_advertising(uint16_t timeout); A publicidade pode ser reiniciada para segundos timeout .
OBSERVAÇÃO
Este comando não está disponível no RAK11310!
lmh_error_status send_lora_packet(uint8_t *data, uint8_t size, uint8_t fport = 0); é usado para enviar um pacote de dados para o servidor Lorawan. *data são um ponteiro para o buffer que contém os dados, size é do tamanho do pacote. Se o FPORT for 0, o FPORTDEFINEND na estrutura G_LORAWAN_SETTINGS será usado.
bool send_p2p_packet(uint8_t *data, uint8_t size); é usado para enviar um pacote de dados sobre o Lora P2P. *data são um ponteiro para o buffer que contém os dados, size é do tamanho do pacote.
Depois que o ciclo TX (incluindo o Windows RX1 e RX2) terminar, o resultado é mantido no sinalizador global g_rx_fin_result , o evento LORA_TX_FIN é acionado e o retorno lora_data_handler() é chamado. Nesse retorno de chamada, o resultado pode ser verificado e, se necessário, podem ser tomadas medidas.
O Cayennelpp é um formato projetado pela MyDevices para integrar os nós de Lorawan à plataforma IoT.
A biblioteca Cayennelpp estende os tipos de dados disponíveis com vários tipos de dados IPSO não incluídos no trabalho original de Johan Stokking ou a maioria dos garfos e obras laterais de outras pessoas, esses tipos adicionais de dados não são suportados pela MyDevices Cayenne.
A API do WisBlock usa mais alguns tipos de dados que estendem os tipos de dados originais e electroniccats para suportar melhor a ampla gama dos módulos do sensor Wisblock.
Para usar os tipos de dados estendidos, a API do WisBlock já inclui o arquivo de cabeçalho necessário.
Para poder usar as funções Cayenne LPP, é necessária uma instância da classe.
/* * LoRaWAN packet */
WisCayenne g_solution_data ( 255 );Antes de adicionar dados, o buffer de pacote precisa ser redefinido
// Reset the packet
g_solution_data.reset();A biblioteca Cayennelpp tem chamadas de API para os diferentes tipos de dados suportados. Veja a API Cayennelpp para obter detalhes. Além dessas chamadas de API, a API Wisblock adiciona mais 5 chamadas a eles. Essas chamadas de API são para diferentes formatos GNSS e para os dados do sensor VOC:
uint8_t addGNSS_4 ( uint8_t channel, int32_t latitude, int32_t longitude, int32_t altitude);
uint8_t addGNSS_6 ( uint8_t channel, int32_t latitude, int32_t longitude, int32_t altitude);
uint8_t addGNSS_H ( int32_t latitude, int32_t longitude, int16_t altitude, int16_t accuracy, int16_t battery);
uint8_t addGNSS_T ( int32_t latitude, int32_t longitude, int16_t altitude, float accuracy, int8_t sats);
uint8_t addVoc_index ( uint8_t channel, uint32_t voc_index); /* *
* @brief Add GNSS data in Cayenne LPP standard format
*
* @param channel LPP channel
* @param latitude Latitude as read from the GNSS receiver
* @param longitude Longitude as read from the GNSS receiver
* @param altitude Altitude as read from the GNSS receiver
* @return uint8_t bytes added to the data packet
*/
uint8_t WisCayenne::addGNSS_4 ( uint8_t channel, int32_t latitude, int32_t longitude, int32_t altitude) /* *
* @brief Add GNSS data in custom Cayenne LPP format
* Requires changed decoder in LNS and visualization
* Does not work with Cayenne LPP MyDevices
*
* @param channel LPP channel
* @param latitude Latitude as read from the GNSS receiver
* @param longitude Longitude as read from the GNSS receiver
* @param altitude Altitude as read from the GNSS receiver
* @return uint8_t bytes added to the data packet
*/
uint8_t WisCayenne::addGNSS_6 ( uint8_t channel, int32_t latitude, int32_t longitude, int32_t altitude) /* *
* @brief Add GNSS data in Helium Mapper format
*
* @param channel LPP channel
* @param latitude Latitude as read from the GNSS receiver
* @param longitude Longitude as read from the GNSS receiver
* @param altitude Altitude as read from the GNSS receiver
* @param accuracy Accuracy of reading from the GNSS receiver
* @param battery Device battery voltage in V
* @return uint8_t bytes added to the data packet
*/
uint8_t WisCayenne::addGNSS_H ( int32_t latitude, int32_t longitude, int16_t altitude, int16_t accuracy, int16_t battery) /* *
* @brief Add GNSS data in Field Tester format
*
* @param latitude Latitude as read from the GNSS receiver
* @param longitude Longitude as read from the GNSS receiver
* @param altitude Altitude as read from the GNSS receiver
* @param accuracy Accuracy of reading from the GNSS receiver
* @param sats Number of satellites of reading from the GNSS receiver
* @return uint8_t bytes added to the data packet
*/
uint8_t WisCayenne::addGNSS_T ( int32_t latitude, int32_t longitude, int16_t altitude, float accuracy, int8_t sats) /* *
* @brief Add the VOC index
*
* @param channel VOC channel
* @param voc_index VOC index
* @return uint8_t bytes added to the data packet
*/
uint8_t WisCayenne::addVoc_index ( uint8_t channel, uint32_t voc_index) Os pacotes de dados do Cayennelpp estão sempre no formato <Channel #><Channel ID><data bytes> .
Para facilitar os codificadores de dados usados nos servidores Lorawan e os dados de integração coletados pelos sensores Wisblock sempre têm o mesmo número de canal (se essas API forem usadas). Aqui está a lista de números de canal atualmente atribuídos, IDs de canal e quais módulos estão usando a combinação.
| Dados | Canal # | ID do canal | Comprimento | Comentário | Módulo necessário | Nome do campo decodificado |
|---|---|---|---|---|---|---|
| Valor da bateria | 1 | 116 | 2 bytes | 0,01 V MSB não assinado | RAK4631 | VOLTAGE_1 |
| Umidade | 2 | 104 | 1 byte | em %rh | RAK1901 | umidade_2 |
| Temperatura | 3 | 103 | 2 bytes | Em ° C. | RAK1901 | temperatura_3 |
| Pressão barométrica | 4 | 115 | 2 bytes | em HPA (MBAR) | RAK1902 | barômetro_4 |
| Iluminância | 5 | 101 | 2 bytes | 1 lux não assinado | RAK1903 | iluminância_5 |
| Umidade 2 | 6 | 104 | 1 byte | em %rh | RAK1906 | umidade_6 |
| Temperatura 2 | 7 | 103 | 2 bytes | Em ° C. | RAK1906 | temperatura_7 |
| Pressão barométrica 2 | 8 | 115 | 2 bytes | em HPA (MBAR) | RAK1906 | barômetro_8 |
| Resistência a gás 2 | 9 | 2 | 2 bytes | 0,01 assinado (kohm) | RAK1906 | analógico_9 |
| GNSS Stand. resolução | 10 | 136 | 9 bytes | 3 byte LON/LAT 0,0001 °, 3 bytes alt 0,01 metro | RAK1910, RAK12500 | GPS_10 |
| GNSS Resolução aprimorada | 10 | 137 | 11 bytes | 4 byte LON/LAT 0,000001 °, 3 bytes alt 0,01 metro | RAK1910, RAK12500 | GPS_10 |
| Temperatura do solo | 11 | 103 | 2 bytes | Em ° C. | RAK12023/RAK12035 | Temperatura_11 |
| Umidade do solo | 12 | 104 | 1 byte | em %rh | RAK12023/RAK12035 | umidade_12 |
| Umidade do solo crua | 13 | 2 | 2 bytes | 0,01 assinado | RAK12023/RAK12035 | analog_in_13 |
| Dados do solo válidos | 14 | 102 | 1 byte | bool | RAK12023/RAK12035 | presença_14 |
| Iluminância 2 | 15 | 101 | 2 bytes | 1 lux não assinado | RAK12010 | iluminância_15 |
| Voc | 16 | 138 | 2 bytes | Índice de VOC | RAK12047 | VOC_16 |
| MQ2 Gas | 17 | 2 | 2 bytes | 0,01 assinado | RAK12004 | analog_in_17 |
| Porcentagem de gás MQ2 | 18 | 120 | 1 byte | 1-100% não assinado | RAK12004 | Porcentagem_18 |
| MG812 GAS | 19 | 2 | 2 bytes | 0,01 assinado | RAK12008 | analog_in_19 |
| MG812 Porcentagem de gás | 20 | 120 | 1 byte | 1-100% não assinado | RAK12008 | Porcentagem_20 |
| MQ3 Gas de álcool | 21 | 2 | 2 bytes | 0,01 assinado | RAK12009 | analog_in_21 |
| MQ3 Álcool Gas Perc. | 22 | 120 | 1 byte | 1-100% não assinado | RAK12009 | Porcentagem_22 |
| TOF distância | 23 | 2 | 2 bytes | 0,01 assinado | RAK12014 | analog_in_23 |
| TOF dados válidos | 24 | 102 | 1 byte | bool | RAK12014 | presença_24 |
| O giroscópio desencadeado | 25 | 134 | 6 bytes | 2 bytes por eixo, 0,01 °/s | RAK12025 | girômetro_25 |
| Gesto detectado | 26 | 0 | 1 byte | 1 byte com identificação de gesto | RAK14008 | digital_in_26 |
| Valor UVI LTR390 | 27 | 2 | 2 bytes | 0,01 assinado | RAK12019 | analog_in_27 |
| Valor UVS LTR390 | 28 | 101 | 2 bytes | 1 lux não assinado | RAK12019 | iluminância_28 |
| INA219 Corrente | 29 | 2 | 2 bytes | 0,01 assinado | RAK16000 | analógico_29 |
| Tensão Ina219 | 30 | 2 | 2 bytes | 0,01 assinado | RAK16000 | analog_30 |
| INA219 Poder | 31 | 2 | 2 bytes | 0,01 assinado | RAK16000 | analógico_31 |
| Touchpad saiu | 32 | 102 | 1 byte | bool | RAK14002 | presença_32 |
| Touchpad Middle | 33 | 102 | 1 byte | bool | RAK14002 | presença_33 |
| Touchpad certo | 34 | 102 | 1 byte | bool | RAK14002 | presença_34 |
| SCD30 Co2 Concentração | 35 | 125 | 2 bytes | 1 ppm não assinado | RAK12037 | Concentração_35 |
| Temperatura SCD30 | 36 | 103 | 2 bytes | Em ° C. | RAK12037 | Temperatura_36 |
| Scd30 umidade | 37 | 104 | 1 byte | em %rh | RAK12037 | Lunidade_37 |
| MLX90632 Temp | 38 | 103 | 2 bytes | Em ° C. | RAK12003 | Temperatura_38 |
| MLX90632 Temperatura do objeto | 39 | 103 | 2 bytes | Em ° C. | RAK12003 | Temperatura_39 |
| PM 1.0 Valor | 40 | 103 | 2 bytes | em ug/m3 | RAK12003 | VOC_40 |
| PM 2.5 Valor | 41 | 103 | 2 bytes | em ug/m3 | RAK12003 | VOC_41 |
| PM 10 Valor | 42 | 103 | 2 bytes | em ug/m3 | RAK12003 | VOC_42 |
| Evento de terremoto | 43 | 102 | 1 byte | bool | RAK12027 | presença_43 |
| Terremoto SI Valor | 44 | 2 | 2 bytes | analógico 10 * m/s | RAK12027 | analógico_44 |
| Terremoto PGA Valor | 45 | 2 | 2 bytes | analógico 10 * m/s2 | RAK12027 | analógico_45 |
| Alerta de desligamento do terremoto | 46 | 102 | 1 byte | bool | RAK12027 | presença_46 |
| Lpp_channel_eq_collapse | 47 | 102 | 1 byte | bool | RAK12027 | presença_47 |
| Status da mudança | 48 | 102 | 1 byte | bool | RAK13011 | presença_48 |
Os IDs de canal em cursivos são formatos estendidos e não são suportados pelos decodificadores de dados da CAYENNE LPP.
Uma lista completa e atualizada de formatos de dados usados pode ser encontrada em nosso rakwireless_standardized_payload
O repo Rakwireless_standardized_payload inclui também um decodificador correspondente.
O código usado aqui é o exemplo API-TEST.ino.
Estes são os necessários incluem e definições para o aplicativo de usuário e a interface da API
Neste exemplo, codificamos as credenciais de Lorawan. É fortemente recomendado não fazer isso para evitar credenciais de nó duplicados
Opções alternativas para configurar credenciais são
# include < Arduino.h >
/* * Add you required includes after Arduino.h */
# include < Wire.h >
// Debug output set to 0 to disable app debug output
# ifndef MY_DEBUG
# define MY_DEBUG 1
# endif
# ifdef NRF52_SERIES
# if MY_DEBUG > 0
# define MYLOG (tag, ...)
do
{
if (tag)
PRINTF ( " [%s] " , tag);
PRINTF (__VA_ARGS__);
PRINTF ( " n " );
if (g_ble_uart_is_connected)
{
g_ble_uart. printf (__VA_ARGS__);
g_ble_uart. printf ( " n " );
}
} while ( 0 )
# else
# define MYLOG (...)
# endif
# endif
# ifdef ARDUINO_ARCH_RP2040
# if MY_DEBUG > 0
# define MYLOG (tag, ...)
do
{
if (tag)
Serial. printf ( " [%s] " , tag);
Serial. printf (__VA_ARGS__);
Serial. printf ( " n " );
} while ( 0 )
# else
# define MYLOG (...)
# endif
# endif
/* * Include the WisBlock-API-V2 */
# include < WisBlock-API-V2.h > // Click to install library: http://librarymanager/All#WisBlock-API-V2
/* * Define the version of your SW */
# define SW_VERSION_1 1 // major version increase on API change / not backwards compatible
# define SW_VERSION_2 0 // minor version increase on API change / backward compatible
# define SW_VERSION_3 0 // patch version increase on bugfix, no affect on API
/* *
Optional hard-coded LoRaWAN credentials for OTAA and ABP.
It is strongly recommended to avoid duplicated node credentials
Options to setup credentials are
- over USB with AT commands
- over BLE with My nRF52 Toolbox
*/
uint8_t node_device_eui[ 8 ] = { 0x00 , 0x0D , 0x75 , 0xE6 , 0x56 , 0x4D , 0xC1 , 0xF3 };
uint8_t node_app_eui[ 8 ] = { 0x70 , 0xB3 , 0xD5 , 0x7E , 0xD0 , 0x02 , 0x01 , 0xE1 };
uint8_t node_app_key[ 16 ] = { 0x2B , 0x84 , 0xE0 , 0xB0 , 0x9B , 0x68 , 0xE5 , 0xCB , 0x42 , 0x17 , 0x6F , 0xE7 , 0x53 , 0xDC , 0xEE , 0x79 };
uint8_t node_nws_key[ 16 ] = { 0x32 , 0x3D , 0x15 , 0x5A , 0x00 , 0x0D , 0xF3 , 0x35 , 0x30 , 0x7A , 0x16 , 0xDA , 0x0C , 0x9D , 0xF5 , 0x3F };
uint8_t node_apps_key[ 16 ] = { 0x3F , 0x6A , 0x66 , 0x45 , 0x9D , 0x5E , 0xDC , 0xA6 , 0x3C , 0xBC , 0x46 , 0x19 , 0xCD , 0x61 , 0xA1 , 0x1E };Declarações a encaminhar de algumas funções (exigidas ao usar o Platformio)
/* * Application function definitions */
void setup_app ( void );
bool init_app ( void );
void app_event_handler ( void );
void ble_data_handler ( void ) __attribute__((weak));
void lora_data_handler ( void );Aqui, o nome do aplicativo está definido como RAK-TEST . O nome será estendido com o NRF52 exclusivo ID do chip. Este nome é usado na publicidade BLE.
/* * Application stuff */
/* * Set the device name, max length is 10 characters */
char g_ble_dev_name[ 10 ] = " RAK-TEST " ;Algumas bandeiras e sinais necessários
/* * Flag showing if TX cycle is ongoing */
bool lora_busy = false ;
/* * Send Fail counter * */
uint8_t send_fail = 0 ; Esta função é chamada no início do início do aplicativo. Nesta função, tudo deve ser configurado necessário antes que o Arduino setup() seja executado. Isso pode ser, por exemplo, as credenciais de Lorawan. Neste exemplo, codificamos as credenciais de Lorawan. É fortemente recomendado não fazer isso para evitar credenciais de nó duplicados
Opções alternativas para configurar credenciais são
g_enable_ble está definido. Se verdadeiro, a interface BLE é inicializada. Se falso, a interface BLE não é ativada, o que pode diminuir o consumo de energia. void setup_app ( void )
{
Serial. begin ( 115200 );
time_t serial_timeout = millis ();
// On nRF52840 the USB serial is not available immediately
while (!Serial)
{
if (( millis () - serial_timeout) < 5000 )
{
delay ( 100 );
digitalWrite (LED_GREEN, ! digitalRead (LED_GREEN));
}
else
{
break ;
}
}
digitalWrite (LED_GREEN, LOW);
MYLOG ( " APP " , " Setup WisBlock API Example " );
# ifdef NRF52_SERIES
// Enable BLE
g_enable_ble = true ;
# endif
// Set firmware version
api_set_version (SW_VERSION_1, SW_VERSION_2, SW_VERSION_3);
// Optional
// Setup LoRaWAN credentials hard coded
// It is strongly recommended to avoid duplicated node credentials
// Options to setup credentials are
// -over USB with AT commands
// -over BLE with My nRF52 Toolbox
// Read LoRaWAN settings from flash
api_read_credentials ();
// Change LoRaWAN settings
g_lorawan_settings. auto_join = true ; // Flag if node joins automatically after reboot
g_lorawan_settings. otaa_enabled = true ; // Flag for OTAA or ABP
memcpy (g_lorawan_settings. node_device_eui , node_device_eui, 8 ); // OTAA Device EUI MSB
memcpy (g_lorawan_settings. node_app_eui , node_app_eui, 8 ); // OTAA Application EUI MSB
memcpy (g_lorawan_settings. node_app_key , node_app_key, 16 ); // OTAA Application Key MSB
memcpy (g_lorawan_settings. node_nws_key , node_nws_key, 16 ); // ABP Network Session Key MSB
memcpy (g_lorawan_settings. node_apps_key , node_apps_key, 16 ); // ABP Application Session key MSB
g_lorawan_settings. node_dev_addr = 0x26021FB4 ; // ABP Device Address MSB
g_lorawan_settings. send_repeat_time = 120000 ; // Send repeat time in milliseconds: 2 * 60 * 1000 => 2 minutes
g_lorawan_settings. adr_enabled = false ; // Flag for ADR on or off
g_lorawan_settings. public_network = true ; // Flag for public or private network
g_lorawan_settings. duty_cycle_enabled = false ; // Flag to enable duty cycle (validity depends on Region)
g_lorawan_settings. join_trials = 5 ; // Number of join retries
g_lorawan_settings. tx_power = 0 ; // TX power 0 .. 15 (validity depends on Region)
g_lorawan_settings. data_rate = 3 ; // Data rate 0 .. 15 (validity depends on Region)
g_lorawan_settings. lora_class = 0 ; // LoRaWAN class 0: A, 2: C, 1: B is not supported
g_lorawan_settings. subband_channels = 1 ; // Subband channel selection 1 .. 9
g_lorawan_settings. app_port = 2 ; // Data port to send data
g_lorawan_settings. confirmed_msg_enabled = LMH_UNCONFIRMED_MSG; // Flag to enable confirmed messages
g_lorawan_settings. resetRequest = true ; // Command from BLE to reset device
g_lorawan_settings. lora_region = LORAMAC_REGION_AS923_3; // LoRa region
// Save LoRaWAN settings
api_set_credentials ();Esta função é chamada depois que BLE e Lora já são inicializados. Idealmente, este é o local para inicializar coisas específicas do aplicativo, como sensores ou atuadores. Neste exemplo, não é utilizado
/* *
* @brief Application specific initializations
*
* @return true Initialization success
* @return false Initialization failure
*/
bool init_app ( void )
{
MYLOG ( " APP " , " init_app " );
return true ;
} Este retorno de chamada é chamado no evento de status . O evento de status é acionado com frequência, o tempo é definido por send_repeat_time . É acionado também por eventos definidos pelo usuário. Consulte o exemplo RAK1904_Example _ Como os eventos definidos pelo usuário são definidos. _ É importante que os sinalizadores de eventos sejam redefinidos. Como exemplo, o evento de status é redefinido por esta sequência de código:
if ((g_task_event_type & STATUS) == STATUS)
{
g_task_event_type &= N_STATUS;
...
} O evento de status é usado para enviar pacotes uplink frequentemente para o servidor Lorawan.
Neste exemplo, o código também reiniciamos a publicidade BLE por 15 segundos. Caso contrário, o BLE Adverstising estará ativo apenas por 30 segundos após a inicialização/redefinição.
void app_event_handler ( void )
{
// Timer triggered event
if ((g_task_event_type & STATUS) == STATUS)
{
g_task_event_type &= N_STATUS;
MYLOG ( " APP " , " Timer wakeup " );
# ifdef NRF52_SERIES
// If BLE is enabled, restart Advertising
if (g_enable_ble)
{
restart_advertising ( 15 );
}
# endif
if (lora_busy)
{
MYLOG ( " APP " , " LoRaWAN TX cycle not finished, skip this event " );
}
else
{
// Dummy packet
uint8_t dummy_packet[] = { 0x10 , 0x00 , 0x00 };
lmh_error_status result = send_lora_packet (dummy_packet, 3 );
switch (result)
{
case LMH_SUCCESS:
MYLOG ( " APP " , " Packet enqueued " );
// Set a flag that TX cycle is running
lora_busy = true ;
break ;
case LMH_BUSY:
MYLOG ( " APP " , " LoRa transceiver is busy " );
break ;
case LMH_ERROR:
MYLOG ( " APP " , " Packet error, too big to send with current DR " );
break ;
}
}
}
} Esse retorno de chamada é usado para lidar com dados recebidos sobre o ble Uart. Se você não precisar de funcionalidade BLE UART, poderá remover completamente essa função. Neste exemplo, encaminhamos os dados recebidos de UART para o intérprete de comando AT. Dessa forma, podemos enviar os comandos AT, tanto pela porta USB quanto pela porta UART BLE BLE.
A comunicação BLE é suportada apenas no RAK4631. O RAK11310 não tem BLE.
# ifdef NRF52_SERIES
void ble_data_handler ( void )
{
if (g_enable_ble)
{
/* ************************************************************ */
/* ************************************************************ */
// / todo BLE UART data arrived
// / todo or forward them to the AT command interpreter
// / todo parse them here
/* ************************************************************ */
/* ************************************************************ */
if ((g_task_event_type & BLE_DATA) == BLE_DATA)
{
MYLOG ( " AT " , " RECEIVED BLE " );
// BLE UART data arrived
// in this example we forward it to the AT command interpreter
g_task_event_type &= N_BLE_DATA;
while (g_ble_uart. available () > 0 )
{
at_serial_input ( uint8_t (g_ble_uart. read ()));
delay ( 5 );
}
at_serial_input ( uint8_t ( ' n ' ));
}
}
}
# endif Este retorno de chamada é chamado em três eventos diferentes:
O evento lora_data é acionado se um pacote de downlink do servidor Lorawan ou um pacote Lora P2P chegou. Neste exemplo, não estamos analisando os dados, eles são impressos apenas no log e sobre o ble uart (se um dispositivo estiver conectado)
O evento LORA_TX_FIN é acionado após o envio de um pacote de uplink terminado, incluindo o Windows RX1 e RX2. Se os pacotes confirmados forem enviados, o sinalizador global g_rx_fin_result contém o resultado da transmissão confirmada. Se g_rx_fin_result for verdadeiro, o servidor Lorawan reconheceu o pacote Uplink enviando um ACK . Caso contrário, o g_rx_fin_result é definido como False, indicando que o pacote não foi recebido pelo servidor Lorawan (nenhum gateway no alcance, o pacote foi danificado no ar. Se os pacotes não confirmados forem enviados ou se o modo Lora P2P for usado, o sinalizador g_rx_fin_result for sempre verdadeiro.
O evento LORA_JOIN_FIN é chamado após a conclusão do ciclo de ingresso/solicitação de aceitação/rejeição. O sinalizador global g_task_event_type contém o resultado da solicitação de junção. Se for verdade, o nó entrou na rede. Se false, a junção não foi bem -sucedida. Nesse caso, o ciclo de junção pode ser reiniciado ou o nó pode relatar um erro.
void lora_data_handler ( void )
{
// LoRa data handling
if ((g_task_event_type & LORA_DATA) == LORA_DATA)
{
/* ************************************************************ */
/* ************************************************************ */
// / todo LoRa data arrived
// / todo parse them here
/* ************************************************************ */
/* ************************************************************ */
g_task_event_type &= N_LORA_DATA;
MYLOG ( " APP " , " Received package over LoRa " );
char log_buff[g_rx_data_len * 3 ] = { 0 };
uint8_t log_idx = 0 ;
for ( int idx = 0 ; idx < g_rx_data_len; idx++)
{
sprintf (&log_buff[log_idx], " %02X " , g_rx_lora_data[idx]);
log_idx += 3 ;
}
lora_busy = false ;
MYLOG ( " APP " , " %s " , log_buff);
}
// LoRa TX finished handling
if ((g_task_event_type & LORA_TX_FIN) == LORA_TX_FIN)
{
g_task_event_type &= N_LORA_TX_FIN;
MYLOG ( " APP " , " LPWAN TX cycle %s " , g_rx_fin_result ? " finished ACK " : " failed NAK " );
if (!g_rx_fin_result)
{
// Increase fail send counter
send_fail++;
if (send_fail == 10 )
{
// Too many failed sendings, reset node and try to rejoin
delay ( 100 );
sd_nvic_SystemReset ();
}
}
// Clear the LoRa TX flag
lora_busy = false ;
}
// LoRa Join finished handling
if ((g_task_event_type & LORA_JOIN_FIN) == LORA_JOIN_FIN)
{
g_task_event_type &= N_LORA_JOIN_FIN;
if (g_join_result)
{
MYLOG ( " APP " , " Successfully joined network " );
}
else
{
MYLOG ( " APP " , " Join network failed " );
// / todo here join could be restarted.
// lmh_join();
}
}
} No Arduino, não é possível definir configurações no arquivo .ino que pode controlar o comportamento das bibliotecas incluídas. Para alterar o log de depuração e o uso do LED BLUE BLE, você deve abrir o arquivo WisBlock-API-V2.h na pasta de origem das bibliotecas.
Para ativar/desativar o depuração da API ( API_LOG() ), abra o arquivo WisBlock-API-V2.h na pasta de origem das bibliotecas.
Procurar
# define API_DEBUG 1no arquivo.
0 -> No debug output
1 -> API debug output
Para ativar/desativar o aplicativo Debug ( MY_LOG() ), você pode encontrar nos exemplos (no arquivo .ino ou app.h)
# define MY_DEBUG 1no arquivo.
0 -> No debug output
1 -> Application debug output
Procurar
# define NO_BLE_LED 1 no arquivo WisBlock-API-V2
0 -> the blue LED will be used to indicate BLE status
1 -> the blue LED will not used
OBSERVAÇÃO
O RAK11310 não tem BLE e o LED azul pode ser usado para outros fins.
A saída de depuração pode ser controlada por define no plataformio.ini API_DEBUG controla a saída de depuração da API Wisblock
0 -> No debug outpuy
1 -> WisBlock API debug output
MY_DEBUG controla a saída de depuração do próprio aplicativo
0 -> No debug outpuy
1 -> Application debug output
NO_BLE_LED controla o uso do LED BLUE BLE.
0 -> the blue LED will be used to indicate BLE status
1 -> the blue LED will not used
Exemplo para saída sem depuração e sem LED azul
build_flags =
- DAPI_DEBUG =0 ; 0 Disable WisBlock API debug output
- DMY_DEBUG =0 ; 0 Disable application debug output
- DNO_BLE_LED =1 ; 1 Disable blue LED as BLE notificatorBiblioteca publicada sob licença do MIT
Créditos:
Funções de comando: Taylor Lee ([email protected])
Liberações de código
api_read_credentials()api_set_credentials() salva para piscarWisBlock API LoRaWAN em vez de GNSS