最近は、おもちゃ病院で使う小型のツールを作っています。
・導通チェッカ(ChaNさんの導通チェッカをTiny402に移植)
・水晶チェッカ(100MHz周波数カウンタ付き)
・「信号みえ太」簡易オシロ付きロジックチェッカ
最初に作ったChaNさんの導通チェッカが、タカチのSW-53という
小型ケースを使っていたので、このサイズにこだわって作っています。
前回 簡易オシロができたので、信号源が欲しいな?という発想で
今回は超小型のファンクションジェネレータを作ることにしました。
今回も元ネタは、TechnoblogyのDavidさんの「Tiny Function Generator」
です。
8年前の記事で、ATTINY85内蔵のPLLを使って64MHzクロックでPWM波形を作ることで、各種波形を1~5kHzまで出しています。
波形や周波数の変更はロータリーエンコーダを使っています。
これを現代のNew Tinyに置き換えたらどうかと思いました。
ATTINY1614はクロックは20MHzでPLLもってませんが、8bit DACを持ってます。
なんなら、AVR DDシリーズなら、クロック24MHz(外部32MHz)まで使えて、10bit DACを内蔵しています。
またAVR32DD20なら、手持ちで持っています(フラッシュ32MB, 20ピン)
マルツで調べるとAVR64DD14なら、14ピンで¥265(税込¥292)でTINY1614 ¥215と¥50くらいしか変わりません。
まずは、手持ちのAVR32DD20をブレッドボードベースでUIとファームを
開発し、その間にAVR64DD14を注文する作戦をとることにしました。
今回の超小型ファンクションジェネレータの仕様は下記のようにしました。20kHzは出せませんが、10kHzでもおもちゃ修理用としては十分です。
ショート時もOKなように470Ωの抵抗を介して出力しますが、ジャンパで
0.01uFのコンデンサを繋いで、CRによる1次のローパスフィルタを構成可能にします。計算では1/2πCR=33.7kHz 10kHzまで出力は落ちないでしょう
-
0.91’ OLEDディスプレイ(128x32)を使う (元記事と同じ)
-
出力波形:サイン波、のこぎり波、三角波、矩形波
-
周波数範囲:10kHz~1Hz(10kHz時、10サンプル)
-
出力電圧:3Vpp 470Ω
-
フィルタ:CR 1次フィルタ あり/なし はジャンパピンで選択
-
電源ON/OFF: 専用ソフト電源スイッチ
-
Sleep:120秒以上操作なしか、電源SWでSleepに入る
-
波形選択・周波数変更:3接点サムスイッチを使用(信号みえ太と同じ)
左(DOWN)中央(波形選択)右(UP)
中央長押し(1秒)で周波数変更桁を変更可能
桁変更時は、LEDが高速点滅 -
設定値記憶(EEPROM)は今回使用せず(1k サイン波で起動)
-
外形: 53 x 36 x 11 mm(ケースはタカチ SW53使用)
-
電池・消費電流:CR2032コイン電池・使用時10mA、Sleep 1uA
前回メモリの心配がありましたが、今回はメモリは潤沢にあるので大丈夫でしょう。
DACを使うので、タイマー割り込み周期がそのまま波形のサンプル出力周波数に影響します。
最初は320kHzで試験して、どこまでいけるか確認します。
サンプル周波数が320kHzなら、20kHzくらいまで出力できますね。
1周期で16ポイントを確保できます。
100kHzに落としても、10kHzで10ポイント。
オリジナルのTINY85の16kHz割込みで5kHzの出力に比べると
相当の性能アップが見込めます。
信号みえ太はArduinoのMegaCoreを使いましたが、今回はAVR開発の
王道、ATMEL Studio(現MicroChip Studio)を使って開発します。
ブレッドボードでUI検討を行う
まずは、ブレッドボードにタクトスイッチと0.91' oled表示器を組んでみます。
回路図はこちら
主要部品はAVR32DD20、128x32 oled表示器、LED、タクトスイッチx4です。
ブレッドボードに組んだ状態はこちらです。
3連サムスイッチの代わりにタクトスイッチを使ってます。
上からSEL、UP、DOWNスイッチです。一番端の赤いスイッチは電源スイッチです。

ソフトUI検討
DDSの実装の前に、まずはUIの検討を行います。
波形の表示は、信号みえ太で作ったDrawLine()、キャラクタ表示はDrawChar()を使います。
上半分を波形名と波形のグラフィック、下半分は周波数とHz表示、それと表示桁です。
表示桁以外は2倍角なのでだいぶ見やすいかと思います。
ファーム説明
ここまでのファームを説明します。
まずは、main.cのコメントです。AVR32DD20でAVR64DD14にあるピンだけを使ってピンを配置しました。
① CPUのピン設定
UPDI用のPF7は使えないので、空きピンはRESET用のPF6だけです。
この2つはFUSE変更が必要なので、使わない方がいいでしょう。
② クロック設定
信号みえ太では、Arduino IDEが裏で設定していましたが、ATMEL Studioでは自前で設定する必要があります。(FUSEも同様。今回はデフォで使用)
③ TCB0でmillis()の実装
TCB0でmillis()を作ります。24MHzクロックなので24000回クロックをカウントして、1mS毎に割り込みを入れます。
④ メイン表示の処理
つぎはメイン表示の処理です。
128x32bitで縦は4ページx8bitです。7x5bitのフォントを2倍角で表示すると14x10bitになります。
上16bit、下16bitに分けて表示します。
下は周波数表示と桁位置表示(1倍角)です。
14bitなので上下1bit余りますから、一番下は桁のカーソル表示に使います。
2倍角スムース表示
2倍角の場合はエッジがギザギザしないように、これもDavidさんの力作スムーシングビッグフォントを使わせてもらいます。
これを使うときは、コードで DrawStringSmooth()を宣言します。
⑤ スイッチ入力
スイッチ入力は、信号みえ太と同じピンチェンジ割り込みを使います。
SEL、UP、DOWNはPDn、電源(PWR)SWはPAnを使います。
それぞれの割り込み処理は、信号みえ太では割り込みハンドラーで処理していました。
今回はTCB1で高速割り込みを使いますので、スイッチによる割り込みはフラグを立てるだけにして、スイッチの処理はメインループのKey_Event()処理で行うようにしました。
信号みえ太のように割込み処理内で_delay_ms()遅延処理があると、他の割り込みが入らなくなるので、リアルタイム応答がメリットである割り込みの意味がなくなってしまいます。
この方がシンプルで、次回述べるキーイベント処理でのDDS割り込みを止めてのブロッキング処理の見通しが良くなります。
⑥ 表示桁(step) 変更処理
キーイベント処理でどのキースイッチが押されたかを判定します。
SELキーだけ、長押し処理で周波数変更の選択桁を変更する処理に入ります。 この時は選択桁は白字に反転文字で数字を表示する必要があります。
このモードではLEDも高速で点滅し、UP/DOWNキーで選択桁が上下します。もう一度、SELキーを押すと反転文字が元に戻り、選択桁の下にカーソルがでます。
⑦ 周波数/波形変更
この状態でUP/DOWNキーを押すと、出力する波形の周波数を変更することができます。
また、SELキーを短押しすると、SINE/SAW/TRI/SQUの順に出力波形が変わります。
⑧ Sleep処理
Sleep処理はいつものChaNさん方式のdo{}while() ループです。
タイマーが入るか、電源SWが入るとSleepになります。
Sleep前処理をうまくやらないと、Sleep電流が下がらないので注意が必要です。
ここまでのファームは下記のgistにUPしました。
https://gist.github.com/todopapa/c041343b97432571e772db2f981fa427
動作確認
今回設計したUIの動作は下のYoutubeで確認できます。
ここまでにいろいろと試行錯誤しましたが、見やすく使いやすいUIになりました。
今回のまとめ
-
ATMEL STUDIOを使ったAVR32DD20でのUI開発はほぼ完了
-
ロータリーエンコーダから3接点サムスイッチへの移植もOK
-
タイマ TCB1を使ったDDS実装と10bitDAC動作確認は次回に実施予定
-
-
Sleep電流の削減はAVR64DD14移植時に再度検討
ラフ検討では、動作中に10~12mA、Sleep中に数十uAでした。
それでは、次回のDDS実装をこうご期待!
今回は、下記のNote記事と同じ内容になります。
参考資料
今回はtechnoblogyさんより、下記の記事を参考にしました。Davidさんの素晴らしい仕事に感謝です!
Tiny Function Generator http://www.technoblogy.com/show?20W6
Tiny Function Generator Sine Wave http://www.technoblogy.com/show?22HF
Two TFT Graphics Libraries http://www.technoblogy.com/show?5N9Y
Smooth Big Text http://www.technoblogy.com/show?3AJ7

