工作と競馬

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

概要

esp-idfのプロジェクトにarduino-esp32を組み込んで使用したところ、Wi-Fiが繋がらずハマったので注意点をメモする。


背景と目的

前回、ESP-WROOM-32からAWS IoTへパブリッシュすることができたが、同プロジェクトにarduino-esp32をコンポーネントとして組み込めば、Arduinoで作成したプログラムを、AWS IoTへの送信ができるはずである。しかし、実際にやってみたところ、Wi-Fiが繋がらず困ったので解決方法について、メモしておく。


詳細

1.症状

まず、arduino-esp32を組み込んだ場合のapp_main関数は、initArduino関数を一番初めに呼ぶ。しかし、これを入れると、Wi-Fi接続ができなくなってしまった。どうやら、initArduinoを呼ぶことで、initialize_wifi関数での処理がうまくいかなくなるようだった。

extern "C" void app_main()
{
    // Arduino初期化
    initArduino();
    
    // WiFiの初期化
    initialise_wifi();

#ifdef CONFIG_MBEDTLS_DEBUG
    const size_t stack_size = 36*1024;
#else
    const size_t stack_size = 36*1024;
#endif
    xTaskCreatePinnedToCore(&aws_iot_task, "aws_iot_task", stack_size, NULL, 5, NULL, 1);
}

2.initialze_wifi関数内で、WiFi.begin()を行えばよい

結局、試行錯誤した結果、

  • initialise_wifi関数内の4行目以降を削除し、ArduinoのWiFi.beginを呼ぶ

ことで、解決できた。

// 変更後
#include "WiFi.h" // インクルード必要

:

// 変更対象の関数
static void initialise_wifi(void)
{
    tcpip_adapter_init();
    wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    WiFi.begin(ssid, password);
}


まとめ

esp-idfのプロジェクトにarduino-esp32を組み込んで使用したときにWi-Fiが繋がらない問題を解決できた。

概要

ESP-WROOM-32で、AWS IoTにデータをパブリッシュしてみた。


背景と目的

ESP-IDFのサンプルには、AWS IoTとの通信プログラムがある。ESP32でセンサ等の測定値を素早くクラウド上に送信するのにちょうどよさそうだ。そこで、サンプルを使ってAWS IoTにデータ送信してみる。


詳細

1.やること

今回は、ESP-IDFのサンプルexamples/protocols/aws-iot/subscribe_publishをそのまま動かす。1秒ごとにパブリッシュするという動作をする。README.mdに一通りやり方が書いてあるのでそれを参考に進める。


2.AWS IoTでThingを作成

AWSのコンソールで、動作確認用にThingを作成。Thing名はESP32Testとした。また、Security>Create certificate ボタンにて、certificateを作成し、xxx.private.pem.keyとxxx.certificate.pem.crtをダウンロードした。また、aws-root-caファイルもダウンロードしてサンプルにあるaws-root-ca.pemと置き換えた。それと、以下の2つを忘れないようにする必要がある。

  • certificateをActivateする。
  • certificateにpolicyをアタッチする。ポリシーは、以下で十分。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iot:Publish",
        "iot:Subscribe",
        "iot:Connect",
        "iot:Receive"
      ],
      "Effect": "Allow",
      "Resource": [
        "*"
      ]
    }
  ]
}

これで、Thingの準備はOK。


3.Private KeyとCertificateの組み込み

組み込み方法は、ここによれば2通りがあるが、今回は、"Option 1: Embedded Key & Cert into App Binary"という方法に従う。

このサンプルのmainというフォルダの下にさらにcertsというフォルダがあるので、そこで2.でダウンロードした2つのファイルをそれぞれprivate.pem.key、certificate.pem.crtという名前に変更して配置する。

これで、必要なファイルの組み込みができた。


4.AWS IoTとの通信に必要な設定の記述

subscribe_publish_sample.cを開き、いくつか編集していく。

4.1 WiFiの設定

本筋と関係はないが、忘れないように。ESP32をWiFiに接続しないと始まらないので、56,57行目のSSIDとパスワード設定を忘れない。

#define EXAMPLE_WIFI_SSID "SSID名"
#define EXAMPLE_WIFI_PASS "パスワード"
4.2 トピックの設定

248行目のTOPICという定数を編集すればよい。ここでは、"test_topic/esp32"をそのまま使う。

4.3 送信したいデータを設定

そして、送信したいデータは、cPayloadという文字配列が用意されており258行目のsprintf文で文字を書き込んでいるので適宜編集する。ここでは、"Hello from SDK : {経過秒数}"という表記をそのまま使う。

sprintf(cPayload, "%s", "送信したい文字列など");

ここまでで、ソースコードの編集は完了。


5.ビルド設定とビルド

make menuconfigにて、SDKの設定を行う。

Component config > Amazon Web Services IoT Platform > AWS IoT Endpoint Hostnameを選択し、2.で作成したThingのコンソール > Interactに表示されているHTTPS Endpoint名(xyz.iot.{リージョン名}.amazonaws.com)を書き込む。(なお、この設定はesp-idf/components/aws-iot/include/aws-iot-config.hに直接書き込んでもできるらしいが、ライブラリを直接編集するのも微妙なので、ここではやらない)

そして、make flashでビルド&書き込みをする。

20170516212557

図5.1 エンドポイントを設定


6.動作確認

シリアルコンソールのログは、以下の通り。1秒ごとにパブリッシュされている。

20170516220930

図6.1 パブリッシュしている様子

また、AWS IoTコンソールのTestメニューにて、"test_topic/esp32"トピックをサブスクライブしてみると、データが到着している。

20170516220923

図6.2 パブリッシュされたのが到着した様子

というわけで、正しく動作させることができた。


まとめ

ESP-WROOM-32で、AWS IoTにデータをパブリッシュできた。

概要

ESP-WROOM-32で、熱画像センサGrid-EYE(Panasonic AMG88シリーズ)を使ってみた。I2C通信したときに、少しハマった点があったので解決方法をメモる。


背景と目的

Grid-EYE(Panasonic AMG88シリーズ)は、64画素の温度分布を得ることができるセンサである。赤外線センサと違い、人が止まっていても、人の位置を知ることができる。データの読出しには、I2Cを使う。今回は、ここ最近遊んでいるESP-WROOM-32のI2Cを使って、データの読出しをしてみる。


詳細

1.Arduino環境でESP-WROOM-32のI2Cを使う

最初、こちらの方法を試したのだが、うまくいかなかった。具体的には、Wire.beginで止まってしまう。(参考サイトの執筆者はできたとのことなので、私のやり方が何か間違っているのかもしれない。)そこで、arudino-esp32で定義されているI2Cの端子番号を調べると、variants\esp32\pins_arduino.hというファイルの中に、

static const uint8_t SDA = 21;
static const uint8_t SCL = 22;

という記述を発見。なので、GPIO21,22を使うことにした。


2.Arduinoで、Grid-EYEのライブラリを作成した人を発見

すでに、こちらに、Grid-EYE用のI2C通信ライブラリを作成している方がおられる。基本的には、Arduino用の標準的なI2CライブラリWire.hと、Grid-EYEのレジスタ構成定義情報を組み合わせてクラス化してあり有用であるので、今回の実験用として、ありがたく使わせていただいた。

しかし、ライブラリのGridEye.pixelOutメソッドを呼ぶと、途中で通信が止まるという問題に遭遇。当該メソッドでは、32バイト(16画素)ずつ4回に分けてデータを読み出しているのだが、オシロスコープで波形を見ると、最初の32バイト読出し後に、Grid-EYEがACKを返さず、SDAがLowのままになってしまっていた。悩んだ挙句、GridEye.pixelOutメソッドを16バイトずつ8回に分けて読出しするように変更したところ、うまくいった。修正後は、以下の感じ。

void GridEye::pixelOut(int *pixelBuf)
{
	int temp;
	byte i, j, buf[16];
	for(i=0; i<8; i++){
		regr(REG_PIXL + (i * 0x10), buf, sizeof(buf));
		for(j=0; j<16; j+=2){
			temp = ((buf[j + 1] & 0xf) << 8) | buf[j];
			if(temp > 2047){
				temp = temp - 4096;
			}
			*pixelBuf++ = temp;
		}
	}
}

詳細は分からないが、arduino-esp32の内部の制御が影響しているのかもしれない。(ライブラリを作成した方は、Arudino Unoを使用)

というわけで、まとめると

  • SDA,SCLはGPIO21,22を使えばよい
  • Arduino用ライブラリのWire.hが使えるが、動作確認が必要

という感じだ。


まとめ

ESP-WROOM-32で、熱画像センサ(Grid-EYE)とI2C通信しようと思ったら少しハマったが、どうにか通信できた。

概要

ESP-WROOM-32で、サーボモータを動かしてみた。


背景と目的

最近、ESP-WROOM-32で遊んでいるが、先日整えたESP-IDF環境にて、サーボモータを動かしてみたくなった。そこで、プログラムを作成してみる。


詳細

1.方法

使用するモータは、手元にあった小型のサーボモータSG90(SG92も同様)。ESP-WROOM-32で、サーボモータを制御するには、こちらによれば、arduino-esp32ライブラリのledcモジュールがPWM制御用ライブラリなので、これを使えばよいということがわかった。


2.実装

ledcモジュールは、arduino-esp32ライブラリの"esp32-hal-ledc.h"である。なので、Arduino環境でそのままインクルードして使えばよいのだが、私は、のちのちESP-IDFのBLEやAWS IoTを使ってプログラムを発展させたいと思っているので、今回は敢えてarduino-esp32ライブラリをESP-IDF環境のプロジェクトに組み込んで使うことにした。組み込む方法は、こちらの下部にある"Using as ESP-IDF component"のとおりである。

そして、ESP-IDFのHello worldサンプルを基にして、実装した結果が以下。主なポイントは、

  • ledcSetup関数で、チャンネル、周波数、分解能を設定
  • ledcAttachPinで、
  • ledcWrite関数で、デューティを設定
  • deg2pw関数は、SG90に対し所望の角度になるように与えるべきパルス幅を算出する。(データシートより換算)

である。

//file: main.cpp
#include "stdio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "Arduino.h"
#include "esp32-hal-ledc.h"
#include "math.h"

#define PWM_BITWIDTH 16

// 角度をパルス幅に変換
int deg2pw(int deg, int bit)
{
    double ms = ((double) deg - 90.0) * 0.95 / 90.0 + 1.45;
    return (int) (ms / 20.0 * pow(2, bit));
}

// スイープするタスク
void hello_task(void *pvParameter)
{
    // 1度ずつ角度を変える
    for (int i = 0; i <= 90; i++) {
        // xサーボの角度を設定
        ledcWrite(1, deg2pw(i, PWM_BITWIDTH));
        vTaskDelay(50 / portTICK_PERIOD_MS); // 50usecごとに1度変化させる
    }
}

// メイン
extern "C" void app_main()
{
    initArduino();

    // サーボ用PWMの設定
    ledcSetup(1, 50, PWM_BITWIDTH); // channel 1, 50 Hz, 16-bit depth
    ledcAttachPin(12, 1); // GPIO12に割り当て

    xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
}


3.動作確認

動作を確認したところ、正しく動いた。


まとめ

ESP-WROOM-32で、サーボモータを動かすことができた。

概要

ESP-WROOM-32の公式開発フレームワークesp-idfを使って、開発環境を整えた。動作確認として、サンプルのHello world!プログラムを走らせた。


背景と目的

前回、Arduino環境(Arduino core for ESP32 WiFi chip)で、ESP-WROOM-32のLチカやiBeacon化をしてみたが、BLEデバイスとしての開発には、公式の開発環境(esp-idf)を使う必要があるらしい。(2017年5月2日現在)実際、私が見た限りArduinoのサンプルではかなりシンプルな例しかなくBLEデバイスを自由に開発するのは厳しそうだった。そこで、公式の開発フレームワークesp-idfを使ってHello world!プログラムが実行できる状態まで環境を整える。


詳細

0.方法を調べる

ESP-IDFの公式ドキュメントはこちら。開発環境をそろえるための大まかな手順は、

  • Toolchainのセットアップ
  • ESP-IDFのインストール
  • Eclipeのセットアップ
  • サンプルプログラムのビルドと書き込み
  • 動作確認

だが、3つ目のステップは今回はサンプルが動けばいいので省略する。なお、私の環境は、Windows10、開発ボードは秋月電子のESP32-DevKitC ESP-WROOM-32開発ボード


1.Toolchainのセットアップ

私の環境は、Windows10なので、こちらを参考に進める。

まず、Windows all-in-one toolchain & MSYSというzipファイルをダウンロード。これは、480MBと大きいのでちょっと時間かかる。DLが終わったら、C:\に解凍。そして、C:\msys32\mingw32.exeを実行してみると、以下の感じ。なお、公式ドキュメントにはカスタムセットアップの方法が書いてあるが、今回は理由がないのでやらない。

20170503120634

図1 Toolchainがインストールされたところ


2.ESP-IDFのインストール

2.1 ESP-IDFのダウンロードとインストール

以下の通り、gitでダウンロード。

cd C:\Users\MyName
mkdir esp
cd esp
git clone --recursive https://github.com/espressif/esp-idf.git

esp-idfからダウンロードして配置してもいいかもしれない。


2.2 環境変数のセットアップ

こちらに従い、C:\msys32\etc\profile.dに、export_idf_path.shというファイルを作成し、先ほどESP-IDFをインストールしたフォルダを記入。パスは、Windowsの場合バックスラッシュをスラッシュに直さなければいけないのを注意。

export IDF_PATH="C:/Users/MyName/esp/esp-idf"

そして、mingw32.exeを(再)起動し、

printenv IDF_PATH

をしたときに、設定したパスが表示されればOK。


3.サンプルプログラムのビルドと書き込み、実行

3.1 サンプルプロジェクトのコピー

公式ドキュメントに従い、hello_worldというサンプルを使ってみる。まず、esp-idf\examples\get-started\hello_worldというフォルダを適当なパスにコピー。今回は、C:Users\MyName\espとした。(パスにスペースが入ってはダメ)


3.2 ボードを接続

ここで、開発ボードをPCに接続し、シリアルポートを確認。今回はCOM3を使う。


3.3 プロジェクトの設定

C:\msys32\mingw32.exeを起動し、プロジェクトのディレクトに移動し、設定を行う。

cd C:Users/MyName/esp/hello_world
make menuconfig

Serial flasher config>Default serial portを選択し、COM3と記入し、saveして完了。


3.4 ビルドと書き込み

いよいよ、ビルドと書き込み。3.3同様に、C:\msys32\mingw32.exeで、プロジェクトのディレクトに移動し以下の1行を実行すれば、ビルドと書き込みをしてくれる。

make flash

正しく書き込めれば、以下のようになる。

20170503125617

図3.4 書き込み完了の状態

4.動作確認

シリアルターミナルで、表示を確認したところ、Hello worldと表示された!正しく動いている模様。これで、開発環境は整ったといえる。素晴らしい。

20170503125407

図4 動作確認

まとめ

ESP-IDFを使った開発環境を整え、Hello worldが走った。これから、どんどんプログラムが作れそうだ。

このページのトップヘ