ESP-IDF4.0入門 その3 まとめ

概要

前回はプロジェクトファイルの構造と、get-startedに入っていたプログラムを説明しました。

今回はexamplesフォルダに入っているプログラムを、何個か調べてみたいと思います。

peripherals\gpio

このプログラムでは2つの入力と、2つの出力ピンを指定しています。このサンプルはmenuconfigで設定ができないので、プログラムを直接書き換えて変更しました。

設定用途
#define GPIO_OUTPUT_IO_0    9赤色LED
#define GPIO_OUTPUT_IO_1    10赤外線LED
#define GPIO_INPUT_IO_0     37Aボタン(HOME)
#define GPIO_INPUT_IO_1     39Bボタン(右)

プログラムの中身をみてみると、出力は比較的単純ですが入力は割り込みをつかっていて、キューにいれて別タスクで処理をする例です。

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}

static void gpio_task_example(void* arg)
{
    uint32_t io_num;
    for(;;) {
        if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
            printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
        }
    }
}

この辺が入力ですね。FreeRTOSも事前に勉強しておかないと意味がわからないと思うので、GPIOのサンプルなのに結構高度な例でした。

peripherals\touch_pad_interrupt

タッチパッドのサンプルです。タッチすると割り込みが発生して触ったパッドが表示されます。

GPIO32と33がArduino Coreだと入れ替わっていましたが、ESP-IDFだと正しい組み合わせです!

//Some registers of touch sensor 8 and 9 are mismatched, we need to swap register index
inline static touch_pad_t touch_pad_num_wrap(touch_pad_t touch_num)
{
    if (touch_num == TOUCH_PAD_NUM8) {
        return TOUCH_PAD_NUM9;
    } else if (touch_num == TOUCH_PAD_NUM9) {
        return TOUCH_PAD_NUM8;
    }
    return touch_num;
}

なぜだと思って、ソースコードを探してみたらやっぱり間違っていたのでコードの中で入れ替えています。。。

Arduino Coreではピン番号で指定するのですが、32のピンを取得しようとすると33で指定しないといけなくて、そうすると本当の33のピンモードがアナログ入力に設定されてしまうバグがあります。

データシートから間違っているの確定したのでArduino CoreのソースもPR出して直してもらおうかしら、、、

Arduino CoreとESP-IDFの違い

内部のソースをみたところ、ハードウエアまわりのアクセス方法がまったく違っていました。

Arduino Core

    uint16_t touch_value = READ_PERI_REG(SENS_SAR_TOUCH_OUT1_REG + (pad / 2) * 4) >> ((pad & 1) ? SENS_TOUCH_MEAS_OUT1_S : SENS_TOUCH_MEAS_OUT0_S);

SENS_SAR_TOUCH_OUT1_REGなどの個別のアドレスを利用してアクセス。データシートのアドレスから素直に取得している感じでした。

ESP-IDF

        *touch_value = (tp_wrap & 0x1) ? \
                            SENS.touch_meas[tp_wrap / 2].l_val: \
                            SENS.touch_meas[tp_wrap / 2].h_val;

SENSという構造体を利用してアクセスしています。

PROVIDE ( SENS = 0x3ff48800 );

上記でセンサーの先頭アドレスに設定してありました。

soc/sens_struct.hの中でセンサーの先頭アドレスからunionなどを使って、構造体を使ってアクセスできるようになっていました。

コードからは直接どのアドレスにアクセスしているのかはわかりにくいですが、データシートをみなくてもコード補完などでなんとなくわかるので使いやすそうですね。

組み方を見ている限り、ESP-IDFとArduino Coreはまったく別の思想で組んでおり、共通化もされていないようでした。

データシートを見ながらアクセス方法を確かめる場合にはArduino Coreのほうが確かめやすいかもしれません。

ESP-IDFのコードは無駄がないのですが直接ハードウエアをアクセスしている感が強く、SDKとしての思想などはあまりないようでした。全般的には読みにくいソースが多いです。

Arduino Coreの方が全般的にSDKとしては、うまくラッピングできているように思えました。

ESP-IDFでArduinoをコンパイルする

上記にESP-IDFでArduinoをコンパイルする方法がありましたので、ためしてみました。

しかしうまくいきませんでした。ArduinoだとESP-IDF3.3系なので4.0系だとmenuconfigでエラーがでました。

まとめ

あとは、各自利用したい機能を、上記ドキュメントを参考に調べてみてください。ちょっと触ったところ、Arduino CoreでわからないことがあったらESP-IDFのソースファイルを見てみないとわからないことが多いです。

しかしながら、普段使うのであればArduino Coreでいい気もしました。最新機能や、ちょっと特殊な用途で困ったときにESP-IDFを使う必要がありますが、個人レベルであればライブラリが充実しているArduino Coreを使ったほうが良さそうです。

コメントする

メールアドレスが公開されることはありません。

管理者承認後にページに追加されます。公開されたくない相談はその旨本文に記載するかTwitterなどでDM投げてください。またスパム対策として、日本語が含まれない投稿は無視されますのでご注意ください。