public:理数研究ラボ2018補助教材

はじめに

本ページは首都大学東京「理数研究ラボ」講座である「アンビエントメディアIoTデバイスのデザインと開発」の補助教材ページです.あくまで補助教材ですので,ここに掲載されている内容が講座内容の全範囲を網羅しているわけではないことに注意してください.

FUJICHAN(フジチャン)は富士山頂の気温と噴火警告レベルを呈示するアンビエントIoTデバイスです.災害情報に意識を向けることは重要と知りながらも,日々の日常ではつい忘れてしまいがちです.そこで私たちは山岳信仰文化を出発点として,インターネット接続とLEDを活用してそれらの情報に自然とアクセス可能なデバイスを開発しました.

FUJICHANは常時インターネットに接続し,気象情報や噴火レベル情報をリアルタイムで取得します.富士山では噴火警告レベルが発表されており,FUJICHANではそのレベルに応じて異なる色や音を出力します.噴火警告レベルは気象庁策定に基づく5段階表示で,対応色がデバイス底面LEDで示されます.富士山頂の気温は専用に作成した気温マップにもとづき,デバイス上部のLED色にて示されます. このプロジェクトを通じ,災害情報を日常の中でより自然に取得可能な仕組みづくりを私たちは目指しています.

Fuji-chan was created as a way of visualising hazard information in an unconventional way. The device provides information visually through LEDs at the top (indicating temperature) and base (indicating volcanic eruption), with an aural alarm also for volcano eruption warnings. By communicating this information simply, virtually anyone can understand the warnings. We also hope that this device promotes the idea of an “Internet of Beautiful Things”, with IoT technology being applied to aesthetically pleasing interactive works.

本研究プロジェクトは2015年よりPaul Haimes(現在産総研所属)と一緒に実施したアンビエントな災害情報提示プロジェクトです. 日常に溶け込むIoT災害デバイスを目指しています.Paulが実施したプロジェクトは

上記,Fujichanの開発フレームワークをそのまま流用し,日本国内の気温や天候を呈示するデバイスを制作します.Fujichanの場合は,富士山頂の気温と噴火レベルでしたが,例えば

  • 実家の今の天気
  • 好きな場所の今の天気
  • 好きな山の今の天気
  • おばあちゃん家の今の気温

等をそれぞれのオブジェを模した形状でデザインして,日常の中で自然な情報呈示を実現するデバイスを制作します.情報というとテレビやラジオ,ウェブニュース,SNS等のメディアを考えると思いますが,これらは一般的にはユーザが能動的に情報取得を行うメディアとして位置づけられています.一方で,風が吹くと音がなる風鈴,風見鶏,よる冷えると凍結する水たまり,といった普段何気なく目にしているものにも,どの程度の風速で風が吹いているか,風向きはどちらか,昨晩はどの程度気温が下がったのか,といった情報が含まれており,生活する中で実は私達は様々な情報を受動的に取得してます.このような後者の性質を持つメディアをアンビエントメディアと呼び,本講座ではアンビエントメディアとIoT(Internet Of Things)を組み合わせたデバイスを制作します.

日付 時間 内容 主担当 概要
8月20日 9:30 - 10:20 研究室の紹介,導入 馬場 活動や研究内容を簡単に紹介します.
10:20-10:30 休憩(パソコン割当等) ワークショップで使用するコンピュータの割当を行います.
10:30-12:00 Fusion360の基礎 小澤,吉野 3次元モデリングソフトウェアの講習
12:00-13:30 お昼
13:30-15:00 CADによるデバイスデザイン 小澤,吉野 実際に自分たちでデザインし,モデルを作成します.
15:00-16:30 Arduino基礎(Lチカ,スピーカ等基礎) 須田 プログラムの基礎とハードウェアを学びます
8月21日 9:30-12:00 ESP8266を利用したネットワークプログラミング 須田 Wifiとマイクロコントローラのプログラムを実践します
12:00-13:30 お昼
13:30-15:00 デバイスと基板の組み立て 須田 fusion360で作成,3Dプリントしたデータと基板を組み立てます
15:00-16:30 撮影(物撮り,インタビュー) 石曽根 制作物をアピールする映像を制作します

Fusion360によるデバイスのデザイン

主担当:吉野,小澤

目標:Fusion360に関する最低限必要な操作方法と基本的な内容を学習し,今回制作するデバイスのデザインができるようになること.3Dプリンタで扱える形式のデータを作成し,3Dプリント出力を体験すること.

当日のFusion360によるデザインの流れ(仮)

googleスライドはここから

3次元モデリングソフトウェアであるFusion360を利用して,デバイスをデザインします.作成したモデルはその日のうちに3Dプリンタで出力し,明日の組み立ての際に利用します.Fusion360はAutodesk社が提供するモデリングソフトウェアで,教育機関に所属する学生であれば無料で利用することができるので,興味のある方は事前に自宅のPC等でソフトウェアを扱ってみるとよいです.すでにウェブ上に多くの教材があります.


ベース部分のモデル

Arduinoを利用したフィジカルコンピューティング基礎

担当:須田,馬場

目標:Arduinoを利用して,プログラミングと電子工作の基本を学び,フィジカルコンピューティング,プロトタイピングといった,実際に動くものを作る上で重要な考え方に触れる.

復習用に追記を行いました(8/23)

フィジカルコンピューティングとは,センサやアクチュエータ(出力部品)を使って,私たちの身の回りの物理的な世界と,コンピュータ上にあるような情報の世界をつなぐことです.今回は,Fujichanデバイスをベースに,日常の中で自然に情報提示するアンビエントメディアを制作します.LEDやスピーカーを使って,光や音といった環境の情報をコントロールします.

Arduinoは,エンジニアだけでなく,デザイナーやアーティストでも,マイクロコントローラ(小さなコンピュータ)を簡単に使えるように作られた汎用マイコンボードです.PC上でプログラムを記述し,それをUSBケーブルで接続されたボードに転送すると,ボード上のマイクロコントローラがプログラム通りに動作します.組み込みと呼ばれる,PCを利用しない小さなデバイスでは,一般的な開発手法です.

https://www.arduino.cc/

Arduinoには,性能や大きさによって様々な種類がありますが,このワークショップでは最も一般的なArduino Unoを使います.購入する場合は,周辺機器が揃っているArduinoをはじめようキット - SWITCH-SCIENCEなどがおすすめです.Arduino IDEは,こちらからダウンロードできます.(8/23追記)

LEDをチカチカさせるプログラム(Lチカ)

sketch_blink.ino
int led = 13;              // ledにつながっているピンは13番
 
// setup()は,最初に一度だけ実行されます.
void setup() {
  pinMode(led, OUTPUT);    // ledのピンを出力モードに設定
}
 
// loop()は,繰り返し実行されます.
void loop() {
  digitalWrite(led, HIGH); // ledのピンをHIGHにして点灯
  delay(1000);             // 1000ミリ秒(=1秒)停止
  digitalWrite(led, LOW);  // ledのピンをLOWにして消灯
  delay(1000);             // 1000ミリ秒(=1秒)停止
}

プログラムを書き込むとき,ボードとシリアルポートが正しく選択されているか注意!


  • プログラミングに使える文字は,半角の英数字と記号です.
  • プログラムは基本的に,上から順番に実行されていきます.
  • Arduinoのプログラムには,必ずsetup()loop()が一つずつ必要です.setup(){ }の中は最初に一度だけ実行され,loop(){ }の中は繰り返し実行されます.
  • //で始まる行はコメントといい,その行はそこから改行されるまで無視されます.
  • int led = 13;は,ledという名前の変数に13という値を記憶させています.変数を作るときは,データの種類を表すというものを指定する必要があり,整数が記憶できるint,小数が記憶できるfloatなどがあります.一度作った変数は,変数の名前だけで使うことができ,=をつけて値を書き換えるなどもできます.
  • pinMode()digitalWrite()delay()のように,後ろに( )がついているものは関数といいます.delay(1000)は「1000ミリ秒(=1秒)停止する」という命令で( )の中の数字(引数といいます)によって,実行結果が変わります.Arduinoには様々な関数が用意されており,最初はこれらを組み合わせてプログラムを書いていきます.

電子工作

Arduinoのピンに様々な電子部品を差し込んで,プログラムで制御できる電子回路を組むことができます.ブレッドボードやジャンプワイヤを使って,半田づけをする必要なく,電子回路を試すことができます.プログラムでも電子回路でも,何度も試作を繰り返して,物を作っていく手法をプロトタイピングといいます.


音を鳴らすプログラム

speaker.ino
int speaker = 9;    // スピーカーをつないだピンは9番
int duration = 500; // 音の長さ
 
void setup() {
 
}
void loop() {
  tone(speaker, 262); // ド
  delay(duration);
  tone(speaker, 294); // レ
  delay(duration);
  tone(speaker, 330); // ミ
  delay(duration);
  tone(speaker, 349); // ファ
  delay(duration);
  tone(speaker, 392); // ソ
  delay(duration);
  tone(speaker, 440); // ラ
  delay(duration);
  tone(speaker, 494); // シ
  delay(duration);
  tone(speaker, 523); // ド
  delay(duration);
  noTone(speaker); // 音を止める
  delay(duration);
}


フルカラーLEDモジュールを使う

フルカラーLEDモジュールを使うには,ライブラリを読み込む必要があります.ライブラリの追加方法などは以下を参照してみてください. http://ws.tetsuakibaba.jp/doku.php?id=arduino:出力基礎:led

複数のLEDの同時制御なども簡単にできますが,以下のプログラムでは1つのLEDに色を設定し,反映させる関数を紹介します.

neoPixel.ino
#include <Adafruit_NeoPixel.h> // ライブラリを読み込む
 
Adafruit_NeoPixel led = Adafruit_NeoPixel(1, 4, NEO_GRB + NEO_KHZ800); // 制御するLEDの数1と,つないだピンの番号4を指定
 
int duration = 1000; // 点灯時間
 
void setup() {
  led.begin(); // LEDを初期化
}
 
void loop() {
  led.setPixelColor(0, led.Color(50,0,0)); // 1つめのLED(0番)を赤色に設定.各色の最大値は255
  led.show(); // 設定を反映させる
  delay(duration);
  led.setPixelColor(0, led.Color(0,50,0)); // 緑
  led.show();
  delay(duration);
  led.setPixelColor(0, led.Color(0,0,50)); // 青
  led.show();
  delay(duration);
}

ふわっと光らせるしくみ

fade2.ino
#include <Adafruit_NeoPixel.h>
 
Adafruit_NeoPixel led = Adafruit_NeoPixel(1, 4, NEO_GRB + NEO_KHZ800);
 
void setup() {
  led.begin();
}
 
void loop() {
  // 変数iの初期値は0,50より小さければ繰り返す.iは繰り返すたびに1ずつ増える.
  for(int i=0; i<50; i++){
    led.setPixelColor(0, led.Color(i, i, i));
    led.show();
    delay(10); // 10ミリ秒停止
  }
  // 変数iの初期値は50,0より大きければ繰り返す.iは繰り返すたびに1ずつ減る.
  for(int i=50; i>0; i--){
    led.setPixelColor(0, led.Color(i, i, i));
    led.show();
    delay(10);
  }
}

for文は,繰り返し処理の書き方です.( )の中で変化する値の初期値,繰り返しを続ける条件,値の変化のしかたの3つを設定し,条件が満たされている間{ }の中を実行します.


Fujichan用の色と時間を指定してLEDをふわっと光らせるプログラム

Fujichanのプログラムでは,色と時間を指定してLEDをふわっと光らせるプログラムを用意しています.Adafruit_NeoPixelとしていたところが,myNeoPixelになっているのは,読み込んだ別ファイルで機能を追加しているからです.

sketch_fade.zip

#include "myNeoPixel.h" // 別ファイルを読み込む
 
myNeoPixel led = myNeoPixel(1, 4); // 制御するLEDの数1と,つないだピンの番号4を指定
 
void setup() {
  led.setup(); // ledの初期設定を行う
}
 
void loop() {
  led.fadeIn(50, 0, 0, 500); // 500ミリ秒かけて赤
  led.fadeOut(500);          // 500ミリ秒かけて消灯
  led.fadeIn(0, 50, 0, 500);
  led.fadeOut(500);
  led.fadeIn(0, 0, 50, 500);
  led.fadeOut(500);
}


データによって変化させる(8/23追記)

複雑なものの開発では,最終的に目指す機能をいくつかに切り分けて開発し,最後にまとめるという開発手法が一般的です.IoTデバイスはインターネットからデータを取得しますが,まずはPCからデータを送ってそれに応じた音や光の変化を検討します.

これまでUSBケーブルを通して,プログラムの書き込みを行なっていましたが,シリアル通信というデータの送受信を行うこともできます.以下のプログラムをArduinoに書き込んだら,ツールバー右にある虫眼鏡マークからシリアルモニターを開きます.通信速度を115200に設定して,数値を入力して送信すると,Arduinoプログラム上の噴火警戒レベルが設定できます.

serial1.ino
int speaker = 9;
 
int funkaLevel = 1; // 噴火警戒レベル(0~5)を記憶する変数を用意
 
void setup() {
  Serial.begin(115200);    // シリアル通信を開始する
  Serial.println("START"); // シリアルモニターに表示
}
 
void loop() {
 
  if( Serial.available() > 0 ){      // もしデータが届いていたら
    float val = Serial.parseFloat(); // 変数を用意して受け取る
 
    Serial.println(val); // 受け取ったデータを表示
 
    funkaLevel = val; // 受け取ったデータを噴火警戒レベルに設定
 
    if(funkaLevel >= 4){               // もし噴火警戒レベルが4以上に設定されたら
      for(int i=0; i<funkaLevel; i++){ // 噴火警戒レベルの数だけ警告音を鳴らす
        tone(speaker, 500);
        delay(400);
        noTone(speaker);
        delay(100);
      }
    }
  }
}

if文という条件に応じた処理の書き方を使って,「もし新しいデータが届いていたら」行う処理を書いています.ifで始まる文は,( )で囲った条件が満たされたとき,{ }で囲われた部分の処理を実行します.


アンビエントメディアとしてのデバイスをデザインするとき,たとえば次のようなことをどう設計するかが重要です.

  • 気温によって,LEDがどんな色に光るか.
  • データが更新されたとき,どんな変化をするか.

下のプログラムは,シリアル通信を使って,気温,噴火警戒レベル,降水量を設定できるようにしてあります(いくつか外部ファイルを読み込んでいますが,プログラムの流れは上のプログラムと同じです).

  • 0 ~ : 気温[°C]
  • 1000~1005 : 噴火警戒レベル(0~5)
  • 2000~ : 降水量[mm/h](プログラムは-2000したを受け取る)
  • 4001 : LEDもスピーカーもOFF

このプログラムを使って,データに応じて情報を提示するプログラムを書いてみます.まずは,これまでにやった,LEDを制御するプログラムの書き方を参考に,気温データを使ってLEDの色を変化させるプログラムを書いてみましょう.噴火警報レベルは,レベル4以上のときレベルの数だけ警報を鳴らすプログラム,降水量は,Fujichan用の雨音を鳴らすプログラムが,あらかじめ動くようにしてあります.

sketch_simplefujichandev.zip

sketch_simplefujichandev.ino

#include "myNeoPixel.h"        // Fujichan用のLED制御プログラム
#include "rain.h"              // Fujichanの雨音プログラム
#include "temperature2Color.h" // Fujichanの気温を色に変換するプログラム
 
myNeoPixel led = myNeoPixel(1, 4); // ledの数は1つ,LEDにつないだピンは4番
// int speaker = 9; // rain.hに書いてあるので,ここでは書かない
 
float temperature   = 0; // 気温(単位は[°C])
int   funkaLevel    = 0; // 噴火警戒レベル
float precipitation = 0; // 降水量(単位は[mm/h])
 
void setup() {
  led.setup();             // LEDの初期設定
  Serial.begin(115200);    // シリアル通信を開始する
  Serial.println("START"); // シリアルモニターに"START"と表示
}
 
void loop() {
  if ( Serial.available() > 0 ) {    // もしデータが届いていたら
    float val = Serial.parseFloat(); // 変数を用意して取り出す
    if ( val < 1000 ) {  // 受け取ったデータが1000より小さいなら
      temperature = val; // 受け取ったデータを気温に設定
      // ここに,変数temperatureを使って,気温が更新された時の処理を書いてみましょう
      /* 気温が更新された時の処理.ここから */
 
 
 
 
 
      /* ここまで */
    }
    else if ( val >= 1000 && val < 2000) { // 受け取ったデータが1000以上かつ2000より小さいなら
      funkaLevel = val - 1000.0;           // 受け取ったデータから1000引いた数を噴火警戒レベルに設定
      // ここに,噴火警戒レベルが更新された時の処理
      if(funkaLevel >= 4){               // もし噴火警戒レベルが4以上なら
        for(int i=0; i<funkaLevel; i++){ // 噴火警戒レベルの数だけ警告音を鳴らす
          tone(speaker, 500);
          delay(400);
          noTone(speaker);
          delay(100);
        }
      }
    }
    else if ( 2000 <= val && val < 3000 ) { // 受け取ったデータが2000以上なら
      precipitation = val - 2000.0;         // 受け取ったデータから2000引いた数を降水量に設定
      // ここに,降水量が更新された時の処理
    }
    else if ( (int)val == 4001 ) { // 受け取ったデータが4001なら
      led.fadeOut(500);            // LEDを消す
      precipitation = 0.0;         // 雨音を止める
      return;
    }
    else { // それ以外なら何もしない
      return;
    }
    // シリアルモニタに3つのデータを表示
    Serial.println();
    Serial.print("temperature: ");
    Serial.println(temperature);
    Serial.print("volcano warning level: ");
    Serial.println(funkaLevel);
    Serial.print("precipitation: ");
    Serial.println(precipitation);
  }
  makeRainSound(precipitation); // Fujichan用の雨音を鳴らす関数
  delay(1);
}

if文をいくつかの条件に分岐させるときは,else文を使います.最初のif文の後に,else if( )のようにif文と組み合わせて書くことで,別の条件が決められます.一つのif文で「〜かつ〜」や「〜または〜」のような複数の条件を判定したい場合は,( )の中の条件を&&(かつ)や||(または)で区切ります.

ESP8266を利用したネットワークプログラミング

担当:須田,馬場

目標:ネットワーク上にあるデータ(気象庁データ)を取得し,その情報をプログラム内で再構成して,光や音に変換して提示することで,アンビエントメディアやIoT(Internet of Things)における情報のあり方を考える.

復習用に追記しました.自宅でプログラムを書き換えるときなどの参考にしてください.(8/23)

ESP8266は,小型で安価なWi-Fiモジュールです.単体でインターネットに接続することができ,Arduinoのプログラムを書き込むこともできるので,IoTの制作に最適です.電源供給や,プログラムの書き換えにはmicroBタイプのUSBケーブルが必要です.


ESP8266は,Wi-Fi通信を用いた様々な使い方があります.Arduinoにも,メニューバーの[ファイル]から開ける[スケッチ例]に,サンプルプログラムが非常に多く用意されています.Fujichanのような使い方の,基本的なプログラムは[ESP8266WiFi]の中の[WiFiClient]というサンプルを参照してください.

Wi-Fiに接続するには

普段から,インターネットを使うとき,Wi-Fiに接続することが多いと思います.Wi-Fiに接続するには,SSIDというネットワークの名前と,接続するためのパスワードが必要です.今回は,プログラムの中にこの2つを直接記述します.ワークショップでは,研究室のWi-Fiに接続しましたが,自宅のWi-Fiに接続する場合は,この2つを変更する必要があります.

Webから情報を取得するには

普段,ChromeやSafariなどのWebブラウザからウェブ上の情報を取得するとき,URLというウェブ上の場所を特定する文字列によって,アクセスを行っています.IoTデバイスから,ウェブ上の情報を取得するときも同様で,今回は,プログラムの中で必要なURLを作ります.データを取得するプログラムはすでにウェブ上にプログラムが準備してあり,ESP8266からアクセスすることで,気温,噴火警戒レベル,降水量を取得することができます.

プログラムのURL:http://tetsuakibaba.jp/test/fuji-chan.php

取得したい場所の2つのURLを用意する

準備したウェブ上のプログラムには,取得したい場所のURLを送って,特定の場所の情報が取得できるようにしてあります.取得したい場所のURLは,気温,降水量はtenki.jpのアメダスから,噴火レベルはtenki.jpの火山情報からそれぞれ取得します.Webブラウザから

https://tenki.jp/

にアクセスし,自分の取得したい場所を選択しましょう.場所によって降水量が取得できない箇所もあるのでご注意ください. 例として,さいたま市のアメダスページにしてみます.次に噴火情報に関してはさいたま市は特に近くに情報を持つ山がないので,デフォルトの富士山のままにしておきます(この情報は使いません).まとめると,数字部分だけが異なる以下の2つのようなURLが用意できていればOKです.

<アメダスurl>:https://tenki.jp/amedas/3/14/43241.html
<火山情報url>:http://www.tenki.jp/bousai/volcano/detail-53.html

プログラムに記述する前に正しくデータが取得できるかはPCのブラウザからでも確認できます.以下のURLはクリックすると,さいたま市の気温,富士山の噴火警戒レベル,さいたま市の降水量が確認できます.自分の取得したい場所に置き換えて,Webブラウザのアドレスバーに入力してアクセスしてみましょう.

http://tetsuakibaba.jp/test/fuji-chan.php?url_temp=https://tenki.jp/amedas/3/14/43241.html&url_vol=http://www.tenki.jp/bousai/volcano/detail-53.html

http://tetsuakibaba.jp/test/fuji-chan.php?url_temp=<アメダスurl>&url_vol=<火山情報url>

ESP8266に書き込むプログラム

最終ファイルsketch_final.zip

このプログラムをダウンロードしてsketch_final.ino開いたら,fujichanClient.hというタブを選択してください.

以下の,Wi-Fiネットワーク設定と,取得したい場所のアメダス・火山情報のURLの部分を,上で確認したものに書き換えます.

// Wi-Fiネットワーク設定
const char* ssid = "********";
const char* pass = "********";
 
// Webサーバ上のプログラムのURL
const char* host = "tetsuakibaba.jp";
const char* path = "/test/fuji-chan.php";
 
// 取得したい場所のアメダス・火山情報のURL
const char* url_temp = "https://tenki.jp/amedas/5/25/50066.html"; // Mt.Fuji
const char* url_vol = "http://tenki.jp/bousai/volcano/314/index.html"; // Mt.Fuji

このプログラムでは,指定したSSIDとパスワードを使ってWi-Fiへ接続するconnect()という関数と,指定したURLを使ってWebサーバからデータを更新するupdate()という関数を用意しています.update()では,HTTPというウェブでの情報のやり取りに広く使われている通信の処理を,プログラム上で記述しています.

fujichanClient.h

#include "Arduino.h"
#include <ESP8266WiFi.h>
#include "myNeoPixel.h"
#include "rain.h"
#include "temperature2Color.h"
 
myNeoPixel led = myNeoPixel(1, 4);
 
// Wi-Fiネットワーク設定
const char* ssid = "********";
const char* pass = "********";
 
// Webサーバ上のプログラムのURL
const char* host = "tetsuakibaba.jp";
const char* path = "/test/fuji-chan.php";
 
// 取得したい場所のアメダス・火山情報のURL
const char* url_temp = "https://tenki.jp/amedas/5/25/50066.html"; // Mt.Fuji
const char* url_vol = "http://tenki.jp/bousai/volcano/314/index.html"; // Mt.Fuji
 
// Wi-Fiへ接続する関数
void connect() {
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    //delay(500);
    led.fadeIn(50, 50, 50, 500);
    led.fadeOut(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("WiFi connected ( IP address: ");
  Serial.print(WiFi.localIP());
  Serial.println(" )");
}
 
// Webサーバからデータを取得する関数
void update(float* _temperature, int* _funkaLevel, float* _precipitation) {
  // (1)Webサーバーに接続する(TCP接続)
  Serial.println();
  Serial.print("connecting to ");
  Serial.println(host);
  WiFiClient client;
  const int httpPort = 80; // HTTP通信のポート番号は80
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  // (2)要求するファイルのURLを用意する
  String url = path;
  url += "?url_temp=";
  url += url_temp;
  url += "&url_vol=";
  url += url_vol;
  Serial.print("Requesting URL: ");
  Serial.println(url);
  // (3)HTTPリクエストをWebサーバーに送信する
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }
  // (4)HTTPレスポンスから必要なデータを取り出す
  while (client.available()) {
    String line = client.readStringUntil('\r');
    //Serial.print(line); // この行を有効にするとHTTPレスポンスの全体が確認できます。
    // 気温、噴火レベル、降水量の順番で並んでおり、カンマで区切られています。
    int commaIndex = line.indexOf(",");          // 行の先頭から何文字目に
    int lastCommmaIndex = line.lastIndexOf(","); // 最初のカンマと2つめのカンマがあるか
    if (commaIndex >= 0) {
      *_temperature = line.substring(0, commaIndex).toFloat();
      *_funkaLevel = line.substring(commaIndex + 1).toInt();
      *_precipitation = line.substring(lastCommmaIndex + 1).toFloat();
    }
  }
  Serial.println();
  Serial.println("closing connection");
 
  Serial.print("temperature: ");
  Serial.println(*_temperature);
  Serial.print("volcano warning level: ");
  Serial.println(*_funkaLevel);
  Serial.print("precipitation: ");
  Serial.println(*_precipitation);
 
  Serial.println(">>> Fuji-chan updated!");
}

プログラムが変更できたら,メニューバーの[ツール]を開いて,ボードやシリアルポートの設定が以下のようになっているか確認して,ESP8266にArduinoプログラムの書き込みを行いましょう.Arduino Unoよりも時間がかかるので注意してください.

シリアルモニターを開いて,インターネットから取得した,気温,噴火警戒レベル,降水量の情報が表示されればOKです.この情報を,先ほど作ったデータに応じた音や光の変化の処理に反映させましょう.(スピーカーのピン番号が9から16に変わっています.直接ピン番号を指定する場合は注意)


プログラムを一つにまとめる

ダウンロードしたプログラム(sketch_final)の大部分は,先ほどシリアルモニターでデータを送ったプログラム(sketch_simpleFujichanDev)と同じです.先ほど作ったデータに応じた音や光の変化の処理を,プログラムの同じ場所に移動させましょう.

setup()の最後で,fujichanClient.hに用意されている,Wi-Fiに接続するconnect()関数を実行しています.接続中はLEDが白色に点滅します.接続に成功すると,Webサーバからデータを取得するupdate()関数を実行して,気温,噴火警戒レベル,降水量のデータを更新しています.update2()は,インターネットから取得したデータをLEDやスピーカーへ反映するプログラムです.下の方にupdate2()関数の本体があるので,この中にも,先ほど作ったデータに応じた音や光の変化の処理を書きます.

#include "FujichanClient.h"
 
#define UPDATE_INTERVAL 60*5 // 更新間隔[秒]
 
float temperature   = 0; // 気温(単位は[°C])
int   funkaLevel    = 0; // 噴火警戒レベル
float precipitation = 0; // 降水量(単位は[mm/h])
 
void setup() {
  led.setup();             // LEDの初期設定
  Serial.begin(115200);    // シリアル通信を開始する
  Serial.println("START"); // シリアルモニターに"START"と表示
 
  // Wi-Fiへ接続する関数
  connect();
  // Webサーバからデータを取得する関数
  update(&temperature, &funkaLevel, &precipitation); // 情報を更新します
  update2();                                         // LEDやスピーカーへ反映します
}
 
void loop() {
 
  ~中略~
 
  if ( metro(UPDATE_INTERVAL) == true ) {              // 更新時間が来たら
    update(&temperature, &funkaLevel, &precipitation); // 情報を更新します
    update2();                                         // LEDやスピーカーへ反映します
  }
}
 
void update2(){
  /* 気温が更新された時の処理.ここから */
 
 
  /* ここまで */
}
 
// 更新時間を教えてくれる関数
static unsigned long int time = 0;
bool metro(int seconds) {
  if ( (millis() - time) > seconds * 1000 ) {
    time = millis();
    return true;
  }
  else {
    return false;
  }
}

補足:データ更新の間隔

データ更新の間隔は,一番下の更新時間を教えてくれる関数で管理しています.loop()の最後で,metro()関数を呼び出して,更新時間が来ていれば,update()update2()を行います.更新間隔はプログラム冒頭の以下の行で設定できます.

#define UPDATE_INTERVAL 60*5 // 更新間隔[秒]

手動で情報更新する場合は,シリアルモニターから「3001」を送信します.


補足:開発環境を整える

Arduino IDEでESP8266を開発するためには,以下の作業が必要です.自宅のWi-Fiに接続するにはArduinoプログラムを書き換える必要があるので,参考にしてください.

  1. macOSの場合はメニューバーの[Arduino]から[Preference],Windowsの場合はメニューバーの[ファイル]から[環境設定]を開いて,[追加のボードマネージャのURL]に,以下のURLを入力して[OK]を押します.http://arduino.esp8266.com/stable/package_esp8266com_index.json
  2. メニューバーの[ツール]から[ボード]の中にある[ボードマネージャ]を開いて,検索バーに「ESP8266」と入力し,該当するものを[インストール]します.選択できるボードの一覧に「ESP8266 Modules」が出ていれば,環境構築は完了です.※出ない場合は,一度Arduino IDEを終了すると反映されます.

参考リンク:Arduino IDEで開発する方法


その他,気軽にメールなどで質問してください.
9192hs@gmail.com(須田)
studio@tetsuakibaba.jp(研究室)

撮影

担当:石曽根

目標:自分で考え,作ったものを自分でプレゼンテーションする経験をすること

みなさんの制作物及びインタビュー動画を作成します.一人30秒程度のインタビューを行います.下記は2017年度の紹介映像になります.参考までに御覧ください.

  • public/理数研究ラボ2018補助教材.txt
  • 最終更新: 2018/08/23 23:41
  • by suda