ちょっとずつしか触ってないArduino Nano Every。
まだライブラリ類が充実していないので、タイマ割込み
とか色々困るところがあったりするんだけど、充実する
まで待ってるわけにもいかないので、あれこれ実験。
直近でやろうとしているのは、ADCを従来のMega328版より
高速に行うこと。
Mega328も、SFRをいじってやれば、Arduinoコアのデフォルト
設定でのADC速度より、少し速くADCを完了させることが可能
なんだけど、可聴域ギリギリ下といった感じ。(約15kHz)
Arduino Nano Everyは、Mega4809のデータシート眺めると、
Mega328よりも約一桁(大体8倍)速くADCを完了することが
できるようになってるみたい。
こないだも書いたけど、多分サンプル&ホールド回路の、
入り口の抵抗が小さくなってたりしてるんだろうと思う。
で、それをふまえてやりたいことはこんな。
(1)素のMega4809用コアで、ADCを行った場合に、1回
あたりどのくらいの速度でADCが完了できるのか
(2)もしArduino環境では遅い設定になっているのであれば、
SFRをいじれば速くできるのか?いじるとしたらどの
レジスタ?ArduinoのC/C++環境からいじるとしたら、
どういうコードを書けばよい?
(3)現状どのくらい速いのかを計測するコードをでっち上げて、
速度を色々見比べてみたい
(4)(3)を行う上で、ICDとか使えないので、ADC1回ごとに
デジタルI/O端子をトグルさせておいて、周波数測定
したいんだけど、そもそもdigitalWriteは遅い(はず)
ので、直接GPIO関係のレジスタをいじりたい
(5)レジスタエミュレーションは、Mega328のレジスタを
エミュレーションしている都合、多分Mega4809
ネイティブのレジスタアクセスよりも遅いはずなので、
ネイティブのアクセス方法とレジスタエミュレーション
を比較してみたい
というわけで、ものすごく迂遠なんだけど、(5)から逆方向
に調べを進めて行きたいなと。
まず、Arduino IDEのサンプルスケッチ「blink」を改造して、
digitalWriteじゃなく、直接SFRいじってblinkを行いつつ、
Delayで時間稼ぎもさせずに、最速でblinkを動かしてみる。
比較対象として、Mega328版のArduino(互換ボード)を
使って、「blink」のコードをこんな風に改造して動かして
みる。
![](https://blogimg.goo.ne.jp/user_image/3d/0e/9e61b553421c5544367a309b0f0899a9.jpg)
Mega328だと、D13(オンボードLED)は、PORT BのPB5に配線
されているので、こんな風に、PORTBの5ビット目をトグル
させてやれば、手っ取り早く目的が達成できる。
で、D13の発振周波数を2倍(HIGHとLOWの分)してやると、
毎秒何回「ADC」と「GPIOへのデジタル出力」が行われて
いるかがわかるわけなんだけど、後者はADCの速度に比較
して極めて小さいので、ひとまず無視してもいいので、
測定した周波数が、1秒間に何回ADCできたかという値になる。
結果、1.987MHz。(これは2倍した後の値)
1秒間にだいたい200万回といったところ。これは、アセンブラ
使って効率的なコードでGPIOをトグルするのに比べれば、
ちょっと遅いといえば遅いんだけど、1回の出力あたりおよそ
8クロック程度の計算なので、まぁ、そんなに悪くないコード
が生成されているとみていいんじゃないかな。
で、懸案のMega4809なんだけど、ネイティブのSFR経由で
GPIOに出力するのは、Mega328とはちょっとコードが違う。
Mega4809のD13は、PORT EのPE2に配線されているんだけど、
https://content.arduino.cc/assets/Pinout-NANOevery_v1.png
このポートにアクセスするためのコードは、
https://tomalmy.com/gpio-on-arduino-nano-every/
https://forum.arduino.cc/index.php?topic=642614.0
このあたりに書かれていたりする。PORT Eであれば、
「PORTE.OUT」っていう変数に、出力したい値を代入
すれば、その内容がPORT E(8ビット分全体)に反映
されるという具合。
また、例によって、「|=」や「&=」といった代入を
使うことで、特定のビットだけを変更することも可能
なのは、Mega328のSFRなんかと一緒。
(ちなみに、色々実験してみた範囲では、ポート単位で
8ビットまとめて入力することも可能だった。例えば、
PORT Eなら、「VPORTE.IN」っていう変数を参照すれば、
8ビット分のデータを読み出すことができた)
こんなコードで実行してみる。(Nano EveryのD13は、
PORT EのPE2なので、PORT Eの2ビット目をトグルする
コード)
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
//digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
VPORTE.OUT |= (1<<2);
//delayMicroseconds(5);
//digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
VPORTE.OUT &= ~(1<<2);
//delayMicroseconds(5);
}
いざ実行して、計測してみると、2.648MHz(2倍した値)。
Mega328よりちょっと速いなぁ。コードの効率がいいのか、
それともGPIO関係の命令の実行速度が速いのか、その辺は
よくわかってないんだけど、少し速いみたい。ほう。
(1回あたり6クロックってことかな?)
さて、Mega328用のコードをレジスタエミュレーションを
通して動かすとどのくらい遅くなるのか…。さっきの
コードを使ってMega4809で実行して、計測してみる。
…2.648MHz。ん?同じだ。レジスタエミュレーションの処理
はいったいどこに行ってしまったんだ?こないだSPI接続の
G-LCDを動かすときにやってみた範囲では、微妙に遅くなって
いたはずなんだけどな。処理の仕方によるのかな…?
でもまぁ、思い切り遅くなっているというわけではないっぽい
ので、もしかしたらMega328用のレジスタエミュレーションを
そのまま使っちゃってもいいんじゃないのかな?という気が
してきた。
さて、(5)が出来たところで、次に(4)を確認してみる。
ADC 1回ごとにGPIOをトグルしてみて、毎秒どのくらいの
回数でADCが実行できるのかを計測してみる。
まず、Arduino Uno(互換)で、analogRead関数でアナログ
入力をするたびに、GPIO(D13)をトグルさせて、その周波数
を計測してみる。
Arduino Unoの場合は…毎秒8926回と出てきた。そうそう。
ADCの速度が結構遅く設定されているから、わざわざSFRを
いじって、最速でADCのサンプルが行える様にしてるきた
んだよな。(可聴域ギリギリでサンプルしたいって場合なら、
この2倍くらいのサンプル速度が欲しい)
※追記:可聴域(20kHz)で考えれば、標本化定理を元に
すると、最低でも20kHzのさらに倍の40kHzは必要になる
よなと思うので、少なくともこの「4倍」以上のサンプル
速度は必要だな、と気づいたので訂正。
じゃぁNano Everyの場合は…毎秒8794回と出てきた。ん?
変わんないじゃん。Mega4809はもともともっと速い速度で
サンプリングしても、最大精度が実現できるのに、なんで
こんなに遅く設定されているんだろう?互換性を考えて
のことなのかなぁ?
なんにしても、こんなに遅い必要はなくて、こないだ調べた
範囲では、8倍ほど速いので、単純計算では毎秒115,384回
のサンプリングを行っても、最大精度で行える計算。
可聴域の5~6倍。
これなら、可聴域よりはるかに高いサンプリングが
最大精度で行えるので、Mega4809はオシロとかに使うには
なかなか使い勝手が良い気がしているところ。
けど、この実験を鑑みるに、Arduino IDEのBOARD情報に
組み込まれている、Mega4809コアのADCの設定は、Mega328
のUnoと同じっぽいので、この性能を思い切り無駄にして
いるみたいだなぁ。
というわけで、(3)(4)は判ったので、(1)(2)
についてようやく調べる段階になった。
Mega4809のデータシートを読めば、どこをいじればADC
の速度を速くできるのかはすぐわかると思うんだけど、
次の問題は、ADC関係のSFRをいじるための、Arduino言語
上でアクセスする変数はどこかに書かれているのか?
ってあたり。
Mega4809関係のコアのソース読めば当然書いてあるん
だろうけど、読みたくない。宗教的な理由で。(手抜き
ともいう)
なので、とりあえず目星をつけて、「大文字」で「SFR
と同じタグ名」でアクセスしてみて、うまくアクセスが
できるかどうかを実験してみるってあたりから手を
付けてみるかなぁ。
https://twitter.com/mucom88/status/1303207102387687427
9月8日は、98の日だったらしいんだけど、そういえばと
ふと思う。8月1日に、これまで「ZX-81の日」っていう
のを聞いた記憶が無いんだよな。
で、ZX-81の日で検索してみたんだけど、なんかヒット
しなかったなぁ。やっぱ、マイナー過ぎなのかなぁ。
https://twitter.com/SuperturboZ/status/1304705218009948161
確か、ZX-81は、Z80搭載で、CPU自らビデオ信号を生成して
いたんではなかったかなぁ。
http://www.net.c.dendai.ac.jp/~anada/#a1
https://twitter.com/kmoroboshi/status/1304041785736347649
P8(正確にはpasocom mini PC-8001)でタイニーゼビウス
勝手移植版。すごいな。
https://twitter.com/navsite/status/1304261198364512256
pasocom mini PC-8001に、大型アップデートらしい。
あぁ、オイラこれ入手してないから、指をくわえて
見ているだけなんだよな。現状。
欲しいよな…
https://twitter.com/L_H_G/status/1302262367560986624
おぉ! PC-8001 Y's(ワイズ)。とても良い。
オイラの知ってるP8の範囲内なんだけど、クオリティーが
すごい。
https://twitter.com/taroohashi/status/1304223058178093056
コシロンのこのビデオ、見たいなと思ってまだ見てないん
だよな。
フィラメントのスプールを載せてグルグルするための
ホルダー。こないだこれとほぼ同じ(同一?)のを買った
のに、買った直後に安いやつ見つけちゃうんだよな…
250円くらい安かった。
https://ja.aliexpress.com/item/33040040443.html
https://twitter.com/HdAnchiano/status/1303798487830728705
スロー映像。これ面白いな。なんでこんな風に、上に
向かってカーブするような軌跡を取るんだろう?
あれか。落ち始めた直後は、落下速度がまだ遅いから
横に広がって、そのあと落下速度が増して来たら、
下に進む成分が大きくなって、横より下に進もうって
いう動きになるのかな。
https://news.yahoo.co.jp/byline/moriakira/20200912-00197787/
台風10号。予想より被害が小さかったっていう評価に
なっているけど、進路が微妙に西側だったからっていう
ことなんじゃないのかなぁ。
でも、中心気圧は高くなったものの、暴風域の範囲は、
当初の予報より広くなってたみたいだな。被害が大きく
なる暴風域が予想より広かったなら、予想以上に被害が
出ててもおかしくなかった。たまたま運が良かったって
ことなんだろうなぁ。
いま関東に近づいてる熱低は、西太平洋の温まった海面を
あまりかき回していないだろうから、次にあの海域で台風
が発生したら、やっぱり強烈な台風になっちゃったりする
んだろうなぁ。
そういえば、3Dプリンタのフィラメントを乾かしたり、
シリカゲルを乾かしたりっていう用途で、何気に布団乾燥機
って、「万能」なんじゃね?って思っていた昨今なんだけど、
もしかして、野菜を乾燥させたりするのにもバリバリ使え
たりするんじゃね?って思って、調べてみた。
https://www.youtube.com/watch?v=i3S26tW91HI
https://agripick.com/1565
やっぱり、やってる人いるんじゃんねぇ。自作している人が
ちらほら。
オイラ、レンコンを薄切りしてレンコンチップを作りたい
んだよな。
以前、リンゴ買ってきて、ネットでみた情報通りに
電子レンジでリンゴチップ作ってみたら、なんかイイカンジ
にはできなかったんだよな。(乾燥しきれないところと、
焦げが出来たところがあったり)
で、布団乾燥機で干したら、イイカンジのリンゴチップ
とかレンコンチップができるんじゃないかな?とか思って
居たところ。