21
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

IoTLTAdvent Calendar 2019

Day 11

ESP32でBLE使いながら電圧(アナログ入力)を取得する

Last updated at Posted at 2019-12-11

IoTLT Advent calendar 2019 11日目を担当しますnorippyです。
大した記事ではないですが、開発の助けになればと思います。

#はじめに
ESP32でラフなプロトタイプを作るときにArduino-ESPライブラリを使って開発を行なっているのですが、その開発をする中でこんな問題を発見しました。

BLEを使いながらアナログ入力を取得すると、値が貼りついて正しい値が取得できない

最初センサーが壊れたのかな?と思ってセンサーを交換したのですが、状況は変わらず。
1つずつ確認したところ、BLEを使いながら、電圧値が取れないというこの問題を見つけました。

対策は無いのか・・・と思い調べたところ、解決策があったので備忘録として残しておきます。

#esp-idfのライブラリを使え!
ArduinoのanalogRead()を使うと動かないです。
ずっと同じ値を出し続けます・・・

この問題の解決方法がesp-idfライブラリを使うというものでした。
この対策ですが、ESP32をArduino-IDEを使おうとした時にインストールするライブラリの中に含まれているライブラリ(多分Arduino用にラップする前のライブラリ)を使います。
そのため、すでにArduino IDEを使ってESP32の開発をされている方は別途何かをインストールする必要はありません!

実際に必要な要素のみを抽出してサンプルコードにしました。
コード上に説明も追加したので、読んでみてください。

sample.c

#include <driver/adc.h>//このヘッダファイルを忘れないように!!

void setup() {
  //ESP32は2つのADコンバーターをサポートしていて、最大で18チャンネル使うことができます。
  //ただ、ADC1とADC2でコードの書き方が違います・・・
  //AD1 GPIO 32~39
  //AD2 GPIO 0,2,4,12~15,25~27

  //セットアップ方法
  //AD1の場合

  adc1_config_width(ADC_WIDTH_BIT_12);
  //何ビットのADCを使うか設定する。今回は12bitにします。
  //adc1の場合はこのように使うチャンネル全体の設定をするコマンドが用意されている。

  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0);
  //AD1のチャンネルの設定をする。
  //ここでどのチャンネルを使うか、0 V ~xx Vの値で変換するかを設定する。
  //引数は(設定したいGPIO,AD変換する電圧範囲)を示している。
  //ADC_ATTEN_DB_0 -> 0~1.1VでAD変換する


  //AD2の場合

  adc2_config_channel_atten(ADC2_CHANNEL_5, ADC_ATTEN_DB_11);
  //AD2と違い、この設定コマンドしかない。
  // ADC_ATTEN_DB_11 -> 0~3.9VでAD変換する


  //set upは以上
}

void loop() {

  int value; //analog値を代入する変数を定義
  //loop内で実際に値を取得します。

  //AD1の場合
  value = adc1_get_raw(ADC1_CHANNEL_0);
  //取得したいチャンネルを指定したらOK!

  Serial.println(value);


  //AD2の場合

  
  //注意 AD2はwi-fiを使っていると使えません!!!!

  esp_err_t r = adc2_get_raw(ADC2_CHANNEL_5, ADC_WIDTH_BIT_12, &value);
  //引数は(どのチャンネルの値を取得するか、その時何ビットでAD変換した結果にするのか、値を代入する変数)を示しています。
  if ( r == ESP_OK ) {//AD1と違い、errorハンドリングがしやすいようになっています。
    printf("%d\n", value );
  } else if ( r == ESP_ERR_TIMEOUT ) {
    printf("ADC2 used by Wi-Fi.\n");
  }

  Serial.println(value);
}

analogRead()より面倒ですが、こうすることでBLEを使いながらanalog値を取得できるようになります。
またコード上に若干書きましたが、この方法で万事解決では無く、仕様上

Wi-Fiを使うと、AD2が使えない!

という問題もあるのでご注意ください。
またコード中に出てきた変数は以下のページに詳細があるので、確認してください。

さいごに

IoTと言いながら、IoT感が無く、すごいシンプルな内容ですみません。
でもセンシングをするという時に意外と使うのがADC。とても重要な機能です。

結局Arduino-IDEを卒業して全てをesp-idfでコードを書けということかもしれませんが、ライブラリが充実しているArduinoをやめるのも中々難しいものです。

21
16
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
21
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?