更新

ブレッドボードを使ったtinyBasic流 ものづくり(ESP8266版)
コンピュータの仕組み: ATtiny2313版
Arduino流: ATtiny4313版ATmega328P版Arduino NANO版ESP8266版
tinyBasic流: Arduino NANO版ESP8266版
WebIO: Arduino流IO制御(Arduino Micro版)

小山智史(弘前大学教育学部)


0. 準備
1. tinyBasicのコマンド操作
2. デジタル出力(1): LEDの点滅
3. デジタル入力: スイッチ操作でLEDのオンオフ
4. アナログ出力: LEDの明るさを変える
5. アナログ入力
6. デジタル出力(2): 液晶ディスプレイ
7. センサーの利用
8. 音の出るものを作る
9. イルミネーション
10. 赤外線リモコン
11. 動くものを作る
12. WiFi経由で制御する
(付録1) tinyBasicのArduinoへの書き込み
(付録2) 入出力に利用できるピン
(付録3) tinyBasic リファレンス
(付録4) 入出力モジュールの例
(付録5) 使用する主な部品


 私達の身近にある電子機器の多くにコンピュータが内蔵されており、このようなコンピュータは「マイコン」と呼ばれます。マイクロコンピュータあるいはマイクロコントローラの略です。マイコンにはメーカーが開発したプログラムが書き込まれています。リモコンの中に入っているマイコンには、押したボタンに応じて決まったパターンで赤外線をオンオフするプログラムが書き込まれています。このプログラムはマイコン製造時に書き込まれ、後から書き換えることはできませんが、フラッシュメモリー(電気的に書き換え可能なプログラムメモリー)を搭載したマイコンを使えば、私達もさまざまな機器を作ることができます。実際に、10章では電池で省電力モードで動作するリモコンの製作例を紹介しています。
 マイコンを使った機器を設計・製作するには、電子回路、論理回路、コンピュータの仕組み、プログラミングなど広範囲の知識が要求されます。これは大変なことではありますが、一方ではこれらのことを学ぶ格好の教材であるということを意味しています。
 このテキストでは、Arduino版tinyBasicを使った実習を行いながら、「マイコンを使ったものづくり」について学習します。

☆ ここでは複雑な電子回路は登場していませんが、電気回路の最低限の知識は前提としています。必要な場合はこちらの資料[4]を参考にしてください。
☆ 本テキストは実習時に適宜解説や補足を行うことを前提にしています。自学自習には適していないかもしれません。
☆ 11章まではArduinoNANOとほとんど同じです。12章のWiFiとtinyBasicの組み合わせが「いったいどういう可能性が開けるのか」試行錯誤中です。

0. 準備

0.1 tinyBasicの準備

 付録1を参考に、ESP8266にtinyBasicのプログラムを書き込みます。

 tinyBasicのプログラムはArduinoのマイコンで動作し、パソコンからの指示を受けて、ハードウェアを制御したり、命令の並び(プログラム)としてRAMに一時保存したり、そのプログラムを1行ずつ順に解釈しながら実行(RUN)したりします(下図左)。

 また、RAMのプログラムはマイコン上のEEPROM(不揮発メモリー)に保存(SAVE)することができます。電源を切るとRAM内のプログラムは消えてしまいますが、EEPROMに保存したプログラムをRAMに読み込むことができ(LOAD)、また電源投入時には自動的に読み込まれてプログラムが自動実行されます。

 プログラムが完成したら、100均などで入手できるUSB電源アダプタを使うとよいでしょう。

 入出力に利用できるピンを付録2にまとめてあります。

0.2 ブレッドボードの使い方

 ここでは下図左のブレッドボードを使います。ボードの内部は下図右のように接続されています。

(外観)(内部の接続)

 ここで、ESP8266を接続しましょう。向きに気を付けて差し込んでください。

(回路図)(実体配線図)

 ここで、ESP8266にラベルを貼っておきます(テプラファイル)。

0.3 通信ソフトTeraTermの準備

 パソコンに通信ソフトTeraTermをインストールします。[設定][シリアルポート]で「ポート」をArduino NANOを接続して現れるポートにし、「ボー・レート」は「115200」にします。また、[設定][フォント]で「サイズ」を「20」ぐらいにすると見やすいかもしれません。設定が終わったら[設定][保存]で保存します。

 通信ソフトで接続すると「HalfByte...Hitany key!」の表示が現れるので、何かキーを押します。そして、「0.2 Arduino NanoにtinyBasicを準備」の後初めて使う場合に一度だけ「new」「save」の操作をしてください。


1. tinyBasicのコマンド操作

1.1 コマンドの実行

 パソコンからTeraTermなどの通信ソフトを用いてESP8266に接続すると、下の画面が表示されます。


パソコンの通信ソフト(TeraTerm)の表示画面
 はじめに、コマンドで直接指示を与える方法を試してみましょう。
print 100
これは、「100を表示しなさい」という「命令」を表していて、この1行が「命令文」になっています。「文」といっても、疑問文や感嘆文があるわけではありません。コンピュータ(tinyBasic)に対して指示を与える「命令文」があるだけです。
 では、次のようにするとどうでしょうか。
print 100*200/50+2 print 30000+2000 print 30000+8000
それぞれ計算結果が表示されますが、最後の命令文は計算結果が扱える数「-32767~32767」を越えてしまったため、正しく表示されません。

 文字列を表示することもできます(日本語も表示できます)。また、「,(カンマ)」で区切ると、文字列や数値(計算結果)を続けて表示することができます。

print "ABC" print "弘前大学" print "100+200" print "100+200=",100+200

(練習)大文字と小文字は区別されないので、キー操作は「print」でも「PRINT」でも構いません。また、「print」の代わりに「?」でも構いません。確かめなさい。

1.2 変数

 「変数」は値をしまっておく入れ物です。変数にはA~Zの名前がついていて(変数名)、26個あります。大文字小文字は区別されません。変数には-32767~32767の整数を格納できます。

X=1 Y=2
と操作すると、「X」「Y」という変数(入れ物)にそれぞれ「1」「2」という値が代入されます。XとYに値を入れたので、以下の操作で変数同士の計算結果が表示されます。
print X+Y


2. デジタル出力(1): LEDの点滅

2.1 LEDを点灯・消灯する

 以下の回路を組み立ててください。


回路図

実体配線図

 LEDはD13ピンに接続します。「dWrite」というコマンドでD13ピンに高い電圧を出力したり低い電圧を出力したりすることができます。

dWrite 13, 1 または dWrite 13,HIGH

と操作すると、D13ピンに高い電圧(3.3V)が出力され、接続したLEDが点灯します。
dWrite 13, 0 または dWrite 13,LOW

と操作すると、D13ピンに低い電圧(0V)が出力され、LEDは消灯します。

上記の「dWrite 13, 1(またはHIGH)」は「D13ピンに1(高い電圧)を出力しなさい」という意味です。

(練習)「dWrite 13, 1」および「dWrite 13, 0」の時のD13ピンの電圧を、テスターで測りなさい。

(練習)LEDを他のピンにつなぎ替えて、点灯・消灯してみなさい。

2.2 プログラムでLEDを点滅させる

 はじめに、「NEW」の操作でプログラムを消去します。

new

 プログラムのはじめの一歩は「Lチカ」です。以下の「プログラム」を入力してください。プログラムは「命令の並び」で、並びの順に実行されます。各行先頭の10~50は「行番号」で、コンピュータの中では、行番号の小さい行から順に並んでいます。先に大きな行番号の行を入力して後から小さな行番号の行を入力しても結果は同じになります。また、同じ行番号で入力しなおせば、置き換えられます。行番号だけを入力するとその行は削除されます。

10 dWrite 13, 1 20 delay 1000 30 dWrite 13, 0 40 delay 1000 50 goto 10

 以下、プログラムの内容について簡単に説明します。10~50の各行は「命令文」になっていて、それぞれ次のような意味です。これにより、行10~50が繰り返されます。

 「LIST」と操作すると、入力したプログラムが表示されます。

list

 「RUN」と操作すると、最も小さい行番号から順にプログラムが実行され、LEDが点滅を繰り返します。

run

 プログラムの実行を中断するには「ESCキー」を押します。

 後から途中にプログラムを挿入したくなることもありますから、行番号は10刻みぐらいにしておきます。

 1行に「:」で区切って複数の命令文を書くことができます。以下のプログラムはこの方法で書き直したものです。動作は同じです。

10 dWrite 13, 1: delay 1000 20 dWrite 13, 0: delay 1000 30 goto 10

 このように入力したプログラムは、RAMに一時保存されていて、電源を切ると消えてしまいます。「SAVE」の操作でEEPROM(不揮発メモリー)に保存することができます。

save

 保存したプログラムは、「LOAD」の操作で読み込まれます。

load

保存できるプログラムはひとつで、名前をつけたりすることはできません。

(練習) (1)上のプログラムを入力し(LISTで確認)、(2)SAVEで保存し、(3)NEWで消去し(LISTで確認)、(4)LOADしなさい(LISTで確認)。また、一旦電源を切り、その後電源を入れてプログラムが自動的にロードされて実行されることを確認しなさい。

(練習) LEDを0.5秒点灯、0.5秒消灯を繰り返すようにプログラムを変更しなさい。また、0.2秒点灯、1.8秒消灯を繰り返すように変更しなさい。

2.3 LEDを高速に点滅させる

 LEDの点灯時間と消灯時間を変更してみます。

 「delay 1000」→「delay 100」→「delay 20」→「delay 10」→「delay 1」と変えて、点滅の様子を確認してください。「delay 10」の時は10ms点灯、10ms消灯を繰り返し、50Hzの点滅になります。「delay 20」(25Hz)の時は点滅しているのがわかりますが、「delay 10」(50Hz)では点滅を感じなくなります。人間の目が感じる「点滅のちらつき」はフリッカと呼ばれ、高速の点滅(50~60Hz)ではちらつきを感じなくなります。

 通常の蛍光灯は100Hz(50Hzの2倍)で点滅しますが、蛍光管の状態によっては発光にムラが生じ50Hzで点滅し、その場合はちらつきが気になることがあります。インバーター式の蛍光灯はちらつきを抑えるために超高速(数10kHz)で点滅させています。また、ブラウン管テレビが毎秒30フレーム(実際にはインターレースで60Hzのフリッカ)、映画のフィルムが毎秒24フレーム(実際には同じフレームを2度映すことで48Hzのフリッカ)になっているのは、このような目の特性を考慮してのことです。

(練習) LEDの点滅速度を30Hz, 40Hz, 50Hz, 60Hzと変化させ、ちらつきが感じられるかどうかを、ブレッドボードを静止した場合と、左右に振った場合の両方で調べなさい。

(練習) 緑色LEDと1kΩの抵抗をD12ピンに追加接続し、そのLEDを1秒毎に点滅させなさい。また、赤色LEDと緑色LEDが1秒毎に交互に点灯するようにしなさい。


3. デジタル入力: スイッチ操作でLEDのオンオフ

3.1 スイッチが押されているかどうか調べる

 下図左のようにD14ピンにスイッチを接続すると、D14ピンはスイッチをオンにすると低い電圧(0V)になり、スイッチをオフにすると高い電圧(5V)になります。これは、下図右のようにマイコンの中に抵抗が内蔵されているためです。この抵抗を「プルアップ抵抗」といいます。「高い電圧に引っ張り上げる抵抗」というような意味です。

回路図
スイッチを接続
回路図
プルアップ抵抗
D14ピンが高い電圧(1)か低い電圧(0)かをdRead(14)で読み取り、PRINTで表示することができます。

print dRead(14)
回路図

(練習) スイッチを押した時と放した時のスイッチ両端の電圧を、テスターで測りなさい。

(練習) スイッチを押した場合と放した場合で、「print dRead(14)」が変化することを確かめなさい。

3.2 スイッチ操作でLEDを点灯・消灯する

 以下のプログラムは、D14ピンの状態を読み取って(0または1)変数Aに代入し、この値をLEDに出力し、これを繰り返します。スイッチを押すとAの値は0になりLEDは消灯し、放すとAの値は1になりLEDは点灯します。

10 A=dRead(14) 20 dWrite 13,A 30 goto 10
回路図

 「!A」はAが0の時に1、Aが1の時に0となるので、以下のようにするとスイッチを押した時にLEDが点灯します。

10 A=dRead(14) 20 dWrite 13,!A 30 goto 10

3.3 スイッチ操作で交互に点灯・消灯する

 以下のプログラムは、スイッチを押すと交互にLEDが点灯・消灯します。考え方は、「スイッチが押された瞬間に(つまりさっき押されていなくて今押されたら)LED表示を反転する」というものです。変数Bには「今のスイッチの状態(0または1)」、変数Aには「さっきのスイッチの状態(0または1)」、変数Lには「今のLEDの点灯状態(1が点灯、0が消灯)」を保存します。

 行20で、現在のD14ピンの状態(1または0)を読み取り、Bに入れます。行30で、スイッチがさっきまで押されていなくて今押されているならLの値を反転(0なら1、1なら0)します(行30)。その後、行40で今のスイッチの状態を記憶し、行50でD13ピン(LED)にLの値を出力します。行60で、少し待ってから行20に行きます。

10 A=1: L=0 20 B=dRead(14) 30 if A=1 if B=0 L=!L 40 A=B 50 dWrite 13, L 60 delay 10 70 goto 20
回路図

 「delay 10」がないと、誤動作することがあります。それは、スイッチを押した時に、ごく短い時間にその接点がオンになったりオフになったりするからです。スイッチを離した時も同様です。スイッチによって異なりますが、10ms程で落ち着きます。この現象は「チャタリング」と呼ばれます。

(練習) 「delay 10」を極端に長くし、例えば待ち時間が2秒になるようにして、どのような動作になるか調べなさい。

(練習) 緑色LEDを増設し、スイッチを押すと赤色LEDと緑色LEDが交互に点灯するようにしなさい。

3.4 スイッチを4回押すと点灯する

 以下のプログラムは、スイッチ操作4回に一度LEDが点灯します。

 上の例ではLEDの表示状態を記憶し、スイッチが押されるとその値を反転させていましたが、ここではCにスイッチが押された回数を記憶します。スイッチがさっきまで押されていなくて今押されているならCの値に1を加えます(行40)。その後、今のスイッチの状態を記憶し(行50)、「C%4=0」つまりCの値を4で割った余りが0であればLEDを点灯し(行60)、そうでなければLEDを消灯します(行70)。最後に、少し待ってから行20に行きます。

10 A=1: L=0: C=0 20 B=dRead(14) 40 if A=1 if B=0 C=C+1 50 A=B 60 if C%4=0 dWrite 13,1: goto 80 70 dWrite 13,0 80 delay 10 90 goto 20
回路図

(練習) 行60の「C%4=0」の箇所を「C%7=0」や「C%4!=0」などに変えて、どのような動作になるか調べなさい。

(練習) 2個の押しボタンスイッチを使い、一方のスイッチを押すとLEDが点灯し、もう一方のスイッチを押すと消灯するようにしなさい。

3.5 スイッチが押されるとLEDを3秒点灯する

 以下のプログラムは、スイッチが押されるとLEDを3秒点灯します。

10 if dRead(14)=0 dWrite 13,1: delay 3000: goto 10 20 dWrite 13,0 30 goto 10
回路図

4. アナログ出力: LEDの明るさを変える

4.1 LEDの明るさを変える

 これまでは、LEDが点灯するか消灯するかでした。しかし、点灯時の明るさを変化させたいこともあります。 aWrite という命令を使い

とすると、指定したピンにアナログ値 0~255 を出力できます。

 LEDの接続はそのままで、以下の操作をしてみましょう。

aWrite 13, 10 aWrite 13, 255

LEDの明るさが変わるのが確認できます。

(練習)LEDの明るさを0~255の範囲で変えてみなさい。また、その時の波形をオシロスコープで観察して記録しなさい。

4.2 プログラムでLEDの明るさを変える

 2.3ではLEDの点灯時間と消灯時間を変えてどのように見えるかを確認しました。ここでは行20と行40を「delay 1」にしてみます(1ms)。

10 dWrite 13,1 20 delay 1 30 dWrite 13,0 40 delay 1 50 goto 10

 既に経験したように、点灯と消灯を高速に切り替えると、私達の目は点滅を認識できなくなります。代わりに、常時点灯している場合よりも少しだけ暗く感じます。「平均的に」半分の明るさになるからです。下図左は、この時のLEDの出力の波形を示したものです。行30の0を1にすれば常時点灯となりますから、LEDの明るさを比較してみてください。私達の目は、明るさが半分になっても、「ちょっと暗くなった」ぐらいにしか感じません。

PWM波形

 次に、行20はそのままにして行40を「delay 9」としてみてください。こうすることにより、1ms点灯、9ms消灯を繰り返すようになり、明るさはより暗く感じられます。この時の波形が上図中央です。

 HIGHとLOWの時間が等しい時「デューティ比50%」、常時HIGHの時「デューティ比100%」、HIGHが1msでLOWが9msなら「デューティ比10%」といいます。この技術は「パルス幅変調(PWM)」と呼ばれ、モータのスピードコントロールや、デジタルオーディオアンプなどに利用されています。

 4.1で使ったaWriteというコマンドを使うと、0/255~255/255のデューティ比で上記のようなPWM信号が出力される仕組みになっています。

(練習) スイッチを押す度に「消灯→暗い→明るい→消灯→...」の動作をするプログラムを作りなさい。

4.3 LEDの明るさを連続的に変える

 デューティ比を連続的に変化させれば、下図のように任意の波形を表すことができます。

PWM波形

 以下は、デューティ比を0%から100%まで少しずつ変化させるプログラムです。暗い状態から次第に明るくなり、その後次第に暗くなり、これを繰り返します。Bが明るさの値、Fが明るさの変化量です。行20でBの値をアナログ出力し、行30でBの値をFだけプラスします。

10 B=5: F=5 20 aWrite 13, B 30 B=B+F 40 if B=0 F=5 50 if B=255 F=-5 60 delay 30 70 goto 20

(練習) スイッチを押すとLEDがだんだん明るくなり、スイッチを離すだんだん暗くなるプログラムを作りなさい。


5. アナログ入力

5.1 アナログ値の入力

 以下のようにA0ピンにボリュームを接続し、ボリュームを中ほどの位置にして以下の操作をしてみてください。ボリュームの位置に応じて0~1023の値が表示されます。aReadは指定されたピンのアナログ値(0~1023)を返す「関数」です。aRead(0)は、A0ピンの電圧(0~5V)に応じて0~1023の値が返ってきます。ボリュームの位置を変えて、表示される値を確認してください。また、1行プログラムで値を時々刻々表示できます。

print aRead(0)
10 print aRead(0): delay 100: goto 10

(練習) A0の電圧をテスターで測り、ボリュームを回すとどのように変化するか調べなさい(ボリュームの位置が左・中央・右)。また、上記のプログラムを動作させた時に、電圧がいくらの時に表示される値がいくらになるかを調べなさい(ボリュームの位置が左・中央・右)。

5.2 アナログ値に応じてLEDの点灯時間を変える

 以下のプログラムは、ボリュームの値に応じてLEDの点滅時間が変化します。

10 dWrite 13,1 20 delay aRead(0) 30 dWrite 13,0 40 delay aRead(0) 50 goto 10
回路図

5.3 アナログ値に応じてLEDを点灯・消灯する

 以下のプログラムは、ボリュームのアナログ値(0~1023)が600未満の時にLEDを点灯します。

10 if aRead(0)<600 dWrite 13,1: goto 10 20 dWrite 13,0 30 goto 10
回路図

5.4 アナログ値に応じて明るさを変える(調光)

 照明の明るさを調整することを「調光」といいます。

 以下のプログラムは、ボリュームのアナログ値(0~1023)に応じてLEDの明るさを連続的に変えます。

10 A=aRead(0)/4 20 aWrite 13, A 30 goto 10
回路図

6 デジタル出力(2): 液晶ディスプレイ

6.1 液晶ディスプレイに文字や数字を表示する

 I2C接続の液晶ディスプレイ(2行16文字)を以下のように接続します。

 CLS、CURSOR、PRINTの3つのコマンドは、通信ソフト(teraTerm等)と液晶の両方の表示に適用されます。

cls print 100

7. センサーの利用

7.1 スイッチをセンサーとして使う

 押しボタンスイッチやスライドスイッチは、操作用のスイッチですが、センサーとしても活躍しています。例えば、CD/DVDデッキやコピー機やプリンタなど動きを伴う機器には、所定の位置に来たがどうかを検知するために、マイクロスイッチが必ずといっていいほど使われています。このような使われ方をするスイッチを「リミットスイッチ」と呼ぶこともあります。

 ふたつの金属片を接触させるだけでスイッチ(センサー)となるので、オリジナルのスイッチを作ることも難しくはありません。所定の水位になったかどうかを検知するピンポン球を使った浮力スイッチ、傾けると金属ボールが移動する傾斜スイッチなど、用途に応じて工夫するのも楽しいでしょう。

 スイッチの値はprintコマンドで表示できます。また、下の1行プログラムでスイッチの様子を時々刻々表示できます。

print dRead(14)
10 print dRead(14): delay 100: goto 10
回路図

7.2 明るさセンサー(CDS): 明るい時にLEDを点灯する

 5.1のボリュームの代わりに明るさセンサー(CDS)をつないでみましょう。CDSは明るくなるほど抵抗値が低くなり、A0ピンの電圧は高くなります。

 printコマンドでA0ピンの値を確認してください。また、下の1行プログラムでA0ピンの値を時々刻々表示できます。

print aRead(0)
10 print aRead(0): delay 100: goto 10

 以下のプログラムは一定以下に暗くなるとLEDが点灯します。プログラムは5.3と同様です。ただし、行10の「600」の値は適切な値に変更する必要があります。

10 if aRead(0)<600 dWrite 13,1: goto 10 20 dWrite 13,0 30 goto 10
回路図

 街路灯などでは、境界値付近でledが点灯したり消灯したり不安定になるのを避けるために、下図のような「ヒステリシス特性」を持たせます。

行30はledが消灯(Lが0)している時に600未満の明るさになったらledを点灯(Lを1)します。行50はledが点灯(Lが1)している時に700以上の明るさになったらledを消灯(Lを0)します。実際の点灯消灯は行60,70で行っています。

10 L=0 20 if L=0 if aRead(0)<600 L=1 30 if L=1 if aRead(0)>=700 L=0 40 dWrite 13,L 50 goto 20
回路図

(練習) 行20の600と行30の700の値を変えて、適切な値をみつけなさい。

7.3 温度センサー(サーミスタ): 温度が高い時にLEDを点灯する

 CDSの代わりに温度センサー(サーミスタ)をつないでみましょう。サーミスタは温度が高くなるほど抵抗値が低くなり、A0ピンの電圧は高くなります。

 printコマンドでA0ピンの値を確認してください。また、下の1行プログラムでA0ピンの値を時々刻々表示できます。

print aRead(0)
10 print aRead(0): delay 100: goto 10

 以下のプログラムは温度がある値以上になるとLEDが点灯します。プログラムは上と同様です。ただし、行10の「25」の値は適切な値に変更する必要があります。

10 if tRead(0)<25 dWrite 13,1: goto 10 20 dWrite 13,0 30 goto 10
回路図

(練習) LEDをエアコンに置き換えて考えてみましょう。街路灯の場合と同様、境界値付近で点灯したり消灯したり不安定になるのを避けるために、下図のような「ヒステリシス特性」を持たせます。

ヒステリシス特性を持たせたプログラムでその動作を確かめなさい。

(練習) 温度が高ければ赤、温度が低ければ青のLEDが点灯するようにしてみなさい。

7.4 音量センサー: 音を検知するとLEDを点灯する

 音量センサーは、マイクが検知する音の大きさに応じてA0ピンの電圧は高くなります。

 printコマンドでA0ピンの値を確認してください。また、下の1行プログラムでA0ピンの値を時々刻々表示できます。

print aRead(0)
10 print aRead(0): delay 100: goto 10

 以下のプログラムは、音を検知したら(A0のレベルが300を超えたら)、LEDを3秒点灯します。

10 if aRead(0)>300 dWrite 13,1: delay 3000: goto 10 20 dWrite 13,0 30 goto 10
回路図

(練習) 5.2のスイッチの代わりに音センサを使い、手をたたくとカウントアップするようにしなさい。

7.5 赤外線反射センサー: 何かに接近するとLEDを点灯する

 赤外線反射センサーは、光を反射する物がない時は1000程度の値、数cmのところに光を反射する物がある時は20~30の値を返します。

 printコマンドでA0ピンの値を確認してください。また、下の1行プログラムでA0ピンの値を時々刻々表示できます。

print aRead(0)
10 print aRead(0): delay 100: goto 10

以下のプログラムは、何かに接近したら(A0のレベルが40より小さくなったら)、LEDを点灯します。

10 if aRead(0)>300 dWrite 11,1: delay 3000: goto 10 20 dWrite 11,0: goto 10
回路図

7.6 温湿度センサー: 温湿度計を作る

 ここでは温湿度センサー(HDC1000)を使います。tRead()で、I2C接続した温湿度センサーから温度を直接読み取ることができます。つまり、23度であれば、tRead()は「23」という値を返します。PRINTコマンドで確認してください。また、1行プログラムで温度を時々刻々表示できます。また、湿度の場合はtRead()の代わりにhRead()を使い、相対湿度(%)を返します。

print tRead()
10 print tRead(): delay 100: goto 10

 以下のプログラムは、温湿度センサー(HDC1000)で測定した温度と湿度を液晶ディスプレイに表示します。なお、パソコンと接続している場合は、通信ソフト(teraTerm等)にも液晶ディスプレイと同じ表示が現れます。

10 cls 20 cursor 0,0 30 print tRead(),chr(&df),"C" 40 cursor 8,0 50 print hRead(),"%RH" 60 delay 1000 70 goto 10

 プログラムを保存(SAVE)しておくと、パソコンと接続しなくても、電源を入れるとプログラムが起動します。ケースに入れれば温湿度計の完成です。


8. 音の出るものを作る

 ここではブザー音で電子オルゴールを作ってみましょう。和音など音にこだわる方は「私だけの電子オルゴール」[8]を参考にしてください。

8.1 音を出す

 LEDと同じ箇所に圧電ブザー(Bzz)を接続し、「1秒ごとにLEDを点滅させるプログラム」を実行してください。するとブザーからカチカチと音が聞こえます。ここで、点灯時間と消灯時間を以下のように1msにしてみましょう。

10 dWrite 13,1 20 delay 1 30 dWrite 13,0 40 delay 1 50 goto 10

 この時の波形は下図のように500Hzの矩形波となり、聞こえるのは500Hzの音です(といっても倍音成分が含まれていますが)。

トーン波形

(練習) オシロスコープでトーン信号の波形を観察しなさい。また、WaveGeneなどの信号発生ソフトを用い、パソコンで500Hzの矩形波を出し、音を比べてみなさい。

8.2 音程を変える

 指定したピンに、指定した周波数の音を、指定した時間出力する tone という命令を使います。以下は時報の音を出すプログラムです。ソが784Hz、ドが1046Hzです。

10 tone 13,784,200 20 delay 400 30 tone 13,784,200 40 delay 400 50 tone 13,784,200 60 delay 400 70 tone 13,1046,1200

(練習) 440Hzのラの音(A4)に対し1オクターブ高いラ(A5)の音は880Hzで、その間は隣同士(半音)の周波数の比が一定(21/12)となるように音階が作られます。表計算ソフトを用い、A4~A6の各音の周波数を計算しなさい。上のプログラム中の784Hzが「ソ」、1046Hzが「ド」であることが確認できます。

(練習) 上のプログラムを参考に、簡単な曲を演奏させるプログラムを作りなさい。

8.3 楽譜を演奏する

 以下は、文字列で記述した楽譜情報を参照しながら演奏するプログラムです。楽譜情報がプログラムと分離されているので、長い曲も表しやすくなっています。

10 P=top(0): @P,"RDDBAGDR RDDBAGER REEcBAFR RdddcABR RDDBAGDR RDDBAGER REEcBAdd ddedcAGR" 20 C=peek(P) 25 if C=13 stop 30 if C=67 F=262: goto 200 40 if C=68 F=294: goto 200 50 if C=69 F=330: goto 200 60 if C=70 F=349: goto 200 70 if C=71 F=392: goto 200 80 if C=65 F=440: goto 200 90 if C=66 F=494: goto 200 100 if C=99 F=523: goto 200 110 if C=100 F=587: goto 200 120 if C=101 F=659: goto 200 130 if C=102 F=698: goto 200 140 if C=103 F=784: goto 200 150 if C=82 delay 300: goto 210 160 P=P+1 170 goto 20 200 tone 13,F,300 210 P=P+1 220 goto 20

(練習) 行10の楽譜を変え、必要な場合は30~140行を拡張し、好きな曲の電子オルゴールを作りなさい。

8.4 楽器を作る

 以下のプログラムは、ボタンを押すと、ボリュームで決まる周波数のブザー音がでます。

10 if dRead(12)=1 goto 10 20 A=aRead(0) 30 tone 13,A,200 40 goto 10

 上のプログラムで一応楽器として使えるのですが、ドレミ...の音を丁度よく出すのは難しいと思います。そこで、ドレミ...の音しか出ないようにしたのが次のプログラムです。

10 if dRead(12)=1 goto 10 20 A=aRead(0) 30 if A>784 tone 13,784,200: goto 10 40 if A>698 tone 13,698,200: goto 10 50 if A>659 tone 13,659,200: goto 10 60 if A>587 tone 13,587,200: goto 10 70 if A>523 tone 13,523,200: goto 10 80 if A>494 tone 13,494,200: goto 10 90 if A>440 tone 13,440,200: goto 10 100 if A>392 tone 13,392,200: goto 10 110 if A>349 tone 13,349,200: goto 10 120 if A>330 tone 13,330,200: goto 10 130 if A>294 tone 13,294,200: goto 10 140 tone 13,262,200 150 goto 10

(練習) ボリュームの代わりに明るさセンサで音程が変わるようにしなさい。また、必要ならば音階を拡張しなさい。

8.5 しゃべるものを作る

 I2C接続した音声合成LSI(ATP3011F4)を使ってスピーカから合成音声を出します。

 まず、コマンド操作で動かしてみてください。

talk "aiueo" talk 123 talk 4,"kakeru",5,"wa",4*5,"desu" talk "ju'nbi/o'-kei"

 日本語音声をしゃべってくれますが、文字列はローマ字で書く必要があります。また、上の最後の操作例のように、アクセントその他さまざまな約束事があります。

 以下の例は、「九九」を合成音声で読み上げるものです[音を聞く]。

10 FOR A=1 TO 9 20 FOR B=1 TO 9 30 TALK A,"kakeru",B,"wa",A*B 40 NEXT B 50 NEXT A

9. イルミネーション

9.1 NeoPixelの利用

 NeoPixelはフルカラーLEDがシリアルに連結されていて(ここでは10連LEDを使用)、1本の信号線で任意のLEDの発光をコントロールできるのが特徴です。tinyBasicでは、A3(D17)ピンに接続した10連NeoPixelをpixelコマンドで制御することができます。パラメータで、順にLEDの番号(0~9)、Redの明るさ(0~255)、Greenの明るさ(0~255)、Blueの明るさ(0~255)を指定します。

 まず、コマンド操作で試してみてください。

pixel 0,50,0,0 pixel 0,0,0,0 pixel 0,50,0,0 pixel 1,0,50,0 pixel 2,0,0,50 pixel 3,50,50,0 pixel 4,0,50,50 pixel 5,50,50,50

9.2 プログラムによる点滅とフラッシュ

 以下のプログラムは、ひとつ目のLEDを赤で点滅させます。1秒点灯・1秒消灯をくりかえします。下図右は点滅の時間的な変化をタイムチャートで示したものです。

10 pixel 0,50,0,0 20 delay 1000 30 pixel 0,0,0,0 40 delay 1000 50 goto 10

10行目を

10 pixel 0,0,50,0 とすると緑で点滅します。

 次のようにすると10個のLEDが点滅します。

10 for i=0 to 9 20 pixel i,0,50,0 30 next i 40 delay 1000 50 for i=0 to 9 60 pixel i,0,0,0 70 next i 80 delay 1000 90 goto 10

20行目を

20 pixel i,0,100,0

40行目を

40 delay 200 とすると明るく短時間点灯する「フラッシュ」になります。

(練習) 10個のLEDが1秒毎に「青→黄→赤」を繰り返すプログラムを作りなさい。

9.3 ワイプ

 以下のプログラムは、10個のLEDを順に点灯させます。このようなイルミネーション効果は「ワイプ」と呼ばれます。

10 for i=0 to 9 20 pixel i,50,0,0 30 delay 1000 40 next i

20行目を

20 pixel i,0,0,0 とすると順に消灯します。

(練習) 「赤のワイプ→緑のワイプ→青のワイプ」を繰り返すプログラムを作りなさい。

9.4 スイープ

 以下のプログラムは、10個のLEDを順に点灯・消灯させます。

10 for i=0 to 9 20 pixel i,50,0,0 30 delay 1000 40 pixel i,0,0,0 50 next i

(練習) 30行目のdelay を100msにし、また、繰り返しスイープするようにしなさい。

9.5 ウェーブ

 以下のプログラムは、2個おきの点灯パターンがスイープし、波(ウェーブ)のように(あるいは追いかけているように)見えます。500行目はサブルーチンになっていて、与えられたR,G,Bの値でウェーブ表示します。10行目は白色、20行目は赤、30行目は緑、40行目は青のそれぞれウェーブで、これを繰り返します。

10 R=50:G=50:B=50:gosub 500 20 R=50:G=0: B=0: gosub 500 30 R=0: G=50:B=0: gosub 500 40 R=0: G=0: B=50:gosub 500 50 goto 10 500 for j=20 to 0 step -1 510 for i=0 to 9 520 if (i+j)%3=0 pixel i,R,G,B:goto 550 530 pixel i,0,0,0 540 next i 550 delay 80 560 next j 570 return

(練習) 520行目を変更し、「1個おき」「3個おき」のウェーブにしてみなさい。

9.6 フェードイン・フェードアウト

 以下のプログラムは、ひとつ目のLEDをだんだん明るくし(赤を0→50)、だんだん暗くし(赤を50→0)、これを繰り返します。

10 for r=0 to 50 20 pixel 0,r,0,0 30 delay 10 40 next r 50 for r=50 to 0 step -1 60 pixel 0,r,0,0 70 delay 10 80 next r 90 goto 10

(練習) 色を変えてみなさい。また速さを変えてみなさい。

(練習) 10個のLEDを同時にフェードイン・フェードアウトさせなさい。

9.7 クロスフェード

 ひとつ目のLEDをフェードアウトしながら、ふたつ目のLEDをフェードインすると滑らかに変化させることができます。これを「クロスフェード」といいます。

10 for r=0 to 50 20 pixel 0,r,0,0 30 delay 10 40 next r 50 for r=50 to 0 step -1 60 pixel 0,r,0,0 70 delay 10 80 next r 90 goto 10

 以下は、クロスフェードをスイープに応用した例で、LEDの点灯位置が滑らかに変化します。

10 for i=0 to 9 20 for r=0 to 50 30 pixel i,50-r,0,0 40 pixel (i+1)%10,r,0,0 50 delay 10 60 next r 70 next i 80 goto 10

9.8 フルカラー表示

 クロスフェードを用いると色を滑らかに変化させることができます。以下のプログラムは、ひとつ目のLEDの色が赤→緑に滑らかに変化します。

10 for r=50 to 0 step -1 20 pixel 0,r,50-r,0 30 delay 10 40 next r

 RGBの値と表示色の関係は下図のようになっています。


 以下のプログラムは、すべてのLEDの色をフルカラーで連続的に変化させます(明るさ最大85)。

10 for W=0 to 255 20 if W<85 B=0:G=W:R=85-G:goto 50 30 if W<170 R=0:B=W-85:G=85-B:goto 50 40 G=0:R=W-170:B=85-R 50 for i=0 to 9 60 pixel i,R,G,B 70 next i 80 delay 10 90 next W 100 goto 10

 以下のプログラムは、すべてのLEDの色を場所を変えながらフルカラーで連続的に変化させます(明るさ最大85)。500行目はサブルーチンになっていて、0~255の色相Wを与えると、R,G,Bの変数に値(各々0~85)がセットされます。30行目でWに値をセットしてから500行目を呼び出しています。

10 for j=0 to 256 step 8 20 for i=0 to 9 30 W=(i*256/10+j)%256:gosub 500 40 pixel i,R,G,B 50 next i 60 delay 10 70 next j 80 goto 10 500 if W<85 B=0:G=W:R=85-G:return 510 if W<170 R=0:B=W-85:G=85-B:return 520 G=0:R=W-170:B=85-R:return

9.9 イルミネーションの例

 以下は、「ドロップ」のイルミネーションの作例です。水滴が滴り落ちるイメージで、最後にキラッと光ります。

10 N=6+rnd(5) 20 for i=0 to N-2 30 u=(i+1)*10 40 for b=0 to u 50 pixel i, u-b,u-b,u-b 60 pixel (i+1)%10,b,b,b 70 delay 3 80 next b 90 delay (10-N)*2 100 next i 110 for b=u to 255 120 pixel N-1,b,b,b 130 delay 3 140 next b 150 for b=255 to 0 step -1 160 pixel N-1,b,b,b 170 delay 3 180 next b 190 delay rnd(2000) 200 goto 10
N:LEDの長さ(ランダムに6~10)...どこまで長くドロップさせるか iをNまで繰り返す  uは最大の明るさ  明るさbを0~u   iのLEDをu-bの明るさで表示(だんだん暗く)   i+1のLEDをbの明るさで表示(だんだん明るく)   3ms待つ  速さ調整 明るさbを最大までだんだん明るくする(キラリ)  速さ調整 明るさbを0までだんだん暗くする  速さ調整 次のドロップまで0~2秒待つ

(練習) オリジナルのイルミネーションを考え、作ってみなさい。


10. 赤外線リモコン

10.1 赤外線リモコンを作る

 テレビなどのリモコンは、ボタンを押すと赤外線LEDが「決められたタイミングで点滅」するように作られています。どのように点滅しているかは、リモコン受光器に向けてリモコンのボタンを押し、受光器の信号をオシロスコープで観測するとわかります。

 実際に観測してみると、各社テレビのリモコン信号は以下のようになっています。図の着色した部分が信号が「オン」の箇所で、「オン」とは「赤外線LEDを13μs点灯し、13μs消灯し、これを一定時間繰り返す」ことです。また、「オフ」とは「一定時間消灯する」ことです。これを参考に、赤外線LEDを点滅させるプログラムを作ればよいわけです。

電源 ON/OFF 40 bf 12 ed
チャンネルUP 40 bf 1b e4
チャンネルDOWN 40 bf 1f e0
ボリュームUP 40 bf 1a e5
ボリュームDOWN 40 bf 1e e1
東芝製テレビのリモコン信号
電源 ON/OFF 02 20 80 00 3d bd
チャンネルUP 02 20 80 00 34 b4
チャンネルDOWN 02 20 80 00 35 b5
ボリュームUP 02 20 80 00 20 a0
ボリュームDOWN 02 20 80 00 21 a1
パナソニック製テレビのリモコン信号
電源 ON/OFF 8f 12 16 d1
チャンネルUP 8f 12 11 a1
チャンネルDOWN 8f 12 12 91
ボリュームUP 8f 12 14 f1
ボリュームDOWN 8f 12 15 e1
シャープ製テレビのリモコン信号
電源 ON/OFF 95 0
チャンネルUP 90 0
チャンネルDOWN 91 0
ボリュームUP 92 0
ボリュームDOWN 93 0
SONY製テレビのリモコン信号

 以下の回路とプログラムは、CHupボタンを押すと各社リモコンの「チャンネルアップ」信号が次々出力され、CHdnボタンを押すと各社リモコンの「チャンネルダウン」信号が次々出力されます。実際には各社の信号を出す必要はありません。

10 L=13:U=14:D=12 20 if dRead(U)=HIGH goto 90 30 f38k L,9000/26:delayus 4500:rcbyte L,$40,$bf,$1b,$e4:delay 90 50 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$80,$00,$34,$b4:delay 90 60 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$b0,$00,$34,$84:delay 90 70 rcbyte L,$8f,$12,$42,$11,$a1:delay 90 80 scbyte L,$90:delay 90 90 if dRead(D)=HIGH goto 20 100 f38k L,9000/26:delayus 4500:rcbyte L,$40,$bf,$1f,$e0:delay 90 110 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$80,$00,$35,$b5:delay 90 120 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$b0,$00,$35,$85:delay 90 130 rcbyte L,$8f,$12,$42,$12,$91:delay 90 140 scbyte L,$91:delay 90 150 goto 20
回路図

10.2 なんでもリモコン

 以下の回路とプログラムは、1個のスイッチ操作で電源・CHup・CHdnをコントロールできる「なんでもリモコン」のtinyBasic版です(オリジナルはこちら)。ブザー音の「ドに電源」「レにCHup」「ミにCHdn」が割り当ててあります。スイッチを押すと「ドーレーミー」とブザー音が鳴るので、希望の箇所でもう一度スイッチを押します。このプログラムはパナソニックTV用です。他社の場合は、510~530の行を変更します。

10 B=12:L=13:S=14:@(0)=262,294,330,349,392,440,494,523 20 if dRead(S)=HIGH goto 20 30 if dRead(S)=LOW goto 30 40 for i=0 to 2 50 tone B,@(i),1000 60 for j=1 to 100 70 if dRead(S)=LOW gosub 500 80 delay 10 90 next j 100 next i 110 goto 20 500 tone B,1000,100: J=100 510 if i=0 f38k L,9000/26:delayus 4500:rcbyte L,$40,$bf,$12,$ed 520 if i=1 f38k L,9000/26:delayus 4500:rcbyte L,$40,$bf,$1b,$e4 530 if i=2 f38k L,9000/26:delayus 4500:rcbyte L,$40,$bf,$1f,$e0 540 i=2:delay 1000:return
回路図

 以下は各社対応のリモコン信号を続けて出すようにしたデモンストレーション用プログラムです。実際には各社の信号を出す必要はありませんので、必要箇所以外はコメントアウトします(511, 521, 531の各行は東芝TV、512, 522, 532の各行はパナソニックTV、513, 523, 533の各行はパナソニックBD、514, 524, 534の各行はシャープTV、515, 525, 535の各行はソニーTV)。

10 B=12:L=13:S=14:@(0)=262,294,330,349,392,440,494,523 20 if dRead(S)=HIGH goto 20 30 if dRead(S)=LOW goto 30 40 for i=0 to 2 50 tone B,@(i),1000 60 for j=1 to 100 70 if dRead(S)=LOW gosub 500 80 delay 10 90 next j 100 next i 110 goto 20 500 tone B,1000,100: J=100 #POWER 510 if i!=0 goto 520 511 f38k L,9000/26:delayus 4500:rcbyte L,$40,$bf,$12,$ed:delay 90 512 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$80,$00,$3d,$bd:delay 90 513 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$b0,$00,$3d,$8d:delay 90 #514 rcbyte L,$8f,$12,$16,$d1:delay 90 515 scbyte L,$95 #CHup 520 if i!=1 goto 530 521 f38k L,9000/26:delayus 4500:rcbyte L,$40,$bf,$1b,$e4:delay 90 522 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$80,$00,$34,$b4:delay 90 523 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$b0,$00,$34,$84:delay 90 #524 rcbyte L,$8f,$12,$11,$a1:daley 90 525 scbyte L,$90 #CHdn 530 if i!=2 goto 540 531 f38k L,9000/26:delayus 4500:rcbyte L,$40,$bf,$1f,$e0:delay 90 532 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$80,$00,$35,$b5:delay 90 533 f38k L,3600/26:delayus 1600:rcbyte L,$02,$20,$b0,$00,$35,$85:delay 90 #534 rcbyte L,$8f,$12,$12,$91:delay 90 535 scbyte L,$91 540 i=2:delay 1000:return
回路図

11. 動くものを作る

 これまでの例では、マイコンの出力ピンにLEDや圧電ブザーを接続しました。ESP8266は最大12mAの電流を流すことができるので、この範囲であれば直接接続できます。この章では、モータなど大きな電流が流れる素子を駆動する例を紹介します。大きな電流が流れる回路を制御する場合は、「電流が流れる経路」を意識することが回路の誤動作を防ぐことにつながります。

11.1 サーボモーターを動かす

 以下のようにサーボモーターを接続します。サーボモーターの電源はVoutからとります。まず、コマンド操作で動かしてみてください。

servo 10,0 servo 10,90 servo 10,180

11.2 プログラムでサーボモーターを動かす

 以下の例は、サーボモーターが車のワイパーのように動きます。

10 P=0: D=1 20 servo 10,P 30 P=P+D 40 if P=180 D=-1 50 if P=0 D=1 60 delay 15 70 goto 20

 以下のように「for文」を使っても結果は同じです。

10 for P=0 to 179 20 servo 10,P 30 delay 15 40 next P 50 for P=180 to 1 step -1 60 servo 10,P 70 delay 15 80 next P 90 goto 10

 以下のプログラムは、ボリュームの値によってサーボモーターの位置(角度)が変わります。

10 A=aRead(0)*9/51 20 servo 10,A 30 delay 15 40 goto 10

(練習) ボリュームの代わりに明るさセンサを使い、明るさで位置が変わるようにしなさい。

11.3 モーターを動かす

 下図のようにモーターを接続します。モーターの電源はVoutからとります。まず、「MOTOR」コマンドでモーターを動かしてみてください。左右のモーターの速度は0~255で指定します。

motor 255,100 motor 100,255 motor 255,255 motor 0,0

11.4 プログラムでモーターを動かす

 以下はボリュームの値によってモーターの回転速度が変わります。

10 A=aRead(4)/4 20 motor A,A 30 goto 10

 以下は音センサモジュールと組み合わせた例で、手を叩く(A6に接続した音センサーが400以上)と1秒間前進します。

10 if aRead(6)<400 goto 10 20 motor 255,255 30 delay 1000 40 motor 0,0 50 goto 10

 以下の例は、車の先端がテーブルから落ちそう(A7に接続した赤外線反射センサーが30以上)になると、少し後退し、右回転して、再び前進します。

10 motor 255,255 20 delay 100 30 if aRead(7)<500 goto 10 40 motor -200,-200 50 delay 500 60 motor 0,200 70 delay 500 80 goto 10

12. WiFi経由で制御する

 これまでは、「ESP8266+tinyBasicソフト」をパソコンの通信ソフト(teraTerm等)で操作してきました。

 上の図はコマンド操作で直接入出力などを指示する様子を、下の図はコマンドに行番号を付し、その並びをプログラムとして保存・実行した様子を表しています。

 本章では、「ESP8266+tinyBasicソフト」をWiFiに接続し、パソコン、タブレット、スマートホンなどから制御できるものを作ります。

12.1 コマンド操作でWiFiに接続しブラウザから制御する

 まず、コマンド操作で既設のWiFiアクセスポイントに接続し、ブラウザからLEDの点灯・消灯を行ってみます。パソコンの通信ソフトで、以下のように入力します。「SSID」と「PASSWORD」の箇所は接続するアクセスポイントに合わせます。また、「myESP」の箇所はWebサーバ名です。

(通信ソフト)
WiFi "SSID","PASSWORD","myESP"

 すると、同じネットワークに接続したパソコンのブラウザで「http://myESP.local」を表示することができます。ただし、Windowsパソコンの場合は、Appleから提供されている「Bonjour」をインストールしておく必要があります。

 ここで、ページ中の「コマンド」入力欄にtinyBasicのコマンドを入力すると、WiFi経由で直接操作することができます。

(ブラウザのコマンド入力欄)
dwrite 13,1(Enter) dwrite 13,0(Enter) awrite 13,50(Enter)

 これらの操作を行うと、LEDが点灯・消灯あるいは指定の明るさで点灯します。また、ブラウザの画面は以下のようになります。

 ブラウザのコマンド操作は、ESP8266のWebSocketサーバを経由して受け付けられ、パソコンの通信ソフトで操作した場合と同様に実行されます。

 引き続き、ブラウザの「tinyBasicコマンド」の入力欄またはパソコンの通信ソフトで以下の操作を行うと、順次ページ中にタイトルやボタンやスライダーが現れます。ボタンの番号は1~9で、番号順に3×3に配置されます。スライダーの番号は上から順に1~3で、「%%」はスライダーの値を表します。

(通信ソフトまたはブラウザのコマンド入力欄)
title "WiFi制御" button 1,"LED ON","dwrite 13,1" button 2,"LED OFF","dwrite 13,0" slider 1,"明るさ","awrite 13,%%"

 ブラウザのコマンド操作の時と同様に、ボタンを押すとボタンに登録されたコマンド操作の情報がESP8266のWebSocketサーバを経由して受け付けられ、実行されます。また、スライダの値が変わるとaWriteコマンドが送られ、実行されます。

 このように、ブラウザの表示画面は、動的に追加・差し替えが行われます。また、複数のパソコンやタブレットから接続した場合は、連動して動作し、同じ画面が表示されます。

12.2 プログラムでWiFiに接続する

 以下は、上で行った操作をプログラムで行うようにしたものです。プログラムは順に実行され、終了しますが、ブラウザのボタン操作でコントロールすることができます。プログラムを保存(SAVE)しておけば、電源投入時に自動的にプログラムが起動するので、ブラウザにははじめからボタンやスライダーが表示されます。

(通信ソフト)
1  WiFi "SSID","PASSWORD","myESP" 10 title "WiFi制御" 20 button 1,"LED ON","dwrite 13,1" 30 button 2,"LED OFF","dwrite 13,0" 40 slider 1,"明るさ","awrite 13,%%"

 ここまでは、パソコンの通信ソフト(teraTerm)でプログラムを入力してきましたが、WiFi接続したパソコンのブラウザからプログラムを入力することもできます。以下のように、ブラウザ画面のプログラム入力欄にプログラムを入力し、を押すと、プログラムがEPS8266に送られ、EEPROMに保存され、実行されます。

(ブラウザのプログラム入力欄)

 一方、を押すとESP8266上にあるプログラムがプログラム入力欄に表示されます。プログラムは1~5まで30日間ブラウザに保存されます。

 上の例では、プログラムは順次実行された後、終了(Ready状態)しますが、次項の例のようにプログラムが実行し続けるような場合は、を押すとプログラムは中断します。通信ソフトでESCキーを押すのと同じです。

 一旦このような状態にしておけば、ESP8266はUSB電源で動作させ、タブレット等のブラウザ画面でコントロールすることが可能となります。ただし、行番号1のWiFi接続コマンドを忘れたり正しく入力しなかったりすると、ブラウザ画面からは直すことができなくなりますので、注意が必要です。この場合は、通信ソフト(teraTerm等)で様子を確認し、接続操作をしなおします。

12.3 スイッチの状態を表示する

 以下は、「3.5 プルアップ抵抗」の時と回路は同じで、プログラムもWiFi接続の箇所を追加しただけです。ブラウザにはプログラムで利用している入出力(スイッチとLED)の状態が表示されます。

1 WiFi "SSID","PASSWORD","myESP" 10 if dRead(12)=0 dWrite 13,1: goto 20 20 dWrite 13,0 30 goto 10
回路図

 下の画面はこれをプログラム2として入力して実行した様子です。

(ブラウザのプログラム入力欄)

 行番号10のdRead(12)でスイッチの状態が読み取られますが、この時WebSocketサーバから値がbroadcastされ、ブラウザはこれを受け取り表示します。

12.4 センサーの利用

 以下は、CDSを用いて明るさをバーグラフ表示する例です。

1 WiFi "SSID","PASSWORD","myESP" 10 title "WiFi制御" 20 bar 2,"明るさ",aread(0)/10 30 delay 100 40 goto 20

 下の画面はこれをプログラム3として入力して実行した様子です。行番号20でブラウザのグラフ表示が更新されます。

(ブラウザのプログラム入力欄)

 行番号20のbarコマンドでバーグラフ表示に必要な情報がWebSocketサーバから値がbroadcastされ、ブラウザはこれを受け取り表示します。

12.5 モーターカーの制御

 以下は、ボタン操作でモーターカーを制御する例です。12.2と同様、プログラムは順に実行され、終了しますが、ボタン操作でコントロールすることができます。

1 WiFi "SSID","PASSWORD","myESP" 10 title "WiFi制御" 20 button 2,"前進","motor 200,200" 30 button 4,"左ターン","motor 0,100:delay 500:motor 0,0" 40 button 5,"停止","motor 0,0" 50 button 6,"右ターン","motor 100,0:delay 500:motor 0,0" 60 button 8,"後退","motor -50,-50"

 下の画面はこれをプログラム4として入力して実行した様子です。

(ブラウザのプログラム入力欄)

 以下は、スライダー操作でモーターカーのスピードを制御する例です。

1 WiFi "SSID","PASSWORD","myESP" 10 title "WiFi制御" 20 slider 1,"モーター","motor %%,%%"

 下の画面はこれをプログラム5として入力して実行した様子です。

(ブラウザのプログラム入力欄)

12.6 NTP時計を作る

 NTPというインターネット上で時刻を合わせる仕組みを使った時計で、液晶ディスプレイに年月日と時分秒が表示されます。WiFiがインターネットに接続されている必要があります。時刻合わせはWiFi接続時とその後24時間に1度行われます。なお、パソコンと接続している場合は、通信ソフト(teraTerm等)にも液晶ディスプレイと同じ表示が現れます。

1 WiFi "SSID","PASSWORD" 10 CLS 20 CURSOR 0,0 30 PRINT YEAR(),"/",MONTH(),"/",DAY() 40 CURSOR 0,1 50 PRINT HOUR(),":",MINUTE(),":",SECOND() 60 DELAY 1000 70 GOTO 10

 プログラムを保存(SAVE)しておくと、パソコンと接続しなくても、電源を入れるとプログラムが起動します。ケースに入れればNTP時計の完成です。

(練習) 月日や時分秒が0~9の時に10の位に「0」が表示されるようにしなさい。

(練習) 8.5の合成音声と組み合わせ、「10時になりました」などとしゃべる「音声時計」を作ってみなさい。


(参考資料)

[1] George Gray, Half-byte tinyBasic, https://halfbyteblog.wordpress.com/
[2] TinyBasic を動かしてみる, http://ht-deko.com/arduino/tinybasic.html
[3] DSbasic, http://desktopstation.net/wiki/doku.php/dsbasic
[4] グラフで考える直流回路, http://siva.cc.hirosaki-u.ac.jp/usr/koyama/lecture/it/elec.html


(付録1) tinyBasicのArduinoへの書き込み

  1. Arduino 1.8.2をダウンロードし、インストールします。
  2. Arduino IDEを起動し、[ファイル][環境設定]で、「追加のボードマネージャのURL」に「http://arduino.esp8266.com/stable/package_esp8266com_index.json」と入力し、OKを押します。[ツール][ボード][ボードマネージャ]で「esp8266」を探し、インストールします。
  3. [スケッチ][ライブラリをインクルード][ライブラリの管理]で、一覧の中から「ESP8266」「esp8266_mdns」「ESP8266HTTP Client」「ESP8266 WiFi」「Servo(esp8266)」をインストールします。
  4. Arduinoを起動し、[ファイル][環境設定]で、スケッチブックの保存場所を確認し、その下にlibrariesフォルダを作ります。
  5. 液晶モジュールを利用するために、ST7032のライブラリ(ZIPファイル)をダウンロードし、解凍して上記librariesフォルダに置きます。この中のST7032.cppの24行目を のようにコメントアウトします。
  6. NTP機能を利用するために、NTPClientライブラリ(ZIPファイル)Timeライブラリ(ZIPファイル)をダウンロードし、それぞれ解凍して上記librariesフォルダに置きます。
  7. WebSocket機能を利用するために、arduinoWebSocketsライブラリ(ZIPファイル)をダウンロードし、解凍して上記librariesフォルダに置きます。
  8. [ツール][ボード]で「Generic ESP8266 Module」を選択し、[ツール][Flash Mode]を「QIO」、[ツール][Flash Size]を「4M(3M SPIFFS)」、[ツール][Reset Method]を「nodemcu」にします。また、ESP8266を接続し、[ツール][シリアルポート]でポートを選択します。
  9. tinybasic8266_20170427.zipを解凍し、ESP8266に書き込みます。WiFi機能利用時のブラウザ表示画面は別ファイル(index.h)にしてあるので、違うデザインにしたり別の機能を加える場合はこのファイルを変更します。

 プログラム(tinybasic8266.ino)は、「Tyny Basic を動かしてみる[2]」のページの中ほどにある「HalfByteTinyBasic_mod.zip」を拡張したものです。拡張した主な内容は以下のとおりです。

  1. プログラム実行の中断(ブレーク)をESCキーで行うようにしたこと
  2. 入力ミスの修正にBS(BackSpace)キーを使えるようにしたこと
  3. 起動時にEEPROMに保存されているプログラムをLOADし、3秒後に自動実行するようにしたこと(プログラムが完成したらパソコン無しで動作する)
  4. %(剰余) &(and) |(or) !=(<>と同じ)の演算子を使えるようにしたこと
  5. dRead()で内部プルアップ抵抗を有効にしたこと
  6. PRINTコマンドで液晶ディスプレイ(ST7032)にも表示させるようにしたこと
  7. 温湿度センサ(HDC1000)用に「tRead」「hRead」関数を追加したこと
  8. サーボモーター制御用に「SERVO」コマンドを追加したこと
  9. モーター制御用に「MOTOR」コマンドを追加したこと
  10. 「TONE」コマンドを追加したこと
  11. 音声合成用に「TALK」コマンドを追加したこと
  12. NeoPixel LED制御用に「PIXEL」コマンドを追加したこと
  13. 赤外線リモコン信号用に「f38k」「RCBYTE」「SCBYTE」の各コマンドを追加したこと
  14. 「PRINT」コマンドでビデオ(有効な場合)と液晶ディスプレイにも表示されるようにしたこと。関連して、「CLS」コマンドや「CURSOR」コマンドもそれらの表示デバイスに適用されるようにしたこと。
  15. 既設のアクセスポイントに接続しWebサーバを起動する「WiFi」コマンドを追加し、関連する「TITLE」「BUTTON」「BAR」などのコマンドと「Year()」「Month()」「Day()」「Hour()」「Minute()」「Second()」などの関数を追加したこと

 通信ソフトで接続すると「HalfByte...Hitany key!」の表示が現れるので何かキーを押し、初めて使う場合に一度だけ「new」「save」の操作をしてください。


(付録2) 入出力に利用できるピン

種類ピン番号
デジタル出力ピン0, 2, 4, 5, 12, 13, 14, 15, 16
(ただし 4, 5 ピンはI2Cで使用)
デジタル入力ピン
アナログ出力ピン
アナログ入力ピンA0

(付録3) tinyBasic リファレンス...グリーンが拡張箇所

□ コマンド

NEW
プログラムを初期化する。変数は「0」に初期化されないので注意。

CLEAR
A~Zのすべての変数の値を0にする。

MEM
メモリーの残量を表示する。

命令文
命令文を入力すると直ちに実行される(行末はEnterキー)。「A=1: B=2: PRINT A+B」のように「:」で区切って1行に複数の文を書いてもよい。

行番号 命令文
行番号をつけて命令文を入力すると、プログラムとして格納される(格納されたプログラムはRUNで実行)。

RUN
格納されたプログラムを先頭の行番号から実行する。

SAVE
EEPROMにプログラムを保存する。最大1000バイトで、プログラムは1つしか保存できない。

LOAD
EEPROMに保存したプログラムをロードする。起動時には自動的にLOADが行われる。

LIST
プログラムすべてを表示する。
LIST 行番号
行番号以降のプログラムを表示する。
LIST 行番号.
行番号のプログラムだけを表示する。

□ 数と変数と演算

-32767~32767の整数。16進表記の場合は、$FF, &FF, #FF のようにする。

定数(組み込み定数)
HIGH(またはHI)は「1」、LOW(またはLO)は「0」と同じ。

文字列
文字列は「"」で囲む。日本語も表示できる。

変数
変数名はA~Zで、大文字小文字は区別されない。変数には-32767~32767の整数を格納できる。
演算
+(加算) -(減算) *(乗算) /(除算) %(剰余) &(and) |(or) !(0なら1, 1なら0)
=(等しい) <>(等しくない) !=(等しくない) >(大きい) >=(以上) <(小さい) <=(以下)

□ 命令文

REM または #
以降行末までコメントとなる。メモリーを消費するので注意。

代入
変数に値を代入する。LETは省略してよい。
(例) LET A=100

POKE 番地, 値
@ 番地, 値
指定した番地に値を書き込む。
(例) POKE 1450,64...1450番地の値を64にする
(例) POKE TOP(0),"ABCDE"...メモリーのフリーエリアの先頭に文字列を"ABCDE"を格納する。文字列の末尾には改行コード(13)が付加される。
利用する時はPEEKを使い、何度も使う文字列で利用する。POKEとINKEYを組み合わせると、実行時に入力した文字列をしまっておくことができる。

FOR ループ
以下の例は1~20を表示する。 10 FOR X=1 TO 20 20 PRINT X 30 NEXT X 以下の例は10~100を表示する。 10 FOR X=0 TO 100 STEP 10 20 PRINT X 30 NEXT X ECHO 「FOR」と「NEXT」を同じ行に書くことはできない。

NEXT 変数
対応するFORループを終了する。

IF 式 文
式がtrueなら文を実行する。式に論理演算を使えないが、「IF A=1 IF B=2 PRINT A+B」のような方法で「AND」を表現できる。ELSEはない。

GOTO 行番号
指定した行番号にジャンプする。

GOSUB 行番号
指定した行番号のサブルーチンを呼び出す。サブルーチンは同じ処理を何度も実行する時に使う。

RETURN
サブルーチンを終了し、呼び出されたGOSUBの次の行に戻る。

STOP
プログラムを終了し、編集画面に戻る。

DELAY 時間
時間はms単位で指定する。

CLS
通信ソフト(teraTerm等)の画面とI2C液晶とビデオ画面をクリヤーする。

PRINT 変数や文字列
? 変数や文字列
変数や文字列を通信ソフト(teraTerm等)の画面とI2C液晶とビデオ画面にに表示する。「,」で区切ると、複数の変数や文字列が連続して表示される。末尾に「;」を置くと改行されない。

INPUT 変数
変数に数値を入力する。 10 X=0 20 PRINT "X? ";: INPUT X 30 PRINT X

OUT 値
シリアルポートに値を出力する。「OUT 65」でシリアル端末に「A」が表示される。

CURSOR X, Y
カーソル位置を(X,Y)にする。XとYは文字単位で位置を指定。その後printで文字を表示する。

AWRITE ピン番号, 値
指定したピン(0)に値(0~255)を出力する。

DWRITE ピン番号, 値
指定したピン(D0~D16)に値(0または1)を出力する。

MOTOR 左速度, 右速度
I2C接続した左右のモーターの速度を指定する。左速度、右速度はそれぞれ-255~255。0で停止。

SERVO ピン番号, 角度
接続したピン(D0~D16)のサーボモーターを指定した角度(0~180)に動かす。

TALK 変数や文字列
変数や文字列を音声合成LSIで読み上げる。「,」で区切ると、複数の変数や文字列を連続して読み上げる。

TONE ピン番号, 周波数, 時間
周波数はHz、時間はmsで指定する。

f38k ピン番号, 繰り返し数
ピンに接続した赤外線LEDを指定回数点灯13μs消灯13μsする。

RCBYTE ピン番号, データ, ...
ピンに接続した赤外線LEDを指定したビットパターンで点滅する。データは複数指定できる。

SCBYTE ピン番号, データ, ...
ピンに接続した赤外線LEDを指定したビットパターンで点滅する(SONY方式)。データは複数指定できる。

WIFI SSID, PASSWORD
WIFI SSID, PASSWORD, ドメイン名
既設のアクセスポイントに接続し、「http://ドメイン名.local」のWebサーバを起動する(省略時のドメイン名は「esp8266」)。

TITLE タイトル
Webページのタイトルを指定する。

BUTTON 番号,名前,コマンド
Webページにボタンを表示する。ボタンの番号は1~9、名前はボタンに表示する文字列、コマンドはボタンを押した時に実行するtinyBasicコマンド。Webページ上でのボタンの配置は横3個×縦3個。

SLIDER 番号,名前,コマンド
Webページにスライダーを表示する。スライダーの番号は1~3、名前はスライダーの左に表示する文字列、コマンドはスライダーを操作した時に実行するtinyBasicコマンド。ただし、コマンド中に「%%」を書くとスライダーの値が代入される。

BAR 番号,名前,値
Webページに横棒グラフを表示する。グラフの番号は上から1~3、名前はバーグラフの左に表示する文字列、値は0~100。

□ 関数

 括弧内に引数を与えると、値が返される。

ABS, POW, SIN, COS
ABS(絶対値)、POW(べき乗)など。SIN, COSは「度」で角度を与え、1000倍した値が返される。
(例) COS(60)...値は500

RND(数)
0から指定した数までの乱数を返す。

PEEK(番地)
指定した番地の値を返す。PEEKを使って、ユーザが入力した文字列を調べることができる。

TOP(0)
未使用メモリーの先頭番地を返す。文字列を格納する時に用いる。

CHR(文字コード)
指定した文字コードの文字を返す。「PRINT CHR(65)」で「A」が表示される。

INKEY(初期値)
キー操作のASCIIコードを返す。キーが押されるのを待つわけではない。 10 M=N 20 A=INKEY(0) 30 IF A=-1 GOTO 20 40 IF A=13 @M,13: RETURN 50 PRINT CHR(A); @M,A 60 M=M+1 70 GOTO 20 文字列を入力してもらう。キーが押されなければ、AはINKEYから0を受け取る。一度キーが押されると、そのASCIIコードがAの値となる。ENTERが押されると、メモリーに改行が格納される。メモリーの番地は+1される。

AREAD(0)
指定したアナログピン(0)から値を読み取る。0~1023の値が返される。

DREAD(ピン番号)
指定したピン(D0~D16)から値を読み取る。0か1の値が返される。0はLOW、1はHIGHを表す。

TREAD()
I2C接続した温湿度センサー(HDC1000)が計測した温度(℃)が返される。

HREAD()
I2C接続した温湿度センサー(HDC1000)が計測した湿度(%)が返される。

YEAR()
MONTH()
DAY()
HOUR()
MINUTE()
SECOND()
WiFi接続し、インターネットに接続されている場合、現在の年・月・日・時・分・秒をそれぞれ返す。NTPサーバはntp.nict.jpで、接続時および24時間に一度時刻合わせが行われる。


(付録4) 入出力モジュールの例

 ブレッドボードで利用できる入出力モジュールの製作例です。

モジュール回路図製作例
可変抵抗モジュール
明るさセンサーモジュール
赤外線反射モジュール
音量センサーモジュール
10連LEDモジュール
NeoPixel(DinはD15に接続)
モーターモジュール
右モーターはA0とA1をGNDに接続
音声合成モジュール

(付録5) 使用する主な部品

部品表
名称 外観 備考
ブレッドボード EIC-301 秋月 190円
ブレッドボード ジャンパーワイヤ 15cm   秋月 10本 300円
ブレッドボード ジャンパーワイヤ EIC-J-S   秋月 250円
LED 秋月 10個 120円
フルカラーシリアルLEDテープ SwitchScience 756円
圧電スピーカー 秋月 2個 100円
プッシュスイッチ DS-660R-C 千石 84円
抵抗 1/4W 4.7Ω, 100Ω, 220Ω, 470Ω, 1kΩ, 10kΩ
100kΩ, 220kΩ
秋月 100本 100円
CDS(光センサ)秋月 30円
温湿度センサ HDC1000秋月 680円
赤外線反射センサ LBR-127HLD   秋月 50円
サーボモーター SG-90   秋月 400円
液晶ディスプレイ AQM1602A   秋月 550円
モータードライバ DRV8830   秋月 170円
音声合成LSI ATP3011F4   秋月 850円
ESP-WROOM-02開発ボード スイッチサイエンス 2160円

koyama@hirosaki-u.ac.jp