百裂拳した基板に部品を取り付け。
![](https://blogimg.goo.ne.jp/user_image/3a/b5/7a7c008edb55e91e48118d7473f715ea.jpg)
こんな感じで、とりあえず動くようになったんだけど、
一悶着あった。
これの原型を作ってたのは去年なので、一番新しい
Arduinoのバージョンでもまだ0022のころ。
Arduino1.0で色々と言語仕様やコア内部のコードが
変わったわけで、以前書いた赤道儀のスケッチが
コンパイルエラー。
まぁ、そこまではある程度想像の範囲内なんだけど、
一つ一つトラブルを潰していかないと…。
一つ目。スケッチのアップロード。AVR ISPmkIIで
ブートローダを書き込んで、fuseの設定を済ます。
さて、Arduino-IDEからテスト用のBlinkスケッチを
アップロード。
…エラー出ちゃう。
![](https://blogimg.goo.ne.jp/user_image/25/cf/a241c426ead7368206d9f36f4cc46de5.jpg)
アレコレ手を尽すもなんだかうまく行かない。
調べていくと、どうもハードの障害ではなさそう。
ブートローダは正常に起動して、LEDが点滅している
状態。boardの選択も間違えてないし…
もしや…と思って、書き込んだブートローダのhexの
元ネタを確認してみると0022、アップロードする
IDEは1.0。まさかこれか?と思って、1.0のアーカイブ
に入ってた328用ブートローダhexファイルで書き込み
しなおしてみる。
…アップロードできた。出来たねぇ。なんだろう?
原因はよくわかんない。他のボードも似たような
ものかな?他のボードについては後でまた確認しよう。
Lチカが出来たので、次。LCD用のテストスケッチを
動かしてみる。
…コンパイルエラー。
error: call of overloaded 'write(int)' is ambiguous
だって。これまでは普通に動いていたスケッチなのに、
型が不明確とかいうとなると…Serial.printでbyte型
の引数が無くなったっていう話があったから、きっと
lcdオブジェクトのストリームでもwriteの扱いが
変わったと考えるのが自然かな。
調べてみると、こんな情報。
http://arduino.cc/forum/index.php?topic=95446.0
外字を表示する場合、writeメソッドを使って
hex値の0~7を出力しないといけないんだけど、
この引数を定数で指定した場合、定数の「型」が
不明のためエラーってことになってるみたい。
で、キャスト掛けて(uint8_t)型に明示することで
回避するらしい。
うーん。ladyadaさんが0017でこの機能を搭載して
くれてから便利に使っていたんだけど、Arduino1.0
との相性問題はあるみたい。
この(uint8_t)型にキャスト掛けて使うのは多分
一時的な回避方法だろうから、今後のバージョンアップ
に期待だな。ちなみに(char *)型にキャストすると
値の解釈が変になって文字化け。Arduinoの公式
リファレンスで示されている「型」ではなく、gcc
のAVR用方言(?)型の(uint8_t)型を使うって
いうのはなぁ…
一応、今回作ったハードの凡そとブートローダ機能、
スケッチの最低限の動作確認が取れたところで、
赤道儀用のスケッチをアップロードしてみる。
…やはりコンパイルエラー。当然ながらLCDに外字を
表示しているところがことごとくエラー。一時的に
ここを(uint8_t)型でキャスト掛けることにする。
…動いた。押しボタンもリセットボタンも全部機能
しているし、LCDもちゃんと表示される。(冒頭の写真)
モーター用コネクタにモーターを繋いでみる。
…動いた。モーターもバッチリ。まぁ、ここまでは
期待通り。ちなみにモーターへの給電は年末に月食を
見に行ったときの7.5Vに倣って7.5Vにあわせておく。
これでも小さい赤道儀なら電力的に充分かなぁと。
さて、圧電スピーカ。
…あれ?音鳴ってない。配線自体は間違えてないはず
なんだけどな…と思って、tone関数を使って音を鳴らす
テストスケッチをアップしてみる。
…鳴る。配線の問題じゃぁ無いな。
実はこの圧電スピーカの配線、かなりトリッキーな
作りこみをしてあるので、簡単には解決できなさそう。
一つはISP端子とデジタル端子が重畳されているので、
このISP端子の動作に影響を及ぼさないための回路作り
(ハード側のつくり)と、もう一つは内蔵タイマー
モジュールの制御(ソフト側制御)。
今回おかしくなっているのは多分後者。
他励振の圧電スピーカなので、CPUの出力端子からは
オン信号じゃなくて矩形波を出力しないと鳴らない
んだけど、PWMのうち4本はモーター制御用に使う
ので、タイマー0、タイマー1を充当。残りのタイマー2
はMsTimer2を使って割り込みを掛けて、経過時間を
計測するのに使ってしまっている…。
ってことで、作った当時に悩みながら捻り出した案。
タイマー2をタイマー割込みだけでなく、PWM出力端子
機能も生かしてしまうということ。(ここがソフト側
の制御部分)
もちろん、途中で周波数を変えちゃうと時間が正確に
測れないから一定の音程しか出力できないんだけど、
処理負荷を増やさずに、PWM出力のオン/オフだけ
制御すれば音が出るわけ。こんな感じで。
void buzz_on() {
if (sound_mode == Sound_on) {
TCCR2A &= ~(1<<COM2A1);
TCCR2A |= (1<<COM2A0); //set ports togling when compare match
}
else {
TCCR2A &= ~(1<<COM2A0);
TCCR2A |= (1<<COM2A1); //set ports no togling when compare match
}
}
void buzz_off() {
TCCR2A &= ~(1<<COM2A0);
TCCR2A |= (1<<COM2A1); //set ports no togling when compare match
}
(このブログシステムのバグらしく、左シフト演算子が
うまくコード化できなかったので、全角文字に変えて
あります)
直接SFRを弄るのはArduinoとしてアレなんだけど、
他に良いアイデアが思いつかなかったからこれで
よしとした。けど、ここがArduino1.0コアとうまく
かみ合わないみたい。
試しにArduino0022で同じスケッチをコンパイルして
アップしてみると、ちゃんと鳴る。ハードの故障では
ないことは明確。
ナニが悪さしてるのか、突き止めるのはちょっと
難しいなぁ。まぁなんとか突き止めていこう。
それにしても、いつも言うけど、コンパイラって
いうのはこういう点がどうしても拭えない欠点に
なっちゃうんだよな。
そのことについてはまた後日。まぁ、Arduino1.0も
まだ安定バージョンというものではない、と言える
のかもしれない。
残った課題。
(1)lcdライブラリのwriteメソッドでバイト出力を
どうするか。
(2)音を出す方法について、既存の方法を踏襲するか
別の方法を編み出すか
(3)アップロード機能について、古い基板の古い
ブートローダでは相性が合わないのか確認
かな。