2025年5月16日 (金)

Arduino UNO R3で周波数を計る

UNO R3での周波数計測回路、過去、あれこれ作ってきました。
その応用で、トランジスタ技術2025年6月号
VCO回路V-f特性の自動スイープ測定器」というタイトルで、
VCOの制御電圧を変えながら出てくる周波数を計るという
回路を載せてもらいました。

これの発端が、
2019年12月20日:Arduino UNOで周波数カウンタ
2021年5月1日:Arduino UNOで周波数カウンタ:アナデバの電力計用ICのために

今回のトラ技記事でも、タイマー1(16bit)のインプットキャプチャ
機能で周波数カウント用のゲートを作っています。
しかし、そのキャプチャ周期を1msとして、前回値との差分で
出したカウント値を積み重ねて、周波数としています。
 10ms(100Hz)ゲートなら1msを10回。
 0.5秒(2Hz)ゲートなら1msを500回。
ゲート時間の基本単位が1msで、好きな周期で周波数が
得られます。
  ※低周波なら周期計測のほうが良いのですが
   それはまた別問題。
アナデバの電力計では、ハードウェアで1秒のゲートパルス
を作りましたが、今回のは1ms=1kHzというATmega328Pでも
出しやすい周波数です。
   タイマー1個で作れる
無符号で加算すれば、タイマーカウンタのオーバーフローを
無視して積算することができます。
こんな具合です。
Aa11_20250516091701
これで、1ms=1kHzのゲート時間を作っておけば、その整数倍で
いくらでも好きなカウント時間に拡張できます。

インプットキャプチャで得られた総パルスから周波数を
求められるので、0.1秒(10Hz)周期で得たカウント値を
  この場合は10Hzが最小桁
10回の移動平均しながら処理すれば、1秒ゲートと同じ
最小桁1Hzの周波数が0.1秒ごとにえられます。
周波数の変化を見るとき、1秒待たなくても0.1秒ごとに
動きが分かります。
  電力計では1秒のを10回移動平均して、
  0.1Hzを読んでます。

| | コメント (0)

2025年5月15日 (木)

Arduino UNO R4 minima 電源供給方法でクロックが変わる#3

2025年5月9日:Arduino UNO R4 minima 電源供給方法でクロックが変わる#2 
この続き。

UNO R4の内蔵クロック、とりあえず判明していることは
 ・USBでPCとつないだときはクロック精度が上がる。
    水晶発振並みに
 ・USBを外して外部電源にした時はクロック精度が落ちて
  しまう。
 ・外部電源のときは「HOCOUTCR」トリミングレジスタで
  周波数を調整できる。
 ・でも、USBにつないだ状態でHOCOUTCRを触ったら、
  なんかおかしい。
この他、ジッタ(周波数の微少変動)の問題もあります。

気になるのは、USB接続時のHOCOUTCR操作。
これがどんなものか、テストプログラムを書いてみました。

 ・D4ポートに内蔵クロックを分周して作った1MHzの方形波を出力。
  この周波数をチェックして内蔵クロックの変化を見る。

 ・D3ポートは32ビットのGPT1タイマーのクロック入力に。
  ここにD4ポートが出す1MHzパルスを入れる。

 ・D2ポートをGPT1タイマーのキャプチャ入力に。
  外部から(正確な)1Hzのパルスを入力。
  その↓エッジでカウント値をラッチ。
  1秒周期なのでHz単位でカウント値が読める。

 ・D8ポートはキャプチャのチェックに使える1Hzパルス。
  でもHOCOUTCRを操作して周波数を変えると、この
  パルスの周波数も変わってしまう。
  1MHzパルスと同じ比で変化するので、D8→D2とつな
  ぐと、HOCOUTCRが変わってもいつも1000000Hzジャスト
  のカウント値が得られる。

UNO R4 minimaとの接続はこんな具合。
H11_20250515151201
USBコネクタを外しても通信できるよう、D0ポートの
TXDでデータを出力しています。
  SrealではなくSerial1で。

・制御スケッチ(ファイルタイプをtxtにしています)
   ・ダウンロード - hoco_02.txt

HOCOUTCRを-10~+10まで変化させた時の1MHz周波数を
順次シリアルデータとして出力します。

・外付け電源のときのデータ。
   ・ダウンロード - aux01.txt

・USB接続でのデータ。
   ・ダウンロード - usb01.txt

それをグラフにすると

・外付け電源のとき
Cap004_20250515151601

まっとうに変化しました。
それが、USB接続ではもうはちゃめちゃに。
Cap006_20250515151701
ほぼ1MHzなんですが、ところどころで、タイミングか
なにかは不明ですが、とんでもない周波数が出ています。

これを見ての評価。
  USB接続のときにHOCOUTCRを触ると、クロック周波数が
  とんでもない値になることがある。

内蔵クロックを分周して作った1MHz、USB接続では
1MHzになるよう合わせ込みをしているようです。
しかし、HOCOUTCRをユーザーが変更すると、競合して
しまうようです。

HOCOUTCRの値は、書いたものがそのまま読み出されま
したので、USBでの周波数合わせではこれは触っていない
ようです。

ということで、
 ・HOCOUTCRを触ってメインクロック周波数を
  変えてはダメ。
 ・クロック周波数の精度がいるのなら水晶発振子を
  使うように。

が結論でしょうか。


ちなみに、1Hz信号発生回路はこんなの。
1hz_osc

「ダイソーのミニケース」 に組んでます。
Osc1hz

8ピンの小マイコンを使うとか、リアルタイムクロックICを
使うとか、あれこれ考えられますが、プログラムを組まなくて
も1Hzが得られる4060Bを使いました。
これの欠点。4060Bひとつだと出てくるのは2Hz。
もう1/2したいわけですが、それに何を使うか。

フリップフロップ4013や4027で1/2するのも手ですが、
ワンゲートロジックに「74LVC1G80」という5本足の
「D type FF」があるんで、これで1/2が作れます。
  電源とGND。
  クロック入力(立ち上がり)とD入力。
  そして/Q(反転)出力。
反転出力というのが面白い。
何かのついでに買っておきますわ。

| | コメント (0)

2025年5月 9日 (金)

Arduino UNO R4 minima 電源供給方法でクロックが変わる#2

2025年5月5日:Arduino UNO R4互換:RA4M1コアボードのクロック 
この続きです。

UNO R4(互換機)、初めての通電がこれ。
2025年5月2日:Arduino UNO R4互換品:RA4M1コアボード

D5ピンに1MHzの方形波を出してあれこれしてて、ムムムっと
なったのです。
   これはまだPLLを試す前

結局、Arduino UNO R4 minimaの純正品を買っちゃいました。
  純正品には水晶発振子は付いていません。
A012

内蔵クロックの話、純正品でも同じでした。

 ・USBで通信+電源供給したら周波数精度が良。
   ジッターはあるけど、水晶発振と見間違えるくらい。
 ・USBを外し、外部電源で動かすと周波数が0.2%ほど下がる。

こんな不可思議現象が起こったのです。

この電源供給の方法、新たにこんなことを試してみました。

(1)USBはつながず外部電源で運転開始。
   リセット起動で、周波数は下がったまま。

(2)外部電源につないだままUSBコネクタ(PCからの)を挿す。
   すると、周波数精度良に。
   D8のloopパルスがずっと見えているので
   リセットはかかっていない。

(3)外部電源につないだままUSBコネクタを抜く。
   すると、周波数が下がる。
   リセットはかかっていない。

ブートローダーが走るのは(1)のときだけ。
(2)と(3)でリセットがかかっていないということは、
この発振周波数変化の原因、
  ブートローダーが何かをしているのか?
は、除外できるでしょう。

そして、マイコンに入っているUSBの信号をオシロで見れるよう
にしてみました。
USB+とUSB-、それにloopパルスと+5V電源を見ます。
USBのケーブルをつなぐタイミングでこんな波形が得られました。
Aa000_20250509165401

USBケーブルをつなぐと、1ms間隔で何かし始めます。
そして30ms後に何かゴニョゴニョ。
その後50msほどは静かで、ふたたび1ms間隔の通信に
なります。
これがUSBケーブルをつないでいる間、続きます。

ゴニョゴニョ部を拡大すると、loopパルスが途切れて
いるのが見えました。
Aa001_20250509165501

割り込みで何かしているのだと推測できます。

USBの割り込み処理がどうなっているのかを追いかければ、
この周波数変化の原因と周波数精度アップの手法が見えて
くるかも・・・でっす。

しかし、(1)→(2)の変化はわかるんですが、(2)で安定した
のに(3)で元に戻ってしまうというのも、なんか不思議です。
1ms周期では割り込みはかかっていません。
(3)で抜いた瞬間のloopパルスを見れるようにかな。

※USBコネクタを抜いた瞬間
記録するにはトリガ源が難しい。
こんな波形が得られました。
Ra15
loopパルスが消えているということは、なんらかの
割り込み処理が行われたという判断になるでしょう。

しかし、ここでクロックを元に戻しているのかどうかは
判断できません。
どこで周波数が変わるのかを調べるのは、ちょいとハードルが
高い。
メインクロックを外に出して、微妙な周波数差を見つけな
ければなりません。
周波数差が大きければなんとかなるんですが。

「ブートローダーが何かをしているのか?
 は、除外できるでしょう。」
と記しましたが、USBの抜き差しを検出して何かの
処理をするよう仕掛けたのはブートローダーに
なるのか、それともUNO R4のsetup()を実行する前の
初期化ルーチンなのか。

| | コメント (9)

2025年5月 8日 (木)

スマートロードスターのスピードメータ修理

忘れたころに修理依頼があります。(これで6件目)
 ・2019年5月28日:修理:スピードメータが動かない
 ・2023年10月 5日:修理:スピードメータが動かない #2
ぱっと見、今回もプリント基板スルーホール部のマイグレーション。

Sm12
Sm13

Sm14
なかなかひどいです。
うまく修理できますかどうか・・・

・真ん中の写真を拡大
Sm15
パターンがつながったところに異常が出ています。
「銀スル」かどうかはどうやって判断すれば?

| | コメント (1)

2025年5月 7日 (水)

Arduino UNO R4備忘録

・システムタイマー
  「AGTタイマー0」で1ms割り込み。
    volatile uint32_t agt_time_msをカウントアップ。

・「agt_time_ms」がmillis()の元。

・micros()はこの値にAGTタイマーそのものの値を加味
  して経過時間を得ている

・delay()もこの値を使ってる。

・delayMicroseconds()はUNO R3と同じでソフトウェアタイマー。
   void delayMicroseconds(unsigned int us)
     UNO R3のように14bitという制限はなさそう。

・割込有効/禁止はこんな命令に
  #define interrupts()   __enable_irq()
  #define noInterrupts()  __disable_irq()

  そして、ARMマイコンの機械語では、

  __STATIC_FORCEINLINE void __enable_irq(void)
     __ASM volatile ("cpsie i" : : : "memory");

  __STATIC_FORCEINLINE void __disable_irq(void)
     __ASM volatile ("cpsid i" : : : "memory");

  「CPSIE I」で割込許可。
  「CPSID I」で割り込み禁止。

  ※Z80のように「EI」「DI」でエエやんっと思っちゃいます。
   長い文字、キライです。

・USBではなくD1端子にシリアル出力する「Serial1.print」。
 残念ながらバッファリング処理してない。
 文字出力が終わるまで、元ルーチンに戻ってこない。

 

※関連
Arduino UNO R4、GPTのレジスタ定義にミス発見

※参考
Arduinoの変数サイズをCPU毎に調べてみた:ラジオペンチblog

| | コメント (0)

«Arduino UNO R4互換:RA4M1コアボードで周波数カウンタ