Saltar al contenido principal

Extendiendo MCP con Grove

Descripción general​

Este documento describe cómo usar el sensor de temperatura y humedad DHT20 a través de la interfaz Grove en la placa de desarrollo SenseCAP Watcher basada en ESP32-S3.

Preparación del hardware​

SenseCAP Watcher para XiaoZhiGrove - Sensor de temperatura y humedad V2.0 (DHT20)

Definición de la interfaz Grove (J5)​

Según el esquema de hardware, la interfaz Grove utiliza los siguientes pines:

Pin GrovefunciónConexión ESP32-S3
Pin 1SCLGPIO48 (I2C0_SCL)
Pin 2SDAGPIO47 (I2C0_SDA)
Pin 3VCCGROVE_3.3V (Alimentación 3.3V)
Pin 4GNDGND

Sensor DHT20​

  • Dirección I2C: 0x38 (Fija, no se puede cambiar)
  • Voltaje de alimentación: 2.0V - 5.5V (usar 3.3V)
  • Protocolo de comunicación: I2C (hasta 400kHz)
  • Rango de medición:
    • Temperatura: -40°C a +80°C (Precisión: ±0.5°C)
    • Humedad: 0% a 100% RH (Precisión: ±3% RH)

Resultado de ejecución​

Estructura de archivos​

Código original:​

Archivos nuevos:​

  • dht20.h

  • dht20.cc

  • Debes colocar los dos archivos anteriores en la siguiente ubicación:

    • ubicación del archivo
      main/boards/sensecap-watcher/
      ├── dht20.h # DHT20 driver header
      └── dht20.cc # DHT20 driver implementation

Archivos modificados​

Nota

El código de ejemplo anterior es solo para referencia. Debes modificarlo según tu modelo de sensor específico, entorno de desarrollo y versión de firmware para asegurar una integración adecuada y una compilación exitosa.

  • Los sensores Grove I2C se pueden conectar directamente al bus I2C.
  • Los sensores no I2C se pueden conectar a través de pines GPIO disponibles, permitiendo una integración flexible de varios tipos de sensores.

Funcionalidad principal (Sensor DHT20)​

1. Inicialización del sensor​

El controlador DHT20 implementa el proceso completo de inicialización:

  • Paso 1. Reiniciar sensor: Enviar comando de reinicio 0xBA
  • Paso 2. Configuración del sistema: Escribir [0x08, 0x00] al registro 0xE1
  • Paso 3. Verificación de calibración: Verificar el bit[3] del registro de estado para asegurar que el sensor esté calibrado
  • Paso 4. Mecanismo de reintento: Reintentar hasta 5 veces si falla la calibración
esp_err_t ret = dht20_sensor_->Initialize();
if (ret == ESP_OK) {
ESP_LOGI(TAG, "DHT20 initialized successfully");
}

2. Lectura de temperatura y humedad​

Proceso de lectura:

  • Paso 1. Activar medición: enviar comando [0xAC, 0x33, 0x00]
  • Paso 2. Esperar medición: retraso de 80ms
  • Paso 3. Leer 8 bytes: [estado, humedad Alta, Media, Baja | temperatura Alta, Media, Baja, CRC]
  • Paso 4. Análisis de datos:
    • Humedad = (valor crudo de 20 bits) × 100 / 2^20
    • Temperatura = (valor crudo de 20 bits) × 200 / 2^20 - 50
float temperature, humidity;
esp_err_t ret = dht20_sensor_->ReadTempAndHumidity(temperature, humidity);
if (ret == ESP_OK) {
printf("Temperature: %.2f°C, Humidity: %.2f%%\n", temperature, humidity);
}

3. Protocolo de comunicación I2C​

FunciónComando/RegistroDatos
Reiniciar sensor0xBA-
Registro de configuración0xE1[0x08, 0x00]
Activar medición-[0xAC, 0x33, 0x00]
Leer estado-1 byte
Leer datos-7 bytes

4. Definición del byte de estado​

BitFunciónValor
bit[7]Estado de medición1=Midiendo, 0=Inactivo
bit[6:4]Reservado-
bit[3]Estado de calibración1=Calibrado, 0=No calibrado
bit[2:0]Reservado-

5. Algoritmo de análisis de datos​

// Humidity data (20 bits)
uint32_t humidity_raw = (data[1] << 12) | (data[2] << 4) | (data[3] >> 4);
float humidity = humidity_raw * 100.0f / 1048576.0f;

// Temperature data (20 bits)
uint32_t temperature_raw = ((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5];
float temperature = temperature_raw * 200.0f / 1048576.0f - 50.0f;

Funcionalidad principal (Interfaz de herramienta MCP interna)​

1. Descripción de la función​

  • Nombre de la herramienta: self.grove.get_temperature_humidity
  • Aplicación de la herramienta: Leer la temperatura y humedad actuales del sensor DHT20 conectado a Grove

2. Ejemplo de llamada​

La IA puede llamarla de la siguiente manera:

result = call_tool("self.grove.get_temperature_humidity", {})

3. Formato de retorno​

  • Éxito:

    {
    "temperature": 25.32,
    "humidity": 65.47,
    "status": "ok"
    }
  • Fallo:

    {
    "error": "DHT20 sensor not initialized"
    }

    o

    {
    "error": "Failed to read DHT20: ESP_ERR_TIMEOUT"
    }

4. Parte del código modificado y explicación​

Inclusión de archivos de encabezado agregados​

  • Agrega las siguientes declaraciones de inclusión al principio de sensecap_watcher.cc:

    #include "dht20.h"
    #include "mcp_server.h"
  • Propósito

    • dht20.h — Introduce las APIs del controlador para el sensor DHT20, habilitando la lectura de temperatura y humedad.

    • mcp_server.h — Proporciona APIs relacionadas con el servidor MCP interno, permitiendo la comunicación y registro de herramientas MCP.

Variable miembro agregada​

  • Agrega la siguiente variable miembro en la clase SensecapWatcher:

    DHT20* dht20_sensor_ = nullptr;
  • Propósito

    • dht20_sensor_ — Un puntero al objeto del sensor DHT20 conectado a través de la interfaz Grove.
      Se utiliza para inicializar, almacenar y acceder al sensor de temperatura y humedad durante todo el ciclo de vida de la instancia SensecapWatcher.
    • Se asigna en InitializeDHT20() y es utilizado por las herramientas MCP para leer datos del sensor.
    • Se inicializa a nullptr para indicar que el sensor aún no ha sido configurado, con verificaciones de nulo realizadas antes de la lectura.

Inicialización DHT20 y herramienta MCP agregadas​

  • Agrega la siguiente función miembro en la clase SensecapWatcher:

    void InitializeDHT20() {
    ESP_LOGI(TAG, "Initialize DHT20 sensor on Grove port");

    // Create DHT20 sensor instance
    dht20_sensor_ = new DHT20(i2c_bus_);

    // Initialize and calibrate the sensor
    esp_err_t ret = dht20_sensor_->Initialize();
    if (ret != ESP_OK) {
    ESP_LOGE(TAG, "DHT20 initialization failed: %s", esp_err_to_name(ret));
    delete dht20_sensor_;
    dht20_sensor_ = nullptr;
    return;
    }

    ESP_LOGI(TAG, "DHT20 sensor initialized successfully");

    // Register MCP tool for reading temperature and humidity
    auto& mcp_server = McpServer::GetInstance();
    mcp_server.AddTool("self.grove.get_temperature_humidity",
    "Read temperature and humidity from the Grove-connected DHT20 sensor.\n"
    "Return format: {\"temperature\": value(°C), \"humidity\": value(%), \"status\": \"ok\"}\n"
    "If reading fails, returns an error message.",
    PropertyList(),
    [this](const PropertyList&) -> ReturnValue {
    if (!dht20_sensor_) {
    return "{\"error\": \"DHT20 sensor not initialized\"}";
    }

    float temperature = 0.0f;
    float humidity = 0.0f;

    esp_err_t ret = dht20_sensor_->ReadTempAndHumidity(temperature, humidity);
    if (ret != ESP_OK) {
    std::string error_msg = "{\"error\": \"Failed to read DHT20: ";
    error_msg += esp_err_to_name(ret);
    error_msg += "\"}";
    return error_msg;
    }

    // Format response as JSON
    char buffer[128];
    snprintf(buffer, sizeof(buffer),
    "{\"temperature\": %.2f, \"humidity\": %.2f, \"status\": \"ok\"}",
    temperature, humidity);
    return std::string(buffer);
    });

    ESP_LOGI(TAG, "DHT20 MCP tool registered: self.grove.get_temperature_humidity");
    }
  • Agregar llamada de inicialización DHT20 en el constructor

    SensecapWatcher() {
    ...
    InitializeCamera();
    InitializeDHT20(); // Initialize Grove DHT20 sensor
    }
  • Propósito

    • InitializeDHT20() — Inicializa el sensor DHT20 en la interfaz Grove y registra una herramienta MCP para permitir el acceso interno a los datos de temperatura y humedad.
    • La función crea la instancia DHT20, la calibra y verifica errores de inicialización.
    • Si la inicialización es exitosa, registra la herramienta MCP self.grove.get_temperature_humidity para leer datos del sensor vía JSON.
    • Se llama en el constructor de SensecapWatcher para asegurar que el sensor esté listo cuando la placa se inicie:

Solución de problemas​

Problemas comunes​

  1. Fallo en la inicialización del sensor
  • Posibles causas:
    • Interfaz Grove no alimentada correctamente
    • Problemas de conexión I2C
    • Sensor no conectado o dañado
  • Solución
    uint32_t grove_power = esp_io_expander_get_level(io_exp_handle, BSP_PWR_GROVE);
    ESP_LOGI(TAG, "Grove power status: %d", grove_power);
  1. Tiempo de espera de lectura agotado
  • Posibles causas:
    • Sensor ocupado
    • Conflicto en el bus I2C
  • Solución
    • Asegurar intervalo ≥1s entre lecturas
    • Verificar otros dispositivos en I2C
  1. Datos inválidos
  • Posibles causas:
    • Sensor no calibrado
    • Verificación CRC falló (no implementada en la versión actual)
  • Solución:
    • Re-inicializar sensor
    • Considerar implementar verificación CRC (data[6])

Referencias​

Mantenimiento​

el código reside en main/boards/sensecap-watcher/, no afecta otras placas.

Soporte técnico​

Loading Comments...