ESP32 ADCを操作する

  • 2021.10.17
  • ADC
ESP32 ADCを操作する

今回はADCを動かしてみます。

この記事は JTAG でデバッグすることを前提にして書いています。
環境構築については こちら をご覧になってください。

投稿時の開発環境を記しておきます。

PC:
Windows10 OS

開発ボード :
ESP32-DevKitCーVE
(Soc : ESP32-D0WD-V3)

デバッガー(H/W):
FT2232D

デバッガー (S/W) :
Visual Studio Code + PlatformIO + ESP-IDF Framework

ADCとは

アナログ・ディジタル・コンバーターの略で、アナログ電圧をディジタル値に変換する機能です。

プロジェクトをつくる

使っていたプロジェクトを開いていたら、File – Close Folder して閉じておきます。

その後にVSCodeからPlatformIOをOpenします。

以下の内容でプロジェクトを新規に作成します。

Name : ESP32E-ADC
Board : Espressif ESP32 Dev Module
Framework : Eresspsif IoT Development Framework

Name : ESP32E の “E” は Framework (Espressif IoT Development Framework)の頭文字を示しています。

(後から見てわかるように、ESP-IDFを使うことを明示しています)

platformio.ini に以下の3行を追加して、 Ctrl + s で保存しておきます。

COM[4]の4の部分はデバイスマネージャーのポート(COMとLPT)で Silicon Labs CP210x から始まるCOMの番号を記述します。

debug_tool = minimodule
upload_port = COM[4]
monitor_speed = 115200

ADCのAPIリファレンスとサンプル

ADCのAPIは こちら を参照してください。

サンプルプログラムは こちら を参考にしました。

PlatformIOで Eresspsif IoT Development Framework を選択したことにより、以下のローカルフォルダからも参照可能なはずです。

C:\Users\xxxxx\.platformio\packages\framework-espidf\examples\peripherals\adc\single_read\adc

(xxxxxは皆さまのユーザー名)

電源電圧を測定する

設定することで-11dBのアッテネーターが使えるようなのですが、これを使っても電源電圧は測定できないようです。

基準電圧(Vref)が1100mV程度ということなので、抵抗で分割した電圧を入力し、マイコン内部のアッテネーターは使わないことにしました。

Vrefは一定ではないようで、調べていたら esp_adc_cal_characterize() という関数で Vrefを得ることができるようなので試してみました。

マイコンへの入力電圧が1100mVを超えない程度に(手持ちの)抵抗は以下の定数を使いました。

コーディングする

main.c を以下のようにコーディングします。

#include 
#include 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "esp_log.h"

static const char *TAG = "adc";

#define DEFAULT_VREF    1100    // (1)デフォルトのリファレンス電圧 [mV]

static esp_adc_cal_characteristics_t *adc_chars; // (2)情報を格納するための構造体へのポインタ

static void check_efuse(void)   // (3)efuseを確認するための関数
{
    //Check if TP is burned into eFuse
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
        ESP_LOGI(TAG, "eFuse Two Point: Supported\n");
    } else {
        ESP_LOGI(TAG, "eFuse Two Point: NOT supported\n");
    }
    //Check Vref is burned into eFuse
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {
        ESP_LOGI(TAG, "eFuse Vref: Supported\n");
    } else {
        ESP_LOGI(TAG, "eFuse Vref: NOT Supported\n");
    }
}

void app_main(void)
{
    //Check if Two Point or Vref are burned into eFuse
    check_efuse();

    adc1_config_width(ADC_WIDTH_BIT_12);    // (4)ADCの分解能を設定する
    adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0);  // (5)ADCのチャンネルとアッテネーターを設定する

    //Characterize ADC
    adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));   // (6)構造体のメモリ確保
    esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_0, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);    // (7)情報を取得する

    int vref = adc_chars->vref; // (8)リファレンス電圧を得る

    while (true)
    {
        int val = adc1_get_raw(ADC1_CHANNEL_0); // (9)0-4095の値を読む
        int devidedVoltage = val * vref / 4095; // (10)分圧された電圧を得る
        int powerSupplyVoltage = 5.7 * devidedVoltage;  // (11)分圧された電圧から電源電圧を得る

        ESP_LOGI(TAG, "devidedVoltage: %d powerSupplyVoltage: %d mV\r\n", devidedVoltage, powerSupplyVoltage);  // (12)ログに出力する

        vTaskDelay(pdMS_TO_TICKS(1000));    // (13)時間待ち

    }
}

ビルドして実行する

ビルド後、エラーがないことを確認して F5キーを押して app_main() にカーソルが来るまで待ちます。

その後、Monitor を起動し、F5キーを押してプログラムを実行します。

以下のように値が表示されれば成功です。

check_efuse()は計測とは無関係ですが、確認するために使ってみました。

こちらの環境では以下の通りでした。

eFuse Two Point: NOT supported
eFuse Vref: Supported

マイコンのADCは「大体これくらいの値」を測定できれば良いと思っているので、まあ合格です。。

ADCカテゴリの最新記事