![]() | ![]() | ![]() | ![]() | ![]() |
|---|
Dirigido a un bajo consumo de energía, esta biblioteca Arduino para los módulos de núcleo de Wisblock Rakwireless se encarga de todos los Lora P2p, Lorawan, BLE, AT Funcionalidad de comando. Puede concentrarse en su aplicación y dejar el resto a la API. Está hecho como compañero de la biblioteca SX126X-Arduino Lorawan
Requiere un poco de replanteamiento sobre las aplicaciones Arduino, porque no tiene la función setup() o loop() . En cambio, todo está impulsado por el evento. El MCU está durmiendo hasta que necesita tomar medidas. Este puede ser un evento de Lorawan, un comando AT recibido sobre el puerto USB o un evento de aplicación, por ejemplo, una interrupción proveniente de un sensor.
Este enfoque facilita la creación de aplicaciones diseñadas para un uso de bajo uso. Durante el sueño, la base Wisblock + Wisblock Core RAK4631 consumen solo 40UA.
Además, la API ofrece dos opciones para configurar la configuración de Lora P2P / Lorawan sin la necesidad de codificarlas en los códigos de origen.
V2 de la biblioteca cambió el formato AT de comando para ser compatible con los comandos RUI3 AT. Consulte el manual de comando AT para RUI3 para ver las diferencias.
La versión V2 solo admite el módulo de núcleo Rakwireless Wisblock RAK4631
Se podría agregar apoyo para el RAK11310 y RAK1200 en el futuro
La API maneja todo desde setup() , loop() , inicialización de Lorawan, manejo de eventos de Lorawan, inicialización BLE, manejo de eventos BLE hasta la interfaz de comando AT.
¡OBSERVACIÓN!
¡La aplicación de usuario no debe tener las funciones setup() y loop() !
La aplicación del usuario tiene dos funciones de inicialización, una se llama al comienzo de setup() , la otra al final. Las otras funciones son las devoluciones de llamada de eventos que se llaman desde loop() . También es posible definir eventos personalizados (como interrupciones de un sensor).
La lectura del sensor, el control del actuador u otras tareas de aplicación se manejan en la app_event_handler() . app_event_handler() se llama con frecuencia, el tiempo entre llamadas está definido por la aplicación. Además, app_event_handler() se llama en eventos personalizados.
ble_data_handler() se llama a los eventos BLE (eventos Ble UART RX por ahora) desde loop() . Se puede utilizar para implementar la comunicación personalizada a través de BLE UART.
¡OBSERVACIÓN!
¡Esta función no es necesaria en el RAK11310!
lora_data_handler() se llama en diferentes eventos de Lorawan
Gráfico TD
A [Boot] -> | Inicio | B (configuración)
B -> | 1 | D (setup_app)
D -> B (configuración)
B -> | 2 | E [Inicializar lora y ble]
E -> B (configuración)
B -> | 3 | G (init_app)
G -> k (configuración terminada)
K -> | Bucle de inicio | I (bucle)
Q [Evento Lora] -> | Wake Up | J
O [Evento del sensor] -> | despertar | JP [Evento BLE] -> | Wake Up | Jr [at comando] -> | despertar | JT [temporizador] -> | despertar | Ji -> J (durmiendo)
K -> | Temporizador de inicio | T
J -> L (app_event_handler)
J -> M (lora_data_handler)
J -> N (BLE_DATA_HANDLER)
J -> S (At Command Handler)
L -> u (leer sensores)
M -> V (Eventos JOIN, TX y RX)
N -> w (manejar los comandos ble AT)
S -> AA (Usuario AT Comandos)
U -> l
V -> m
W -> n
Aa -> s
L -> j
M -> j
N -> j
S -> J

Todos los comandos AT se pueden encontrar en el manual de comando AT , no todos los comandos RUI3 AT son compatibles. ¿Se puede recuperar una lista de comandos AT disponibles con AT? desde el dispositivo
Se han agregado dos comandos AT personalizados al conjunto de comandos RUI3 AT predeterminado:
Descripción: Establezca el intervalo de transmisión automático
Este comando permite establecer el intervalo en segundos entre las transmisiones automáticas de paquetes. Si se establece en 0, la transmisión automática de paquetes está deshabilitada.
| Dominio | 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 o AT_PARAM_ERROR |
Ejemplos :
ATC+SENDINT?
ATC+SENDINT: Get or Set the automatic send interval
OK
ATC+SENDINT=?
ATC+SENDINT:60
OK
ATC+SENDINT=60
OK
Descripción: Mostrar el estado del dispositivo
Este comando permite al usuario obtener el estado del dispositivo actual.
| Dominio | Parámetro de entrada | Valor de retorno | Código de retorno |
|---|---|---|---|
| Estado ATC+? | - | ATC+STATUS: Show LoRaWAN status | OK |
| ATC+status =? | - | <tatus> | OK |
Ejemplos :
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
Descripción: Configuración del puerto
Este comando permite al usuario acceder y configurar la configuración del puerto.
| Dominio | Parámetro de entrada | Valor de retorno | Código de retorno |
|---|---|---|---|
| Puerto ATC+? | - | AT+PORT=<Port><CR>. Get or Set the Port | OK |
| ATC+PORT =? | - | 1-223 | DE ACUERDO |
ATC+Port = <Input Parameter> | 1-223 | - | Ok o at_param_error |
Ejemplos :
ATC+PORT?
ATC+PORT: Get or Set the Port=[1..223]
OK
ATC+PORT=?
ATC+PORT:2
OK
ATC+PORT=2
OK
Atrás
Comenzando con Wisblock API V1.1.2 Los comandos AT pueden extenderse por los comandos AT definidos por el usuario. Esta nueva implementación utiliza la función analizador de la función de comando AT AT WISBLOCK AT. Además, los comandos AT personalizados se enumerarán si el AT? se usa.
¡OBSERVACIÓN! En RUI3 Custom AT Los comandos se llaman con ATC en lugar de AT !
Para extender los comandos AT, se requieren tres pasos:
Los comandos AT personalizados se enumeran en una matriz con el formato struct ATCMD_T. Cada entrada consiste en el comando AT, el texto de explicación que se muestra cuando el comando se llama con A? y punteros a las funciones para consulta, ejecute con parámetros y ejecute sin parámetros. Aquí hay un ejemplo para dos comandos AT 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; Observación 1
La estructura para comandos AT personalizados se extiende para la compatibilidad RUI3. El código anterior escrito para Wisblock-API V1.X debe ajustarse a esta nueva estructura.
Observación 2
Para las funciones que no son compatibles con el comando AT, un NULL debe colocarse en la matriz.
Observación 3
El nombre g_user_at_cmd_list se corrige y no se puede cambiar o no se detectan los comandos personalizados.
Observación 4
Los permisos se dan como una cadena. Las entradas válidas son "R" (solo leer), "W" (solo escribir), "RW" (leer y escribir)
Se debe proporcionar una variable con el número de comandos AT personalizados:
/* * Number of user defined AT commands */
uint8_t g_user_at_cmd_num = sizeof (g_user_at_cmd_list_example) / sizeof ( atcmd_t ); OBSERVACIÓN
El nombre g_user_at_cmd_num se corrige y no se puede cambiar o no se detectan los comandos personalizados.
Para cada comando personalizado, se deben escribir los comandos de consulta y ejecución. Los nombres de estas funciones deben coincidir con los nombres de funciones utilizados en la matriz de comandos AT de personalización. El comando Ejecutar recibe como parámetro el valor del comando AT después del valor = del valor.
Las funciones de consulta ( =? ) No reciban y los parámetros y siempre deben regresar con 0. Las funciones de consulta guarde el resultado de la consulta en la matriz de char global g_at_query_buffer , la matriz tiene un tamaño máximo de ATQUERY_SIZE que es de 128 caracteres.
Ejecutar funciones con parámetros ( =<value> ) Recibir valores o configuraciones como un puntero a una matriz de char. Esta matriz incluye solo el valor o el parámetro sin el comando AT. Por ejemplo, el manejo de la función Ejecutar ATC+SETDEV=12000 recibiría solo el 120000 . El valor o parámetro recibido debe verificarse para la validez y si el valor del formato no coincide, se debe devolver un AT_ERRNO_PARA_VAL . Si el valor o el parámetro es correcto, la función debe devolver 0 .
Las funciones de ejecución sin parámetros se utilizan para realizar una acción y devolver el éxito de la acción como 0 si exitoso o AT_ERRNO_EXEC_FAIL si la ejecución falló.
Estos ejemplos se usan para establecer una variable en la aplicación.
/* ******************************************************************* */
// 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 );Estos cinco ejemplos explican el uso de la API. En todos los ejemplos, las devoluciones de llamada API y las funciones adicionales (lecturas de sensores, manejo de IRQ, servicio de ubicación GNSS) se separan en sus propios bocetos.
El WisBlock-API-V2 también se ha utilizado en los siguientes proyectos de plataforma:
Cuando se usa con el RAK4631, la actualización de firmware sobre BLE ya está incluida en la biblioteca. Las actualizaciones de firmware para el RAK4631 se pueden realizar utilizando la caja de herramientas Nordic NRF (disponible para Android e iOS) o con la caja de herramientas WisBlock (mi aplicación Android).
Para la actualización, copie el archivo de actualización creado (generalmente llamado firmware.zip) desde la carpeta .pio/build/{dispositivo}, copiéelo a su teléfono y use una de las aplicaciones para actualizar el firmware.
Si la actualización del firmware a través de BLE falla, actualice el dispositivo al último cargador de arranque para el RAK4631 con la versión v0.4.3. Puede encontrar el último gestor de arranque en el repositorio de WisBlock
La API proporciona algunas llamadas para la administración, para enviar el paquete Lorawan, para enviar datos BLEART y activar eventos.
void api_set_version(uint16_t sw_1 = 1, uint16_t sw_2 = 0, uint16_t sw_3 = 0);
Se puede llamar a esta función para establecer la versión de la aplicación. La versión de la aplicación se puede solicitar mediante comandos AT. El número de versión se construye a partir de tres dígitos:
sw_1 ==> Aumento de la versión principal en el cambio de API / no compatible con versiones anteriores
sw_2 ==> Aumento de la versión menor en el cambio de API / Compatible con retroceso
sw_3 ==> Aumento de la versión del parche en Bugfix, sin efecto en API
Si no se llama a api_set_version , la versión de la aplicación predetermina a 1.0.0 .
void api_reset(void);
Realiza un reinicio del módulo de núcleo de Wisblock
void api_wake_loop(uint16_t reason);
Esto se usa para despertar el bucle con un evento. La reason debe definirse en app.h Después de que la aplicación bucle despertará, llamará a la app_event_handler() con el valor de reason en g_task_event_type .
Como ejemplo, esto se puede usar para despertar el dispositivo de la interrupción de un sensor de acelerómetro. Aquí, como ejemplo, un extracto del código de ejemplo del accelerometer .
En accelerometer.ino se define el evento. La primera definición es establecer la señal, la segunda es borrar el evento después de que se manejara.
/* * Define additional events */
# define ACC_TRIGGER 0b1000000000000000
# define N_ACC_TRIGGER 0b0111111111111111 Luego en lis3dh_acc.ino en la función de devolución de llamada de interrupción void acc_int_handler(void) el bucle se despierta con la señal ACC_TRIGGER
void acc_int_handler ( void )
{
// Wake up the task to handle it
api_wake_loop (ACC_TRIGGER);
} Y finalmente en accelerometer.ino , el evento se maneja en 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);
Se puede llamar a esta función para enumerar la configuración completa del dispositivo WISBLOCK a través de USB. La salida 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)
Detiene el temporizador que despierta el MCU con frecuencia.
void api_timer_restart(uint32_t new_time)
Reinicia el temporizador con un nuevo valor. El valor está en milisegundos
void api_read_credentials(void);
void api_set_credentials(void); Si la configuración de Lora P2P debe estar codificada (por ejemplo, la frecuencia, el ancho de banda, ...) Esto se puede hacer en setup_app() . Primero, la configuración guardada debe leerse desde Flash con api_read_credentials(); , luego se pueden cambiar la configuración. Después de cambiar la configuración, debe guardar con api_set_credentials() . Como la API de WISBLOCK verifica si es necesario guardar algún cambio, los valores cambiados solo se guardarán en el primer arranque después de flashear la aplicación.
Ejemplo:
// 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 (); Observación 1
¡La configuración codificada se debe establecer en void setup_app(void) !
Observación 2
Tenga en cuenta que los parámetros que se cambian con este método se pueden cambiar en el comando o BLE, ¡pero se restablecerán después de un reinicio !
api_ble_printf() se puede usar para enviar datos a través del UART BLE. print , println e printf es compatible.
OBSERVACIÓN
¡Este comando no está disponible en el RAK11310!
Por defecto, la publicidad BLE solo está activa durante 30 segundos después de la encendido/reinicio para reducir el consumo de energía. Llamando void restart_advertising(uint16_t timeout); La publicidad se puede reiniciar para timeout de segundos.
OBSERVACIÓN
¡Este comando no está disponible en el RAK11310!
lmh_error_status send_lora_packet(uint8_t *data, uint8_t size, uint8_t fport = 0); se usa para enviar un paquete de datos al servidor Lorawan. *data son un puntero al búfer que contiene los datos, size es el tamaño del paquete. Si el FPORT es 0, se utiliza el FPortDefined en la estructura G_lorawan_Settings.
bool send_p2p_packet(uint8_t *data, uint8_t size); se usa para enviar un paquete de datos a través de Lora P2P. *data son un puntero al búfer que contiene los datos, size es el tamaño del paquete.
Después de que se terminen el ciclo TX (incluidas las ventanas RX1 y RX2), el resultado se mantiene en el indicador global g_rx_fin_result , el evento LORA_TX_FIN se activa y se llama la devolución de llamada lora_data_handler() . En esta devolución de llamada se puede verificar el resultado y, si es necesario, se pueden tomar medidas.
Cayennelpp es un formato diseñado por MyDevices para integrar los nodos de Lorawan en su plataforma IoT.
La Biblioteca Cayennelpp extiende los tipos de datos disponibles con varios tipos de datos IPSO que no se incluyen en el trabajo original de Johan Stokking o la mayoría de las horquillas y trabajos laterales de otras personas, estos tipos de datos adicionales no son compatibles con MyDevices Cayenne.
La API de WISBLOCK utiliza algunos tipos de datos más que extienden los tipos de datos originales y electrónicos para soportar mejor la amplia gama de los módulos del sensor WisBlock.
Para usar los tipos de datos extendidos, la API WISBLOCK ya incluye el archivo de encabezado requerido.
Para poder usar las funciones de Cayenne LPP, se requiere una instancia de la clase.
/* * LoRaWAN packet */
WisCayenne g_solution_data ( 255 );Antes de agregar datos, el búfer de paquetes debe restablecerse
// Reset the packet
g_solution_data.reset();La biblioteca Cayennelpp tiene llamadas API para los diferentes tipos de datos admitidos. Vea la API de Cayennelpp para más detalles. Además de estas llamadas API, la API Wisblock agrega 5 llamadas más. Estas llamadas API son para diferentes formatos GNSS y para los datos del 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) Los paquetes de datos Cayennelpp siempre están en el formato <Channel #><Channel ID><data bytes> .
Para que sea más fácil en los codificadores de datos utilizados en los servidores Lorawan y los datos de integración recopilados por los sensores de Wisblock siempre tienen el mismo número de canal (si se usa estas API). Aquí está la lista de números de canal asignados actualmente, ID de canal y qué módulos están utilizando la combinación.
| Datos | # De canal | ID de canal | Longitud | Comentario | Módulo requerido | Nombre de campo decodificado |
|---|---|---|---|---|---|---|
| Valor de la batería | 1 | 116 | 2 bytes | 0.01 V MSB sin firmar | RAK4631 | voltaje_1 |
| Humedad | 2 | 104 | 1 byte | en %rh | RAK1901 | humedad_2 |
| Temperatura | 3 | 103 | 2 bytes | en ° C | RAK1901 | temperatura_3 |
| Presión barométrica | 4 | 115 | 2 bytes | En HPA (Mbar) | RAK1902 | barómetro_4 |
| Iluminación | 5 | 101 | 2 bytes | 1 Lux sin firmar | RAK1903 | Illuminance_5 |
| Humedad 2 | 6 | 104 | 1 byte | en %rh | RAK1906 | humedad_6 |
| Temperatura 2 | 7 | 103 | 2 bytes | en ° C | RAK1906 | temperatura_7 |
| Presión barométrica 2 | 8 | 115 | 2 bytes | En HPA (Mbar) | RAK1906 | barómetro_8 |
| Resistencia de gas 2 | 9 | 2 | 2 bytes | 0.01 firmado (kohm) | RAK1906 | Analog_9 |
| GNSS Stand. resolución | 10 | 136 | 9 bytes | 3 bytes lon/lat 0.0001 °, 3 bytes alt 0.01 metro | RAK1910, RAK12500 | GPS_10 |
| Resolución mejorada de GNSS | 10 | 137 | 11 bytes | 4 bytes lon/lat 0.000001 °, 3 bytes alt 0.01 metro | RAK1910, RAK12500 | GPS_10 |
| Temperatura del suelo | 11 | 103 | 2 bytes | en ° C | RAK12023/RAK12035 | temperatura_11 |
| Humedad del suelo | 12 | 104 | 1 byte | en %rh | RAK12023/RAK12035 | humedad_12 |
| Humedad del suelo crudo | 13 | 2 | 2 bytes | 0.01 firmado | RAK12023/RAK12035 | analog_in_13 |
| Datos de suelo válidos | 14 | 102 | 1 byte | bool | RAK12023/RAK12035 | presencia_14 |
| Illuminance 2 | 15 | 101 | 2 bytes | 1 Lux sin firmar | RAK12010 | Illuminance_15 |
| Vocero | 16 | 138 | 2 bytes | Índice de VOC | RAK12047 | VOC_16 |
| Gas MQ2 | 17 | 2 | 2 bytes | 0.01 firmado | RAK12004 | analog_in_17 |
| Porcentaje de gas MQ2 | 18 | 120 | 1 byte | 1-100% sin firmar | RAK12004 | porcentaje_18 |
| Gas de MG812 | 19 | 2 | 2 bytes | 0.01 firmado | RAK12008 | analog_in_19 |
| Porcentaje de gas MG812 | 20 | 120 | 1 byte | 1-100% sin firmar | RAK12008 | porcentaje_20 |
| Gas de alcohol MQ3 | 21 | 2 | 2 bytes | 0.01 firmado | RAK12009 | analog_in_21 |
| MQ3 Alcohol Gas Perc. | 22 | 120 | 1 byte | 1-100% sin firmar | RAK12009 | porcentaje_22 |
| TOF Distancia | 23 | 2 | 2 bytes | 0.01 firmado | RAK12014 | analog_in_23 |
| Datos de TOF válidos | 24 | 102 | 1 byte | bool | RAK12014 | presencia_24 |
| Gyro activado | 25 | 134 | 6 bytes | 2 bytes por eje, 0.01 °/s | RAK12025 | gyrometer_25 |
| Gesto detectado | 26 | 0 | 1 byte | 1 byte con identificación de gesto | RAK14008 | digital_in_26 |
| Valor UVI LTR390 | 27 | 2 | 2 bytes | 0.01 firmado | RAK12019 | analog_in_27 |
| Valor UVS LTR390 | 28 | 101 | 2 bytes | 1 Lux sin firmar | RAK12019 | Illuminance_28 |
| Ina219 actual | 29 | 2 | 2 bytes | 0.01 firmado | RAK16000 | Analog_29 |
| INA219 voltaje | 30 | 2 | 2 bytes | 0.01 firmado | RAK16000 | Analog_30 |
| INA219 PODER | 31 | 2 | 2 bytes | 0.01 firmado | RAK16000 | Analog_31 |
| Touchpad izquierda | 32 | 102 | 1 byte | bool | RAK14002 | presencia_32 |
| Centro táctil | 33 | 102 | 1 byte | bool | RAK14002 | presencia_33 |
| Panel táctil a la derecha | 34 | 102 | 1 byte | bool | RAK14002 | presencia_34 |
| Concentración de CO2 SCD30 | 35 | 125 | 2 bytes | 1 ppm sin firmar | RAK12037 | concentración_35 |
| Temperatura SCD30 | 36 | 103 | 2 bytes | en ° C | RAK12037 | temperatura_36 |
| Humedad SCD30 | 37 | 104 | 1 byte | en %rh | RAK12037 | humedad_37 |
| MLX90632 TEMP DE SENSOR | 38 | 103 | 2 bytes | en ° C | RAK12003 | temperatura_38 |
| MLX90632 TEMP de objeto | 39 | 103 | 2 bytes | en ° C | RAK12003 | temperatura_39 |
| Valor PM 1.0 | 40 | 103 | 2 bytes | en ug/m3 | RAK12003 | VOC_40 |
| Valor PM 2.5 | 41 | 103 | 2 bytes | en ug/m3 | RAK12003 | VOC_41 |
| Valor de PM 10 | 42 | 103 | 2 bytes | en ug/m3 | RAK12003 | VOC_42 |
| Evento de terremoto | 43 | 102 | 1 byte | bool | RAK12027 | presencia_43 |
| Valor de SI de terremoto | 44 | 2 | 2 bytes | análogo 10 * m/s | RAK12027 | Analog_44 |
| Valor PGA de terremoto | 45 | 2 | 2 bytes | análogo 10 * m/s2 | RAK12027 | Analog_45 |
| Alerta de cierre del terremoto | 46 | 102 | 1 byte | bool | RAK12027 | presencia_46 |
| LPP_CHANNEL_EQ_COLLAPSE | 47 | 102 | 1 byte | bool | RAK12027 | presencia_47 |
| Estado de cambio | 48 | 102 | 1 byte | bool | RAK13011 | presencia_48 |
Los ID de canal en cursiva son formatos extendidos y no son compatibles con los decodificadores de datos de Cayenne LPP estándar.
Se puede encontrar una lista completa y actualizada de formatos de datos usados en nuestro RAKWIRELECT_STANDARDED_PAYLOAD
El repositorio RAKWIRELELS_STANDARDED_PAYLOAD incluye también un decodificador coincidente.
El código utilizado aquí es el ejemplo API-Test.ino.
Estas son las incluyas y definiciones requeridas para la aplicación de usuario y la interfaz API
En este ejemplo, codificamos las credenciales de Lorawan. Se recomienda encarecidamente no hacer eso para evitar las credenciales de nodo duplicadas
Las opciones alternativas para configurar las credenciales son
# 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 };Declaraciones de avance de algunas funciones (requeridas cuando se usa 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 );Aquí el nombre de la aplicación se establece en RAK-Test . El nombre se extenderá con la ID de chip única NRF52. Este nombre se usa en la publicidad BLE.
/* * Application stuff */
/* * Set the device name, max length is 10 characters */
char g_ble_dev_name[ 10 ] = " RAK-TEST " ;Se requieren algunas banderas y señales
/* * Flag showing if TX cycle is ongoing */
bool lora_busy = false ;
/* * Send Fail counter * */
uint8_t send_fail = 0 ; Esta función se llama al comienzo del inicio de la aplicación. En esta función, todo se debe configurar que se requiera antes de ejecutar Arduino setup() . Esto podría ser, por ejemplo, las credenciales de Lorawan. En este ejemplo, codificamos las credenciales de Lorawan. Se recomienda encarecidamente no hacer eso para evitar las credenciales de nodo duplicadas
Las opciones alternativas para configurar las credenciales son
g_enable_ble . Si es cierto, la interfaz BLE se inicializa. Si es falso, la interfaz BLE no se activa, lo que puede reducir el consumo de energía. 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 función se llama después de que BLE y Lora ya se inicializan. Idealmente, este es el lugar para inicializar cosas específicas de la aplicación, como sensores o actuadores. En este ejemplo no se usa
/* *
* @brief Application specific initializations
*
* @return true Initialization success
* @return false Initialization failure
*/
bool init_app ( void )
{
MYLOG ( " APP " , " init_app " );
return true ;
} Esta devolución de llamada se llama en el evento de estado . El evento de estado se activa con frecuencia, el tiempo se establece mediante send_repeat_time . También es activado por eventos definidos por el usuario. Consulte el ejemplo RAK1904_EXample _ Cómo se definen los eventos definidos por el usuario. _ Es importante que los banderas de eventos se restablezcan. Como ejemplo, el evento de estado se restablece por esta secuencia de código:
if ((g_task_event_type & STATUS) == STATUS)
{
g_task_event_type &= N_STATUS;
...
} El evento de estado se utiliza para enviar paquetes de enlace ascendente con frecuencia al servidor Lorawan.
En este código de ejemplo, también reiniciamos la publicidad BLE durante 15 segundos. De lo contrario, BLE Adverstising solo está activo durante 30 segundos después de la encendido/reinicio.
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 ;
}
}
}
} Esta devolución de llamada se utiliza para manejar los datos recibidos sobre el UART. Si no necesita la funcionalidad BLE UART, puede eliminar esta función por completo. En este ejemplo reenviamos los datos recibidos del intérprete AT Command. De esta manera, podemos enviar los comandos AT a través del puerto USB o sobre el puerto BLO UART.
La comunicación BLE solo es compatible con el RAK4631. El RAK11310 no tiene 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 Esta devolución de llamada se llama en tres eventos diferentes:
El evento Lora_Data se activa si ha llegado un paquete de enlace descendente del servidor Lorawan o un paquete Lora P2P. En este ejemplo, no estamos analizando los datos, solo se imprimen en el registro y sobre ble UART (si un dispositivo está conectado)
El evento Lora_tx_fin se activa después de que se termina un paquete de enlace ascendente, incluidas las ventanas RX1 y RX2. Si se envían paquetes confirmados , la bandera global g_rx_fin_result contiene el resultado de la transmisión confirmada. Si g_rx_fin_result es verdadero, el servidor Lorawan reconoció el paquete de enlace ascendente enviando un ACK . De lo contrario, el g_rx_fin_result se establece en False, lo que indica que el servidor Lorawan no recibió el paquete (sin puerta de enlace en el rango, el paquete se dañó en el aire. Si los paquetes no confirmados se envían o si se usa el modo Lora P2P , el indicador g_rx_fin_result siempre es verdadero.
El evento Lora_Join_Fin se llama después de que se termina el ciclo de solicitud de solicitud/aceptación de unión/rechazo. La bandera global g_task_event_type contiene el resultado de la solicitud de unión. Si es cierto, el nodo se ha unido a la red. Si False la unión no tuvo éxito. En este caso, el ciclo de unión podría reiniciarse o el nodo podría informar un error.
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();
}
}
} En Arduino no es posible definir la configuración en el archivo .ino que pueda controlar el comportamiento de las bibliotecas incluidas. Para cambiar el registro de depuración y el uso del LED azul BLE, debe abrir el archivo WisBlock-API-V2.h en la carpeta de origen de las bibliotecas.
Para habilitar/deshabilitar la depuración API ( API_LOG() ) Abra el archivo WisBlock-API-V2.h en la carpeta de origen de las bibliotecas.
Buscar
# define API_DEBUG 1en el archivo.
0 -> No debug output
1 -> API debug output
Para habilitar/deshabilitar la depuración de la aplicación ( MY_LOG() ) que puede encontrar en los ejemplos (ya sea en el archivo .ino o app.h)
# define MY_DEBUG 1en el archivo.
0 -> No debug output
1 -> Application debug output
Buscar
# define NO_BLE_LED 1 En el archivo WisBlock-API-V2
0 -> the blue LED will be used to indicate BLE status
1 -> the blue LED will not used
OBSERVACIÓN
RAK11310 no tiene BLE y el LED azul se puede usar para otros fines.
La salida de depuración se puede controlar por define en el API_DEBUG de Plataforma.ini los controles la salida de depuración de la API WISBLOCK
0 -> No debug outpuy
1 -> WisBlock API debug output
MY_DEBUG controla la salida de depuración de la aplicación en sí
0 -> No debug outpuy
1 -> Application debug output
NO_BLE_LED controla el uso del LED azul BLE.
0 -> the blue LED will be used to indicate BLE status
1 -> the blue LED will not used
Ejemplo para no tener salida de depuración y sin 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 bajo la licencia MIT
Créditos:
AT Funciones de comando: Taylor Lee ([email protected])
Lanzamientos de código
api_read_credentials()api_set_credentials() guarda para flashearWisBlock API LoRaWAN en lugar de GNSS