Top/電子工作/ESP32

ESP32

  中国の Espressif Systems 社が作成したマイクロコントローラで、次の特徴を持つ。

開発用ボード

  ESP32用の開発ボードはいくつかある。今回は、Switchscience の ESPr Developer 32 を使用する。
   中国の安いボード(ESP-32S ESP-32 Development Board,以下 中国ボード)を買った。これを使ったときの違いも書く。

使用前の準備

  1. ピンヘッダの半田付け
    まずはこれから。これをしないと、プロトタイピングできない。

  2. Arduino IDE のダウンロードと初期設定
    • ポータブルな環境にするには、"Windows ZIP file for non admin install"を選択する。
      もちろん献金してよい。しかし、献金しなくても "Just Donwload" ボタンでファイルを取得できる。
      1.8.5 が最新版(2018-08-16 (木) 17:44:23時点)

    • Switchscience の解説ページを参照して、Arduino IDE で ESP32 ボードを使えるようにする。
      • ファイル > 環境設定
        設定タブの「追加のボードマネージャーのURL:」に
        https://dl.espressif.com/dl/package_esp32_index.json 
        を書き込み OK をクリックする。

      • ツール > ボード:"Arduiono/Genuin Uno" にマウスのポインターを合わせ、
        現れたタブからボードマネージャを選んでクリック。窓に、ESP32 を入力すると、
        "esp32 by Expressif Systems"が現れる。これをクリックし、「インストール」をクリックする。
        ボードの定義がダウンロードされてインストールされる。

        中国ボードの場合には、CP2102 というチップを使ってパソコンと通信する。そのドライバは
        自動的にインストールされない。そのため、対応したドライバをあらかじめインストールする。
        Silicon labsのページから、適切なものをダウンロードし、 展開してインストーラを起動すれば
        導入できる。

      • ツール > ボード:"Arduiono/Genuin Uno" にマウスのポインターを合わせ、
        ESP32 Dev Module を選択する。

      • ツール > シリアルポート
        それらしい COM3 などを選択する。選択しないと通信できない。

  3. はまったところ
    1. コンパイルがエラーで止まる。
      Mc Afee のウィルス対策ソフトのリアルタイムスキャンが影響している。これを止めると、コンパイルできる。

    2. ツール > シリアルポートで選べない。
      USB Type B micro のコネクタが深く刺さっていないと、COMポートが認識できない。
      ちなみに、シリアル通信のデバイスドライバは、Windows が勝手にインストールしてくれる。

    3. コンパイルが遅い
      このページ(Arduino IDEのビルドを速くする|オブジェクトファイルの出力先を固定する)
      参照して変更すると、少し早くなったように思う。

    4. プログラムの書き込みに失敗する
      • シリアルモニタが開いていたら、これを閉じる。
      • 通信速度を 115200 に落としてみる。

テストプログラム

  接続できたと思ったら、次のプログラム(Arduino ではスケッチと呼ぶ)を試してみる。

  1. Arduino としての機能
    次のスケッチを実行し、ツール > シリアルモニタ でシリアルモニタ(別枠の窓)を表示させる。
    右下の通信速度を、スケッチ中の 115200bps に変更する。
    void setup() {
      Serial.begin(115200);
    }
    
    void loop() {
      Serial.println("Hello World.");
      delay(1000); 
    }
    うまくいけば、1秒(1000ミリ秒)に1回、"Hello World." と表示される。

  2. Wi Fi としての機能
    ファイル > スケッチ例 > (EES32 Dev Module 用のスケッチ例から) Wi Fi > Wi Fi Scan を選択する。
    次のスケッチが表示される。
    #include "WiFi.h" 
    
    void setup()
    {
        Serial.begin(115200);
    
        // Set WiFi to station mode and disconnect from an AP if it was previously connected
        WiFi.mode(WIFI_STA);
        WiFi.disconnect();
        delay(100); 
    
        Serial.println("Setup done");
    }
    
    void loop()
    {
        Serial.println("scan start");
    
        // WiFi.scanNetworks will return the number of networks found
        int n = WiFi.scanNetworks();
        Serial.println("scan done");
        if (n == 0) {
            Serial.println("no networks found");
        } else {
            Serial.print(n);
            Serial.println(" networks found");
            for (int i = 0; i < n; ++i) {
                // Print SSID and RSSI for each network found
                Serial.print(i + 1);
                Serial.print(": ");
                Serial.print(WiFi.SSID(i));
                Serial.print(" (");
                Serial.print(WiFi.RSSI(i));
                Serial.print(")");
                Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
                delay(10);
            }
        }
        Serial.println(""); 
    
        // Wait a bit before scanning again
        delay(5000);
    }
    うまくいけば、無線LANの情報が表示されるはずである。

  3. その他
    1. ホール素子
      ファイル > スケッチ例 > (EES32 Dev Module 用のスケッチ例から) ESP32 > Hall Sensor
      内蔵のホールセンサの値(磁場に関係した量)を表示できる。

    2. タッチセンサ
      ファイル > スケッチ例 > (EES32 Dev Module 用のスケッチ例から) ESP32 > Touch > Touchread
      GPIO4 のピンからケーブルを伸ばすと、それに接触したかどうかで判定できる。
      いわば、タッチセンサ―として機能する。それを試すプログラム。

SPI で気圧センサ BME280 の値を読みとる

  1. 概要
    観測装置として、観測装置の置き場所と、センサの値の回収はいつも問題になる点である。無線LAN
    が使えて、センサーの値を送信できれば好都合である。ESP32と BME280 を用いてこれを実現する。
    SPIについてはArduino/SPIを参照のこと。

  2. 手順
    1. 配線する
      参考URLに示したページの SPI の方を参考に接続する。

    2. ESP32 で BME280 のデータを SPI で読みとるためのライブラリをありがたく使わせていただく。
      1. github のここから、"clone or download" を選んで zip ファイルをダウンロードする。
      2. ここを参考に、ライブラリをインストールする。
      3. Arduino IDE で スケッチ > ライブラリをインクルード で ESP32_BME280_SPI を選択する。

    3. プログラム
      参考URLに示したページの SPI の方のサンプルプログラムを
      ファイル > スケッチ例 > ESP32_BME280_SPI > ESP32_BME280_SPI_sample01
      を選択して開く。これを実行し、シリアルモニタで値が表示されるか確かめる。


  3. 参考URL

NTP で時刻を取得する

  1. 概要
    NTP(Network Time Protocol)は、ネットワークを使って時計を同期するための通信規約である。
    これを用いてネットワーク越しに時刻を特定できる。

  2. 参考URL

IFTTT で利用する。

  1. IFTTT を使う際の考え方
    こちらのページにまとめた。IFTTTの webhooksサービスを利用する。そのためには、
    https で ifttt.com に HTTP の POST あるいは GET でデータを送信しなければならない。

  2. https で特定のサイトにアクセスする。
    • 予備知識
      ブラウザは、http と https を区別なくアクセスするように見える。しかし、マイコンで https で
      開設されているサイトにアクセスするには、工夫が必要になる。サンプルプログラムは、
      ファイル > スケッチ例 > (EES32 Dev Module 用のスケッチ例から) Wi Fi Client Secure > Wi Fi Client Secure
      で得られる。

    • 証明書の取得
      ESP32からIFTTTを使ってLINE Notifyで通知を送ってみた/スケッチの設定」を参照して、
      送信先であるifttt.comにアクセスするための証明書を取得する。
      -----BEGIN CERTIFICATE-----
      MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
      EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
      EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
      ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
      NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
      EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
      AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
      DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
      E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
      /PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
      DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
      GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
      tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
      AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
      FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
      WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
      9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
      gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
      2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
      LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
      4uJEvlz36hz1
      -----END CERTIFICATE-----

    • IFTTT への通信
      HTTP の GET あるいは POST という方法でデータを送信する。送信方法については、次のページを参照した。
    • スケッチのサンプル
      そんなこんなで作成したスケッチのサンプルを示す。
      4番ピンに触ると、IFTTT へのトリガーとして働くスケッチ。Xで埋められている部分は、それぞれの
      ユーザーが設定する項目であることを示している。
      WiFiIDs.h
      const char* ssid      = "XXXXXXXXXXXXX";          // your network SSID (name of wifi network)
      const char* password  = "XXXXXXXXXXXXX";          // your network password
      const char* IFTTTkey  = "XXXXXXXXXXXXXXXXXXXXXX"; // IFTTT webhook key for me
      const char* server    = "maker.ifttt.com";        // Server URL
      const char* EventName = "XXXXXXXXXX";             // IFTTT Event Name 
      
      const char* ifttt_root_ca= \
        "-----BEGIN CERTIFICATE-----\n" \
        "MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx\n" \
        "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT\n" \
        "EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp\n" \
        "ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz\n" \
        "NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH\n" \
        "EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE\n" \
        "AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw\n" \
        "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD\n" \
        "E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH\n" \
        "/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy\n" \
        "DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh\n" \
        "GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR\n" \
        "tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA\n" \
        "AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE\n" \
        "FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX\n" \
        "WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu\n" \
        "9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr\n" \
        "gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo\n" \
        "2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO\n" \
        "LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI\n" \
        "4uJEvlz36hz1\n" \
        "-----END CERTIFICATE-----\n";
      プログラム本体
      /*  IFTTT trigger sample */
      
      #include <WiFiClientSecure.h>
      #include "WiFiIDs.h" 
      
      WiFiClientSecure client;
      
      int val1 = 1000, val2 = 1001, val3 = 1002; // dummy data
      
      void setup() {
        // Serial Monitor
        Serial.begin(115200);
        // WiFi
        WiFi.begin(ssid, password);
        while (WiFi.status() != WL_CONNECTED) {  // attempt to connect to Wifi network:
          Serial.print(".");
          delay(500);
        }
        Serial.println("WiFi Connected");
        // CACert
        client.setCACert(ifttt_root_ca);
      }
      
      void loop() {
        val3 = val2;
        val2 = val1;
        val1 = touchRead(T0);
        Serial.println(val1);
        if ( val1 + val2 + val3  < 80 ) { // touched
          Serial.println("\nStarting connection to server...");
          if (!client.connect(server, 443)) {
            Serial.print  ("Connection failed!");
            Serial.println(server);
            return;
          } 
      
          String request = "/trigger/";
          request += EventName;
          request += "/with/key/";
          request += IFTTTkey;
          request +=  "?value1=" + String(val1)
                      + "&value2=" + String(val2)
                      + "&value3=" + String(val3); 
      
          Serial.println("GET " + request + " HTTP/1.1"); 
      
          client.println("GET " + request + " HTTP/1.1");
          client.print  ("Host: ");
          client.println(server);
          client.println("Connection: close");
          client.println();
      
          while (client.connected()) {
            String line = client.readStringUntil('\n');
            if (line == "\r") {
              Serial.println("headers received");
              break;
            }
         }
          client.stop();
          
          val1 = 1000, val2 = 1001, val3 = 1002;
          delay(10000);
        }
        delay(100);
      }

Google スプレッドシートに記録する

Smart Config


トップ   新規 検索 最終更新   ヘルプ   最終更新のRSS