エントリー

カテゴリー「make:」の検索結果は以下のとおりです。

aitendoのGPSモジュールの不良について

  • 2016/04/19 12:12
  • カテゴリー:make:

 aitendoのLCDに,同時に買ったGPSモジュールを組み合わせて,新しいGPS時計を作るという話を,ちらっと先日書きました。実はこの製作,現在進行中なのですが,なかなか難しい問題に遭遇してしまい,目下解決策を検討中です。

 いくつかのアイデアを試しましたがどうもうまくいかず,これでダメなら「万策尽きた」と白旗を揚げようと思っていた方法で,現在検証中です。

 ちらっと書きますと,1PPSパルスで画面の更新を行うという方法に起因します。HPGGAセンテンスで時刻を得ますが,問題はこの時刻の情報と1PPSがまったく非同期で,1PPSに対して前後してしまうということです。

 GPGGAで時刻を得てから1PPSで更新するという単純な方法だと,1PPSの直前で1秒進んだ時刻を得ていないといけません。そこで1秒進めたんですが,場合によってはすでに1秒進んだ状態でGPGGAに載ってくる場合があることがわかりました。

 これも,正確な別の時計を横に並べて,時刻をこまめに比較したから分かった事で,GPS時計だけを見ていたら気が付きません。

 GPGGAの時刻情報を1秒進めるかそのまま使うか,条件分岐が必要なわけですが,問題はその条件です。なにせプログラムを実行しているマイコンにとって,時計はGPSのみであって,正確な時刻との比較など出来ません。GPSから出てくる時刻がすべて正しいと考えるしかないわけです。

 で,この問題を対策するのに,手間取っています。まずは条件をつかまえる事,そして対策できたかを確認すること,この2つが必要なのですが,なにせ1秒進めるかそのままでいいかは,不定期に発生するものです。数秒で発生するかもしれないし,ずっと発生しないかもしれません。それで時間がかかっています。

 さて,この製作過程でaitendoのGPSモジュールの問題点を見つけてしまいました。

 今回時計に使った「NEO6M-ANT-4P」というモジュールとパッチアンテナのセットは,GPSモジュールにu-bloxのNEO6Mを使っていて,高感度,多機能で,かゆいところに手が届き,しかも安価と,欲しい人には盆と正月がいっぺんに来たくらいうれしいGPモジュールです。

 現在は値上がりして2800円になったとは言え,今でも十分安いと思います。

 さてこのNEO6M-ANT-4Pは,Warm Start用に衛星の情報を残すための充電式バックアップ電池と,設定情報を保存するためのEEPROMが搭載されています。

 ところが,どうも設定を記憶してくれないようなのです。電源を入れている時は設定の変更が反映されているのですが,電源を切って一晩おくと,初期状態に戻ってしまいます。

 初期状態では,1PPSのパルスは衛星をつかまえていない時には出てこないので,1PPSで割り込みをかけて表示の更新を行うというプログラムでは,衛星を掴むまで表示が全く出てこないことになります。

 衛星をつかまえずとも,モジュール内蔵のRTCの情報を表示出来ればうれしいわけで,そのために設定の変更を行ってどんなときも1PPSが出てくるようにしてあったのです。

 しかし翌日には出なくなっています。

 他にも,ボーレートの変更や,余計なメッセージを出さないようにするなどの設定変更を行っていたのですが,翌日にはそれが元にすべて戻っていて,困ってしまいました。

 当初,ツール(u-center)の使い方が悪いのだろうと思っていたのですが,頑張ってあちこちいじってみても状況は変わりません。いよいよ困り果てて調べて見ると,どうも設定が消える人と消えない人がいるようです。

 そしてさらに調べていくと,バックアップ電池が不良の場合にこの症状が出るという情報を手に入れました。いわく,バックアップ電池が不良と判断されるとCold Startになるため,設定が初期化される,ということです。

 ん?ほんとかいな。

 Cold Startって不揮発メモリであるEEPROMに書き込んだ内容さえも初期化してしまうんでしょうか。だとしたら設定の保存はバッテリバックアップで行われているだけということですから,そもそもEEPROMなんて意味がないと言うことになりませんか?

 まあとにかく,このバックアップ電池をわざとショートして電圧を下げてやると簡単に現象の再現ができるので,原因としては間違いないと思います。しかし,そうなるとEEPROMへの設定の保存(あるいはその読み出し)が確実に行えるようになるには,どうしたらいいんでしょうね。

 この問題,小容量の二次電池で設定がバックアップされているという話ですから,現時点できちんと設定が保存されている人でも,電池が切れてしまえば発生するはずです。つまり,設定の保存先をEEPROMだと思っていたら,実はSRAMでしたということですので,後で泣くことになりそうです。

 根本的には,EEPROMへの設定保存が行えるようになることなのですが,海外ではEEPROM未搭載のボードを改造して設定の保存を行うケースを見つけたものの,もともとEEPROMが搭載されていると場合の対処法は結局見つけることが出来ませんでした。

 あーめんどくさい。

 複数買った人でも,電池は全滅していたという話も聞きますので,どうも個体不良と言うよりはロット不良の可能性もあるんじゃないでしょうか。中国製というのは随分良くなってきましたけども,こういう品質の問題をどうも軽く考えているようで,個体不良は仕方がないとしても,この手の傾向不良を減らせないのは問題だなあと思います。

 で,電池を良品に交換するということも考えたのですが,それでも電池が切れればアウトですので,やっぱり根本対策ではありません。ならば,初期化された設定の状態で使うというのが一番確実です。

 幸いなことに,デフォルトの設定のままでも問題なく動くようにAVR側のソフトを書くことが出来ましたので,これで行きます。

 もっとも,衛星をつかまえないと1PPSが出てこないというのは困ったもので,その間表示が全く更新されません。1PPSが来ない間は勝手に更新するというソフトを組んでもいいんですが,もう面倒くさいので、1PPSが出てこないうちは表示が代わらないという仕様にしました。つまり,信用出来る時刻情報が1PPSという形で得られるまでは,表示を行わないという考え方です。

 一応これで,バッテリが死んでいてもCold Startから起動するGPS時計が出来ました。GPSモジュールをいちいちPCのソフトでいじらなくても,買ってきてすぐ使えるメリットはありますが,せっかくつかまえていた衛星の情報がすっかりなくなってしまうため,毎度毎度Cold Startになって,時刻情報が得られるまでに時間がかかってしまうことは,残念な所です。

 まあ,気が向いたらここにCR2032でも付けてみましょう。

 それにしてもAitendo,一筋縄ではいかないお店です。そこがまた面白いんですけどね。

LCD8812K4-01でキャラクタ表示も出来た

  • 2016/04/11 13:54
  • カテゴリー:make:

 LCD8812K4-01という特価LCDですが,やり残していたキャラクタ側のLCDも動かしてみる事にしました。

 これまでにセグメント側のLCDを表示させ,時計を作ってみたわけですが,LCDの下側にあるキャラクタ表示エリアも動かす事が出来れば,もう完璧です。

 aitendoによると,ここはパラレルの「普通」のLCDということです。まあこの世界で「普通」の「パラレル」といえば,HD44780互換のLCDのことで,これに従って動かすということでしょう。

 ということで,さっと試してみました。随分昔にGPSを使った時計を作ったのですが,この時に用意したtiny2313とLCDを動かすプログラムを,そのまま組み立ててみました。

20160411135615.JPG


 写真の通り,ちゃんと表示出来ています。

 LCDは8ビットのバスを持っていますが,ちゃんと4ビットモードでも動きますので,8本全部を繋ぐ必要はありません。

 また,表示エリアについてですが,16文字x1行という構成ではなく,8文字x2行という構成になっています。

 プログラムでは,1行目に大文字でABC...と10文字を,2行目には小文字でabc...と10文字を表示するようにしています。結果として,左側の8文字は1行目の内容が,右側の8文字は2行目の内容が表示されています。

 ドットが丸いので,独特の雰囲気があります。これとセグメントが青バックの白文字で表示されているというのは,なかなか面白いと思います。

 ということで,LCD8812K4-01の解析が終わりました。これでもうこのLCDは自由に使う事が出来ます。時計と温度計でも作るかと思っていましたが,ふとaitendoでGPSモジュールを買ってあり,1つ余っていることを思い出しました。

 これは1PPSも出せるモジュールですので,これでGPS時計を作り直してみるのが,一番手頃で面白そうです。このLCD,もうちょっと買っておこうかなあ。

AVRtiny13Aでつくるシリーズ番外編 LCD8812K4-01を動かしてみる

  • 2016/04/07 13:42
  • カテゴリー:make:

20160407134351.jpg

 ATtiny13Aを使った工作,今回は番外編です。

 先日,aitendoで99円で購入した,I2CのセグメントLCDを使ったTCXO時計が壊れてしまったことを書きました。

 TCXOの時計だけに時刻はほとんど狂うことなく,それだけにLCDの破損は非常に残念でした。原因は未だ不明ですし,完動品のLCDが手元にないため交換して治ることも確認出来ず,本当にLCDが悪いのかどうかも実は断言出来ません。

 しかし,tiny13AからはちゃんとI2Cで信号が出ていますし,Si5351Aの設定も出来ていることから,やはりLCDに問題がある可能性が濃厚でしょう。

 同じLCDが手に入らないものかなあと探してみましたが,既に売り切れており同じ物は手に配送にありません。全く同じ物でなくてもいいと「I2Cでセグメント」という条件で探してみても,なかなか見つかりません。

 そういえば,先日GPSモジュールをaitendoで買った時に,199円の特価LCDを2つ買ってあったことを思い出しました。これに交換しようと考えたのですが,それはそう簡単にできません。

 このLCDは,「LCD8812K4-01」という品名で売られているものですが,少なくとも昨年の12月頃には売られていたようです。値段は199円と安いのですが,実はデータシートがなく,サンプルコードもありません。要するに動かすにはそれなりに努力が必要なものだということです。それでこの値段はちょっと高いかなあ。

 壊してしまったI2CセグメントLCDの場合,ピン配置もサンプルコードも出ていました。発売されてからの時間も経っていたので,いろいろな人が実際に動かしていたので,そこも問題はありませんでした。

 ですが,今回のLCD8812K4-01については情報が不足している上に,動作例がありません。分かっていることは,LCDコントローラが2つ載っていることと,それぞれ独立したインターフェースであること,セグメント側はSPI(でもHT1621の仕様書にはSPIとは一切書かれていないし,実際のところSPIとは違います),キャラクタ側は8ビットパラレルであること,電源は5V単電源であること,そしてピン配置です。

 問題なのは,仮にセグメントだけを使う場合でも,SPIなのでI2CのLCDの代わりにはならないということです。SPIで繋げばいいだけじゃないかというなかれ。I2CのLCDだからこそSi5351Aとバスを共用でき,そのおかげで8ピンしかないtiny13Aでも時計が作れるのです。

 ですがSPIのLCDを使うとなると,バスをSi5351Aと共用できませんから,I2Cとは別にSPIも用意しないといけません。SPIが3本,I2Cが2本,32,768kHz入力に1本,これですでに6本ですから,ボタンが置けません。うーん,2313を使うしかないのか。

 もう一度考えます。

 I2CはLCDを制御する役割がなくなり,Si5351Aの初期設定だけに使う物になったので,設定後は入力に切り替え,ボタンを置いても良さそうです。そうするとどうにかピンは足りますね。

 どっちにしても,LCDを動かしてみないことには先に進めません。そこで,この前人未踏のLCD8812K4-01を,とりあえずセグメント側だけ動かしてみることにしました。


(1)ハードウェア

 このLCDの端子は16個あります。電源とGNDは共通ですが,セグメントとキャラクタで別々の信号が出ています。今回はセグメントだけを使いますが,セグメントはSPIという情報から,前半の5ピンが関係しそうです。

 aitendoのサイトでは,1ピンからCS,WR,A0,VDD,GNDと並んでいるということですが,SPIにA0なんて端子はありませんし,搭載されていると書かれているHT1621というLCDコントローラの仕様書を見ても,そういう端子はありません。

 そこで,A0というのはDATAであると仮定しました。そして本来HT1621に備わっている読み出し用の端子RDは,このLCDでは外には出ていないものとしました。書き込み専用ということですね。

 仕様書をさらに見ていると,読み出しの際にはRDをクロックにしてデータが出てくるようですけども,これは明らかにSPIじゃありません。ですのでこのLCDはSPIではないということになるのですが,書き込み専用とすれば,SPIと見なして動かす事が出来ます。


(2)SPIをソフトで書く

 SPIは単純ですので,HT1621の仕様書に従ってソフトで実装することにします。マイコンはもちろんtiny13Aです。

 仕様書を見ているとリードについても書かれていますが,RD端子が外に出ていないので今回は無視です。書き込みのみを実装します。

 で,ちょこちょこと書いてみると,なにやら動いているようです。結構あっさり動いてしまったので拍子抜けです。

 コマンドとデータの書き込みを行う関数をさっと書いて,一応簡単なライブラリのような物を作っておきます。

 不安があるのは,ウェイトをどこにどれくらい置くべきかがさっぱりわからないことです。インターフェースのタイミングはわかりますが,例えば電源投入後最初のコマンドを投げるまどれくらい待てばいいかとか,内部発振器の発振安定時間はいくつかとか,コマンドを投げてそれが有効になるまでの時間がどれくらいか等,全然かかれていません。

 とりあえず動いた,と言うやり方で進めるしかなさそうです。こういうのはトラブルの原因になるんだけどなあ。まぁしゃあないですね。


(3)初期設定をどうする

 ここまでで一応LCDを叩けるようになったのですが,初期設定の手順やコマンドの役割などが不明なままです。HT1621の仕様書だけでは正確なところはわかりませんし,LCDごとに異なる設定が必要な箇所もあります。

 とりあえず必要っぽいのは,SYS ENというコマンドと,LCD ONというコマンドを発行することのようです。ところが,これだけだとどうも動作が不安定になってしまいます。具体的には,4ビット目のデータが電源投入のタイミングによって,ちゃんと反映されたりしなかったりするのです。ですから,すべてのセグメントを点灯させようとしてすべて1を書き込んでいるのに,時々一部のセグメントが点灯しません。8になったり9になったりするのです。

 きっとタイミングの問題だろう,特に最後に書き込むデータがおかしいのならデータ送信後に送るCSのタイミングじゃないかと,ここのウェイトを調整しましたが,発生頻度に変化こそあれ,完治しません。困った。

 そこでもう少し調べて見ると,RC256kというコマンドを発行すれば安定して動作することがわかりました。


(4)マッピングを調べる

 初期化までは出来ました。この時点でRAMにデータを書き込みさえすれば,何らかの表示が行われるようになりました。

 次は思い通りにセグメントを点灯させるために,RAMとセグメントの対応を調べます。

 HT1621は,32x4bitのRAMを持っており,これが各セグメントに繋がっています。よって全部で128のセグメントを個別に操作できるわけです。しかし,どこにどのセグメントが繋がっているのかが分かりません。これはもう,地道に実際に点灯させて調べていくしかないです。

 私の場合,まず32のすべてのアドレスに対し1を書き込み,点灯したセグメントに「1」とLCDの写真に書き込みました。次にデータを2にして同じ事をやり,次に4,その次は8と繰り返します。

 終わったら,アドレス1つに0x0fを書き込んで,点灯したセグメントに対してアドレスを書き込んでいきます。結局,128の組み合わせを総当たりで試したわけですね。

 そして,分かったマッピングから,フォントを作ります。あまり複雑な関数を作るとメモリが足りないとか言われそうなので,必要最小限の機能に絞った小さな関数で済むようにします。


 ということで,LCD8812K4-01を実際に動かしたソースです。これを実行すると写真のように左から0,1,2,3,4,5・・・と10桁分数字が並びます。

続きを読む

AVRtiny13Aでつくるシリーズ6 気圧センサとI2Cのリード

  • 2016/04/05 09:44
  • カテゴリー:make:


 そろそろ面倒くさくなってきたtiny13を使った工作ですが,今回で一応一区切りです。I2Cについては,よく考えるとライトはやっていますが,リードはやっていません。センサなどを繋いだ場合はリードがメインになるだけに,これをやっていないというのは少々物足りません。

 なにかないかなとジャンク箱を漁っていたら,随分昔に秋月で購入した気圧センサ,フリースケールのMPL115A2が出てきました。600円。今,同じ物が400円で売られているんですね。

 I2Cで繋がる気圧センサとしては数年前からよく知られたメジャーなものです。デジタルで情報が飛んできますが,残念ながら値を結構複雑な計算で求めねばなりませんし,チップごとに校正された補正値を読み込んで,その係数を使う必要があったりとなかなか面倒です。

 そのわりには,今ひとつ精度も良くないという事らしく,人気の方は今ひとつという感じです。

 ですが,ちょうどI2Cのリードを試すにはちょうどいいですし,600円もしたんですから使ってみたいと思いました。しかし,この気圧センサはLGAというピンのないパッケージに入っており,小型である事もあいまって,実装が大変です。

 変換基板などもありませんので細いワイヤーで信号を引っ張り出すことにしますが,電源とGNDとI2Cの信号線だけですから,4本だけです。それならなんとかなるでしょう。

 ということで,信号線を引っ張り作業を始めたのですが,これがなかなか難しい。すぐに熱が回ってしまうので,一度付けたハンダがポロッと外れてしまうこともしばしばです。

 そうこうしているうちに,なんと電源のランドがハンダゴテの熱で剥がれてしまいました。万事休す。もうダメだ。俺は寝る。

 しかし,虫眼鏡でよく見ると,剥がれたランドのそばに,電源のパターンが走っています。ここにワイヤーをハンダ付けすればなんとかなるかも知れません。

 慎重に他の信号も引っ張り出して,とにかく外部にピンを出す事に成功しました。

 でも,これで動く保証はありません。というか,ほぼ壊れていると考えていいでしょう。そこで,mbedで動作を確認します。サンプルコードを探すと,あったあったありました。

 さくっと実行すると,気圧と温度と高度がLCDに表示されます。それなりに意味のある数字が出ているようですので,とりあえずこの気圧センサは生きているようです。

 で,あとはtiny13Aです。

 I2Cのライブラリの中に,リードを行う関数が用意されてはいるのですが,これをコールすればそれでいいというような簡単な話ではありません。

 MPL115A2の仕様書を読んでいると,リードの際にはまずコマンドを発行して読みたいレジスタを指定するとあります。それが済んだらリードをするという事です。

 ここで注意すべきは,ホストがリードを行う場合には,アドレスに+1しないといけないということです。この+1は,R/Wビットといって,ホストがライトするときには0,リードするときには1を書きます。

 これを0ビット目とし,あとはアドレスを1から7ビット目まで置いた合計8ビットを,スタートコンディションの次に送ります。

 MPL115A2のI2Cアドレスは0x60なのですが,ライトの時には0xc0を,リードの時には0xc1を送る必要があるということですね。

 ところが,スタートコンディションに続いてアドレスを送り,コマンドを送った後,どうやってR/Wビットを1にしてリードモードにすればいいのでしょう。

 仕様書によると,ここはリピートスタートコンディションを送るとのこと。

 べた書きすると,こんな感じになります。

    I2C_Start();
    I2C_write(0xc0);    //    addr + R/W bit = 0
    I2C_write(0x04);    //    command 0x04(read add = 0x04)

    I2C_Start();    // Repeat start condition(W/O Stop condition)
    I2C_write(0xc1);    //    addr + R/W bit = 1

    a0m = I2C_Read();
    a0l = I2C_Read();
    b1m = I2C_Read();
    b1l = I2C_Read();
    b2m = I2C_Read();
    b2l = I2C_Read();
    c12m = I2C_Read();
    c12l = I2C_Read();
    I2C_Stop();

 これは8つの補正値を読み出すコードなのですが,I2Cではストップコンディションを発行する前にスタートコンディションを発行すると,それはリピートスタートコンディションと見なされて,バスが解放されないまま,アドレスを再送出来るのです。

 ところが,変換開始から変換後の値を読み出すところは,またちょっと違うんです。これも仕様書によると,以下のようになります。

    I2C_Start();
    I2C_write(0xc0);    // addr + R/Wbit = 0
    I2C_write(0x12);    // command = 0x12, 0x01(convert start)
    I2C_write(0x01);   
    I2C_Stop();

    _delay_ms(5);

    I2C_Start();
    I2C_write(0xc0);    // addr + R/Wbit = 0
    I2C_write(0x00);    // command 0x00(read add=0x00)

    I2C_Start();        // Repeat start condition
    I2C_write(0xc1);    // addr + R/Wbit = 1

    bm = I2C_Read();
    bl = I2C_Read();
    tm = I2C_Read();
    tl = I2C_Read();
    I2C_Stop();

 0x12というのは変換開始のコマンド,次の0x01はダミーです。ここで一度ストップコンディションを発行してバスを解放しています。そして数ms待った後で,改めてスタートコンディションを出しているんです。

 あとはどこを読みたいか書き込んで,リピートスタートコンディションを出してから読むという流れなのですが,変換開始のコマンドのあと,わざわざバスを解放しないといけない理由がよく分かりません。

 まあ,普通に考えたら5msも待つんですから,その間にバスを明け渡して他が使えるようにしないといけないわけですが,今回のようにバスを占有しても問題がない場合は,別にいいんじゃないかと思ったのです。

 しかし,試してみたらダメでした。

 やはり仕様書の通りに書かないとダメのようです。

 で,あとは気圧と温度の表示なのですが,これがとても面倒くさい。とても1kバイトのメモリに入りそうにないと悟った私は,とりあえず気温だけ表示することにしました。

    t = tm<<2 | tl>>6;
    t = 250-(t-498)*1000/535;
    lcd_cmd(0xc0);   
    lcd_data(t/100 + 0x30);
    lcd_data(t/10%10 + 0x30);
    lcd_data('.');
    lcd_data(t%10 + 0x30);
    lcd_data('C');

 tはint型で,tmとtlはchar型です。tmを2ビットずらし,tlを6ビットずらして,トータル10ビットの値として,int型に格納します。出来るだけ小数点を使わないようにするために,補正式をちょっと修正しました。本当は,25-(t-498)/5.35で計算するんだそうです。でもおかしいんですよ。472で25度になるという話なのに,この式だと25度にならないですよね・・・まあいいか。

 一応これで温度の表示は出来たのですが,値がとにかく数度単位でばらつくんです。それでももうやる気を失って,やめました。

 ということで,なんとなくだらけたところで,このシリーズはちょっと休憩。小さい小さいマイコンを気軽に使いたいという話から,なぜか限界ギリギリを責める話になってしまったわけですが,これはこれでパズルを解くような面白さがあって,とても楽しかったです。

 たまにはこういうこともやってみるものです。

AVRtiny13Aでつくるシリーズ5 温度と時刻を同時に表示

  • 2016/04/04 12:02
  • カテゴリー:make:

 さてさて,お次はTCXOの時計と,LMT01の温度計を組み合わせたものです。LCDにはAQM0802を使って,1ライン目には温度を,2ライン目には時計を表示します。写真が好きな割にはうまく撮れずに恥ずかしいです。

20160404221135.JPG

 右側にあるのがLCDのAQM0802,その左下に8ピンDIPのATtiny13A,その上にはLMT01を寝かせておいてあります。

 LMT01の左側にはTCXOの出力(0.8Vp-pのなんちゃって正弦波)をCMOSレベルに変換するトランジスタ(2SC1815)があり,トランジスタの足下には10MHzのTCXOであるTG-5021があります。

 さらにその左側には2.85VのLDOがあって,すべてに電源を供給しています。LCDの電源としてはかなり低めで動作が心配されましたが,コントラストが低くなってしまったのでそこを調整した以外に,今のところ不具合はありません。

 左下の白い四角いものは押しボタンスイッチです。左が時を,右が分を進めます。両方押すと秒がゼロにリセットされ,離すとカウントを始めます。

 なんでもない時計ですが,実力で時計は1ppm以内の精度,温度計は0.5度以内というもので,これを8ピンの50円マイコンで作ってみようというのですから,なかなか面白そうだと思いませんか。

 ソフトとしては,これまで紹介した時計と温度計を組み合わせるだけです。割り込みは2種類から発生しますので,ここがうまく動くか,ちょっと心配な所です。また,それなりに処理が重いので,割り込み処理が間に合うか,また割り込み以外の処理が次の割り込みに間に合うか,そのあたりも気がかりなところです。

 メモリサイズは,あまり心配していませんでした。というのも,それぞれLCD駆動部分をいれて80%程でしたので,ここを共通化すれば収まるだろうと思っていたのです。

 ですが,やっぱりそうは問屋が卸しません。問題が噴出です。

 まず処理の問題。割り込み処理が間に合わないらしく,LMT01のパルスを正しくカウントしていないようです。これは処理順番を変更して対策。

 次に,割り込みの外の処理が重すぎて,時々変な数字を表示します。これも順番を変更して対策。

 そしてやっぱりダメだったメモリ。出来たバイナリは,1.2kBになっていました。2割もオーバーしているというのは,もう絶望的です。ちょっとやそっとで入る大きさではないですよ。しかも,温度のマイナス表示は外してあります。

 この,メモリを削って行く作業というのは実に地道な作業なのですが,もともと1kバイトしかありませんし,豊富な機能があるわけではないので,削る機能もありません。

 手始めに,LCDとI2Cのウェイトを削って行きます。すると,みるみる減っていきます。AVRのdelayというのは,実は結構なステップ数になると聞いたことがあるのですが,あっという間に100バイトほど減りました。

 もともと必要で入れてあったウェイトですから,外していい物はないはずなのですが,そういうきれい事を言っているわけにはいきません。1つずつ外して,動くかどうかを見て,また外して・・・を繰り返し,とにかく実力依存で動くところまで,削り取りました。

 なにかあったら,速攻でコケるだろうなあ。

 それでもまだオーバーしています。次はLMT01です。以前,摂氏に変換するのにカウント数*10/16-500をする,と書いたことがあるのですが,ここを減らします。

 カウント数が1234だとしましょう。この計算式に従うと,271となります。つまり27.1度ですね。

 これを書き直します。カウント数を10倍するのはあきらめます。これを右に4ビットシフトします。これで1/16されて,値は771となります。

 さて,よくよく見てみると,オフセットである500を減算して影響があるのは,100の位だけです。あとの10の位と1の位はなにも変化しません。それなら,この771を表示する際に,100の位の7から5を引き算し,あとはそのまま表示することにします。

 こうすると,演算が8ビットで済むので,少し減ります。シフトとの合わせ技で数バイト減りました。もちろん,マイナス表示は割り切ります。氷点下になるような場所にいたら体に悪いです。

 キーのチャタリング対策のウェイトも全部外しました。LCDの初期化も,本当に最低限必要な物だけにしました。そして,表示部分も,キャラクターコードのオフセット分0x30を,表示関数の中で加算するようにして,毎回加算することをやめました。

 これで,なんと1018バイト。ギリギリ入りました。かろうじて動いている感じです。

 さて,ここまで来て安心した私は,クロックの設定をデバッグ用の内蔵9.6MHzから,外部10MHzに書き換えることにしました。クロックの設定を9600000から10000000にして,ビルドします。

 すると,あろうことか,1030バイトになりました。オーバーしたため書き込みが出来ないと怒られて気が付いたんですが,せっかくの苦労が水の泡です。クロックを変えるだけで,なんでこんなに増えるのかと泣きたくなりましたが,これはおそらく,コードサイズに影響が大きい,delayで回るループの回数が変わったからでしょう。クロックが速くなると,それだけループもたくさん回すことになります。

 ということで,わずか400KHzの差だというなら,もうそのままでいいじゃないかということで,クロックは9600000にしました。

 これで最終的に1018バイト。これで書き込み,動作を確認しました。メモリもほぼ使い切り,機能的にもこれが限界でしょう。精度はTCXOですので申し分なく,温度計もとりあえずおかしな値を表示してはいません。

 文字化けや表示の乱れもなく,安定して動いてくれているのはいいのですが,消費電流が結構大きいのです。TCXOの電源を安定化したいので2.85VのLDOを通してすべての電源を供給していますが,LDOの入力で5.3mA流れています。

 5.4mAですから,仮に2000mAの単三電池を2本使ったとすると,単純計算で370時間。およそ2週間で電池切れです。これはかなり厳しいです。

 深夜にLCDを消すというのはどうかと考えたのですが,それでも減るのは1mA弱。3日ほど伸びるだけです。電池を4本にすれば1ヶ月,6000mAクラスのリチウム電池を使えば1.5ヶ月です。

 中途半端ですよね。10mA以下ですからACアダプタを出してくるのはもったいないですが,かといって電池ではすぐに切れてしまいます。こうなってくると消費電力を下げる工夫を考えたいのですが,これがなかなか難しいです。

 まず考えつくのはtiny13Aのクロックを下げる事ですが,10MHzで時計を作っている以上は,1/8の分周器しか使えません。でも,1.25MHzでは処理が追いつかないのは明白ですから,これはあきらめます。

 1秒ごとに表示を更新するだけだから,それ以外はスリープに入れればいいとも思うのですが,残念ながら1秒間に625回入る割り込みと,温度センサのパルスのカウント,そしてI2Cの通信でほぼずっと全速力で回っているCPUを止められません。

 それと,実はTCXOが2mAほど消費しています。tiny13Aが2mA,LCDが1mAとして合計で5mAですから,TCXOだけを動かすことにしても,2mA以下にはならないのです。仮に2mAになったとして約40日です。これで電池が切れてしまうというのは,程度の問題とは言え,面倒な事には変わりがないでしょう。

 なので,もうあきらめます。電池で動かすことを最初に目標に置いて,そのために必要な対策を最初から盛り込んでいかないといけなかったと思います。例えばクロックは明らかに周波数が高すぎますから,最大でも32.768kHz,可能であればここはリアルタイムクロックで閉じてしまい,tiny13AはRTCからの割り込みで1秒ごとにデータをもらう仕事に徹します。

 そして夜中はLCDを消します。これでおそらく24時間平均で1.2mA,だいたい3.5ヶ月動く計算です。3ヶ月持てば充電式の電池を使うなら,なんとか許せるでしょうか。

 そう考えると,市販されている時計の,なんと低消費電力なことでしょうか。腕時計なんか,小さな電池1つで,何年も動きます。専用のLSIに専用のディスプレイ,専用の水晶発振子でトータルの精度を維持するという,強烈な技術の集大成です。

 どういうわけだか,私は時計を作るのが好きなのですが,ことこの分野においては,消費電力においても,あるいは精度においても,プロが作る製品に,アマチュアの工作は全く追いつかないことを思い知らされます。

 そうそう,ところで,Si5351Aを使ったTCXO時計を作ったとここに書きましたが,壊れてしまいました。

 どういう訳だかわからないのですが,どうもaitendoの特価LCDが壊れてしまったらしく,手にとって他の人に紹介した直後から表示が消えてしまったことを考えると,どうも静電気で破壊したんじゃないかと思います。LCDの消費電流がゼロのまま,まったく変化しません。

 I2Cで動くセグメントLCDってなかなか貴重で,交換しようにも手頃な物がないのです。残念ですがこの時計はあきらめるしかありません。10日ほど動かしましたが,目視で分かるようなズレが出なかったことを,ここに書いておきたいと思います。

ユーティリティ

2026年04月

- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -

検索

エントリー検索フォーム
キーワード

ユーザー

新着画像

過去ログ

Feed