LoginSignup
5
3

More than 3 years have passed since last update.

ESP32で温度と湿度をAWS IoTへ送ってグラフ化してみた

Last updated at Posted at 2020-08-09

はじめに

こちらの続きです。
ESP-IDFを使ってESP32からAWS-IoTにつないでみた

上記で利用したesp-aws-iotのサンプルをカスタマイズして、温湿度センサのデータをAWS IoTへ送ってみました。

【今回の環境】

センサはアスクルで買いました。アスクルは文房具だけじゃないのですね。

センサの接続

IMG_20200809_155521.jpg

ESP32 Si7021
3V3 VIN
GND GND
IO21 SDA
IO22 SCL

センサのデータを読み取るプログラム

Adafruit Si7021を操作するライブラリは、ArduinoやPython用のものはありましたが、ESP-IDFで使えそうなものはありません。とはいえI2Cの操作を一から書くのも自身が無かったので、ググって以下の記事を参考にさせていただきました。
Hardware Interactions: Part 4 – I2C Temperature and Humidity Sensor

まず、サンプルのsubscribe_publish_sample.cの中に、以下3つの関数を追加定義。

  • int initSensor(void)
  • float readTemp(void)
  • float readHumid(void)
#include "driver/i2c.h"

// Commands for Si7021
#define SI_7021_ADDRESS                 0x40
#define SI_7021_MEASURE_HUMIDITY        0xE5
#define SI_7021_MEASURE_TEMPERATURE     0xE3
#define SI_7021_TIMEOUT                 (1000 / portTICK_RATE_MS)

static int initSensor(void)
{
    esp_err_t           error;

    i2c_config_t config;
    config.sda_io_num = 21;
    config.sda_pullup_en = GPIO_PULLUP_ENABLE;
    config.scl_io_num = 22;
    config.scl_pullup_en = GPIO_PULLUP_ENABLE;
    config.mode = I2C_MODE_MASTER;
    config.master.clk_speed = 100000;

    error = i2c_param_config(I2C_NUM_0, &config);
    if (error != ESP_OK) {
        ESP_LOGI(TAG, "Failed to configure shared i2c bus: %s", esp_err_to_name(error));
        return -1;
    }

    error = i2c_set_timeout(I2C_NUM_0, 100000);
    if (error != ESP_OK) {
        ESP_LOGI(TAG, "Failed set timeout for i2c bus: %s", esp_err_to_name(error));
        return -1;
    }

    error = i2c_driver_install(I2C_NUM_0, config.mode, 512, 512, 0);
    if (error != ESP_OK) {
        ESP_LOGI(TAG, "Failed to install driver for i2c bus: %s", esp_err_to_name(error));
        return -1;
    }

    return 0;
}

static float readTemp(void)
{
    i2c_cmd_handle_t    handle;
    esp_err_t           error;

    // Write measure humidity command
    handle = i2c_cmd_link_create();
    i2c_master_start(handle);

    i2c_master_write_byte(handle,
            SI_7021_ADDRESS << 1 | I2C_MASTER_WRITE,
            I2C_MASTER_ACK);
    i2c_master_write_byte(handle,
            SI_7021_MEASURE_TEMPERATURE,
            I2C_MASTER_ACK);

    i2c_master_stop(handle);
    error = i2c_master_cmd_begin(I2C_NUM_0, handle, SI_7021_TIMEOUT);
    i2c_cmd_link_delete(handle);
    if (error != ESP_OK) {
        ESP_LOGI(TAG, "Failed to write temperature command: %s", esp_err_to_name(error));
        return 0;
    }
    vTaskDelay(50 / portTICK_RATE_MS);

    // Read two bytes from the temperature and humidity sensor
    uint8_t tmpMSB;
    uint8_t tmpLSB;

    handle = i2c_cmd_link_create();
    i2c_master_start(handle);

    i2c_master_write_byte(handle,
        SI_7021_ADDRESS << 1 | I2C_MASTER_READ,
        I2C_MASTER_ACK);

    i2c_master_read_byte(handle, &tmpMSB, I2C_MASTER_ACK);
    i2c_master_read_byte(handle, &tmpLSB, I2C_MASTER_NACK);

    i2c_master_stop(handle);
    error = i2c_master_cmd_begin(I2C_NUM_0, handle, SI_7021_TIMEOUT);
    i2c_cmd_link_delete(handle);
    if (error != ESP_OK) {
        ESP_LOGI(TAG, "Failed to read temperature: %s", esp_err_to_name(error));
        return 0;
    }

    float temp = ((uint16_t) tmpMSB << 8) | (uint16_t) tmpLSB;
    temp *= 175.72;
    temp /= 65536;
    temp -= 46.85; 

    return temp;
}

static float readHumid(void)
{
    i2c_cmd_handle_t    handle;
    esp_err_t           error;

    // Write measure humidity command
    handle = i2c_cmd_link_create();
    i2c_master_start(handle);

    i2c_master_write_byte(handle,
            SI_7021_ADDRESS << 1 | I2C_MASTER_WRITE,
            I2C_MASTER_ACK);
    i2c_master_write_byte(handle,
            SI_7021_MEASURE_HUMIDITY,
            I2C_MASTER_ACK);

    i2c_master_stop(handle);
    error = i2c_master_cmd_begin(I2C_NUM_0, handle, SI_7021_TIMEOUT);
    i2c_cmd_link_delete(handle);
    if (error != ESP_OK) {
        ESP_LOGI(TAG, "Failed to write humidity command: %s", esp_err_to_name(error));
        return 0;
    }
    vTaskDelay(50 / portTICK_RATE_MS);

    // Read two bytes from the temperature and humidity sensor
    uint8_t humMSB;
    uint8_t humLSB;

    handle = i2c_cmd_link_create();
    i2c_master_start(handle);

    i2c_master_write_byte(handle,
        SI_7021_ADDRESS << 1 | I2C_MASTER_READ,
        I2C_MASTER_ACK);

    i2c_master_read_byte(handle, &humMSB, I2C_MASTER_ACK);
    i2c_master_read_byte(handle, &humLSB, I2C_MASTER_NACK);

    i2c_master_stop(handle);
    error = i2c_master_cmd_begin(I2C_NUM_0, handle, SI_7021_TIMEOUT);
    i2c_cmd_link_delete(handle);
    if (error != ESP_OK) {
        ESP_LOGI(TAG, "Failed to read humidity: %s", esp_err_to_name(error));
        return 0;
    }

    float humid = ((uint16_t) humMSB << 8) | (uint16_t) humLSB;
    humid *= 125;
    humid /= 65536;
    humid -= 6; 

    return humid;
}

そして、whileループの手前でinitSensor()を呼んでセンサを初期化し、whileループの中でメッセージを送っている部分を以下で置き換えます。

    sprintf(cPayload, "{\"Temperature\": %.02f, \"Humidity\": %.02f}", readTemp(), readHumid());
    paramsQOS1.payloadLen = strlen(cPayload);
    rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS1);

あとはいくつか微修正。
MQTTのトピック名を変更。

    const char *TOPIC = "esp32/temphumid";

whileループの中の待ち時間を1秒から20秒に変更。

    vTaskDelay(20 * 1000 / portTICK_RATE_MS);

ビルドと書込み

ビルドして書込みます。

idf.py build
idf.py -p COM3 flash

AWS IoTのコンソールで確認すると、良い感じでメッセージが送られてきています。

キャプチャ.PNG

AWS側でグラフ化

グラフ化に際してはこちらを参考にさせていただきました。
AWS IoT に上げたデータをCloudWatchで簡単にグラフ化する

AWS IoTで「ルール」を作成

AWS IoTの「ACT」-「ルール」を開き、

キャプチャ.PNG

「ルールの作成」へ。以下の設定をして「ルールの作成」をクリック。

項目 設定値
名前 ESP32_TempHumid
ルールクエリステートメント SELECT * FROM 'esp32/temphumid'
アクション CloudWatch Logsにメッセージデータを送信する
ロググループ名 ESP32_TempHumid(新規作成)
ロール CloudWatch(新規作成)

CloudWatchでグラフ化

続いて、CloudWatchの画面で「インサイト」を開きます。
先ほど作成したロググループを選択し、クエリ欄に以下を入力して「クエリの実行」をクリックすると、ESP32から送られた温度の一分毎の平均値が表示されます。

stats avg(Temperature) by bin(1m)

キャプチャ.PNG

「ダッシュボードに追加」をクリックし、新しく作ったダッシュボードに折れ線グラフを追加します。

キャプチャ.PNG

もう一度「インサイト」に戻って、湿度についても同様に追加すると、温度と湿度が良い感じでグラフ表示されるようになりました。

キャプチャ.PNG

おしまい。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3