メカニカル-メモリアル~めかめもっ!~

東京工業大学.rogy.ROBO-ONE,メカトロ技術系ブログ

ESP32で照明をつけてみた(ソフト編)

してみました。実際の動作はこの動画を見てください(動作は1分3秒から)。


[ESP32]スマホから部屋の電気をつけてみる

 こちらのブログ記事のために作った作品です。実用目的ではありません。 http://titech-ssr.blog.jp/archives/1067443012.html 全体のソースコードは当面非公開の予定です。
 当記事は制作する上で必要となった技術や考えを書いています(ソフト編)。

 秋月のESP32評価ボードについて、Arduino IDE環境によるSDカードの使い方、複数のUARTの使い方(コマンドサーボの使い方)、htmlのメインプログラムからの独立、wifiを介した時刻の取得、あたりをしていく方法を書いていきます。

SDカードの使い方

 基本はESP32 Dev Module用のスケッチ例の中のSD_Testを流用。とりあえずスケッチを開くと

/*  
 * Connect the SD card to the following pins:  
 *  
 * SD Card | ESP32  
 *    D2       -  
 *    D3       SS  
 *    CMD      MOSI  
 *    VSS      GND  
 *    VDD      3.3V  
 *    CLK      SCK  
 *    VSS      GND  
 *    D0       MISO  
 *    D1       -  
 */  

とあるのでそれに従って線を繋ぎます。ESP32の配線の記載は(自分の環境だと)arduino-1.8.2/hardware/espressif/esp32/variants/esp32/pins_arduino.hにありました(私の同輩のけり君に教わりました。優秀マンです)。SDカード側は、例えば
akizukidenshi.com
なら取扱説明書に書いてあるのでそれに従います。GNDとVCCはボードに書いてあるところに素直に繋ぎます。
 SD_Testを実行すれば一連の動作はわかると思います。基本的にはappendFileを使え今回の目標(スイッチのon-offのログとその時間を記録する)はできました。

複数のUARTの設定(コマンドサーボの使い方)

 地味に大変な内容でした。サーボはFutaba RS304をコマンドモードで使っています。なのでこの項目を読んでもPWMは出てきません(ちなみにESP32は標準だとanalogWriteが使えなく、過去にひっかかりました)。逆に、複数のUART通信をESP32で行いたい場合は有用です(RS304を使う如何にかかわらず)。

UARTの設定

結論だけ書くと
UART1.cpp

#include<HardwareSerial.h>  
#include"UART1.h"  
HardwareSerial  Serial1(1);  
void UART1_Configuration() {  
  Serial1.begin(115200, SERIAL_8N1, 32, 25);//speed,config,Rx,Tx  
}  

と書けばOK。どこにそんなことが書いてあるかというと、arduino-1.8.2/hardware/espressif/esp32/cores/esp32/HardwareSerial.h とHardwareSerial.cpp です。ここにパソコンと繋ぐ標準のSerial(Serial.beginで使い始められるやつ)の設定のようなものがあるのでそれに準じるだけです。
 もう少し細かく説明すると、

HardwareSerial Serial1(1)  

 C++に詳しくないので適当な解説ですが、Serial1という名前でUARTの1番を使えるようにします。esp32には3つのUARTが付いていて、当然名前は(クラスにつけられるものであれば)なんでもいいので、ここは例えば

HardwareSerial servo(2)  

でもいい(はず)です。esp32には3つのUARTがついていて、うち1つ(0番)はパソコンと繋がっているの基本的にはいじりたくないです。

Serial1.begin(115200, SERIAL_8N1, 32, 25);//speed,config,Rx,Tx  
}  

 先ほど名前をつけたものの初期設定です。1つ目は通信速度。115200とか9600とかのそれ。2つ目が「8bit,non parity,stopbit = 1」の意味。変える必要があればSERIAL_7E2とかにするだけ。
 3つ目がRx、4つ目がTx。テストボードと繋ぎたい番号を書きます。なんでこのピンにしたかは忘れましたが、データシートとにらめっこしていい感じのものを選びました。
 あとは

 Serial1.write((uint8_t)sendbuf, (uint8_t)numofsendbuf+1);

とかで完成! Serial1.printfとかも必要に応じて使っていきましょう。

サーボの設定

 futabaのコマンドサーボRS304は公式のサンプル(arduino用)が落ちているのでそれを真似れば動きます。ただ自分は自作したものがあるのでそれを使ってちょちょいとしました。載せようかと思ったのですが、可読性が悪いので載せません。
 今回試運転中はusbから駆動していましたが,wifiに接続したうえでサーボを1つ動かすのは安定してできました。

NTP時刻を取得する

 wifiに繋ぐところはESP32 Dev Module用のSimpleWifiServerを使えばいい感じです。中身のyourssid(パソコンでネットに繋ぐときに一覧で出てくるやつ)とyourpasswordを適当なものを入れればOKです。注意点として「GET /H」はスペースが入っていることがあります。更に脆弱性として、この「GET /H」とかの文字はpost機能を使っているので、例えばurlの末尾に直接「/GET /HGET /L」とか書いたら両方実行してしまいます。postを使うのが悪いというより自分の実力不足ゆえの脆弱性な気がしますが、とりあえずはいいかなあと今回は無視しました。
 で,NTP時刻を取得する方法はまたしてもけり君のサイトから。この方法だと時間も日にちも取得できます。
kerikeri.top
 これのTime.cppとTime.hをそのまま拝借しました。しばらくは独学で頑張っていたのですが、聞いたらスマートに解決しました。感謝。

htmlを外部に書く

 完全に他人の成果物ですが。みずほというこれまた同輩(優秀)が勝手にやってくれました(感謝してます)。arduino IDE(というかCとかC++)の#include"hoge.h"はhoge.hの中身をそのまま写したことと同じになります(プリプロセス)。それを使って、
好きなようにhtmlを書く→rubyコンパイルできる形に変更→お目当ての場所でincludeする
を行います。これによって通常のhtmlでデザインを調整し(勿論ブラウザも利用できる)、簡単にesp32に実装できるようになりました。
具体的なソースを以下にぺたり。
html.rb

#!/usr/bin/env ruby  
# coding: utf-8  
  
  
html = <<-"HTML"  
HTTP/ontent-type:text/html  
  
#{File.read(ARGV[0])}  
HTML  
  
htmldat = <<-"C"  
char* html = #{  
  html  
      .inspect  
      .gsub(/(\\n)/, "\\1\\\n")};  
C  
  
puts htmldat  
File.write("html.h", htmldat)  

使用方法はコマンドライン
./html.rb hoge.html
と打ち,出力されたhtml.hを利用するだけ。htmlを更新するためにはコマンドを叩かなければならない不便さこそありますが、デザインの修正がより柔軟にできるようになりました。特に複雑なhtmlを書きたい人にこそ有用な変更だと思います(今回の1ページだけの簡単htmlですら楽さを実感できたのですから)。

フォームに入ってきた数字をint型に収める

 別の記事にまとめます。