小学校でもプログラミングの授業がはじまりました。プログラミングを勉強すると、考え方や物事の進め方を学ぶことができるそうです。。。でもただ、勉強するだけでは面白くないよね。そう、高専では目的を持ってプログラムを学びます。今日は熱中症対策ロボを作製するぞ!
袋の中身を確認しましょう。ちゃんと入っていますか?
@マイコンボード
Aヘッダーピン
Bマイコンボード用ケース
CUSB通信ケーブル
D温湿度センサー
EフルカラーLED
Fジャンパー線
G袋
使うボードはこれだ! マイコンボードと呼ばれている。真ん中にあって黒い四角いところから銀色の足が4方向に各8本ずつ。合計で32本の銀色の端子が出ているのが、このマイコンボードの本体で、中にはコンピュータの計算を司るCPU(Central Processing Unit)と呼ばれるコア部分と、その他LEDを点けたりスイッチの入力を読み取ったりある程度の情報を覚えることができるメモリ等が詰め込まれているぞ!
パソコンのUSBポートとマイコンとをUSB通信ケーブルで接続します。
接続すると、「ON」と書かれた電源LEDが点灯し、「L」と書かれたL-LEDが点滅します。電源ランプが点灯していない人はスタッフに声をかけてください・・・ケーブルの接続不良か、あるいはボードが壊れているかもしれません。
プログラミングにはArduinoIDE*という開発環境を使います。
緑色の顔のようなアイコンをダブルクリックします。
※デスクトップにアイコンが無い場合は、スタート→Arduinoの順にクリックしてください
* 家のコンピュータでやってみたい人は、オープンキャンパスの
サイトにある「おまけArduinoの開発環境を整えよう。」
を読んでArduinoIDEをインストールしてみてね。
10分もあればできると思います。
起動するとこんな感じ(下図)です。ウィンドウの上にファイル名が示され、メニューバーと呼ばれる場所には「ファイル」「編集」「スケッチ」「ツール」「ヘルプ」などのメニューコマンドがあります。プログラムを書いたら「ファイル」メニューから「保存」か「名前を付けて保存」をすることで、プログラムを保存することができます。なお、Arduinoではプログラムのことをスケッチといいます。
よく使うのは「✅」マークのボタンで示された、プログラムの検証です。これは自分で書いたプログラムがちゃんとマイコン上で動くかを検証するためのボタンです。
次によく使うのは「⇒」マークで示された、プログラムをマイコンボードに転送するボタンです。マイコンにプログラムを転送するとマイコンが自動的に動き始めます。
マイコンが動き始めてからよく使うのが、「虫眼鏡」のマークで示された、シリアルモニタを起動するボタンです。これを使うと、マイコンからのメッセージを表示するなど、マイコンと通信することができます。
最初のプログラムでは、マイコンに「 Hello!! 」と言わせてみましょう。
といっても、今回のマイコンには音を出すスピーカなどはついていません。ですので、マイコンに「 Hello!! 」という文字を出力させます。ここで、文字を出力?と言われておかしいなと思った人もいるでしょう。そうです、マイコンにはディスプレイなど文字を表示する装置が付いていません。
そこでマイコンで出力した文字を、通信ケーブルを使ってパソコンのディスプレイに出力します。それを実現するのがシリアルモニタです。シリアルモニタとは、マイコンとパソコンとを繋いでいる通信ケーブルでやり取りされている内容を表示してくれる便利なモニターなのです。
メニューバーの「ツール」から「シリアルポート」を選び、マイコンがUSBケーブルで接続されているシリアルポートを選びます。下の図ではCOM1とCOM11という2つのシリアルポートが表示されていますが、これはパソコンによって変わります。たぶん、下の方の番号のシリアルポートを選ぶとよいでしょう。次に行うシリアルポートの確認で失敗するようであれば、他の番号を選択してみてください。
メニューバーの「ツール」から「ボード情報を取得」をクリックします。ウィンドウが現れ「ボード情報」が表示されれば、シリアルポートが正しく設定されています。
うまく設定できていないと、ボード情報ウィンドウは現れず、コンソールにエラーメッセージが表示されます。
その場合には、シリアルポートの番号を変更するか、USBケーブルを抜き差しする等、物理的な接続を確認しましょう。
|
それでは下記のプログラムを打ってみましょう。マウスで枠内の文字を選択してコピー&ペーストすると楽です。
void setup() { Serial.begin(9800); }
void loop() { Serial.println(" Hello!! "); delay(1000); }
|
プログラムを打ち終わったら「Ctrl」+「t」を同時に押してください。見やすいように自動的に成型してくれます。
まず、void setup()と呼ばれる関数のなかで、マイコンに必要な設定を行います。具体的にはパソコンとマイコンの通信設定を行います。通信速度を9800bpsに設定します。
次に,void loop()と呼ばれる関数の中で、パソコンのシリアルモニタに「 Hello!! 」と表示します。次に、1000ミリ秒、つまり1秒間停止します。マイコンはvoid loop()という関数を繰り返し実行し続けるようにできているので、シリアルモニタには1秒おきに「 Hello!! 」という文字が表示されることになります。
*関数ってなに? プログラム言語では処理の固まりに名前を付けます。それを関数といいます。上のプログラムでは、void setup () とvoid loop()という2つの関数があり、各々setup、loopという関数名が付いています。関数名の後の中カッコ始まり「{ 」から中カッコ終わり「 }」までの間に、マイコンに行わせたい処理を書きます。
検証が終わると、コンソールに「コンパイルが完了しました。」と表示されます。
プログラムに間違いがあると、コンソールにエラーの内容が表示されます。下記の例は、文字の打ち間違いと、日本語をプログラム中に入れてしまった場合の例です。
プログラムをマイコンに転送(書き込み)
ボードへの書き込みが完了しましたと出たら成功です。すでにマイコンは皆さんが書いたプログラムの内容を実行し始めています。次にマイコンの動作を確認してみましょう。
シリアルモニタが現れます。8行目の「 Hello!! 」を他の文字に変たり、9行目のdelayの値を変更して再度マイコンボードに転送すると、表示やタイミングの変更ができます。
LEDをチカチカしてみましょう!略して「Lチカ」といいます。
今回は、すでに用意されているスケッチ例を使ってみます。メニューバーから「ファイル」→「スケッチ例」→「01.Basics」→「Blink」を選択します。
新しいウィンドウが立ち上がり、Blinkのスケッチ例が現れます。このまま検証してマイコンボードにプログラムを書きこんでもよいのですが、PCの環境によってはエラーが発生します。それは、スケッチ例が置いてある場所に対して、書き込みや編集の権限がない場合に起こります。そこで、スケッチを自分のフォルダーに保存する必要があります。「ファイル」の中から「名前を付けて保存」を選択してください。保存先として「ライブラリ」の下の「ドキュメント」の下の「Arduino」を選択し「Blink」という名前で保存するのが良いでしょう。
スケッチ例は、間違いなく動くと思うので「検証」を行わず「マイコンボードに書き込み」を実行してみましょう。そうすると自動的にプログラムの「検証」が行われマイコンへとプログラムが書き込まれます。動作が始まると、Lのランプが1秒間隔で点灯と消灯を繰り返します。
プログラムの本体である、setup関数(最初に一度だけ実行される)と、loop関数(何度も繰り返し実行される)は28行目以降にあります。setup関数内のpinModeという命令で、13番ピンを出力モードとします。INPUTと打つと入力モードとなり、スイッチを接続した場合に使います。loop関数内ではdigitalWriteという命令で、13番ピンの電圧を+5Vとします。そうすると13番ピンに接続されたLEDが点灯します。次にdelay命令で1秒間待った後、再度digitalWrite命令を使い、13番ピンの電圧を今度は0Vとします。そうすると13番ピンに接続されたLEDが消灯します。その後delay命令で1秒間待ち、loop関数の最初に戻る、という動作を繰り返します。なお、「//」で始まる行はコメント行と言ってプログラムを説明するためのもので、マイコンの動作には関係しません。英語が読めると内容がより理解できます。英語の勉強にもなりますね。
3色の色を表示できるLEDをマイコンに接続していろいろな色を表示させてみましょう。LEDには銀色に伸びる端子が4本ついています。いちばん長いのがアノードと呼ばれる端子でここに+3.3Vの電圧を加えます。短い端子はカソードと呼ばれます。アノードと各色のカソードとをそれぞれプラスとマイナスにつなぐと赤、緑、青色に点灯します。
#define RLED 8 #define GLED 9 #define BLED 10
void setup() { pinMode(RLED, OUTPUT); pinMode(GLED, OUTPUT); pinMode(BLED, OUTPUT); Serial.begin(9600); } void loop() { Serial.println("赤 RED"); digitalWrite(RLED, LOW); delay(1000); digitalWrite(RLED, HIGH);
Serial.println("緑 GREEN"); digitalWrite(GLED, LOW); delay(1000); digitalWrite(GLED, HIGH);
Serial.println("青 BLUE"); digitalWrite(BLED, LOW); delay(1000); digitalWrite(BLED, HIGH); } |
赤色のLEDを点灯する命令は「 digitalWrite(RLED, LOW); 」、消灯する命令は「 digitalWrite(RLED, HIGH); 」。コンピュータの処理は人間の目に見えない速さ、なので少し待ってもらう必要があり、待つ命令は「
delay(1000); 」だ。 青や緑の場合は、RLEDのところをBLEDやGLEDに変えればいい。
【チャレンジ問題1】 黄色、紫色と白色を作ってみよう!
【チャレンジ問題2】 ピンク色を作ってみよう!(超難問)
【チャレンジ問題3】 時間とともに7色に変化させてみよう!!(激問)
答えは、オープンキャンパス電気電子システム工学科のページにあるぞい!
温度と湿度を測ることができるセンサー(AM2302)をマイコンに接続し、温度と湿度を読み取りシリアルモニタを使って表示します。
上の図のように配線します。赤色の電源ラインに5Vを差しセンサーに電源を供給します。黄色は温度や湿度などの信号を送信するラインで、マイコンの2番ピンに接続します。プログラム中の「#define DHTPIN 2」が2番ピンに信号線が接続されていることを意味しています。黒色のラインはGNDラインです。マイコンのGNDと書かれたところに接続します。新規ファイルを作成し下記コードをコピー&ペーストしてマイコンボードに書き込みましょう。温度と湿度がシリアルモニタに表示されます。
#include <Adafruit_Sensor.h> #include <DHT.h> #include <DHT_U.h>
#define DHTPIN 2 #define DHTTYPE DHT22 DHT_Unified dht(DHTPIN, DHTTYPE);
void setup() { Serial.begin(9600); dht.begin(); }
void loop() { delay(2000); sensors_event_t event; dht.temperature().getEvent(&event); Serial.println((String)"温度 " + (String)event.temperature + "℃"); dht.humidity().getEvent(&event); Serial.println((String)"湿度 " + (String)event.relative_humidity + "%"); Serial.println("--------------------------------"); } |
いよいよ総まとめです。「フルカラーLED」と「温度と湿度を表示」を組み合わせて、熱中症予防マシンを作成しましょう。
WBGT値とは温度と湿度から算出される熱中症予防指針です。下表で熱中症への警戒レベルがわかります。同じ温度でも湿度が高い場合は熱中症の危険度が上がります。
薄ピンク |
注意 |
黄色 |
警戒 |
ピンク |
厳重警戒 |
赤 |
危険 |
WBGT値をLEDで下記の4パターンで表示し、警告を行うプログラムをマイコンに書き込みます。
注意 |
緑の点灯 |
||||||
警戒 |
黄色の点滅 |
|
|
|
|
|
|
厳重警戒 |
赤の点滅 |
|
|
|
|
|
|
危険 |
赤と黄色 早い点滅 |
|
|
|
|
|
|
#include <Adafruit_Sensor.h> #include <DHT.h> #include <DHT_U.h>
#define RLED 8 #define GLED 9 #define BLED 10
#define DHTPIN 2 #define DHTTYPE DHT22 DHT_Unified dht(DHTPIN, DHTTYPE);
// 熱中症警報用マトリクス // 0:注意、1:警戒、2:厳重警戒、3:危険 int wbgt[20][17] = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2}, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2}, {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3}, {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3}, {0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3}, {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3}, {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3}, {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3}, {1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}, {1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, {1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, {1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, {2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, {2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, {2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3} };
void setup() {
Serial.begin(9600); pinMode(RLED, OUTPUT); pinMode(BLED, OUTPUT); pinMode(GLED, OUTPUT);
LED_Initial(10); Serial.println("熱中症警告システム Adafruit AM2302"); dht.begin(); }
void loop() {
double temp_act, hum_act;
sensors_event_t event; dht.temperature().getEvent(&event); temp_act = event.temperature ; Serial.println("温度 " + String( temp_act ) +" ℃"); dht.humidity().getEvent(&event); hum_act = event.relative_humidity; Serial.println("湿度 " + String( hum_act ) + " %"); Serial.println("--------------------------------"); int necchu; if ((temp_act < 21) || (hum_act < 20)) { necchu = 0; if ( temp_act < 0 ) necchu = 4; } else { necchu = wbgt[int (temp_act - 21)][int ((hum_act / 5) - 4)]; }
String mess[5];
mess[0] = "注意"; mess[1] = "警戒"; mess[2] = "厳重警戒"; mess[3] = "危険"; mess[4] = "零下警報"; Serial.println("WBGT値 " + mess[necchu]);
WARNNING(necchu); } /**************************************************** 警報レベルによってLEDの色と点灯パターンを変化 させる。 0:注意 緑、点灯 1:警戒 黄色、ゆっくり点滅 2:厳重警戒 赤、はやめに点滅 3:危険 赤と黄色が交互に素早く点滅 4:零下警報 青、点灯 ****************************************************/ int flag = 0; void WARNNING( int necchu) { // 0:注意、1:警戒、2:厳重警戒、3:危険 4:零下警報 digitalWrite(RLED, HIGH); digitalWrite(GLED, HIGH); digitalWrite(BLED, HIGH);
switch (necchu) { case 0: //0:注意 緑 digitalWrite(GLED, LOW); for (int n = 0; n < 20; n++) { delay(100); } break;
case 1: //1:警戒 黄色 digitalWrite(RLED, flag); digitalWrite(GLED, flag); for (int n = 0; n < 5; n++) { flag = 1 - flag; digitalWrite(RLED, flag); digitalWrite(GLED, flag); delay(400); } break;
case 2: //2:厳重警戒 赤 digitalWrite(RLED, flag); for (int n = 0; n < 8; n++) { flag = 1 - flag; digitalWrite(RLED, flag); delay(250); } break;
case 3: //3:危険 赤黄色の点滅 digitalWrite(RLED, LOW); for (int n = 0; n < 20; n++) { flag = 1 - flag; digitalWrite(GLED, flag); delay(100); } break;
case 4: //4:寒すぎる 青点灯 digitalWrite(BLED, LOW); for (int n = 0; n < 20; n++) { delay(100); } break;
default: digitalWrite(RLED, flag); digitalWrite(GLED, flag); digitalWrite(BLED, flag); } }
/* LED を赤、青、緑、で点灯させる 初回動作 */ void LED_Initial(int num) { int n; for (n = 0; n < num; n++) {
Serial.println(" R"); digitalWrite(RLED, LOW); delay(100); digitalWrite(RLED, HIGH);
Serial.println(" B"); digitalWrite(BLED, LOW); delay(100); digitalWrite(BLED, HIGH);
Serial.println(" G"); digitalWrite(GLED, LOW); delay(100); digitalWrite(GLED, HIGH); } } |