Digitalians' Alchemy Diary Archive



あるけみすとの居る風景:2009 年 05 月

2009/05/31(日)

 ATtiny13A 遊びのつづき。赤外線リモコンの受信をやってみた。前回のようないい加減なアルゴリズムではノイズを拾って誤動作が多くなるので、もう少しまじめに考える。今回使っている古い DENON のリモコンは、こんなデータを送っているみたい。

DENON リモコンタイムチャート

 こんなアルゴリズムでいけそう。

 パルスの間隔を測るには、IRリモコン受信素子からの入力の立ち下がりで割り込みをかけて直前の割り込みからの時間を計ればよい。データのフォーマットから見て時間分解能は10マイクロ秒程度は欲しいところだが、一方データの切れ目を正しく認識するためには、秒単位の無信号区間を正しく認識する必要がある。時間を 16 bit 整数で処理したのではオーバーフローしてしまうし、かといって 32 bit 整数を使うとプログラムが大きくなって 1 KBytes の制限を簡単に越えてしまう。タイマオーバーフローの割り込みルーチンを少し工夫しないといけない。

 で、いろいろ試行錯誤の結果、こんなプログラムができた。リモコンのボタンに対応して PWM 出力を変化させるようになっている。コンパイルしたバイナリは 876 bytes だった。1 KBytes なんてすぐいっぱいになっちゃうねえ。まあ、本格的に使おうと思ったらアセンブリ言語で書くことになるんだろうな。

2009/05/30(土)

 ヒメの運動会。スローガンが「限界を超えろ!」云々だったり、騎馬戦に妙に気合いが入っていたり、当地独特の(?)ノリについていけないところは相変わらず多いが、まあ幼稚園の時と比べると子供たちが中心にやっている(ように見える)ぶん心安らかに見てられるかな、という印象だった。スローガンは事前に学校から募集のプリントが配られていて、似たような傾向の去年のスローガンを見て妻が頭を抱えていたので、「ケンカ売ったったらええんちゃう? 『みんなちがってみんないい』とか」などと無責任なことを言っていたのだが、結局応募はしなかった。ところで、ヒメはかけっこでトップだったらしく(ごちゃごちゃしていたのでわからなかった)、幼稚園の運動会でのあのちんたらぶりと比べるとずいぶん進歩したようである。新体操教室でトレーニングしている成果が出ているのかも知れない。もっとも、5人中の1番だからそう大したことはないけどね。

2009/05/29(金)

 HMDT 木下さんが、書籍「Dynamic Objective-C」のプレゼント企画をやっておられます。連載されているとき、こんな濃い内容の連載が長く続いていること自体がすごい(筆者も企画も)と思っていたのだが、とうとう本になったんですね。てか3月発売だからだいぶ前か。木下さんのブログもかなり昔(Darwin 解体新書の頃)から愛読しているけど、プレゼント企画はスルーしていた。今回はいつもより競争率低そうだから手を挙げてみよっと。デザインパターンのあたりは専門知識が足りなくて連載ではついていけなかったんだけど、本になったのを読んだら少しぐらいは理解できるかも知れんし。

 Objective C は素晴らしい言語だと思う(Objective C 2.0 はちょっと保留だけど…)。なんというか、「いいかげんさ」加減が絶妙なのね。システム組み込みのクラスにあとからメソッドを追加できる、とかね。「うわ、こんなので動いちゃうんだ」というのが快感。だからコーディングが楽しくなる。iPhone みたいな小さいシステムにまで Objective C を採用するなんてすごいと思う。"Think Different" というのはそういうことだったのか、と今頃になって思ったりする。

2009/05/25(月)

 お約束の LED 点滅…はサンプルそのままなので、PWM出力をやってみた。いくつかモードがあるが、Fast PWM Mode というのがわかりやすい。初期状態ではシステムクロックは 1.2 MHz なので、これを8分周してタイマークロックにする。"Set OC0A on Compare Match, Clear OC0A at TOP" モード (COM01:0 = 0b11) にして、値を OCR0A にセットする。PWM 出力は OC0A(ピン5)に出てくる。セットした値が255の時出力は完全に0、0 の時ほとんど1(256クロックに1回だけ0)になる。「負論理」になってしまうのがイマイチ使いにくいが、「完全に0」が実現できることは必要なので、やむなくこうした。

 テストプログラム。ピン3にLEDをつなぎ、ピン5の出力をテスターで測る。5秒ごとに電圧が変化するはず。

#include <avr/io.h> #include <util/delay.h> int main(void) { DDRB = 0b00010001; /* pin 3 (bit 4) and pin 5 (bit 0) for output */ TCCR0A = 0b11000000 /* PWM: set OC0A on compare match and clear at TOP */ | 0b00000011; /* Fast PWM */ TCCR0B = 0b00000000 /* Fast PWM with TOP = MAX */ | 0b00000010; /* Clock prescale by 8 */ OCR0A = 0; /* PWM duty ratio */ for (;;) { char i; for (i = 100; i >= 0; i--) _delay_ms(50); PORTB ^= 0b00010000; /* toggle the LED */ OCR0A = 128; for (i = 100; i >= 0; i--) _delay_ms(50); PORTB ^= 0b00010000; OCR0A = 255; for (i = 100; i >= 0; i--) _delay_ms(50); PORTB ^= 0b00010000; OCR0A = 128; for (i = 100; i >= 0; i--) _delay_ms(50); PORTB ^= 0b00010000; OCR0A = 0; } return 0; /* never reached */ }

 Makefile も少し手直しが必要。-p $(DEVICE) をそのまま使うと、-p attiny13a となるが、これはエラーになってしまう。

DEVICE = attiny13a CLOCK = 1200000 PROGRAMMER = -c avrisp -b 19200 -P /dev/tty.usbserial-A7006Uq3 -p t13 OBJECTS = main.o ... AVRDUDE = avrdude $(PROGRAMMER) # -p $(DEVICE) を削り、PROGRAMMER の行で指定

2009/05/24(日)

 ATtiny13A のプログラミングに挑戦中。何はともあれデータシートに目を通す。プログラムエリア 1 KBytes(!)、スタティックRAM 64 Bytes(!!)。狭ッ! パソコンのプログラミングですっかりお大尽スタイルが身に付いてしまっているから、メモリ節約の精神を育まなければならない。そもそも、初めてプログラミングに手を染めた時から、RAM は 64 KBytes 「も」あったんだからなあ。そうか、こういうのを業務としてがりがり書いている人たちがいて、その人たちが今の我々の電化生活を支えているんだな。今どきあらゆる電化製品にマイコンは組み込まれてるものね。当たり前のことだけど、改めて自分の手でこういうものに触ってみると、感慨深いものがある。

 必要な道具を揃えていく。まずはクロスコンパイラ一式。CrossPack というパッケージを使う。Mac OS 10.3 以上対応、ユニバーサルバイナリ。コマンドラインのツールのみだが、どうせそんなに大きなプログラムは書きようがないのだから、これで十分。

 次に、マイコンにプログラムを書き込むプログラマー。これはいろいろ調べたのだが、Arduino をプログラマーとして流用できるという記事を見つけた(Arduino AVR In System Programmer (ISP))。ページの下の方のコメント欄にあるリンクをたどって、mega-isp のページから avrisp.03.zip をダウンロード。解凍すると Arduino のスケッチが出てくる。配線は、スケッチの中のコメントに書いてある通りで、Arduino のピン 10, 11, 12, 13 をそれぞれ ATtiny13A の RESET, MOSI, MISO, SCK(ピン 1, 5, 6, 7)に接続する。また、ATtiny13A の Vcc, GND(ピン 8, 4)は Arduino の 5V, GND にそれぞれつなぎ、間にバイパスコンデンサ(セラミック 0.1μF)を入れる。Arduino のピン 7, 8, 9 には LED(8 は赤,7, 9 は緑)をつけて、150Ωの抵抗を介して GND につなぐ。

 avrdude を使ってテストしてみる。さっそくハマってしまった。

$ avrdude -b 19200 -c avrisp -p t13 -P /dev/tty.usbserial-A7006Uq3 avrdude: stk500_getsync(): not in sync: resp=0x15 avrdude done. Thank you.

 何が Thank you だよ、Sorry とか何とか言えんのかこら。これはえらく手こずったが、gdb でステップ実行すると正常に動作するのがヒントになって、解決できた。原因は「Mac, Linux では、Arduino の USB-serial ポートをパソコン側でオープンすると、そのたびに Arduino がリセットされ、ブートローダから実行が始まる。Arduino 2009 の場合はこれにおよそ 0.5 秒かかるので、その間はデータを送ってはいけない」ということだった。Duemilanove の公式リファレンスに書いてある(Automatic (software) Reset のところ)。avrdude のコマンドラインオプションか何かでディレイを設定できないかといろいろ調べてみたが、どうやら avrdude にパッチを当てないとしょうがないみたい。

--- stk500.orig.c 2009-05-23 22:56:56.000000000 +0900 +++ stk500.c 2009-05-23 22:57:00.000000000 +0900 @@ -660,6 +660,7 @@ { strcpy(pgm->port, port); serial_open(port, pgm->baudrate? pgm->baudrate: 115200, &pgm->fd); + sleep(1); /* Toshi Nagata; for use Arduino 2009 as an AVR writer */ /* * drain any extraneous input

 これでどうやら、ATtiny13A への書き込みは正常にできるようになった。なんとなく、マイコンのプログラミングは Windows 必須かなというイメージがあったのだが、Mac だけでなんとかなりそう。

2009/05/22(金)

 ダンゴムシの赤ちゃんを確認した。4月にもいたような気がしていたのだが、これはどうも別の虫だったらしい。今度はちゃんと虫メガネで拡大してダンゴムシの形をしているのを確かめたので、間違いない。冬を越してから今までの間に、成虫の方がだいぶ死んでしまったのだが、なんとか赤ちゃんが成長してにぎやかになってくれるといいのだが。

2009/05/21(木)

 朝から、某講習会。最初から最後までパワーポイントを使った講義だったが、講師は座って原稿を読み上げているだけで、画面を全く指し示さない。そのかわり、画面の文字がゆらゆら揺れたり、一部が拡大されて強調表示になったりすることで、かろうじて口頭の説明内容と画面が同期するようになっている。パワーポイントの資料は静止画でいいから、話している部分を指差してくれたらよかったのに。それならもう少し目を開けて聞いていられたかもしれない。言い訳だなこりゃ。

 夜、今月いっぱいで異動する後輩の送別会。楽しい飲み会になった。

2009/05/19(火)

 ここまで来たらやっぱりリモコンでプラレール車両のモータ制御に挑戦しないといかんやろな、と。先行研究はたくさんあるし、市販品のリモレールもあるので新鮮味はまったくないのだが、人まねであっても自分の手で組み立てればいろいろ覚えることもあろう。なんせハードウェア工作は経験値限りなくゼロに近いんだし。

 詳しく回路図とその解説が書かれている Badmojo 電子研 さんのページをお手本にする。車両に組み込まないといけないので、小さなユニバーサル基板にがんばってハンダ付けした。トランジスタを逆向けにつけて頭を抱える、という間抜けなミスを(しかも2回も)しつつも、なんとかリレーとFETを載せた実験基板は完成。モータをつないで回してみたところ、PWMで回転速度は一応制御できているみたい。リレーを使った逆回転もできた。

 次はマイコンの組み込みか。まさか Arduino2009 を積んで走る訳にもいかないしな。実は ATTiny13A を調達済みなのだが(Arduino から入門したんだから、やっぱり PIC じゃなくて AVR でしょ)、さてファームウェアの書き込みがちゃんとできるかどうか…

2009/05/16(土)

 「Arduino でプラレールのストップレール制御」のつづき。赤外線リモコンでコントロールしてみる。受光素子は PL-IRM0208-A538(秋月)。割り込みを使うので、digital In 2 に接続。リモコンのデータフォーマットは FUTABA WEB さんを参考にした。受信素子の出力の変化を割り込みで捕まえて、間隔をマイクロ秒単位で測ってパターン照合すればいいわけね。

 まずは手持ちのリモコンの出力を調べてみた。古〜いDENONのCDデッキのリモコンが余っていたので、これを調査。スケッチはこちら。シリアルモニターで見てみると:

# 37 72 34 65 34 72 34 174 34 74 34 65 34 179 34 67 34 76 34 65 34 72 34 174 34 70 35 65 34 70 35 4778 37 72 34 65 34 72 34 174 34 74 34 172 34 72 34 174 34 183 34 172 34 179 34 67 34 177 34 172 34 177 34 4220 37 72 35 64 34 72 34 174 34 74 34 65 34 179 34 67 34 76 34 65 34 72 34 174 34 70 34 65 34 70 35 4778 37 72 34 65 # 16 # 35 72 32 68 34 72 34 174 34 74 34 65 35 179 32 69 34 76 34 65 34 72 34 174 34 70 35 65 34 70 34 4778 37 72 34 65 34 72 34 174 34 74 34 172 34 72 34 174 34 183 34 172 34 179 32 69 34 177 35 172 34 177 34 4220 37 72 34 65 34 72 34 72 137 74 34 65 34 179 34 67 34 76 34 65 34 72 34 174 34 70 35 65 34 70 34 4779 37 72 34 65

 数字の単位は10マイクロ秒。んーなんかリーダ部がないような気がするんですけど、こういうフォーマットもありなのかな。"# 16" の行はノイズを拾ったもの。上のログでは1回だけだが、実はけっこう頻繁に出る。

 ついで、サーボモータとLED(7セグメントLEDは外した)をつけて、2つのボタンで発進・停止ができるようにしてみた。スケッチはこちら。いい加減なアルゴリズムだが、一応動いているみたい。明日はレイアウトに組み込んでテストだな。

2009/05/10(日)

 この週末、子供たちは「無限つみき」にハマっていた。9x3x1cm の白木の木片が200個あるだけ、という極度に単純なおもちゃなのだが、これが意外に面白く奥が深い。遊んでいるうちに想像力が刺激されるらしく、けっこう凝ったものを作っていた。まあ、高く積んだのが倒れてしまって大泣き、という事故が起きるとめんどくさいことになるのだが。

2009/05/06(水)

 「Arduino でプラレールのストップレール制御」のつづき。レイアウトに組み込んでみた。

Arduino-ストップレール3.1 レイアウトの上半分。基本は、自動乗り換え駅を真ん中に置いた大きな単一ループ。斜めに配した大鉄橋と二連クリアドームの高架が気に入っている。
Arduino-ストップレール3.2 レイアウトの下半分。複線区間が続くが、ここは並走する。一方、上の写真で乗り換え駅の手前にある複線区間は対面で走る。対面で走る方ももう少し長くする予定だったのに、複線曲線レールが5本しかない。8本あるはずなのに…
Arduino-ストップレール3.3 Arduino ストップレールの配置。駅の直前で自動ターンアウトレールで分岐して、小さいループで本線の少し手前に戻る(何もつながずに縦に一本置いてある直線レールは、レールの継ぎ目の浮きを支えるもの)。Arduino ボードは大した機能はなく、単に手動で停止/発進して赤/緑のLEDが連動するだけ。

 位置センサで電車の存在を検出して、ぶつからないようにストップレールを制御、というのは工作のテーマとしては面白いんだけど、手で操作する余地がなくなってしまう。見てるだけじゃつまらんもんね。坊は、2段スピードの車両だけを集めてわざわざ低速でまったりと走らせていた。うーん、やっぱり本体の速度制御が本命?

2009/05/05(火)

 「Arduino でプラレールのストップレール制御」のつづき。タクトスイッチ2個と7セグメントLED2桁を追加した。

Arduino-ストップレール2.1 全景。単4エネループ6本で動かせるようにした。
Arduino-ストップレール2.2 ブレッドボード周りの配線。
Arduino-ストップレール2.3 7セグメントLEDの下にも配線してます。
Arduino-ストップレール2.3 実体配線図。

 これでどう遊ぶかが問題なんだな。最初、赤スイッチを押すと10秒間停止して(LEDで残り時間をカウントダウン)自動的に発進、ただし緊急用に緑スイッチを押して手動発進できる、というのを作ってみた。ところが、子供たちにやらせると、「赤で止めて緑で発進」とばかりやっていて、これじゃあ手動のストップレールを操作しているのと何も変わらない。そこで、「赤スイッチを押すと3秒間カウントダウンしてから停止、5秒したら自動発進」というのを作ってみたら、タイミングを合わせて押す遊びをいちおうやってくれた。意外なことに、ヒメの方が熱心で、坊はすぐに飽きてしまう。電子系のギミックにはあまり興味がないのかな。まあ、自分でやってみても大して面白くないので、飽きてしまうのが正しいリアクションと言うべきかもしれん。いちおうスケッチを公開しておきます。

2009/05/04(月)

 岡崎市図書館「りぶら」へ。移転前の図書館はなんともせせこましい建物だったが、今は広々としてとても見やすく、過ごしやすくなっていた。特に子ども図書室は、通路が広いし、棚が低くて見通しがきくし、たいへんよろしい。ただ、肝心の蔵書はいまひとつインパクトを欠いている気がする。定番の本は一通りそろえてあるんだけど、面白そうな本がなかなか見つからないんだな。ハコ(建物)は良くなったので、ぜひ中身も充実させていただきたい。

2009/05/03(日)

 また風邪をひいてしまった。名古屋の人ごみでもらってきたようでもあるし、妻が少し前から調子が悪かったのと同じ症状なので単にそいつをもらったようでもある。一瞬だが38度近い熱も出たりして、結局先週の平日は一度も研究室に顔を出せなかった。今日はほぼ回復。