ESP32-DevKitC-VEはESP32-WROVER-Eを搭載したボードです。

USB接続するだけで使え手軽にESP32の世界を楽しめます。
ESP32-WROVER-Eには1つのモジュール内にWi-FiとBluetooth V4.2BR / EDR BLEの通信機能が含まれています。またESP32-WROVER-Eは32ビットマイコンとしても高機能です。MCUは32ビットマイコンとして使うこともできます。

開発環境はArduino IDEを使います。

■Arduino IDEの準備

  1. Arduino IDEを起動します。
    インストールしていない方は公式サイトのこちらからダウンロードしてインストールします。最新バージョンをインストールしてください。
  2. “ファイル”→”基本設定”を開きます。
  3. 追加のボードマネージャのURL”の部分に次のURLをコピーして貼り付けます。
    https://dl.espressif.com/dl/package_esp32_index.json
  4. OKボタンを押します。
  5. “ツール”→”ボード”をクリックし更に右側に表示される”ボードマネージャ”をクリックします。
  6. 先ほどURLを環境設定の部分で指定しているので「検索をフィルタ」と書かれたボックスにに”esp32″と入力すると一覧にボードが表示されます。一覧から”esp32 by Espressif Systems”を選択してインストールしてください。その時の最新バージョンをインストールしてください。

  7. “インストール”ボタンを押します。
    これでボードに必要なファイルが自動的にダウンロードされてインストールされます。
  8. インストールが完了すると”ツール”→”ボード”→”esp32″の一覧に”ESP32 Wrover Module”という名前が表示されますのでこれを選択します。
    似たような名前が多いので間違えないようご注意ください。
    画面上部にデバイス名が正しく表示されていることを確認します。

■ハードウエアの準備と設定

  1. 本体のmicroUSBポートとパソコンを接続してください。

    USBケーブルには品質のよいものをご使用ください。品質の悪いものや古いものを使ったことによって正しくパソコンに認識されないというケースが多々発生しています。必ずUSBケーブルには良い品質のものをご使用ください。

    ESP32は消費電流の大きなデバイスです。200mA以上の電流が流れることがあります。USBポートは最大で1ポートあたり500mA流せますがハブを使っていると1つのデバイスに流せる電流は減ります。本機をパソコンと接続する時はパソコンのUSBポートに直接接続するか、電源付きのUSBハブをご使用ください。電流が十分供給できない場合、予期せぬ動作をしたり正しくパソコンに認識されないなどトラブルの原因となります。

  2. ESP32-DevKitC-32Eをパソコンと接続すると、自動的にデバイスドライバーがインストールされ、仮想COMポートが作られます。
    仮想COMポートとは、パソコンがESP32-DevKitC-32Eと通信するためのポートです。Silicon Labs社のCP210xが使われています。
    通常、Windowsでは仮想COMポートドライバーのデータはWindows Updateからダウンロードされインストールさるため、ユーザーが操作する必要はありません。しかし、何らかの原因で仮想COMポートドライバが自動的にインストールされない場合には、下記のURL先からデバイスドライバーをダウンロードして手動でインストールしてください。

    ESP32-DevKitC-32Eをパソコンと接続しても自動的に仮想COMポートドライバがインストールされずない場合には下記のURL先からファイルをダウンロードして手動でインストールしてください。
    https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers

    ※”DOWNLOADS”タブに移動して”CP210x VCP Windows”をクリックしてダウンロードしてください。zipファイルを展開すると”CP210xVCPInstaller_x??.exe” があります。??はWindowsのビット数です。64ビット版の場合にはx64を、32ビット版の場合にはx86を実行してください。
  3. ESP32-DevKitC-32Eをパソコンと接続したらWindowsのデバイスマネージャーの”ポート(COMとLPT)”のツリーから、”Silicon Labs CP210x USB to UART Bridge(COMx)”を探してCOMポート番号を調べます。

    上図の場合にはCOM3に設定されています。


    パソコンに正しく認識されない場合にはケーブルとデバイスドライバを疑ってください。
    少なくとも次のことは必ずお試しください。

    ・別のケーブルを使ってみる
    ・別のUSBポートに挿入してみる
    ・USBハブを介している場合にはPCのポートに直接接続する
    ・別のパソコンがあれば別のパソコンで試してみる
    ・上記の仮想COMポートドライバを手動でインストールしてみる

    本製品は完成した電化製品とは違って開発者向け製品です。お客様ご自身で色々とお試し頂きトライアンドエラーで問題を解決していくものとなっています。

     

  4. ツール”→”ポート”をクリックして手順3で確認したESP32-DevKitC-32Eのポート番号を選択します。
    そのほかの設定はデフォルトで問題ありませんが、一応メニュー項目をそれぞれ確認していただき、設定項目が次のようになっていることを確認してください。

これでIDE最初の設定は完了です。

続いて実験のためにESP32-DevKitC-32EにLEDを接続してみましょう。

ESP32-WROOM-32EはGPIOがHレベルの時3.3Vです。
ピンの状態が視認しやすいようにLEDを取り付けます。ここでは32ピンにLEDを接続します。LEDは順方向電圧が1.8V、順方向電流が2mA~8mA程度なので、LEDはESP32-WROOM-32Eのピンには直結できません。必ず抵抗器を通して接続します。下図は接続例です。ブレットボードなどに装着するとより簡単に配線ができます。

抵抗器は150Ω~470Ω程度の間で選択します。順方向電圧が1.8V、順方向電流が8mA程度のLEDだとすると200Ω程度の抵抗器が必要になります。330Ω程度の抵抗が無難です。図のように配線してみましょう。

LEDは足の長い方がアノード(A)、足の短い方がカソード(K)です。通常はA側をGPIO側に、K側をGNDと接続します。該当ピンがHレベルになると電流が流れてLEDが点灯します。

■プログラムを書いてみる Lチカ編

それではプログラムを早速書いてみましょう。最も簡単なLED点滅プログラム(Lチカ)を書いてみます。200ミリ秒間隔で指定したピンをHigh-Lowさせるだけのプログラムです。

今回はピンとして32ピンを指定しました。適宜変更してスケッチを書いてみてください。

※但し35,34は入力専用なので使えません。

int LED = 32;

void setup() {
  pinMode(LED,OUTPUT);
}

void loop() {
  digitalWrite(LED,HIGH);
  delay(200);
  digitalWrite(LED,LOW);
  delay(200);
}

では早速コンパイル(ビルド)してプログラムをESP32-WROOM-32Eにダウンロード(書き込み)してみましょう。
ツールバー画面左上にある「→」のボタン(書き込み)を押します。

ファイルを保存していない場合にはファイル保存のダイアログが表示されますので適当なディレクトリに保存してください。

コンパイルは少し時間がかかります。プログラムに誤りがなければコンパイル後に自動的に書き込みが実行されます。
ウインドウ下の「出力」という部分に進捗状況が表示されるので確認してください。
使用されているフラッシュメモリーのサイズやRAMの容量が表示されます。

綴りミスやエラーがある場合にはオレンジ色のエラーが表示されるので確認してください。

書き込みが完了すると「Hard resetting via RTS pin…」と表示されます。

32ピンと接続したLEDが点滅していることを確認してください。

点滅する周期を変更したりしてプログラムを変えてみてお試しください。

■ピンの状態を取得してみる

GPIOを入力設定にしてその状態に応じて処理を分岐するプログラムを作ってみましょう。

入力と聞くと「スイッチを付けなくては」と思いますが、ESP32-DevKitC-32Eには2つのスイッチが付いています。1つはENピンと接続されていてプログラムでは使えませんが“BOOT”と書かれたスイッチはGPIO0と接続されており実験に利用できます。

GPIO0を入力ピンとして使ってみましょう。入力ピンの場合にはスイッチを押していない時にピンの論理状態をHighにするか、Lowにするかをプルアップ又はプルダウンによって決めなければいけません。ESP32では指定したピンを入力ピンに設定するとともにそのピンを内部プルアップする機能があります。これを使えば外部にプルアップ用抵抗器を接続する必要がなく利用できます。但し、プルダウンの設定はできませんのでご注意ください。

次のプログラムはGPIO0のスイッチを押した時にLEDが点灯、離すと消灯するプログラムです。

const int ledPin = 32;
const int swPin = 0;

void setup() {

  pinMode(ledPin, OUTPUT);
  pinMode(swPin, INPUT_PULLUP);

}

void loop() {

  int sw_state = digitalRead(swPin);

  if (sw_state==HIGH){
    digitalWrite(ledPin, LOW);
  }else{
    digitalWrite(ledPin, HIGH);
  }  

}



適当にファイル名を付けて保存してコンパイルして書き込んでみてください。 pinMode()では入力ピンとする時にだけINPUT_PULLUPを引数として指定すると内部プルアップが有効になります。 ピンの状態はdigitalRead()関数で読み込みます。 戻り値はint型変数に代入します。その値をif文で判定します。 スイッチを押していない時はプルアップによりGPIO0はHighレベルなのでLEDは消灯に、押した時はLowなのでLEDを点灯させます。

if文で判定する条件式では比較演算子を使いますが、「等しい」時は==は2つです。注意してください。

■WEBサーバー機能でブラウザからLEDを制御をする

次に同じ回路でスケッチを変更しWEBサーバー機能を試してみましょう。 ESP32はWi-Fi通信機能が付いていますのでそのままWi-Fiに接続できます。またTCP/IPなどネットワーク接続に必要なプロトコルスタックを内蔵しているので簡単にネットワーク通信ができます。 WEBサーバー機能を使うことでブラウザから本機にアクセスしてLEDを消灯させたり点灯させたり、点滅させたり制御ができます。 “yourssid“と”yourpasswd“のところにご自分のWi-Fi環境のSSIDとパスワードをセットしてください。これが間違っているとそもそもWi-Fiに接続できないのですべて失敗してしまいます。 SSIDは大文字・小文字の区別があります
#include <WiFi.h>

const char *ssid = "yourssid";
const char *password = "yourpasswd";

const char html[] =
  "<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'>\
  <title>Hello Wifi</title></head>\
  <body>\
    <div>\
      <h2>LEDテストページ</h2>\
    </div>\
    <div>\
        <p>32ピンのLEDを<span style=\"color: #ff0000;\"><strong>点灯</strong></span>させるには <a href=\"/H\">ここ</a>をクリックします.</p>\
      </div>\
      <div>\
        <p>32ピンのLEDを<span style=\"color: #0000ff;\"><strong>消灯</strong></span>させるには <a href=\"/L\">ここ</a>をクリックします.</p>\
      </div>\
      <div>\
        <p>32ピンのLEDを<span style=\"color: #339966;\"><strong>点滅</strong></span>させるには下のボタンを押します.</p>\
      </div>\
      <div><form method=\"get\" action=\".\">\
        <input type=\"submit\" name=\"blink\" value=\"点滅開始\" />\
      </form></div></body></html>";

WiFiServer server(80);

const int LEDpin = 32;
int mode_f = 0;

void setup() {
  Serial.begin(115200);
  pinMode(LEDpin, OUTPUT);

  delay(10);

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop() {

  if (mode_f==1){
    blinkLED();
  }

  WiFiClient client = server.available();

  if (client) { 
    Serial.println("New Client."); 
    String currentLine = "";   

    while (client.connected()) {  
      if (client.available()) { 
        char c = client.read();   
        Serial.write(c);   

        if (c == '\n') {    
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            client.print(html);
            client.println();
            break;
          } else {
            currentLine = "";
          }

        } else if (c != '\r') {
          currentLine += c;  
        }

        if (currentLine.endsWith("GET /H")) {
          digitalWrite(LEDpin, HIGH);
          mode_f=0;
        }

        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LEDpin, LOW);
          mode_f=0;
        }

        if (currentLine.endsWith("GET /?blink")) {
          blinkLED();
          mode_f=1;
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");
  }
}

void blinkLED(){
  digitalWrite(LEDpin, LOW);
  delay(200);
  digitalWrite(LEDpin, HIGH);
  delay(200);
}

内容としては最初のhtml配列のところでHTMLデータを代入しています。
注意すべき点は行替えのところには”\”(もしくはバックスラッシュ)を入れることです。Arduino IDEのフォント設定が英語フォントの場合には\はバックスラッシュとして表示されます。

また”(ダブルクォーテーション)は、\” として書くことも注意してください。間違えるとブラウザでアクセスした時に正しいページが表示されません。特にタグの部分の文字列に注意してください。

★LED点灯/消灯/点滅の仕組み★

LED点灯時は http://yourAddress/H

LED消灯時は http://yourAddress/L

LED点滅時は http://yourAddress/?blink

へ飛ぶように作られています。いずれもHTTPのGETメソッドを使っています。
一番簡単な方法なのでGETメソッドを使っていますが、改造すればもちろんPOSTメソッドでも作れます。

もう1つポイントとしてはボタンです。ボタンはtype属性をsubmitとしています。
その前にaction属性を使ってボタンが押された時、ページのトップに移動するようにしています。そうしないと、例えば  http://192.168.0.100/H の状態でボタンを押すと http://192.168.0.100/H/?blink となってしまい正しく判定ができなくなってしまうためです。

ではビルド、書き込み、そして動作確認をしてみましょう。

  1. ボードに書き込む前にシリアルターミナルを表示させておきます。そうすることでモジュールが正しくWi-Fiに接続できたか、またDHCPで割り当てられたIPアドレスがいくつなのかを知ることができます。
  2. Arduino IDEの”ツール”→”シリアルモニタ”をクリックして画面下にシリアルモニターを表示させておきましょう。
  3. 「書き込み」ボタンを押してプログラムをビルドして書き込みを実行します。
  4. 書き込みが完了すると、「シリアルモニター」にESP32-WROOM-32Eに割り当てられたIPアドレスが表示されます。これを控えておきます。もし接続できない場合にはSSIDやパスワードが間違っている可能性があります。またESP32-WROOM-32EにUSBバスから給電される電流が足りていないなどの原因があります。USBハブに電源付きのものを使ってお試しください。
  5. パソコン等のブラウザでこのIPアドレスに接続してみましょう。ブラウザを起動してアドレス欄にIPアドレスを入力してエンターキーを押します。下図のようにページが表示されれば成功です。
  6. 「ここ」の部分をクリックしてその通りにLEDが点灯したり消灯したりするか確認してください。

続いて「点滅開始」をクリックするとLEDが点滅すること確認してください。なおこのプログラムでは割込を使わずに点滅するサブルーチンをloop関数の中で定期的に呼び出して点滅させています。loop関数内ではWi-Fiの処理も行っておりWi-Fiの処理の方に時間がかかると点滅が止まる場合があります。このプログラムはデモなのでその点はあまり気にしていませんが、より実用的なプログラムを書く場合には割込を使うなど工夫が必要になります。

■スイッチを押すとLINEに通知する(Messaging API使用)

スイッチを押したとき、LINEで通知を送るプログラムを作ってみましょう。

LINEで通知を送る仕組みとしてLINE Notifyというサービスがありましたが、残念ながらサービスが終了してしまいました。その代わりMessaging APIを使った方法が提供されています。しかし通知できるメッセージ数には制限があり無料で使えるのは200通/月となっています。

Messaging APIを使うためにはトークンを取得するための「Messaging APIチャネル」が必要となります。LINE公式アカウントでMessaging APIの利用を有効にします。

  1. LINEビジネスIDの登録が必要となります。下記ページにアクセスします。
    https://entry.line.biz/form/entry/unverified
  2. 画面の指示に従いアカウントを作成します。
    PCでLINEを使っている場合にはLINEアカウントで作成するほうが便利です。そうでない場合にはメールアドレスでアカウントを作ってください。
  3. アカウント名は適当でかまいませんが分かりやすい名前にします。例えば「ESP32 LINE通知」などとします。
  4. その他の項目は画面の指示に従って入力します。
  5. 完了すると、LINEのメッセージが送られてきますので確認してください。
  6. 「LINE Official Account Manager」へログインします。
  7. 「情報利用に関する同意について」などが表示されるので内容を確認して同意して進んでください。
  8. ホーム画面を表示させます。

ここまでで登録が完了しました。次の手順でMessaging APIを使えるようにしていきます。

  1. ホーム画面右上の「設定」をクリックします。左側にメニューが表示されるので「Messaging API」をクリックします。
  2. 「Messaging APIを利用する」をクリックします。
  3. 「プロバイダーを選択」が表示されます。ここではこのMessaging APIを使う団体や組織、企業名等を入力します。個人であれば名前などにしてください。入力したら「同意する」を押します。
  4. プライバシーポリシーと利用規約については何も入力しないで「OK」をクリックします。
  5. 「Messaging APIを利用」画面が表示されるので「OK」をクリックします。
  6. ステータスやチャネル情報などが表示されます。Messaging APIが有効になりました。引き続き操作をします。
    「その他の設定は LINE Developers から行えます。」の「 LINE Developers 」をクリックします。

  1. 画面上部の「コンソール」をクリックします。
  2. 作成したプロバイダー名をクリックします。
  3. すでに作成されたチャネルが表示されていますのでそれををクリックします。
  4. 画面上部の「Messaging API設定」タブをクリックします。
  5. Messaging APIに関する詳細情報が表示されます。画面の下部に進むと「チャネルアクセストークン(長期)」という項目があるので、その部分にある「発行」をクリックします。すると、長手文字列のアクセストークンが表示されます。このアクセストークンをプログラムで使いますので、コピーしてメモ帳などに貼り付けて保存しておきます。
  6. 最後にLINE公式アカウントに「友だち登録」する必要があります。先ほどのコンソール画面で表示されたQRコードをスマホ等から読み込みます。
    友だち登録を完了させてください。
    友達登録が完了するとLINE公式アカウントからメッセージが届きます。
  7. またユーザーIDが必要です。「チャネル基本設定」タブにある「あなたのユーザーID」で確認できますのでこのIDも控えておきます。

それでは、このアクセストークンを使ってスケッチを作ってみましょう。

Arduino IDEを表示させます。このスケッチではArduinoJson ライブラリが必要 ですので、ライブラリマネージャからインストールします。

  1. Arduino IDEで「ツール」→「ライブラリを管理」をクリックします。
  2. 左側のメニューの検索ボックスに”ArduinoJson”と入力します。
  3. 表示されたら「インストール」をクリックしてインストールしてください。

#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

const char* ssid = "あなたのSSID";
const char* password = "あなたのパスワード";

const char* channelToken = "取得したトークン";
const char* userId = "ユーザーID";

const int switchPin = 0;
bool prevSwitchState = HIGH;

void sendLineMessage(String message) {
  HTTPClient http;
  http.begin("https://api.line.me/v2/bot/message/push");
  http.addHeader("Content-Type", "application/json");
  http.addHeader("Authorization", "Bearer " + String(channelToken));

  // JSONデータを作成
  StaticJsonDocument<512> jsonDoc;
  jsonDoc["to"] = userId;

  JsonArray messages = jsonDoc.createNestedArray("messages");
  JsonObject msg = messages.createNestedObject();
  msg["type"] = "text";
  msg["text"] = message;

  String requestBody;
  serializeJson(jsonDoc, requestBody);

  int httpResponseCode = http.POST(requestBody);

  if (httpResponseCode > 0) {
    Serial.println("LINEメッセージ送信成功: " + String(httpResponseCode));
    Serial.println(http.getString());
  } else {
    Serial.println("送信失敗: " + String(httpResponseCode));
  }

  http.end();
}

void setup() {
  Serial.begin(115200);
  pinMode(switchPin, INPUT_PULLUP);

  WiFi.begin(ssid, password);
  Serial.print("Wi-Fi接続中");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWi-Fi接続成功");
}

void loop() {
  bool currentState = digitalRead(switchPin);
  if (prevSwitchState == HIGH && currentState == LOW) {
    Serial.println("スイッチが押されました");
    sendLineMessage("スイッチが押されました");
    delay(1000); // 誤送信防止
  }
  prevSwitchState = currentState;
  delay(10);
}

スケッチをビルドしてボードに書き込んでください。

動作確認をしてみましょう。ボードのBOOT0スイッチ(GPIO0)を1回押してみてください。LINEで「スイッチが押されました」という通知が出れば完成です。

なお、よくある間違いとしてユーザーIDが正しくない場合があります。ユーザーIDは、uから始まる長い文字列です。LINE Developers のコンソール画面から確認できますので、間違いがないか確認してください。

この仕組みを使えばいろいろと応用ができそうです。もちろんGPIOを増やして使うこともできますし、変化のあったGPIO毎にメッセージ内容も変えられるのでいろいろと楽しめそうです。ただし月に200通までの制限がありますので使いすぎにはご注意ください。