M5Stack Core2 for AWSでCO2センサ「MH-Z19C」を使ってCO2を検出します。「PlatformIOでM5Stack Core2 for AWSの開発環境の構築」で環境構築したPlatformIOを用いて、プログラムはESP-IDFで作成します。CO2センサ「MH-Z19C」は、M5Stack Core2 for AWSのポートCを使用し、Uartを使って接続します。最初にUartのTxとRxを接続してループ状態にしてUartの入出同動作を確認、その後、CO2センサ「MH-Z19C」を使ってCO2を検出します。

Uart-EchoのためのM5Stack Core2 for AWSの接続

M5Stack Core2 for AWSのポートCは、次のようにUart-RXD(GPIO13)/TXD(GPIO14)が接続されています。

Uartの動作を確認するために、次のようにTXDとRXDを接続してループ状態にします。

購入したケーブルがGrove互換ケーブルだったようで、ケーブルの色順が純正と異なり黄色と白が順番が違っています。またGroveコネクタにロックがあって接続できないので、ロックをニッパーで切る必要があります。M5Stack Core2 for AWSのポートCにはマーキングがされていなく、ポートAと同じ向きで接続します。

Uart-Echoアプリの作成

espressif/esp-idf」の「esp-idf/examples/peripherals/uart/uart_echo/main/uart_echo_example_main.c」を参考にして、次のようにVS Code上のPlatformIOでUart-Echoアプリ「uart_echo」を作成します。19行目のuart_write_bytes関数でUartのTxに出力し、22行目のuart_read_bytes関数でUartのRxから入力します。

main.c

   ・・・
void app_main()
{
    ESP_LOGI("MH-Z19C", "start app!!");

    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .rx_flow_ctrl_thresh = 122,
    };
    uart_param_config(uart_num, &uart_config);
    uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    uart_driver_install(uart_num, 1024 * 2, 0, 0, NULL, 0);

    ESP_LOGI("MH-Z19C", "app 10");
    uart_write_bytes(uart_num, (const char *)txdata, BUF_SIZE);
    ESP_LOGI("MH-Z19C", "app 20");
    //    uint8_t *data = (uint8_t *)malloc(BUF_SIZE);
    int len = uart_read_bytes(uart_num, rxdata, BUF_SIZE, 1000 / portTICK_RATE_MS);
    esp_log_buffer_hex("Read data:", rxdata, BUF_SIZE);
    ESP_LOGI("MH-Z19C", "app 30");
}
   ・・・

Uart-Echoアプリの実行

VS Code上のPlatformIOでUart-Echoアプリ「uart_echo」を実行します。UartのTxに出力した「00 01 02 03 04 05 06 07 08 09」が入力されています。

   ・・・
?[0;32mI (294) spi_flash: flash io: dio?[0m
?[0;32mI (294) cpu_start: Starting scheduler on PRO CPU.?[0m
?[0;32mI (0) cpu_start: Starting scheduler on APP CPU.?[0m
?[0;32mI (302) MH-Z19C: start app!!?[0m
?[0;32mI (302) MH-Z19C: app 10?[0m
?[0;32mI (312) MH-Z19C: app 20?[0m
?[0;32mI (312) Read data:: 00 01 02 03 04 05 06 07 08 09 ?[0m
?[0;32mI (322) MH-Z19C: app 30?[0m

MH-Z19Cのメッセージ仕様

MH-Z19Cのマニュアル」から取得したメッセージ仕様を次に示します。

UARTの通信仕様を次に示します。

MH-Z19CのCO2データ要求のメッセージとその応答を示します。

CO2値は「 high level *256+low level」により求めます。

M5Stack Core2 for AWSとMH-Z19Cとの接続

M5Stack Core2 for AWSとCO2センサ「MH-Z19C」の結線を次に示します。

M5Stack Core2 (Port C) MH-Z19C
5V Vin
GND GND
TXD Rx
RXD Tx

M5Stack Core2 for AWSとCO2センサ「MH-Z19C」の接続画像を次に示します。

MH-Z19Cアプリの作成

m5stack/Core2-for-AWS-IoT-EduKit」の「Smart-Thermostat」をベースにし、「External Grove Connector Expansion Ports」を参考にして、次のようにVS Code上のPlatformIOでMH-Z19Cアプリ「MH-Z19C_test」を作成します。

上記で作成したUart-Echoアプリ「uart_echo」では、ポートCの5Vの電圧が供給されません。これはたぶんM5Stack Core2 for AWSではバッテリー管理「AXP192」により電源の制御を行っているためと思われます。

構成ファイル「sdkconfig」の「CONFIG_SOFTWARE_EXPPORTS_SUPPORT」を次のように設定し、ポートCの使用を可能とします。

   ・・・
CONFIG_SOFTWARE_EXPPORTS_SUPPORT=y

「Smart-Thermostat」に次のコードを組み込みます。

  • 6行目でCO2データ要求のメッセージを定義します。13行目でCore2ForAWS_Port_C_UART_Send関数によりCO2センサ「MH-Z19C」に送信します。
  • 23行目でCore2ForAWS_Port_C_UART_Receive関数によりCO2センサ「MH-Z19C」から応答メッセージを受信し、28行目でCO2データ値に編集します。

main.c

   ・・・
#include "driver/uart.h"
#include "driver/gpio.h"

#define BUF_SIZE (9)
uint8_t txdata[BUF_SIZE] = {0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
uint8_t rxdata[BUF_SIZE];

static void uart_tx_task(void *arg)
{
    while (1)
    {
        Core2ForAWS_Port_C_UART_Send((char *)&txdata[0], BUF_SIZE);
        vTaskDelay(pdMS_TO_TICKS(2000));
    }
}

static void uart_rx_task(void *arg)
{
    int rxBytes;
    while (1)
    {
        rxBytes = Core2ForAWS_Port_C_UART_Receive(rxdata);
        if (rxBytes > 0)
        {
            esp_log_buffer_hex("Read data:", rxdata, rxBytes);
            uint16_t co2data = rxdata[2];
            co2data = co2data * 255 + rxdata[3];
            ESP_LOGI(TAG, "CO2: %d", co2data);
        }
        vTaskDelay(pdMS_TO_TICKS(100)); // Read more frequently than transmit to ensure the messages are not erased from buffer.
    }
}

void app_main()
{
    Core2ForAWS_Init();
    Core2ForAWS_Display_SetBrightness(80);
    Core2ForAWS_LED_Enable(1);

    xMaxNoiseSemaphore = xSemaphoreCreateMutex();

    ui_init();

    esp_err_t err = Core2ForAWS_Port_PinMode(PORT_C_UART_TX_PIN, UART);
    if (err == ESP_OK)
    {
        Core2ForAWS_Port_C_UART_Begin(9600);
        xTaskCreate(uart_rx_task, "uart_rx", 1024 * 2, NULL, configMAX_PRIORITIES, NULL);
        xTaskCreate(uart_tx_task, "uart_tx", 1024 * 2, NULL, configMAX_PRIORITIES - 1, NULL);
    }
}

MH-Z19Cアプリの実行

VS Code上のPlatformIOでMH-Z19Cアプリ「MH-Z19C_test」を実行します。MH-Z19Cからの応答メッセージ「ff 86 02 82 43 00 00 00 b3」が入力され、応答メッセージからCO2値を取得すると「640」になりました。息を吹きかけるとCO2値が増加していることが確認できます。

   ・・・
␛[0;32mI (2822) atecc608: ok: locked␛[0m
␛[0;32mI (2822) atecc608: Get the device info (type)...␛[0m
␛[0;32mI (2862) atecc608: ok: 60 03␛[0m
␛[0;32mI (2892) gpio: GPIO[26]| InputEn: 0| OutputEn: 0| OpenDrain: 1| Pullup: 1| Pulldown: 1| Intr:0 ␛[0m
␛[0;32mI (3992) Read data:: ff 86 02 82 43 00 00 00 b3 ␛[0m
␛[0;32mI (3992) MAIN: CO2: 640␛[0m
␛[0;32mI (5992) Read data:: ff 86 02 83 43 00 00 00 b2 ␛[0m
␛[0;32mI (5992) MAIN: CO2: 641␛[0m
␛[0;32mI (7992) Read data:: ff 86 02 83 43 00 00 00 b2 ␛[0m
␛[0;32mI (7992) MAIN: CO2: 641␛[0m
␛[0;32mI (9992) Read data:: ff 86 02 82 43 00 00 00 b3 ␛[0m
␛[0;32mI (9992) MAIN: CO2: 640␛[0m
␛[0;32mI (11992) Read data:: ff 86 02 83 43 00 00 00 b2 ␛[0m
␛[0;32mI (11992) MAIN: CO2: 641␛[0m
␛[0;32mI (13992) Read data:: ff 86 02 82 43 00 00 00 b3 ␛[0m
␛[0;32mI (13992) MAIN: CO2: 640␛[0m
␛[0;32mI (15992) Read data:: ff 86 02 82 43 00 00 00 b3 ␛[0m
␛[0;32mI (15992) MAIN: CO2: 640␛[0m
␛[0;32mI (17992) Read data:: ff 86 03 7a 43 00 00 00 ba ␛[0m
␛[0;32mI (17992) MAIN: CO2: 887␛[0m
␛[0;32mI (19992) Read data:: ff 86 06 44 43 00 00 00 ed ␛[0m
␛[0;32mI (19992) MAIN: CO2: 1598␛[0m
␛[0;32mI (21992) Read data:: ff 86 07 0b 43 00 00 00 25 ␛[0m
␛[0;32mI (21992) MAIN: CO2: 1796␛[0m
␛[0;32mI (23992) Read data:: ff 86 07 9d 43 00 00 00 93 ␛[0m
␛[0;32mI (23992) MAIN: CO2: 1942␛[0m
␛[0;32mI (25992) Read data:: ff 86 07 f9 43 00 00 00 37 ␛[0m
␛[0;32mI (25992) MAIN: CO2: 2034␛[0m
␛[0;32mI (27992) Read data:: ff 86 08 38 43 00 00 00 f7 ␛[0m
␛[0;32mI (27992) MAIN: CO2: 2096␛[0m
␛[0;32mI (29992) Read data:: ff 86 08 4a 43 00 00 00 e5 ␛[0m
␛[0;32mI (29992) MAIN: CO2: 2114␛[0m
␛[0;32mI (31992) Read data:: ff 86 08 65 43 00 00 00 ca ␛[0m
␛[0;32mI (31992) MAIN: CO2: 2141␛[0m
␛[0;32mI (33992) Read data:: ff 86 08 70 43 00 00 00 bf ␛[0m
␛[0;32mI (33992) MAIN: CO2: 2152␛[0m
␛[0;32mI (35992) Read data:: ff 86 08 71 43 00 00 00 be ␛[0m
   ・・・

構成ファイル「sdkconfig」の「CONFIG_SOFTWARE_EXPPORTS_SUPPORT」の変更方法

上記では構成ファイル「sdkconfig」の「CONFIG_SOFTWARE_EXPPORTS_SUPPORT」を直接エディタで編集して、ポートCの使用を可能としましたが、次のコマンドを使用してメニューを表示します。

> pio run --environment core2foraws --target menuconfig

次のように、「Component config ?> Core2 for AWS hardware enable >Expantion Ports A,B,C」を設定します。