差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
public:理数研究ラボ2018補助教材 [2018/08/23 16:00] suda [Arduinoを利用したフィジカルコンピューティング基礎] |
public:理数研究ラボ2018補助教材 [2018/08/23 23:41] (現在) suda [ESP8266を利用したネットワークプログラミング] |
||
---|---|---|---|
行 138: | 行 138: | ||
----- | ----- | ||
- | + | < | |
- | **音を鳴らすプログラム** | + | |
<code cpp speaker.ino> | <code cpp speaker.ino> | ||
int speaker = 9; // スピーカーをつないだピンは9番 | int speaker = 9; // スピーカーをつないだピンは9番 | ||
行 168: | 行 167: | ||
} | } | ||
</ | </ | ||
+ | < | ||
----- | ----- | ||
行 189: | 行 189: | ||
void loop() { | void loop() { | ||
- | led.setPixelColor(0, | + | led.setPixelColor(0, |
led.show(); // 設定を反映させる | led.show(); // 設定を反映させる | ||
delay(duration); | delay(duration); | ||
行 204: | 行 204: | ||
- | **ふわっと光らせるしくみ** | + | < |
<code cpp fade2.ino> | <code cpp fade2.ino> | ||
#include < | #include < | ||
行 229: | 行 229: | ||
} | } | ||
</ | </ | ||
+ | < | ||
- | ----- | + | **for文**は,繰り返し処理の書き方です.'' |
- | + | ||
- | * **for文**は,繰り返し処理の書き方です.'' | + | |
----- | ----- | ||
行 261: | 行 260: | ||
</ | </ | ||
< | < | ||
+ | |||
----- | ----- | ||
行 288: | 行 288: | ||
funkaLevel = val; // 受け取ったデータを噴火警戒レベルに設定 | funkaLevel = val; // 受け取ったデータを噴火警戒レベルに設定 | ||
- | if(funkaLevel >= 4){ // もし噴火警戒レベルが4以上なら | + | if(funkaLevel >= 4){ // もし噴火警戒レベルが4以上に設定されたら |
for(int i=0; i< | for(int i=0; i< | ||
tone(speaker, | tone(speaker, | ||
行 300: | 行 300: | ||
</ | </ | ||
- | ----- | + | **if文**という条件に応じた処理の書き方を使って,「もし新しいデータが届いていたら」行う処理を書いています.'' |
- | + | ||
- | * **if文**という条件に応じた処理の書き方を使って,「もし新しいデータが届いていたら」行う処理を書きます.'' | + | |
----- | ----- | ||
行 311: | 行 309: | ||
* <wrap hi> | * <wrap hi> | ||
- | 下のプログラムは,シリアル通信を使って,気温,噴火警戒レベル,降水量を設定できるようにしてあります(基本的な流れは上のプログラムと同じです). | + | 下のプログラムは,シリアル通信を使って,気温,噴火警戒レベル,降水量を設定できるようにしてあります(いくつか外部ファイルを読み込んでいますが,プログラムの流れは上のプログラムと同じです). |
* 0 ~ : 気温[°C] | * 0 ~ : 気温[°C] | ||
* 1000~1005 : 噴火警戒レベル(0~5) | * 1000~1005 : 噴火警戒レベル(0~5) | ||
行 321: | 行 319: | ||
{{ : | {{ : | ||
+ | < | ||
<code cpp> | <code cpp> | ||
#include " | #include " | ||
行 390: | 行 389: | ||
} | } | ||
</ | </ | ||
+ | < | ||
- | ----- | + | if文をいくつかの条件に分岐させるときは,**else文**を使います.最初のif文の後に,'' |
- | + | ||
- | * if文をいくつかの条件に分岐させるときは,**else文**を使います.最初のif文の後に,'' | + | |
- | * 一つのif文で「〜かつ〜」や「〜または〜」のような複数の条件を判定したい場合は,'' | + | |
====== ESP8266を利用したネットワークプログラミング ====== | ====== ESP8266を利用したネットワークプログラミング ====== | ||
行 403: | 行 400: | ||
</ | </ | ||
- | **ESP8266**は,小型で安価なWi-Fiモジュールです.単体でインターネットに接続することができ,Arduinoのプログラムを書き込むこともできるので,IoTの制作に最適です. | + | <WRAP center round important 60%> |
+ | 復習用に追記しました.自宅でプログラムを書き換えるときなどの参考にしてください.(8/ | ||
+ | </ | ||
- | [[https:// | + | **ESP8266**は,小型で安価なWi-Fiモジュールです.単体でインターネットに接続することができ,Arduinoのプログラムを書き込むこともできるので,IoTの制作に最適です.電源供給や,プログラムの書き換えにはmicroBタイプのUSBケーブルが必要です. |
- | [[http:// | + | |
+ | * [[https:// | ||
+ | * [[https:// | ||
----- | ----- | ||
- | **取得したい場所の2つのURLを取得する** | + | <wrap lo> |
- | データを取得するプログラムはすでにウェブ上に準備してあり,ESP8266からアクセスすることで,気温,噴火警戒レベル,降水量を取得することができます.ただし場所によって降水量が取得できない箇所もあるのでご注意ください.気温,降水量はtenki.jpのアメダスから,噴火レベルはtenki.jpの火山情報から取得します.ESP8266に書き込むArduinoのプログラムの中に,取得したい場所のURLを記述するので,Webブラウザから | + | **Wi-Fiに接続するには** |
+ | |||
+ | 普段から,インターネットを使うとき,Wi-Fiに接続することが多いと思います.Wi-Fiに接続するには,**SSID**というネットワークの名前と,接続するための**パスワード**が必要です.今回は,プログラムの中にこの2つを直接記述します.ワークショップでは,研究室のWi-Fiに接続しましたが,自宅のWi-Fiに接続する場合は,この2つを変更する必要があります. | ||
+ | |||
+ | **Webから情報を取得するには** | ||
+ | |||
+ | 普段,ChromeやSafariなどのWebブラウザからウェブ上の情報を取得するとき,**URL**というウェブ上の場所を特定する文字列によって,アクセスを行っています.IoTデバイスから,ウェブ上の情報を取得するときも同様で,今回は,プログラムの中で必要なURLを作ります.データを取得するプログラムはすでにウェブ上にプログラムが準備してあり,ESP8266からアクセスすることで,気温,噴火警戒レベル,降水量を取得することができます. | ||
+ | |||
+ | プログラムのURL:%%http:// | ||
+ | |||
+ | **取得したい場所の2つのURLを用意する** | ||
+ | |||
+ | 準備したウェブ上のプログラムには,取得したい場所のURLを送って,特定の場所の情報が取得できるようにしてあります.取得したい場所のURLは,気温,降水量はtenki.jpのアメダスから,噴火レベルはtenki.jpの火山情報からそれぞれ取得します.Webブラウザから | ||
https:// | https:// | ||
- | にアクセスし,自分の取得したい場所を選択しましょう.例として,さいたま市のアメダスページにしてみます.次に噴火情報に関してはさいたま市に関しては特に近くに情報を持つ山がないので,デフォルトの富士山のままにしておきます(この情報は使いません).まとめると以下の2つです. | + | にアクセスし,自分の取得したい場所を選択しましょう.場所によって降水量が取得できない箇所もあるのでご注意ください. |
+ | 例として,さいたま市のアメダスページにしてみます.次に噴火情報に関してはさいたま市は特に近くに情報を持つ山がないので,デフォルトの富士山のままにしておきます(この情報は使いません).まとめると,数字部分だけが異なる以下の2つのようなURLが用意できていればOKです. | ||
- | * <アメダスurl>:https:// | + | <アメダスurl>:https:// |
- | | + | <火山情報url>:http:// |
- | プログラムに書く前に正しくデータが取得できるかはPCのブラウザからでも確認できます.以下のURLはクリックすると,さいたま市の気温,富士山の噴火警戒レベル,さいたま市の降水量が確認できます.自分の取得したい場所に置き換えて,Webブラウザのアドレスバーに入力してアクセスしてみましょう. | + | プログラムに記述する前に正しくデータが取得できるかはPCのブラウザからでも確認できます.以下のURLはクリックすると,さいたま市の気温,富士山の噴火警戒レベル,さいたま市の降水量が確認できます.自分の取得したい場所に置き換えて,Webブラウザのアドレスバーに入力してアクセスしてみましょう. |
http:// | http:// | ||
行 432: | 行 445: | ||
----- | ----- | ||
- | **ESP8266に書き込む** | + | **ESP8266に書き込むプログラム** |
- | <wrap em> | + | <wrap em> |
- | {{ : | + | |
- | このプログラムの以下の部分を,自分の取得したい地域のアメダスurl,火山情報urlに書き換えます.'' | + | このプログラムをダウンロードしてsketch_final.ino開いたら,fujichanClient.hというタブを選択してください. |
+ | |||
+ | {{ : | ||
+ | |||
+ | 以下の,Wi-Fiネットワーク設定と,取得したい場所のアメダス・火山情報のURLの部分を,上で確認したものに書き換えます. | ||
<code cpp> | <code cpp> | ||
+ | // Wi-Fiネットワーク設定 | ||
+ | const char* ssid = " | ||
+ | const char* pass = " | ||
+ | |||
+ | // Webサーバ上のプログラムのURL | ||
+ | const char* host = " | ||
+ | const char* path = "/ | ||
+ | |||
// 取得したい場所のアメダス・火山情報のURL | // 取得したい場所のアメダス・火山情報のURL | ||
const char* url_temp = " | const char* url_temp = " | ||
行 445: | 行 469: | ||
</ | </ | ||
- | **ESP8266書き込み設定** | + | このプログラムでは,指定したSSIDとパスワードを使ってWi-Fiへ接続する'' |
+ | |||
+ | < | ||
+ | <code cpp> | ||
+ | #include " | ||
+ | #include < | ||
+ | #include " | ||
+ | #include " | ||
+ | #include " | ||
+ | |||
+ | myNeoPixel led = myNeoPixel(1, | ||
+ | |||
+ | // Wi-Fiネットワーク設定 | ||
+ | const char* ssid = " | ||
+ | const char* pass = " | ||
+ | |||
+ | // Webサーバ上のプログラムのURL | ||
+ | const char* host = " | ||
+ | const char* path = "/ | ||
+ | |||
+ | // 取得したい場所のアメダス・火山情報のURL | ||
+ | const char* url_temp = " | ||
+ | const char* url_vol = " | ||
+ | |||
+ | // Wi-Fiへ接続する関数 | ||
+ | void connect() { | ||
+ | Serial.println(); | ||
+ | Serial.println(); | ||
+ | Serial.print(" | ||
+ | Serial.println(ssid); | ||
+ | WiFi.begin(ssid, | ||
+ | while (WiFi.status() != WL_CONNECTED) { | ||
+ | // | ||
+ | led.fadeIn(50, | ||
+ | led.fadeOut(500); | ||
+ | Serial.print(" | ||
+ | } | ||
+ | Serial.println(); | ||
+ | Serial.print(" | ||
+ | Serial.print(WiFi.localIP()); | ||
+ | Serial.println(" | ||
+ | } | ||
+ | |||
+ | // Webサーバからデータを取得する関数 | ||
+ | void update(float* _temperature, | ||
+ | // (1)Webサーバーに接続する(TCP接続) | ||
+ | Serial.println(); | ||
+ | Serial.print(" | ||
+ | Serial.println(host); | ||
+ | WiFiClient client; | ||
+ | const int httpPort = 80; // HTTP通信のポート番号は80 | ||
+ | if (!client.connect(host, | ||
+ | Serial.println(" | ||
+ | return; | ||
+ | } | ||
+ | // (2)要求するファイルのURLを用意する | ||
+ | String url = path; | ||
+ | url += "? | ||
+ | url += url_temp; | ||
+ | url += "& | ||
+ | url += url_vol; | ||
+ | Serial.print(" | ||
+ | Serial.println(url); | ||
+ | // (3)HTTPリクエストをWebサーバーに送信する | ||
+ | client.print(String(" | ||
+ | " | ||
+ | " | ||
+ | unsigned long timeout = millis(); | ||
+ | while (client.available() == 0) { | ||
+ | if (millis() - timeout > 5000) { | ||
+ | Serial.println(">>> | ||
+ | client.stop(); | ||
+ | return; | ||
+ | } | ||
+ | } | ||
+ | // (4)HTTPレスポンスから必要なデータを取り出す | ||
+ | while (client.available()) { | ||
+ | String line = client.readStringUntil(' | ||
+ | // | ||
+ | // 気温、噴火レベル、降水量の順番で並んでおり、カンマで区切られています。 | ||
+ | int commaIndex = line.indexOf("," | ||
+ | int lastCommmaIndex = line.lastIndexOf("," | ||
+ | if (commaIndex >= 0) { | ||
+ | *_temperature = line.substring(0, | ||
+ | *_funkaLevel = line.substring(commaIndex + 1).toInt(); | ||
+ | *_precipitation = line.substring(lastCommmaIndex + 1).toFloat(); | ||
+ | } | ||
+ | } | ||
+ | Serial.println(); | ||
+ | Serial.println(" | ||
+ | |||
+ | Serial.print(" | ||
+ | Serial.println(*_temperature); | ||
+ | Serial.print(" | ||
+ | Serial.println(*_funkaLevel); | ||
+ | Serial.print(" | ||
+ | Serial.println(*_precipitation); | ||
+ | |||
+ | Serial.println(">>> | ||
+ | } | ||
+ | </ | ||
+ | < | ||
+ | |||
+ | プログラムが変更できたら,メニューバーの[ツール]を開いて,ボードやシリアルポートの設定が以下のようになっているか確認して,ESP8266にArduinoプログラムの書き込みを行いましょう.Arduino Unoよりも時間がかかるので注意してください. | ||
{{ : | {{ : | ||
- | シリアルモニターを開いて,インターネットから情報が取得できていればOKです. | + | シリアルモニターを開いて,インターネットから取得した,気温,噴火警戒レベル,降水量の情報が表示されればOKです.この情報を,先ほど作ったデータに応じた音や光の変化の処理に反映させましょう.(スピーカーのピン番号が9から16に変わっています.直接ピン番号を指定する場合は注意) |
- | データの更新はデフォルトだと5分おきに行われます. | + | |
- | シリアルモニターから「3001」を送ると,手動で更新できます. | + | |
----- | ----- | ||
- | **プログラムを合わせて完成させる** | + | **プログラムを一つにまとめる** |
+ | |||
+ | ダウンロードしたプログラム(sketch_final)の大部分は,先ほどシリアルモニターでデータを送ったプログラム(sketch_simpleFujichanDev)と同じです.< | ||
+ | |||
+ | '' | ||
+ | |||
+ | <code cpp> | ||
+ | #include " | ||
+ | |||
+ | #define UPDATE_INTERVAL 60*5 // 更新間隔[秒] | ||
+ | |||
+ | float temperature | ||
+ | int | ||
+ | float precipitation = 0; // 降水量(単位は[mm/ | ||
+ | |||
+ | void setup() { | ||
+ | led.setup(); | ||
+ | Serial.begin(115200); | ||
+ | Serial.println(" | ||
+ | |||
+ | // Wi-Fiへ接続する関数 | ||
+ | connect(); | ||
+ | // Webサーバからデータを取得する関数 | ||
+ | update(& | ||
+ | update2(); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | |||
+ | ~中略~ | ||
+ | |||
+ | if ( metro(UPDATE_INTERVAL) == true ) { // 更新時間が来たら | ||
+ | update(& | ||
+ | update2(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void update2(){ | ||
+ | /* 気温が更新された時の処理.ここから */ | ||
+ | |||
+ | |||
+ | /* ここまで */ | ||
+ | } | ||
+ | |||
+ | // 更新時間を教えてくれる関数 | ||
+ | static unsigned long int time = 0; | ||
+ | bool metro(int seconds) { | ||
+ | if ( (millis() - time) > seconds | ||
+ | time = millis(); | ||
+ | return true; | ||
+ | } | ||
+ | else { | ||
+ | return false; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ----- | ||
+ | |||
+ | **補足:データ更新の間隔** | ||
+ | |||
+ | データ更新の間隔は,一番下の更新時間を教えてくれる関数で管理しています.'' | ||
+ | |||
+ | < | ||
+ | #define UPDATE_INTERVAL 60*5 // 更新間隔[秒] | ||
+ | </ | ||
+ | |||
+ | 手動で情報更新する場合は,シリアルモニターから「3001」を送信します. | ||
+ | |||
+ | ----- | ||
+ | |||
+ | **補足:開発環境を整える** | ||
+ | |||
+ | Arduino IDEでESP8266を開発するためには,以下の作業が必要です.自宅のWi-Fiに接続するにはArduinoプログラムを書き換える必要があるので,参考にしてください. | ||
+ | |||
+ | - macOSの場合はメニューバーの[Arduino]から[Preference],Windowsの場合はメニューバーの[ファイル]から[環境設定]を開いて,[追加のボードマネージャのURL]に,以下のURLを入力して[OK]を押します.'' | ||
+ | - メニューバーの[ツール]から[ボード]の中にある[ボードマネージャ]を開いて,検索バーに「ESP8266」と入力し,該当するものを[インストール]します.選択できるボードの一覧に「ESP8266 Modules」が出ていれば,環境構築は完了です.※出ない場合は,一度Arduino IDEを終了すると反映されます. | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | 参考リンク:[[http:// | ||
+ | |||
+ | ----- | ||
- | 先ほど作ったデータに応じた音や光の変化(sketch_simpleFujichanDev)を,インターネットからデータを取得するプログラム(sketch_simpleFujichan)に移動させれば,プログラムは完成です. | + | その他,気軽にメールなどで質問してください.\\ |
+ | 9192hs@gmail.com(須田)\\ | ||
+ | studio@tetsuakibaba.jp(研究室) | ||
====== 撮影 ====== | ====== 撮影 ====== | ||
担当:石曽根 | 担当:石曽根 |