Rustやっつけフェーズ(8) チューリングパターン (wio-terminal, nalgebra)

前回はこちら。

今回は生き物の模様が出来るさまを数式で再現出来るんじゃないかというチューリングパターンをwio-terminal上で動かしてみる。

内容的にはこちらのお方がPythonで書かれたものをRustで写経。

夏休み研究体験2019 テーマ2:反応拡散方程式

行列計算にはnalgebraを使用。

やっつけフェーズとは

恥ずかしげもなく汚コードを晒しながらも、とにかく動くものを作り続けるフェーズ。

チューリングパターン

出来上がり

最後は何やら意味ありげなマークで安定する。

コード

wio_reactdiff

main

Rustやっつけフェーズ(7) フーリエぐるぐる

前回はFFT:高速フーリエ変換を使用して音ボタンを作成した。

今回はフーリエ繋がりで「任意の関数は、三角関数級数で表すことができる」というフーリエ級数の視覚化を 行う。

具体的にはこのお方達がやっているような円を繋いでぐるぐる回した先をなぞっていくと波形になるという例のやつ。

やっつけフェーズとは

どう書けば正解なのかわからないままとにかく動くものを作っていくフェーズ。

フーリエぐるぐる

出来上がり

コード

wio_elldiski

main

2023/5/20 追記
いまさらだが、以下のオブジェクトをGitにアップするのを忘れていた。誰も見ていないからいいか。
wio-polywave

今回はここまで。

Rustやっつけフェーズ(6) FFTボタン (wio-terminal, fft)

前回正弦波のピッチ周波数をLCDに表示できるところまで行った。

今回は、ある音程とボタンを対応付けて音でリモコン操作を行う。
昭和の昔から受け継がれる伝統的な方法である。

FFTボタン

出来上がり

発音のボリュームを控えているため反応が今ひとつ芳しくないが、なんとなく上手くいってる感じである。

デザイン

各ボタンに以下の音程を割当て。

音程 ボタン
レ:1174.659 5way右
ミ:1318.510 5way左
ド:1046.502 5way下
ド:523.251 Top左
ソ:783.991 Top中央
レ:587.330 5way上
ミ:659.255 5way中央

許容誤差を上下10hzに設定。

コード

wio_fftbutton

main

今回はここまで。

Rustやっつけフェーズ(5) FFT

前回まででアナログクロックはボタン操作での時刻合わせと、ショボいながらもトースト通知が出来るようになった。 そうなると次はボタンに触れずに時刻合わせをするリモコン操作が視野に入ってくる。
「基礎から学ぶ組込みRust」に掲載のmic_fftを流用し、音でのボタン操作を行う。

まずはこのお方のように正弦波のピッチを周波数表示できるところまでやってみる。 ピッチを取る際の基本的な考え方、閾値や補正を参考にさせてもらった。

また、こちらのお方からは、ダウサンプリング時のポイントを、

こちらのお方からは、双2次(BiQuad)フィルタの作り方を、参考にさせてもらった。

やっつけフェーズとは

規約やモダンな書き方に拘らず作りたいものを作り、動けばいいというフェーズ。

FFT

出来上がり

正弦波の発音は、こちらのお方のページを使用させてもらった。 12平均律と周波数

デザイン

以下の設定でピッチ周波数をLCDに表示する。

項目 設定
サンプリングレート 83333.33hz(固定)
サンプリングデータ 4096個
ダウンサンプリング比 1/4
バンドパスフィルタ 880hzを中心として上下1オクターブ以外をカットオフ
窓関数 ハニング窓(通称ハン窓)
FFT用配列 1024個
閾値 25000以上(単位はよくわからん:経験値)
FFT配列インデックスあたりの周波数幅 20.344hz

フィルタ、窓関数をかけるタイミングは以下のとおり。

  • サンプリングデータ取り出し
    データがなくなるまで以下繰返し
    • バンドパスフィルタ
      カットオフ周波数:800(単位:Hz)
      帯域幅:1(単位:octave)
    • データ間引き
      カウント % 4 = 0なら、ハン窓系数を掛けて
      FFT用配列に格納

この後rfft_1024を呼び出し→512個の結果に対してノルムの二乗を取り、閾値以上かつ現在までの最大値であれば、その配列インデックスをピッチとする。

そして最後に謎の補正をかける。

コード

LCDへの周波数表示はatsamd-wio_terminalのexamplesにあるTerminalを流用。
wio-mic-pitch(main)

wio_fft(FFT)

wio_biquad(双2次(BiQuad)フィルタ)

wio_term(ターミナル表示)

今回はここまで。

Rustやっつけフェーズ(4) アナログクロック トースト通知

前回アナログクロックの時刻合わせをボタンを使って行えるようにした。
しかし、針を進めてみるまで時針、分針、秒針のどれがどっちに動くかがわからない。
現在の設定を表示するようしたいのだが、ずっと表示されるのではなくある程度したら消えてくれるやつがいい。
トースト通知と言うそうだが呼称を初めて知った。
仕事中に出てくるとチョーうぜーやつ。

やっつけフェーズとは

Rust初心者、組込初心者の免罪符を頭上に掲げ、規約やモダンな書き方に拘らず作りたいものを作り、動けばいいというフェーズ。

アナログクロック トースト通知

出来上がり

ショボい...ショボい...が、必要な情報は伝わってくる。

デザイン

  • 表示内容はwio_buttonから現在状態を取得する。
    • 今回はHou(時) or Min(分) or Sec(秒) プラス +(前に進む) or -(後ろに進む)
  • いずれかのボタンが押されたら表示。
  • 一定時間経過したら表示を消す。
    • 今回一定時間の測り方は諸事情あり(手抜き)、カウント回数とする。 回数は経験値で設定する。

wio_toast

mainは変更箇所のみ。

main

コード

諸事情あり、rushjobなコード。 いずれリファクタリングしたい。

wio_toast

main

今回はここまで。

Rustやっつけフェーズ(3)アナログクロック ボタン操作

前回までで作成したアナログクロックはsdl2ではos時間を表示できるが、wio-terminal上では電源を入れると00:00:00からスタートする。

時計としての役目を果たすには大体でもいいから現在の時刻を表示してほしものである。

ネットワークから時刻を取得する方法もあるはずだが、このお方もおっしゃるとおり、手動の時刻合わせが最低限ほしい。

ということで、今回はボタンを使って時刻合わせを行う。

やっつけフェーズとは

Rustと組込が初心者だという免罪符を掲げ、規約やモダンな書き方に拘らず、動けばいいというフェーズ。

アナログクロック ボタン操作

出来上がり

ボタン操作をするので画面がぶれる。
言い忘れたが、youtubeも初心者である。

デザイン

◾️ボタンの割当て

①上部左と中央ボタンを交互に押す事で針を進める。
②5Wayスイッチに以下を設定。
・左 :時針
・中 :分針
・右 :秒針
・上 :進める方向をプラスに
・下 :進める方向をマイナスに
③現在押してるボタンと直近押されたボタンが同じなら何もしない。

◾main

先人の肩を拝借し以下の構成とする。
atsamd-wio_terminalのexamplesにあるbuttonsのボタンコントロール、ボタンイベントキュー、ボタンインタラプトを拝借し、mainに配置。

◾️wio_buttons

ボタンイベントの判定や、設定の初期化などは別オブジェクトとして作成。

variant付きenumを使ってかっこよく作ってみようと思ったが断念。まだ早すぎたようだ。
そんな残骸が散りばめられている。

main

wio_buttons

コード

相性の悪かったgithub desktopとようやく折り合いがついたので、コードを格納することができた。

wio_buttons

今回はここまで。

Rustやっつけフェーズ(2)アナログクロック on sdl2

前回アナログクロックをwio-terminalに表示する過程で、「基礎から学ぶ組込みRust」で掲載されているwio-splashをベースとして各参考プログラムからひとつのオブジェクトを作成した。

「基礎から学ぶ組込みRust」ではwio-splashをDrawableオブジェクトとすることで、wio-terminal・sdl2・wasmでオブジェクトがそのまま使え、表示出来るという例題がありそれにならって作っている。

ちなみにRust界ではオブジェクトとは言わないのだが、簡単に表現しようとするとそうなってしまうのは初心者としては致し方がない所である。

やっつけフェーズとは

規約やモダンな書き方に拘らず、動けばいいというフェーズ。

アナログクロック on sdl2

出来上がり

画面に映ってるipadは古い3世代目のもの。そこからvncでさらに古いimac2009lateに裏で入っている。

デザイン

前回作成のオブジェクトをmainで使用し、廻すだけ。 シミュレータなので前準備が簡単。 chronoからos時間を取ってきているので、時間もぴったり。

今回はmainの方だけ。

draw-wioclock-sdl2

もとネタのembedded-graphicsのexamplesにあるdemo-analogclockはsdl2で動いていたので、今回動くのもあたりまえっちゃあたりまえなんだけど、一応構成を変えてるのでこの確認は避けて通れない。 ちなみにwasmは諦めた。トライはしてみたのだか、なんかrust以外のjsやらを触らなきゃいけないっぽい感じがしたのでじゃあいいや、となった。

コード

github desktopと相性が悪いのか全然進まない。 だけど、今回までのコードはほぼコピペでコメントもそのままになってるというちょっと上げるにははばかられる状態で、あといまさらきれいに直す気力もないので今回もパス。

今回はここまで。