Integración de STM32 y ESP01S con la plataforma IoT OneNet mediante MQTT

La implementación de un ecosistema de hogar inteligente requiere una comunicación robusta entre los nodos de sensores y la nube. En este artículo, detallaremos cómo configurar la plataforma OneNet de China Mobile y cómo programar un microcontrolador STM32 utilizando un módulo WiFi ESP01S para transmitir datos de telemetría mediante el protocolo MQTT.

Configuración del Entorno en OneNet

Para iniciar el proyecto, es fundamental estructurar correctamente la jerarquía en la consola de desarrollador de OneNet. No es necesario crear un producto por cada sensor; basta con un único producto que albergue múltiples dispositivos o modelos de datos.

  1. Creación del Producto: Acceda al cantro de desarrolladores y cree un nuevo producto seleccionando "WiFi" como método de conexión y "Esquema personalizado" para el desarrollo.
  2. Gestión de Dispositivos: Dentro del producto, añada un dispositivo. Es crucial que el nombre del dispositivo sea alfanumérico (inglés), ya que este servirá como el ClientID en la configuración MQTT.
  3. Definición del Modelo de Cosas (Thing Model): Configure los identificadores de propiedades para los datos que se enviarán (por ejemplo: temperatura, humedad, intensidad lumínica). Estos identificadores deben coincidir exactamente con las claves enviadas en el paquete JSON desde el microcontrolador.

Parámetros de Conexión MQTT

Para establecer el enlace, se requieren los siguientes parámetros estándar proporcionados por la plataforma:

  • Dirección del servidor: mqtts.heclouds.com
  • Puerto: 1883
  • Tópico de Publicación: $sys/{ProductID}/{DeviceName}/thing/property/post
  • Tópico de Suscripción: $sys/{ProductID}/{DeviceName}/thing/property/post/reply

Validación mediante Comandos AT

Antes de integrar el código en el microcontrolador, se recomienda verificar la conectividad del ESP01S mediante un adaptador USB-TTL a 115200 baudios usando la sigueinte secuencia de comandos:

AT+CWMODE=1
AT+CWJAP="SSID_WIFI","PASSWORD_WIFI"
AT+MQTTUSERCFG=0,1,"DeviceID","ProductID","Token_de_Autenticacion",0,0,""
AT+MQTTCONN=0,"mqtts.heclouds.com",1883,1
AT+MQTTPUB=0,"$sys/PID/DID/thing/property/post","{\"id\":\"123\",\"params\":{\"temp\":{\"value\":24}}}",0,0

Implementación en STM32 (Librería HAL)

El siguiente código muestra una abstracción para gestionar la comunicación entre el STM32 y el ESP01S a través de UART. Se ha reestructurado la lógica para mejorar la legibilidad y el manejo de datos.

Gestión del Módulo WiFi (iot_wifi.c)

#include "iot_wifi.h"
#include "usart.h"
#include <stdio.h>
#include <string.h>

#define WIFI_SSID       "MiRedHome"
#define WIFI_PASS       "clave12345"
#define ONENET_PID      "zv9My9QY4s"
#define ONENET_AUTH     "version=2018-10-31&res=..."

char wifi_buffer[512];
uint16_t buffer_index = 0;

void WiFi_Reset_Buffer(void) {
    memset(wifi_buffer, 0, sizeof(wifi_buffer));
    buffer_index = 0;
}

// Función para enviar comandos AT y esperar respuesta
uint8_t WiFi_Send_Command(char *cmd, char *expected_res, uint32_t timeout) {
    HAL_UART_Transmit(&huart2, (uint8_t *)cmd, strlen(cmd), HAL_MAX_DELAY);
    
    uint32_t tick = HAL_GetTick();
    while (HAL_GetTick() - tick < timeout) {
        if (strstr(wifi_buffer, expected_res) != NULL) {
            WiFi_Reset_Buffer();
            return 0; // Éxito
        }
        HAL_Delay(10);
    }
    return 1; // Error por tiempo de espera
}

void WiFi_Init_Sequence(void) {
    printf("Iniciando ESP01S...\r\n");
    
    WiFi_Send_Command("AT\r\n", "OK", 500);
    WiFi_Send_Command("AT+RST\r\n", "ready", 2000);
    WiFi_Send_Command("AT+CWMODE=1\r\n", "OK", 500);
    
    char join_ap[128];
    sprintf(join_ap, "AT+CWJAP=\"%s\",\"%s\"\r\n", WIFI_SSID, WIFI_PASS);
    WiFi_Send_Command(join_ap, "OK", 5000);

    char mqtt_cfg[256];
    sprintf(mqtt_cfg, "AT+MQTTUSERCFG=0,1,\"SmartNode\",\"%s\",\"%s\",0,0,\"\"\r\n", ONENET_PID, ONENET_AUTH);
    WiFi_Send_Command(mqtt_cfg, "OK", 1000);

    WiFi_Send_Command("AT+MQTTCONN=0,\"mqtts.heclouds.com\",1883,1\r\n", "OK", 2000);
}

void WiFi_Publish_Sensors(int t, int h, int l) {
    char payload[256];
    char pub_cmd[512];
    
    // Construcción del JSON según formato OneNet
    sprintf(payload, "{\\\"id\\\":\\\"1\\\"\\,\\\"params\\\":{\\\"temp\\\":{\\\"value\\\":%d}\\,\\\"humi\\\":{\\\"value\\\":%d}\\,\\\"light\\\":{\\\"value\\\":%d}}}", t, h, l);
    
    sprintf(pub_cmd, "AT+MQTTPUB=0,\"$sys/%s/SmartNode/thing/property/post\",\"%s\",0,0\r\n", ONENET_PID, payload);
    
    WiFi_Send_Command(pub_cmd, "OK", 1000);
}

Configuración de la Comunicación Serial

Para que el sistema funcione, es necesario configurar dos puertos UART en el STM32:

  • UART1: Utilizado como consola de depuración para monitorear el estado del sistema en la PC.
  • UART2: Interfaz física conectada a los pines TX/RX del ESP01S. Se debe habilitar la interrupción por recepción (IT) para capturar las respuestas del módulo WiFi sin bloquear el procesador.
// Callback de recepción UART
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART2) {
        if (buffer_index < sizeof(wifi_buffer) - 1) {
            wifi_buffer[buffer_index++] = temp_byte;
        }
        HAL_UART_Receive_IT(&huart2, &temp_byte, 1);
    }
}

Bucle Principal (main.c)

En la función principal, se inicializan los periféricos y se entra en un ciclo donde se leen los sensores y se envían los datos a la nube periódicamente. Se recomienda el uso de variables de tipo int32_t para mantener la compatibilidad con el modelo de datos de OneNet.

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    MX_USART2_UART_Init();

    WiFi_Init_Sequence();

    while (1) {
        // Simulación de lectura de sensores
        int32_t raw_temp = 25;
        int32_t raw_humi = 60;
        int32_t raw_lux = 400;

        WiFi_Publish_Sensors(raw_temp, raw_humi, raw_lux);
        
        HAL_Delay(5000); // Enviar datos cada 5 segundos
    }
}

Es importante notar que, al integrar funciones de red de alto consumo de tiempo como estas, el rendimiento de otros periféricos (como pantallas OLED) puede verse afectado si no se utiliza un sistema operativo de tiempo real (RTOS). Si la latencia es crítica, considere mover la lógica de comunicación a una tarea de baja prioridad en FreeRTOS.

Etiquetas: OneNet MQTT STM32 ESP8266 IoT

Publicado el 7-29 16:29