プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

Hello ESP world

ESP32に入門しました。
ESP32は Wi-FiBluetoothを内蔵するマイコンで、Arduinoの開発環境と類似のプログラムでIOTが出来ます。
このようなボード(開発ボード)が1400円ぐらいで売っていて、Arduinoより安くコンパクトです。

f:id:s51517765:20201219153447p:plain
左からArduinoNano互換、ESP32-WROOM-32、ArduinoUnoR3

ESP(32)といったとき、上記のような開発ボードであったり、SOCだけの場合があるので購入するときは注意ですね。
Arduinoに対してネットワークや無線通信が付いていて安い点は魅力ですが、Arduino Unoと比較すると、AnalogWriteが使えるピンが少ない点が注意です。

またVersionが違うのか、メーカーが違うのかオリジナルなのかコンパチなのかわかりにくい気がします。
Arduinoオープンソースで互換品がたくさん出ていて、しかし「Arduino」という名前は本家しか使ってはいけないという明確なルールがありますが、ESP32の場合はこのESP32という名称自体はSOCでしかないので、よくわからない互換品がいろいろ出ている、ということになっている気がします。

それで適当に安いのを買ったらWebの情報と違ってなかなか動かない、ということに遭遇してしまいます。

Amazonで同じもの(と思われるもの)を買っても同じものが来ないかもしれません。

環境設定

それでは使ってみます。
Arduino IDEにESP32を追加します。
rikoubou.hatenablog.com
deviceplus.jp

ボードはESP32 Dev moduleを選択します。
f:id:s51517765:20201213182622p:plain

・トラブルその1
USBケーブルが原因でポートが見つかりません。
teratail.com
USBケーブルを交換したら認識しました。

コントロールパネルでUSBデバイスが認識されることを確認しながらUSBケーブルを選びます。
f:id:s51517765:20201219161456p:plain

・トラブルその2
書き込み時にErrorが出て書き込めません。
このときは、Connecting... となったところでBootボタンを長押しすると書き込めるということです。Connectされたら離して大丈夫です。
また特定のdigitalピン(とりあえずD2はだめでした、D5はOK)がプルアップ(結線されている)されていると書き込めない場合があります。
このときは書き込み時そのピンのリード線を外しておきます。
f:id:s51517765:20201213182124j:plain
www.opensourcetech.tokyo

もう少し使ってみる

簡単なHello worldをしたら、もう少し実際的なプログラム書きます。
ESP32の一番メリットであるWifi接続でWebhookを試します。
Line notifyとWifi接続は↓を利用しました。Wifi ConnectのところでTryError中断処理を追加しました。
next.rikunabi.com

回路

ボタンを押したらLineにメッセージを送るようにします。
f:id:s51517765:20201219160723j:plain
circuits4you.com

f:id:s51517765:20201219163859j:plain
D5ピンを5kΩでプルアップ、タクトスイッチを押したときGNDになるようにしています。
プルアップ抵抗はGPIOの電流を制限する意味もあり10kΩ前後がよく使われます(ここではすぐ出てきた5kΩを適当に選択)。
ESP32の場合はGPIOの電流はMax 20~40mAとのこと(細かくはこれから使っていきながら調べる予定)で、3.3Vで20mA、マージン20%とすると、198Ω以上が絶対必要になります。
ここではスイッチの検知だけなのでもっと抑えてよいです。
だいたいプルアップ抵抗は5kΩ以上、と思っておくといいと思います。

完成

f:id:s51517765:20201219164350p:plain

#include <WiFi.h>
#include <WiFiClientSecure.h>
const char* ssid = "++++++++";
const char* password = "++++++++";
const char* token = "++++++++";

void wifiConnect() {
  int tryCount = 0;
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);  // Wi-Fi接続
  while (WiFi.status() != WL_CONNECTED) {  // Wi-Fi 接続待ち
    delay(100);
    Serial.printf(".");
    tryCount += 1;
    if (tryCount > 30) {
      Serial.println("\nwifi connect NG");
      return;
    };
  }
  Serial.println("\nwifi connect OK");
}

void sendLine(String message) {
  const char* host = "notify-api.line.me";
  WiFiClientSecure client;
  Serial.println("Try");
  //LineのAPIサーバに接続
  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);
  delay(500);
}

void setup() {
  Serial.begin(115200);
  wifiConnect();
}

void loop() {
  //ボタンが押されたら
  if (digitalRead(5) == LOW) {
    Serial.print("Button pushed.\n");
    sendLine("Hello ESP world!!");
  }
  delay(100);
}