ESP32-DevKitC-32EはESP-WROOM-32Eを搭載したボードです。
USB接続するだけで使え手軽にESP32の世界を楽しめます。
ESP-WROOM-32Eには1つのモジュール内にWi-FiとBluetooth V4.2BR / EDR BLEの通信機能が含まれています。またESP-WROOM-32Eは32ビットマイコンとしても高機能です。MCUのコアはESP32-D0WD-V3です。32ビットマイコンとして使うこともできます。
開発環境はArduino IDEを使います。
■Arduino IDEの準備
- Arduino IDEを起動します。
インストールしていない方は公式サイトのこちらからダウンロードしてインストールします。最新バージョンをインストールしてください。 - “ファイル”→”基本設定”を開きます。
- 追加のボードマネージャのURL”の部分に次のURLをコピーして貼り付けます。
https://dl.espressif.com/dl/package_esp32_index.json - OKボタンを押します。
- “ツール”→”ボード”をクリックし更に右側に表示される”ボードマネージャ”をクリックします。
- 先ほどURLを環境設定の部分で指定しているので「検索をフィルタ」と書かれたボックスにに”esp32″と入力すると一覧にボードが表示されます。一覧から”esp32 by Espressif Systems”を選択してインストールしてください。その時の最新バージョンをインストールしてください。
- “インストール”ボタンを押します。
これでボードに必要なファイルが自動的にダウンロードされてインストールされます。 - インストールが完了すると”ツール”→”ボード”→”esp32″の一覧に”ESP32 Dev Module”という名前が表示されますのでこれを選択します。
似たような名前が多いので間違えないようご注意ください。
画面上部にデバイス名が正しく表示されていることを確認します。
■ハードウエアの準備と設定
- 本体のmicroUSBポートとパソコンを接続してください。
USBケーブルには品質のよいものをご使用ください。品質のわるいものや古いものを使ったことによって正しくパソコンに認識されないというケースが多々発生しています。必ずUSBケーブルには良い品質のものをご使用ください。
ESP32は消費電流の大きなデバイスです。200mA以上の電流が流れることがあります。USBポートは最大で1ポートあたり500mA流せますがハブを使っていると1つのデバイスに流せる電流は減ります。本機をパソコンと接続する時はパソコンのUSBポートに直接接続するか、電源付きのUSBハブをご使用ください。電流が十分供給できない場合、予期せぬ動作をしたり正しくパソコンに認識されないなどトラブルの原因となります。 - 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を実行してください。 -
ESP32-DevKitC-32Eをパソコンと接続したらWindowsのデバイスマネージャーの”ポート(COMとLPT)”のツリーから、”Silicon Labs CP210x USB to UART Bridge(COMx)”を探してCOMポート番号を調べます。
上図の場合にはCOM3に設定されています。
パソコンに正しく認識されない場合にはケーブルとデバイスドライバを疑ってください。
少なくとも次のことは必ずお試しください。
・別のケーブルを使ってみる
・別のUSBポートに挿入してみる
・USBハブを介している場合にはPCのポートに直接接続する
・別のパソコンがあれば別のパソコンで試してみる・
・上記の仮想COMポートドライバを手動でインストールしてみる
本製品は完成した電化製品とは違って開発者向け製品です。お客様ご自身で色々とお試し頂きトライアンドエラーで問題を解決していくものとなっています。 - ツール”→”ポート”をクリックして手順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 となってしまい正しく判定ができなくなってしまうためです。
ではビルド、書き込み、そして動作確認をしてみましょう。
- ボードに書き込む前にシリアルターミナルを表示させておきます。そうすることでモジュールが正しくWi-Fiに接続できたか、またDHCPで割り当てられたIPアドレスがいくつなのかを知ることができます。
- Arduino IDEの”ツール”→”シリアルモニタ”をクリックして画面下にシリアルモニターを表示させておきましょう。
- 「書き込み」ボタンを押してプログラムをビルドして書き込みを実行します。
- 書き込みが完了すると、「シリアルモニター」にESP32-WROOM-32Eに割り当てられたIPアドレスが表示されます。これを控えておきます。もし接続できない場合にはSSIDやパスワードが間違っている可能性があります。またESP32-WROOM-32EにUSBバスから給電される電流が足りていないなどの原因があります。USBハブに電源付きのものを使ってお試しください。
- パソコン等のブラウザでこのIPアドレスに接続してみましょう。ブラウザを起動してアドレス欄にIPアドレスを入力してエンターキーを押します。下図のようにページが表示されれば成功です。
- 「ここ」の部分をクリックしてその通りにLEDが点灯したり消灯したりするか確認してください。
続いて「点滅開始」をクリックするとLEDが点滅すること確認してください。なおこのプログラムでは割込を使わずに点滅するサブルーチンをloop関数の中で定期的に呼び出して点滅させています。loop関数内ではWi-Fiの処理も行っておりWi-Fiの処理の方に時間がかかると点滅が止まる場合があります。このプログラムはデモなのでその点はあまり気にしていませんが、より実用的なプログラムを書く場合には割込を使うなど工夫が必要になります。
■スイッチを押すとLINEに通知する
もう少し複雑なプログラムにも挑戦してみましょう。
皆様お使いになっていると思うメッセージングサービスのLINEに通知を送る内容です。ESP32-DevKitC-32EのGPIO0のスイッチが押されると、LINEで”スイッチが押されました”と通知されるプログラムを作ってみましょう。
LINEに通知をするにはいくつかの方法があります。今回は “LINE Notify“というサービスを使ってみます。あらかじめ登録しておいたグループに対して通知を送れます。その他にはIFTTTというサービスを使った方法もあります。
まずは”LINE Notify“を友達に追加します。”LINE Notify“のページに飛ぶとトップページにQRコードが表示されますのでスマホのLINEアプリでこのQRコードをスキャンして友達を追加してください。
最初に「アクセストークン」と呼ばれる文字列を取得します。このトークンを使うことでESP32プログラム内からLINEに対して通知が送れるようになります。
- “LINE Notify“にアクセスしてログインしてください。
- 右上のアカウント名のところをクリックするとメニューが表示されますので「マイページ」を選択します。
- 「アクセストークンの発行」のところにある「トークンを発行する」ボタンを押します。
- トークン名は通知される時に表示されますので、ここでは適当に「ESP32スイッチ」とかにしておきます。
続いて「通知を受信するトークルームを選択してください」のところではグループを選択しますが、自分だけが受信する場合には「1:1でLINE Notifyから通知を受け取る」にチェックを入れて発行するを押してください。 - トークンが発行されます。
このトークンはとても大切ですので必ず控えておいてください。
赤文字で表示されたトークンを続いて作るプログラムの中で使用します。
では早速プログラムを書いてみましょう。
今回はGPIO0を内部プルアップされた入力ピンとして使用し、スイッチが押されると(GP0がLowになると)LINEに通知が飛ぶようにします。
Wi-Fiへの接続部分などは先の例と同じですので解説は省略します。
プログラム中の”yourssid“と”yourpasswd“には実際にご利用のWi-Fi環境のパラメーターを記述してください。
“const char* token = “your LINE Notify token”;“ の部分です。your LINE Notify token の部分には先ほどの手順で発行したLINE Notifyのトークンをそのままコピーしてください。
#include <WiFi.h>
#include <ssl_client.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
const char *ssid = "yourssid";
const char *password = "yourpassed";
const char* host = "notify-api.line.me";
const char* token = "yourLINE Notify token";
const int LEDpin = 32;
const int SWpin = 0;
void wificonnection(){
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());
}
void send_message(String message) {
WiFiClientSecure client;
client.setInsecure();
Serial.println("Connecting to LINE API Server..");
if (!client.connect(host, 443)) {
Serial.println("Connection failed");
return;
}
Serial.println("Connected!");
String query = String("message=") + message;
String request = String("") +
"POST /api/notify HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Authorization: Bearer " + token + "\r\n" +
"Content-Length: " + String(query.length()) + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n\r\n" +
query + "\r\n";
client.print(request);
while (client.connected()) {
String line = client.readStringUntil('\n');
Serial.println(line);
if (line == "\r") {
break;
}
}
String line = client.readStringUntil('\n');
Serial.println(line);
}
void setup() {
Serial.begin(115200);
pinMode(LEDpin, OUTPUT);
pinMode(SWpin, INPUT_PULLUP);
delay(10);
wificonnection();
}
void loop() {
int sw_state = digitalRead(SWpin);
if (sw_state==HIGH){
digitalWrite(LEDpin, LOW);
}else{
digitalWrite(LEDpin, HIGH);
send_message("GP0ボタンが押されました!");
}
}
シリアルターミナルでログを見たいのでArduino IDEの”ツール”→”シリアルモニタ”を選択してモニターを表示させておいてください。
コンパイルして書き込んでみてください。
書き込みが成功するとシリアルモニターにWi-Fiへの接続状況が表示されます。接続が正しく完了すると本機に割り当てられたIPアドレスが表示されます。
続いて本体の”BOOT”ボタン(GPIO0ボタン)を1回押してください。
LINE APIのサーバーに接続を試みます。成功すれば下記のようにログに表示されます。
Connecting to LINE API Server..
Connected!
続いて処理が行われます。処理中はLEDが点灯しています。処理が数秒程度で完了しLINE Notifyに通知が送られてきます。スマホ等で確認してみましょう。
どうでしょうか?正しく通知は送られてきましたか?
この仕組みを使えばいろいろと応用ができそうです。もちろんGPIOを増やして使うこともできますし、変化のあったGPIO毎にメッセージ内容も変えられるのでいろいろと楽しめそうです。