リンク

  • ninja analize
  • にほんブログ村

  • ジオターゲティング
  • ヤドカリ図鑑
  • リーフリング
  • NinjaTool
  • カウンター
    無料カウンター

« 分蜂間近 | メイン | 巣箱の改良 »

2015年4月17日 (金)

クリスタルの異常発振??

只今作成中のミツバチの巣箱の重量を測定して記録していく重量計ですが

乾電池の1.5Vからの昇圧もなんとなく上手くいけそうな感じになり

SDカードへの書き込みも無事にできるようになり

データ書き込みのプログラムもまとまり

完成を見据えて、ケースを作製する材料のアクリル板もオーダーしたところで思わぬ不具合が・・・・


この重量計には巣箱の重量を測定して表示するだけではなく、測定した値をその巣箱ごとに記録していく機能を付けているけれども、この重量のデータを残していく上で重要なのが日時のデータなので、回路の中には日時を刻む時計の機能もある。

しかし、この時計の機能に不具合が・・・・

どんな不具合かと言うと

この時計は、あくまでも時計なので、重量計のスイッチを切っていても時刻は止まらずに刻み続ける必要があるので、スイッチをOFFにしても内部の時計機能だけは動作させている。

この時計機能が、普段テストしている時は何の問題もなく正確に時刻を刻んでいるように見えたのですが、スイッチをOFFにしたまましばらく放置して再度スイッチを入れてみると、確かに時刻を刻み続けているけれども、なぜかものすごく早く時刻が進んでいる事に気付いた。

数パーセントの狂いではなく、2倍以上のスピードで進んでいる事になる狂いだった。(狂いと呼べる範囲ではない)

ひょっとして、クリスタル発振子のパルスにノイズが乗ってカウント数が大幅に増えたのか?

しかし、いつもお世話になっているO-Familyさんに相談したところ、スリープ時のノイズが影響するのは考え難いとの事だったので、プログラムをもう一度、ゆっくりと再確認してみたけれども、時刻を早く刻んでしまうような間違いは見当たらない・・・・・

いったい何が原因なのか、いろいろネットサーフィンしてみると、クリスタル発振子は「オーバートーン」という異常発振(周波数が高くなる)をする事があるらしいく、その状態になると周波数が奇数倍になるんだとか??

そう言えば・・・・・・

昨夜、異常を感じてからもう一度時刻を合わせてスイッチをOFFにしたのが夜の12時前だったけれども、今朝7時頃にスイッチONにして確認してみたところ装置が示す時刻は22時になっていた。そして帰宅してもう一度確認すると夜の8時の時点で、装置の時刻は17日の11時半。という事は20時間経過した時点で装置の時刻は55.5時間進んでる。

約3倍程度進んでる事になる・・・・・

奇数倍・・・・・
ひょっとして、オーバートーンという現象が起きてるのか??

これを確かめるのに、とりあえず、スイッチOFF時のパワーセーブからの1秒毎の復帰に合わせてLEDが点滅するようにしてみたところ、普通に1秒のピッチで点滅しているので、このオーバートーンは違う・・・・・・・・


クリスタルが正常に発振してるという事はクリスタル自体でも回路の問題でも無く、残っているのはプログラムの問題だけのはずなので、プログラムの中から、時計の機能以外の部分を全て削除し、時計機能だけを残してテストしてみると、スリープ時に時刻が異様に進んでしまう症状に変わりは無い。

ここで、スリープ時の割り込みのタイミングを確認するためにもう一度、パワーセーブのすぐ後に、LEDを10msecだけ点灯させる

Powersave
Test = 1 

Waitms 10
Test = 0

↑TESTというのは、LEDを点灯させるポート

こんなコードを入れてみて、再度確認したところ、前回と同じく、LEDは正確に1秒ピッチで点滅するけれども、スリープから再起動させたところ、なぜかスリープ時の時刻が正常に進むようになった??

この前記のコードの前後も書くと

P_down:
 Powersave   'パワーセーブモードに     
 Test = 1    ’LEDを点灯  
 Waitms 10  ’10msec間点灯
 Test = 0  ’LEDを消灯  
 If Sw_power = 1 Then Goto P_down  'スイッチがが押されていなければループさせる

上記のコードはパワーセーブの状態からTimer2の1秒毎の割り込みで復帰し、すぐにスイッチの状態を確認して、スイッチが押されていなければすぐに再度スリープさせていたコードの中に、LEDを点灯させるコードを挿入している。

少し前に、LEDの点滅で1秒の割り込みを確認したとき(スリープ時には異様に時刻が進んだとき)のLEDを点灯させるコードは

Toggle Test だけだった

このコードを

Test = 1 
Waitms 10
Test = 0

こう書くことで、時刻が正確に進むようになったので、ひょっとして待ち時間を入れてやる必要が有るのか?、と O-Familyさんに尋ねてみたところ、Timer2を32.768KHzで動かす場合、マイコンの動作クロックを8MHzになると処理時間が短くなり(速く処理できる)、Timer2が仕事を完了する前にスリープに入ってしまうとの事でした。

そんなところで、動作クロックを8MHzにするなら、スリープ復帰から再度スリープに入る間に10~30μsecの待ち時間を入れるべきだとアドバイスを頂きました。


そこで、上記のプログラムのLEDの点滅のコードの代わりに、Waitus などの待ち時間を入れれば解決するんですが、よくよく考えてみれば、いつもの癖で8MHzを使っていたけれども、この重量計のプログラムには8MHzで動かさないと処理できないようなスピードを要求する仕事は無いし、そもそも省電力を望むなら8MHzで作るよりも1MHzにするべきじゃないか??、と考えを改め、1MHzでプログラムを組み直した。


そして、スリープ時にも無事に時刻を刻んでくれるようになりました。

O-Familyさん、今回もありがとうございました。



電気には、まだまだ分からない事が多過ぎる・・・・・(笑)

コメント

割り込みが多重にかかって、時計のカウントが速く進むようになる現象は

AVRのタイマーで32768Hzをカウントして1秒の割り込みを行っているなら
タイマーオーバーフロー状態は 約30usの間続きますから
(32768Hz=30.5us後にカウンタ+1される)
それより短い時間で割り込みルーチンを抜けて、割り込みを待つメインルーチンに戻ると
(まだタイマーオーバーフロー状態なので)再度、割り込みが発生します。
これはAVRではそういうものとして扱うしかありません。

どこかで 31us以上の waitを入れいぇ、多重割り込みが発生しないようにするしかありません。

◆中年会社員Aさん

何が起こってるのかさっぱり分からなかったんですが、何気なく入れたLEDの点滅で糸口が掴めました。
ホント、分からない事が多過ぎます(笑)
この30μsecというのは32768Hzの1カウントなんですね

>多重割り込みが発生しないようにするしかありません。

動作クロックを1MHzに切り替えたところ無事に進む様になりましたが、再度異常が発生する様ならwaitを入れるようにしてみます。

コメントを投稿