ESP8266 SDK環境での開発に挑戦 Wi-FiでPWM制御(技適済みWi-Fiモジュール「ESP8266」で始めるIoT入門)

oshikiri oshikiri

「ESP8266」で始めるIoT入門シリーズはこちらからお読みいただけます

IMGP1636
IMGP1602

前回に続き、SDKの解説です。
予告していたI2Sまでは、ハード的にはSRAMの追加が必要であったり、ソフト的にもかなり複雑なので、今回はPWMをスマホからコントロールする作例を説明します。

機能としてはArduino IDEでもできますが、SDKで試してみて、違いに慣れていただければと思います。

作例は簡単で実用的なものを用意しました。具体的には、スマホやPCでRGBの値をスライダーで設定、ESP8266がそれぞれの値を受信して、その値に応じてLEDを調光します。レーザー刻印したアクリル板を使って、調光式フォトスタンドを作成します。

・作成したファイル
前回のuserフォルダの
user_webserver.c
user_main.c
を変更しました。GitHubには念のためappファイダを丸ごといれてあります。
https://github.com/cerevo/techblog_ESP8266_8th
buildやESP8266への書き込みの手順は前回の記事と同じです。

・PWMの記述説明
software PWMのAPIが解説されていますので、2C-ESP8266__SDK__Programming Guide__EN_v1.3.0.pdfの7.4. PWM Relatedや、espressifサイトの[ESP8266] PWM Demo等( http://bbs.espressif.com/viewtopic.php?f=31&t=1378 )を参考にしてください。
まず、どのGPIOをPWMに割り当てるか設定します。
¥VM¥Share¥esp_iot_sdk_v1.5.2¥include¥eagle_soc.h
ファイルを参照しながら、PWM*にGPIO割り付けます。
pwm_init()で初期化します。
pwm_set_periodで周期設定、
pwm_get_dutyでH期間を設定します。
設定範囲は最小0から、最大:周期 * 1000 /45が設定値なので、1kHzの場合は、22222となります。Arduino IDEより、細かな設定が可能です。
pwm_startでpwm制御を開始します。周期はtimerが共通なので全PWM同じ設定となりますが、dutyは個別に設定可能なので明るさは各ch毎に制御できます。

さらにこれらを使った、user_light()関数が用意され便利に使用できます。
user_light()では、あらかじめPWM 5ch設定されており、PWM0-5はGPIOとモジュールpinの対応は以下になります。

ch GPIO pin num
PWM0 GPIO12 pin 4
PWM1 GPIO15 pin 6
PWM2 GPIO13 pin 5
PWM3 GPIO14 pin 3
PWM4 GPIO05 pin 14

周期1kHzでよければ
user_light_init()で初期化
user_light_restart();だけでpwm開始します。
明るさを変えるためにdutyを変えた場合は、その度に
pwm_start()する必要があります。
下記のように記述し、3chにLEDを繋ぐと同じタイミングで徐々に明るく光ります。

user_light_init();
user_light_restart();

for(;;){
num++;

if(num >= 22222){
num = 0;
}

user_light_set_duty(num, 0);
user_light_set_duty(num, 1);
user_light_set_duty(num, 2);
pwm_start();

os_delay_us(100);
}

・WebServer
user_webserver.cを参照ください。簡単に関数を説明します。
user_webserver_init関数
softAPの設定とブラウザからアクセスされるポートは80番ポートなので、80番ポートを受 信可能としてます。SERVER_SSL_ENABLE を定義すると無線LANにパスワードがかけれます(今はcerevo)

webserver_recv関数
TCPの80番ポートにアクセスされると、webserver_recv関数にコールバックされます。
SWITCH文でGETか、POSTの分岐があります。ブラウザからアクセスされた場合、GETメソッドなので先ほど記載したHTMLを返すようにしています。POSTの場合は、スライダーの値をURLエンコードする形でPOSTするように記載していますので、HTTPのボディ部のパースをしています。
・HTMLの記述
コード内ではわかりにくいので、HTML(ESP_SLIDER.html)をGitHubに用意しました。

https://github.com/cerevo/techblog_ESP8266_8th

コード上ではあくまで文字列として扱うので1行毎に””で囲うなどの加工が必要です。
コード上と比べてみてください。
注意点は、PCとESP8266がWi-FIに繋がるので、ESP8266から送信したHTMLに外部参照があると受信できません。そのため、JQeryなどは使えないことになります。
今回は、HTML5標準のスライダー機能を使ってブラウザ上のUIを表現しています。3つのスライダーを用意して0−1023で可変し、ESP8266にPOSTするときは、httpのホディ部に silder1 = xx & silder2 = xx & silder3 = xx、のように入ります。この方式をURLエンコード方式といいます。

シリアルでも通信内容を出力しているので、動作時にシリアルモニターで確認ください。
pict02
pict03

・簡単な処理の流れ
主な処理は、user_webserver.cで行っています。また、サンプルコード流用のため、使っていない機能もありますのでご了承ください。

はじめに、スマートフォンからESP8266にWi-Fi接続してください。接続情報は以下の通りです。
SSID:ESP_Cerevo
PASSSWORD:なし

その後、URL:192.168.4.1にアクセスするとESP8266が上述のHTMLを出力し、ブラウザがGETします。ブラウザのスライダーの値に変化があった場合、値を読み込み、ESP8266に一続きの文字列としてPOSTします。ESP8266は”&”をキーに文字列を解釈して分離し、slider*numに数値として格納します。
slider*num範囲は0−1024なので、dutyの範囲の0−22222に対応するよう22倍します。
pwm_set_duty(silder*_num, PWM_CHANNEL);で、duty 3ch分設定し、
pwm_start();で調光します。

user_main.cでは、
user_webserver_init()の呼び出しと、
pwmの初期化だけ行ってします。
user_light_init();
pwm_set_duty(10000, 0);

・注意点
LEDを3つ接続するとWi-Fiの消費電流に加えて多くの電流が流れるため、LDOを外付けしててもUSBバスパワーの500mAを超えてしまう可能性と、ESP8266全体のIOに流せる電流値を超えてしまう場合があります。まずはLED1個から試して、別電源か電池駆動にして3ch以上を試してください。

手元の作例では、3灯でUSBバスパワー+LDO3.3Vではリセットが掛かって動作しないこともありました。安定化電源3.3V使用時、定常的に3灯MAXで130mA程度流れていました。参考にしてピークやLEDの制限抵抗や電源設計してください。
pict04

・作例
冒頭は、娘が母親のためにデザインしたフォトフレームを自分が具現化したものです。
透明プラ板やアクリルに、レーザーカッターで刻印してライトを当てると刻印が浮かび上がるので、お手軽に楽しめます。カードゲームのお気に入りのキャラクタを飾ってエンブレムを刻印して、スマートフォンでパーソナルカラーを調光するなどもできるかと思います。
回路は単純にESPにLEDをつなぐだけですが、LEDを複数点灯する場合は、デジタルトランジスタなどをポートに追加して電流を流せるようにと、全体の電流仕様を満たす電源構成にしてください。電子工作用の汎用的なLEDであれば、単三電池2本でも3灯くらいは問題ないかと思います。

スター付き画像

pict05