更新

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

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


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


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

☆ ここでは複雑な電子回路は登場していませんが、電気回路の最低限の知識は前提としています。必要な場合はこちらの資料[4]を参考にしてください。
☆ 本テキストは実習時に適宜解説や補足を行うことを前提にしています。自学自習には適していないかもしれません。

0. 準備

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

 ここでは下図(a)のブレッドボード(EIC-701)を使います。ボードの内部は下図(b)のように接続されています。


(a) ブレッドボード(EIC-701)の外観

(b) ブレッドボードの内部の接続

 Arduino Nanoをブレッドボードに下図(b)のように装着します。USBケーブルをパソコンに接続すると、電源(5V)がパソコンから供給されます。(a)が回路図、(b)が実体配線図です。


(a) 回路図(電源はUSBから供給される)

(b) 実体配線図

 ここで、初めてブレッドボードを使う場合は、練習としてLEDと抵抗を下図(a)のように接続してみます。電流の流れは(c)のようになります。ブレッドボードの内部の結線も含めて「電流が流れる経路」を意識することが重要です。


(a) 回路図

(b) 実体配線図

(c) 電流の流れ

0.2 Arduino NanoにtinyBasicを準備

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

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

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

 プログラムが完成したら、電池を直接接続したり、100均などで入手できるUSB電源アダプタを使うとよいでしょう。ただし、電池とUSBを同時に接続しないよう注意してください。

[パソコンと接続してプログラム作成]
[完成後は自立動作]

Arduino Nanoで製作(電源はUSBから供給)
→「SAVE」→
電池で利用

 このテキストはArduino Nanoとブレッドボードを使ったものづくりの練習を中心に扱っています。テレビ画面に表示する応用例は14章に紹介しました。

0.3 通信ソフトTeraTermの準備

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

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


1. tinyBasicのコマンド操作

1.1 コマンドの実行

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


パソコンの通信ソフト(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を点灯・消灯する

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


(a) 回路図

(b) 実体配線図

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

dWrite 11, 1 または dWrite 11,HIGH

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

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

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

 LEDが点灯する時の電流の流れは下図のようになります。

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

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

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

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

new

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

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

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

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

list

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

run

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

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

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

10 dWrite 11, 1: delay 1000 20 dWrite 11, 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 スイッチが押されているかどうか調べる

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

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

print dRead(7)
回路図

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

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

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

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

10 A=dRead(7) 20 dWrite 11,A 30 goto 10
回路図

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

10 A=dRead(7) 20 dWrite 11,!A 30 goto 10

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

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

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

10 A=1: L=0 20 B=dRead(7) 30 if A=1 if B=0 L=!L 40 A=B 50 dWrite 11, 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(7) 40 if A=1 if B=0 C=C+1 50 A=B 60 if C%4=0 dWrite 11,1: goto 80 70 dWrite 11,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(7)=0 dWrite 11,1: delay 3000: goto 10 20 dWrite 11,0 30 goto 10
回路図

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

4.1 LEDの明るさを変える

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

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

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

aWrite 11, 10 aWrite 11, 255

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

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

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

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

10 dWrite 11,1 20 delay 1 30 dWrite 11,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 11, 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の値が返ってきます。PRINTコマンドを使い、ボリュームの位置を変えて、表示される値を確認してください。また、1行プログラムで値を時々刻々表示できます。

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

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

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

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

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

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

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

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

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

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

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

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

6. デジタル出力(2): 数字表示LED

6.1 数字表示LEDに数字を表示する

 数字表示LED(7セグメントLED C-551SR)に数字を表示してみます。下図の回路を組み立ててください。

 「5」を表示したい場合は a, c, d, f, g を点灯し、b, e を消灯すればいいので、以下のコマンド操作で数字表示LEDに「5」が表示される。

dwrite 2,1 dwrite 3,0 dwrite 4,1 dwrite 5,1 dwrite 6,0 dwrite 7,1 dwrite 8,1
回路図

 これを簡便にするために、7セグメントLEDのa~gをD2~D8に接続した場合は「NUMLED」コマンドで指定した数(0~9)を表示させることができるようになっています。

numled 5
回路図

(練習) 表示する数字を他の数字に変更してみなさい。

6.2 数字表示LEDにカウントアップ表示する

 以下のプログラムは7セグメントLEDに1秒毎に0→9と表示をカウントアップします。

10 for I=0 to 9 20 numled I 30 delay 1000 40 next I 50 goto 10
回路図

 以下のプログラムは7セグメントLEDに1秒毎に0~9の数をランダムに表示します。

10 numled rnd(10): delay 1000: goto 10
回路図

 以下は、スイッチを押すと数字表示がカウントアップするプログラムです。

10 C=0 20 if C<9 if dRead(12)=0 C=C+1: delay 300 30 numled C 40 goto 20
回路図

6.3 アナログ値を数字表示LEDに表示する

 以下のプログラムは、ボリュームのアナログ値(0~1023)に応じて、数字表示LEDに0~9を表示させます。

10 A=aRead(0)/103 20 numled A 30 goto 10
回路図

(練習) 数字表示が9~0にカウントダウンするプログラムを作りなさい。

(練習) 1秒毎ではなく50ms毎に高速でカウントアップするようにしなさい。また、スイッチが押されるとカウントを停止するようにしなさい。

(練習) 1秒毎に0~9の数をランダムに表示し、スイッチが押されるとそこで停止するようにしなさい。

6.4 数字の2桁表示

 数字表示LEDに2桁以上の数字を表示するにはどうしたらいいでしょうか。LED毎にa~gをつなげばいいのですが(スタティック点灯)、Arduinoのピンが不足してしまいます。このような場合はダイナミック点灯と呼ばれる方法が用いられます。この方法は、身近にあるさまざまな表示装置に使われています。

 2個の数字表示LEDのa~gに表示したい数字のパターンを出力し、D9ピンを「0(低い電圧)」にすると「10の桁」に、D10ピンを0にすると「1の桁」に表示されます。

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

 「23」を表示させたい時は以下のようにします。

dWrite 9,1 dWrite 10,1 numled 2 dWrite 9,0 dWrite 9,1 numled 3 dWrite 10,0 dWrite 10,1 (「numled 2」以降を繰り返す)
回路図

 以上のコマンド操作をプログラムで行うと以下のようになります。

10 dWrite 9,1 20 dWrite 10,1 30 numled 2 40 dWrite 9,0 50 delay 1000 60 dWrite 9,1 70 numled 3 80 dWrite 10,0 90 delay 1000 100 dWrite 10,1 110 goto 30
回路図

 ここで、行50と行90を「delay 1000」→「delay 100」→「delay 20」→「delay 10」→「delay 1」と変えてみてください。2.3の時と同様にフリッカが私たちの目にはわからなくなります。

 次に、0~99の数値を表示するにはどうしたらいいでしょうか。今、以下の行25のように変数Tに23という値を入れておきます。行30ではTの10の位の「2」を「T/10」で求め、出力しています。行70ではTの1の位の「3」を「T%10(Tを10で割った余り)」で求め、出力しています。他は前と同じです。行25で0~99の任意の値を指定できます。

10 dWrite 9,1 20 dWrite 10,1 25 T=23 30 numled T/10 40 dWrite 9,0 50 delay 1000 60 dWrite 9,1 70 numled T%10 80 dWrite 10,0 90 delay 1000 100 dWrite 10,1 110 goto 30
回路図

6.5 アナログ値を数字表示LEDに2桁で表示する

 以下のプログラムは、ボリュームのアナログ値(0~1023)に応じて、数字表示LEDに0~99の2桁で表示させます。行25で「aRead(0)*100/1024」を計算したいのですが、「aRead(0)*100」が数値の範囲 -32767~32767 を越えてしまうので、このようにします。

10 dWrite 9,1 20 dWrite 10,1 25 T=aRead(0)*25/256 30 numled T/10 40 dWrite 9,0 50 delay 1000 60 dWrite 9,1 70 numled T%10 80 dWrite 10,0 90 delay 1000 100 dWrite 10,1 110 goto 30
回路図

7. デジタル出力(3): 液晶ディスプレイ

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

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

 CLS、CURSOR、PRINTの3つのコマンドは、通信ソフト(teraTerm等)と液晶の両方の表示に適用されます。ビデオ表示を利用している場合はそちらにも適用されます。

cls print "COUNT: "; print 100

7.2 液晶ディスプレイにカウントアップ表示する

 以下のプログラムは、1秒毎にカウントアップ表示します(通信ソフトの画面にも表示されます)。

10 C=0 20 cls 30 print "COUNT: ",C 40 delay 1000 50 C=C+1 60 goto 20
回路図

 以下のプログラムは、スイッチを押すとカウントアップするプログラムです(通信ソフトの画面にも表示されます)。

10 C=0 20 if C<9 if dRead(7)=0 C=C+1: delay 300 30 cls 40 print "COUNT: ",C 50 goto 20
回路図

7.3 アナログ値を液晶ディスプレイに表示する

 以下のプログラムは、ボリュームのアナログ値(0~1023)を液晶ディスプレイに表示させます(通信ソフトの画面にも表示されます)。

10 A=aRead(0) 20 cls 30 print "VAL: ",A 30 goto 10
回路図

8. センサーの利用

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

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

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

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

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

8.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 11,1: goto 10 20 dWrite 11,0 30 goto 10
回路図

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

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

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 11,L 50 goto 20
回路図

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

8.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 11,1: goto 10 20 dWrite 11,0 30 goto 10
回路図

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

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

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

8.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 11,1: delay 3000: goto 10 20 dWrite 11,0 30 goto 10
回路図

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

8.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
回路図

8.6 明るさセンサー(CDS): 明るさを数字表示LEDに表示する

 以下のプログラムは、明るさを数字表示LEDに0~9の数字で表示させます。プログラムは6.5と同様です。

10 A=aRead(0)/103 20 numled A 30 goto 10
回路図

8.7 温度センサー: 温度計を作る

 8.3で使ったサーミスタでもいいのですが、温度計を作ろうとすると校正が必要となります。

 ここでは温度センサモジュール(LM61)を使います。temp(0)で、A0ピンに接続した温度センサーから温度(-30~50)を直接読み取ることができます。つまり、23度であれば、temp(0)は「23」という値を返します。PRINTコマンドで確認してください。また、1行プログラムで温度を時々刻々表示できます。

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

 以下は温度を液晶ディスプレイに表示する例です。

10 cls 20 print temp(),chr(&df),"C" 30 delay 1000 40 goto 10

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

 以下は5.5のダイナミック点灯の方法を使ってLEDに2桁表示する例です。

10 dWrite 9,1 20 dWrite 10,1 25 T=temp(0) 30 numled T/10 40 dWrite 9,0 50 delay 10 60 dWrite 9,1 70 numled T%10 80 dWrite 10,0 90 delay 10 100 dWrite 10,1 110 goto 20
回路図

(練習) 上記の「delay 10」の箇所(10ms)を遅くすると(100ms)表示がどうなるか観察しなさい。また、速くすると(1ms)表示がどうなるか観察しなさい。

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

 ここでは温湿度センサー(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)しておくと、パソコンと接続しなくても、電源を入れるとプログラムが起動します。ケースに入れれば温湿度計の完成です。


9. 音の出るものを作る

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

9.1 音を出す

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

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

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

トーン波形

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

9.2 音程を変える

 指定したピンに、指定した周波数の音を、指定した時間出力する tone という命令を使います。以下は時報の音を出すプログラムです。ソが784Hz、ドが1046Hzです。初めにtoneコマンドで指示した音が出ることを確認し、それからプログラムにします。音の終了を待たずにプログラムは次に進むので、多くの場合は次行にdelayを置きます。

tone 11,784,200 tone 11,784,200 tone 11,784,200 tone 11,1046,3000
10 tone 11,784,200 20 delay 1000 30 tone 11,784,200 40 delay 1000 50 tone 11,784,200 60 delay 1000 70 tone 11,1046,2000

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

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

9.3 楽譜を演奏する

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

10 P=top(0): POKE 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 11,F,300 210 P=P+1 220 goto 20

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

9.4 楽器を作る

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

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

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

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

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

9.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

10. イルミネーション

10.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

10.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秒毎に「青→黄→赤」を繰り返すプログラムを作りなさい。

10.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 とすると順に消灯します。

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

10.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にし、また、繰り返しスイープするようにしなさい。

10.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 540 530 pixel i,0,0,0 540 next i 550 delay 80 560 next j 570 return

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

10.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を同時にフェードイン・フェードアウトさせなさい。

10.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

10.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

10.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秒待つ

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


11 赤外線リモコン

11.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=2:D=7 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
回路図

11.2 なんでもリモコン

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

10 B=8:L=13:S=2:@(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)。

 下の写真は、Arduino ProMini(8MHz)を使い電池で動作させている様子です。

20 sleep
のように省電力モードにすると、待機時の消費電流は250μAでした(sleepを使わない場合は3.5mA)。

10 B=8:L=13:S=2:@(0)=262,294,330 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
回路図


回路図

Arduino ProMiniを使い電池で動作

12. 動くものを作る

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

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

 以下のようにサーボモーターを接続し、コマンド操作で動かしてみてください。

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

12.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

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

12.3 モーターを動かす

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

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

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

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

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

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

10 if aRead(0)<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(0)<500 goto 10 40 motor -200,-200 50 delay 500 60 motor 0,200 70 delay 500 80 goto 10

13. 押しボタン信号機

 押しボタン信号機の制御プログラムです。まず行10で「車用信号を青」、行20で「歩行者用信号を赤」にします。行30と行40で歩行者のボタンが押されるまで待ち、ボタンが押されると、4秒後に行60で「車用信号を黄色」にし、4秒後に行80で「車用信号を赤」、行90で「歩行者用信号を青」にします。その後16秒待ち、行110~160で歩行者用信号を点滅させます。行170で「歩行者用信号を赤」にして4秒後に行190行で「車用信号を青」にして、以上を繰り返します。

10 dWrite 2,0: dWrite 3,0: dWrite 4,1 20 dWrite 12,1: dWrite 11,0 30 B=dRead(7) 40 if B=1 goto 30 50 delay 4000 60 dWrite 2,0:dWrite 3,1:dWrite 4,0 70 delay 4000 80 dWrite 2,1:dWrite 3,0:dWrite 4,0 90 dWrite 12,0: dWrite 11,1 100 delay 16000 110 for I=1 to 8 120 dWrite 12,0:dWrite 11,1 130 delay 500 140 dWrite 12,0:dWrite 11,0 150 delay 500 160 next I 170 dWrite 12,1: dWrite 11,0 180 delay 4000 190 dWrite 2,0: dWrite 3,0: dWrite 4,1 200 A=B 210 goto 30

 以下は歩行者用の「カッコー」の音を付け加えた例です。

10 e=659: c=523 20 dWrite 2,0: dWrite 3,0: dWrite 4,1 30 dWrite 12,1: dWrite 11,0 40 B=dRead(7) 50 if B=1 goto 40 60 delay 4000 70 dWrite 2,0: dWrite 3,1: dWrite 4,0 80 delay 4000 90 dWrite 2,1: dWrite 3,0: dWrite 4,0 100 dWrite 12,0: dWrite 11,1 110 for I=1 to 5 120 tone 10,e,100: delay 400 130 tone 10,c,200: delay 900 140 tone 10,e,100: delay 100 150 tone 10,e,100: delay 100 160 tone 10,c,200: delay 1000 170 next I 180 for I=1 to 8 190 dWrite 12,0:dWrite 11,1: delay 500 200 dWrite 12,0:dWrite 11,0: delay 500 210 next I 220 dWrite 12,1: dWrite 11,0 230 delay 4000 240 dWrite 2,0: dWrite 3,0: dWrite 4,1 250 A=B 260 goto 40

 また、以下はこれを発展させた「交通安全教室用信号機」です。


14. ビデオ表示

14.1 テレビに表示する

 下図左のようにテレビと接続します。写真のような先端に抵抗とジャンパピンを付けたケーブルを作っておくと便利です。

 パソコンの通信ソフトで操作している時はテレビにも同じ画面が表示されます。といっても、下の写真のように画面は80×48ドット(480バイトのVRAM)で、4×6ドットの文字フォントです。

 グラフィック表示のコマンドをいくつか試してみましょう。

plot 30,30,1 plot 40,40,1 line 0,0,79,0,1 line 79,0,79,47,1 circle 20,20,8,1 box 40,20,60,30,1

 以下は、正弦波形を描くプログラムです。

10 cls 20 for x=1 to 79 30 plot x,24-sin(x*9)/45,1 40 next x

 以下は、ランダムな場所に四角を表示・消去を繰り返すプログラムです。

10 cls 20 W=80: H=48 30 for i=1 to 10 40 x=rnd(W-5): y=rnd(H-5) 50 box x,y,x+5,y+5,1 60 delay 1000 70 box x,y,x+5,y+5,0 80 next i

 以下は、ボールを動かすプログラムです。

10 cls 20 for x=8 to 72 30 circle x,24,8,11 40 delay 50 50 circle x,24,8,10 60 next x

14.2 プログラムでビットマップ画像を表示する

 以下は64×48ドットのビットマップ画像を表示するプログラムです。画像を表示し、その後右にスライドします。適当な方法で、画像のピクセルパターンを用意する必要があります。

10 cls 20 bmp 0,0,"ffffc00000007fff","ffffc00000001fff", "fffe0000000003ff","fffc0000000000ff", "fff80000000000ff","fff000000000007f", "ffe000000000003f","ff0000000000003f" 30 bmp 0,8,"ff0000000000001f","ff2f00000000000f", "ff1fc0000000000f","ff000c000000000f", "ff003f000000000f","ff0020400000000f", "fc0000fc1800000f","fc00000f7f3c000f" 40 bmp 0,16,"f80000037f7e000f","f8000000007e0003", "f01c00c0001cf7c3","f03e03c00000efcf", "f03e07c00e00000f","c03f1ff01f000003", "c03ffff03f800003","cf3ffff87fc380c3" 50 bmp 0,24,"ce3fffffffc3c0c3","c03fc03fffe7f1cf", "c03f003ffffff3c0","ff3fff3fff0fff88", "ff1ffffffc0fff1c","ff9ffffff043ff3c", "ff8fffc03ff3ff38","ff8fffc03ff3fe00" 60 bmp 0,32,"ffcfffff3ffffc01","ffc7fffffffffcff", "ffc3fffffffff8ff","fff3ff007ffff1ff", "fff1ff0c7fffc3ff","fff0ff0c7fffc7ff", "fffc7f0c7fff8fff","fffe3f807ffe1fff" 70 bmp 0,40,"ffff3fc0fffe3fff","ffff07c3fff07fff", "fff023ffffe1ffff","ffe0203fff83ffff", "ff07e00000003fff","fc0fe3ffff8f0fff", "fc3fe3ffff8f0fff","f0ffe3ffff8fc1ff" 80 shift 1,3:delay 99:goto 80

14.3 ビデオゲーム「PONG」を作る

 以下のプログラムはPONGゲームのtinyBasic版です。A0ピンに接続したボリュームでラケットを動かします。このプログラムを入力した時点で残りのメモリー容量はあとわずかしかありませんので、作ることができるプログラムのサイズはこの程度です。

(変数の説明) WとHはそれぞれスクリーンの幅と高さ、AとBはそれぞれプレイヤーとコンピュータのスコア、XとYはボールの座標、DとEはX方向とY方向の移動方向、UとVはラケットの位置、QはBラケットのボール到着予定位置、Cは開始時の1秒カウンタです。

(プログラムの説明) 行120~230がボールの移動。行140~150が得点追加。行160~170がラケットにヒット。行240~280がプレーヤーのラケット移動。行290~370がコンピュータのラケット移動、特に行300~310がコンピュータのラケットが動き始めるまでの遅れを決めている部分で、ここで強弱を調整しています。ラリーが続くと強弱が変化するようにしても面白いでしょう。

 下の写真は、Arduino ProMiniを使い電池で動作させている様子です。ケースに入れれば、立派な(?)「ビデオゲーム機」となります。

10 cls:A=0:B=0:W=48:H=32 20 line 0,0,W-1,0,1:line W-1,0,W-1,H-1,1 30 line W-1,H-1,0,H-1,1:line 0,H-1,0,0,1 40 U=H/2-3:V=U 50 line W-5,U,W-5,U+5,2:line 4,V,4,V+5,2 60 cursor 8,1:print A:if A=9 stop 70 cursor 3,1:print B:if B=9 stop 80 D=1:E=1:if (U+V)&1 E=-1 90 X=5:Y=V+3:plot X,Y,1 100 C=50 110 if C>0 C=C-1: goto 240 120 plot X,Y,2 130 X=X+D 140 if X=0 A=A+1:goto 60 150 if X=W-1 B=B+1:goto 60 160 if X=W-5 if Y>=U if Y<=U+6 D=-D:tone 440,100 170 if X=4 if Y>=V if Y<=V+6 D=-D:tone 440,100 180 Y=Y+E 190 if Y=0 E=-E 200 if Y=H-1 E=-E 210 if X=W-5 if Y=U if E=1 E=-1 220 if X=W-5 if Y=U+5 if E=-1 E=1 230 plot X,Y,2 240 line W-5,U,W-5,U+5,2 250 U=H-1-aRead(0)/16 260 if U<0 U=0 270 if U>H-6 U=H-6 280 line W-5,U,W-5,U+5,2 290 if D=1 goto 400 300 if x>27 goto 400 310 if x=27 if A<=B goto 400 320 line 4,V, 4,V+5,2 330 if E=1 Q=Y+X-4:if Q>=H Q=64-H 340 if E=-1 Q=Y-X+4:if Q<0 Q=-Q 350 if Q<V+3 if V>0 V=V-1 360 if Q>V+3 if V<25 V=V+1 370 line 4,V,4,V+5,2 400 delay 20:goto 110 A:Playerスコア,B:Compuスコア,W:画面幅,H:画面高 枠線描画 枠線描画 U:Aラケット位置(画面右), V:Bラケット位置(画面左) ラケット描画 Aスコア表示(画面右) Bスコア表示(画面左) DはXの増分, EはYの増分 ボール位置(X,Y)にボール描画 サーブまでの待ち時間 サーブまで待つ ボール消去 Xの位置更新 Aが得点 Bが得点 Aラケット(画面右)にヒット Bラケット(画面左)にヒット Yの位置更新 上の壁の跳ね返り 下の壁の跳ね返り Aラケットの上隅で方向変化 Aラケットの下隅で方向変化 ボール表示 Aラケット消去 Aラケット位置はボリューム値 Aラケット位置を範囲内に修正 Aラケット位置を範囲内に修正 Aラケット表示 ボール右移動ならBラケット動かさない ボールが境界位置より遠ければBラケット動かさない ボールが境界位置でB勝っていればBラケット動かさない Bラケット消去 ボール方向が下の時のBラケットボール到着予定位置Q ボール方向が上の時のBラケットボール到着予定位置Q Qに応じてBラケットを上に移動 Qに応じてBラケットを下に移動 Bラケット表示 20ms毎に繰り返す

回路図


PONGの表示画面


Arduino ProMiniを使い
完成後は電池で動作させた例

14.4 ビデオゲーム「シンプルシューター」を作る(学生の作品)

 以下のプログラムは学生の作品です。

シンプルシューター(製作: 山田駿太郎)
 外観は以下の写真のようになっている。また、ディスプレイに表示される画面にはプレイ画面とリザルト画面が あり、それぞれ以下のような画面である。
 プレイ画面の下側に表示された細長いものがプレイヤーの操作する自機である。ボリュームを回すことによって、左右に移動することができる。また、ボタンを押すと自機から真っ直ぐと画面上側に向かって弾が発射される。弾を発射すると、何かにぶつかるまで再び弾を発射することはできない。
 自機のほかに表示されている二つの大きな四角がエネミーである。エネミーは画面上部から出現し、画面下側へ向かってゆっくりと直進する。エネミーに自機の発射した弾が命中すると、そのエネミーは消失し、画面上部から新たなエネミーが出現する。また、エネミーは画面最下部に到着することでも消失し、その場合も新たに画面上部から出現する。この際、右上に表示される3つの小さな四角のうち、1つが消える。これは残りライフであり、すべて無くなるとゲームオーバーとなってリザルト画面に移行する。
 リザルト画面ではGAME OVERの文字とともにスコアが表示される。スコアは倒したエネミーの数×10点で計算される。より高いスコアを目指すことがこのゲームの目的であり、楽しみでもある。
10 cls: clear: w=48: h=48: s=0: i=0: e=0: a=0: n=0: c=0 20 line 0,0,w-1,0,1: line w-1,0,w-1,h,1 30 line w-1,h-1,0,h-1,1: line 0,h-1,0,0,1 40 if n<=2 plot 50,3,2: if n<=1 plot 50,5,2: if n<=0 plot 50,7,2 50 p=aread(0)/22 60 if p<3 p=4 70 if p>w-4 p=w-5 80 if s=1 plot x,y,2 90 box p,w-4,p,w-3,2: plot x,y,1: box r-1,l-1,r+1,l+1,11: box t-1,m-1,t+1,m+1,11: delay 20 100 box p,w-4,p,w-3,2: plot x,y,0: box r-1,l-1,r+1,l+1,10: box t-1,m-1,t+1,m+1,10 110 if a=0 a=1: goto 140 130 if a=1 l=l+1: m=m+1 : a=0 140 if dread(12)=0 i=1: goto 150 150 if dread(12)=1 i=0 160 if s=0 if i=1 x=p: y=h-4 : s=1 170 y=y-1 180 if y=0 s=0 190 if e=1 goto 220 200 r=rnd(40): r=r+4: e=1 210 l=3 220 if r>x-2 if r<x+2 if l>y-2 if l<y+2 e=0: s=0: y=-256: c=c+1 250 if l=48 e=0: n=n+1 260 if f=1 goto 290 270 t = rnd(40): t=t+4 : f=1 280 m=3 290 if t>x-2 if t<x+2 if m>y-2 if m<y+2 f=0: s=0 : y=-256: c=c+1 300 if m=48 f=0: n=n+1 400 if n>=3 goto 420 410 goto 20 420 cls: ? "GAME OVER" 430 ? "SCORE:",c*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を起動し、[ファイル][環境設定]で、スケッチブックの保存場所を確認し、その下にlibrariesフォルダを作ります。
  3. 液晶モジュールを利用するために、ST7032のライブラリ(ZIPファイル)をダウンロードし、解凍して上記librariesフォルダに置きます。
  4. NeoPixel LEDを利用するために、NeoPixelのライブラリ(ZIPファイル)をダウンロードし、解凍して上記librariesフォルダに置きます。
  5. [ツール][ボード]で「Arduino NANO」を選択し、[ツール][プロセッサ]で「ATmega328」を選択します。また、Arduino NANOを接続し、[ツール][シリアルポート]でポートを選択します。
  6. tinybasic20170428.zipを解凍します。ビデオ機能を利用しない場合はこのままでOKです。ビデオ表示やキーボードを接続する場合は、下表を参考に1行目のTVMODEの定義を1~4に変更します。有効にする機能によって作成できるプログラムのサイズ(概ね文字数)が異なります。13.213.4のように少し大きなプログラムの場合は、TVMODEを3にします。
    TVMODE 0 1 2 3 4
    NeoPixel - - - -
    I2C接続(液晶ディスプレイ,
    モータ, 音声合成, 温湿度センサ)
    - -
    赤外線リモコン - -
    ビデオ表示 -
    キーボード接続 - - -
    最大のプログラムサイズ(バイト)1022700584953837
  7. ビデオ表示を有効にする場合は、ArduinoIDEの「ライブラリを管理」でTVoutライブラリを組み込んでおきます。TVoutフォルダの中にTVoutfontsフォルダがあるので、librariesフォルダの下に移動します。また、video_gen.zipを解凍し、TVoutフォルダの中のvideo_gen.cppを上書きします。今のArduinoのバージョンではasm_macros.hで行っているアセンブラのマクロ定義がうまく展開されずエラーとなるため、マクロ定義を使わないようにしました。
  8. キーボードを接続する場合は、ArduinoIDEの「ライブラリを管理」でPS2Keyboardライブラリを組み込んだ後、日本語キーボードに対応するためにDECOさんの「PS/2キーボードを接続してみる」の下の方にあるps2keyaoard_240_mod.zipを解凍し、2つのファイルを上書きします。
  9. 以上の準備ができたらtinybasic.inoをArduino NANOに書き込みます。

 プログラム(tinybasic.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. 電池駆動のための「SLEEP」コマンドを追加したこと
  15. 7セグメントLED表示用の「NUMLED」コマンドを追加したこと
  16. 「PRINT」コマンドでビデオ(有効な場合)と液晶ディスプレイにも表示されるようにしたこと。関連して、「CLS」コマンドや「CURSOR」コマンドもそれらの表示デバイスに適用されるようにしたこと。
  17. ビデオ表示が有効な場合、「SET」「RESET」コマンドの代わりに「PLOT」コマンドを使い、パラメータで色指定するようにしたこと。また、ビットマップパターンをビデオ表示する「BMP」コマンドを追加したこと

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

 下図左のようにテレビやキーボードと接続すると、パソコンを使わずにプログラミングができます(このテキストでは扱っていません)。接続したキーボードとパソコンの通信ソフトのどちらからも操作できます。キーボードの接続については、「PS/2キーボードを接続してみる」を参考にしました。


テレビとキーボードの接続

テレビの表示画面

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

 入出力に利用できるピンは下表のとおりです。D0~D13はすべてデジタル入力(Din)、デジタル出力(Dout)として利用できますが、アナログ出力(Aout)として利用できるピンは限られています。また、アナログ入力(Ain)として利用できるピンは専用に用意されています。

ピン AVR 通常 7seg
利用時
ビデオ
利用時
ビデオ・PS/2
キーボード
利用時
備考
D0PD0RX Din: dRead()で利用
(内部プルアップ抵抗有効)
* SLEEP時はD2がLOWになるとWake up

Dout: dWriteで利用

Aout: aWriteで利用
D1PD1TX
D2PD2 Din* Douta Din DoutPS2 Data
D3PD3 Din Dout Aoutb Din Dout Aout*PS2 Clock
D4PD4 Din Doutc Din Dout
D5PD5 Din Dout Aoutd Din Dout Aout
D6PD6 Din Dout Aoute Din Dout Aout
D7PD7 Din Doutf Video out
D8PB0 Din Doutg Din Dout
D9PB1 Din Dout Aout *Video sync
D10PB2 Din Dout Aout
D11PB3 Din Dout Aout *Audio out
D12PB4 Din Dout
D13PB5 Din Dout
A0/D14PC0 Ain Din Dout aRead() で利用
A1/D15PC1 Ain Din Dout
A2/D16PC2 Ain Din Dout
A3PC3 NeoPixel Pixelで利用
A4PC4 SDA I2Cデバイスを接続
tRead(), hRead(), motor, talk, LCD表示などで利用
A5PC5 SCL
A6 Ain aRead() で利用
A7 Ain

(付録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の整数を格納できる。
配列
@(0~)で代入・参照する。変数には-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
通信ソフトの画面、I2C液晶およびビデオ画面をクリヤーする。

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

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

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

AWRITE ピン番号, 値
指定したピン(D3,D5,D6,D9,D10,D11)に値(0~255)を出力する。

DWRITE ピン番号, 値
指定したピン(D2~D13)に値(0または1)を出力する。これを使ってLEDやモーターをオンオフできる。

MOTOR 左速度, 右速度
左速度、右速度はそれぞれ-255~255。0で停止。

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

TONE ピン番号, 周波数, 時間
TONE ピン番号
周波数はHz、時間はmsで指定する。ピン番号のみを指定した場合は音を停止する。ただし、以下に記すTVと接続した場合は、ピン番号は指定しない(D11ピン固定)。

SLEEP
マイコンをSLEEP(省電力)モードにする。SLEEPモード時、Arduino Mini Pro(8MHz)で約250μA(実測)。D2ピンがPullUp状態となり、スイッチでLOWにするとSLEEPから復帰する。

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

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

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

NUMLED 数
D2~D8に接続した7セグメント数字表示LEDに「数(0~9)」を表示する。0~9以外の数を指定すると表示が消える。

PIXEL LED番号, R, G, B
指定したLED(0~9)に指定した色で点灯する。R(赤),G(緑),B(青)の明るさはそれぞれ0~255で指定する。なお、NeoPixelの制御信号(Din)はA3(D17)に接続する。

□ 関数

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

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

RND(数)
0から指定した数-1までの乱数を返す。RND(5)は0~4のいずれかの整数値を返す。

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

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

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

INKEY(初期値)
キー操作のASCIIコードを返す。キーが押されるのを待つわけではない。

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

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

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

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

□ 命令文と関数(グラフィック)...TV表示が有効な場合

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

PLOT X座標,Y座標,色
指定した座標(X,Y)にプロットする。色は0(黒), 1(白), 2(反転)で、以下についても同様。

LINE 始点のX座標, 始点のY座標, 終点のX座標, 終点のY座標, 色
画面に線を表示する。

BOX 始点のX座標, 始点のY座標, 終点のX座標, 終点のY座標, 色
画面に四角形を表示する。色は0(黒線), 1(白線), 2(線反転), 10(黒ベタ), 11(白ベタ), 12(反転ベタ), 他(白線黒ベタ)...反転表示に不具合あり!

CIRCLE 中心のX座標, 中心のY座標, 半径, 色
指定した座標に円を描く。色は0(黒線), 1(白線), 2(線反転), 10(黒ベタ), 11(白ベタ), 12(反転ベタ), 他(白線黒ベタ)...反転表示に不具合あり!

GET(X座標, Y座標)
座標(X,Y)の値(0または1)を返す。

SHIFT 移動量, 方向
表示画面を指定方向に指定量シフトする。方向は 0(UP), 1(DOWN), 2(LEFT), 3(RIGHT)。

INVERT
画面を白黒反転する。

BMP X座標, Y座標, 文字列
BMP X座標, Y座標, 文字列, 文字列, ...
座標(X,Y)からX方向に文字列で表したビットパターンを連続表示する。「0」~「F」の文字で4ピクセルの色(0:黒, 1:白)を表す(下表)。文字列を「,」で区切ると次のビットパターンは座標(X,Y+1)から表示される。
文字ピクセルパターン
(0:黒, 1:白)
文字ピクセルパターン
(0:黒, 1:白)
0
1
2
3
4
5
6
7
0000
0001
0010
0011
0100
0101
0110
0111
8
9
A
B
C
D
E
F
1000
1001
1010
1011
1100
1101
1110
1111

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

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

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

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

部品表
名称 外観 備考
Arduino Nano 秋月 2780円
(互換品が400円程度で入手できます)
ブレッドボード EIC-701 EIC-701 秋月 300円
ブレッドボード ジャンパーワイヤ 15cm   秋月 10本 300円
ブレッドボード ジャンパーワイヤ EIC-J-S   秋月 250円
LED 秋月 10個 120円
フルカラーシリアルLEDテープ SwitchScience 756円
数字表示LED C-551SR 秋月 40円
圧電スピーカー 秋月 2個 100円
プッシュスイッチ DS-660R-C 千石 84円
抵抗 1/4W 4.7Ω, 100Ω, 220Ω, 470Ω, 1kΩ, 10kΩ 秋月 100本 100円
CDS(光センサ)秋月 30円
温湿度センサ HDC1000秋月 680円
温度センサ LM61CIZ秋月 4個 200円
赤外線反射センサ LBR-127HLD   秋月 50円
サーボモーター SG-90   秋月 400円
リレー SS1A05   秋月 5個 280円
液晶ディスプレイ AQM1602A   秋月 550円
モータードライバ DRV8830   秋月 170円
音声合成LSI ATP3011F4   秋月 850円

koyama@hirosaki-u.ac.jp