2019年12月8日日曜日

STM32のUARTのDMA送信におけるバッドノウハウ

STM32F4のDMAを使ったUART送信、下記の仕様なのでちょっと勝手の悪いところがありました。

Circular
一度Enableにすると、メモリ上のデータを繰り返し送信し続ける。
Normal
送信後、各種フラグをクリアする必要があり、CPUの命令を消費してしまう。

ゲームボーイのカートリッジでRAMの値を外部に送信しようとすると、NormalではCPUを使う時間が増えるため、動作に支障が出ます。かといってCircularでは、同じ値を送信し続けるので受信側に工夫が必要になってしまいます。最低限必要なデータを、最低限のCPU消費で送信したいのです。

今回のバッドノウハウ

今回は1バイトだけ送信したいので、Circularモードに設定したうえで次のようにENABLEの直後にDISABLEを続けると、ちょうど1バイトだけ送信したところでDMAが止まり、Circularモードなので何事もなく再開します。

DMA_Cmd(DMA1_Stream6, ENABLE);
DMA_Cmd(DMA1_Stream6, DISABLE);

ただこれはボーレートとの兼ね合いもたまたまちょうど良かっただけかもしれません。複数のバイト列を送信する場合には使えないので、そのときは改めて方法を考える必要があります。

2019年11月9日土曜日

ゲームボーイの上で動くソフトウェアと通信をする

ゲームボーイのカートリッジを自分で作って遊んでいます。いままでカートリッジ側のROM・RAM・MBCをすべてマイコンに実装したものを作って遊んでいましたが、カートリッジの外からRAMにデータを書き込む方法が見つからず難儀していました。

マイコン側CPUの処理を使うとゲームボーイが止まる

このカートリッジでは、ゲームボーイに対するROMデータの出力をマイコンのCPUがまかなっています。

  1. ゲームボーイ側がカートリッジにアドレスを渡す。
  2. マイコンがアドレスを受け取る。
  3. Read/Writeのどちらか、バンク設定があるのかを判断して、返すべきデータを決める。
  4. マイコンがデータを出力する。

1バイトとはいえ、どのデータを返すかが決まるまでにいくつかの条件分岐が入ります。なので、外部通信等で他の処理がCPUを使用すると、このデータを返す処理が間に合わずゲームボーイ側がハングアップします。

外部通信の受信をDMAに任せたらどうか

今回、受信したデータをそのままカートリッジRAMの領域に直接書き込む形にしたら問題が解決しました。DMAのサンプルコードをみると、受信したあとそのデータを確かめるためのコールバック関数があったりしますが、その部分が動くとCPUを使ってしまうため、その部分は絶対に使わないようにします。ゲームボーイのソフト側は、DMAの書き込み先に合わせた特定のアドレスだけを読むようにすれば、カートリッジRAMに書き込んだデータをゲームボーイ内で扱うことができます。

実装例

ゲームボーイのカートリッジRAMにMIDIデータを書き込み、MIDIノートオンのときにゲームボーイ側で音を鳴らす仕組みです。

MIDIは、フォトカプラで受信後はbaudrateが31250のUARTとしてそのまま扱えるので、マイコンのDMAで直接RAMに書き込むことができます。書き込まれる予定のアドレスをゲームボーイ側は常時監視し続け、MIDIノートオンのメッセージを受信したら、ノート番号に合わせた音程で音を鳴らすという仕組みになっています。

2019年7月1日月曜日

大量のセンサーデータの可視化にKibana+Elasticsearchが最適だった話

第52回のIoTLTで話した内容を、改めて記載します。

センサーの測定値を数分おきに取得していたんですが、2年ほど動かしていると結構な量になりまして、CSVに変換してExcelでグラフにしようとすると描画まで強烈に待たされるようになってました。何かいい方法はないかと困っていたところ、同じく3月のIoTLTで発表のあったKibanaを使って可視化をがんばる話を聞き、これは良さそうと思って試しました。

Kibanaについて

Kibanaは全文検索エンジンElasticsearchのフロントエンドとして動くWebアプリなので、Kibanaを使うにはElasticsearchも合わせて使います。Elasticsearchにどんどんデータを溜め込み、ブラウザ経由でKibanaに接続してグラフを設定します。

基本機能はオープンソースになっていて無料で使えるのもありがたいです。

Linuxだと環境構築がすごく楽

たまたま持て余していたPCにLinux (Ubuntu 18.04) を載せて動かしています。公式に記載のaptを使った手順に従うと、光の早さで構築できました。最初はもともと入っていたWindows 10で動かそうとしたのですが、特にKibanaのZipパッケージはNode.jsのモジュールがまるっと入っており(KibanaはNode.jsのWebアプリとして動作する)、解凍で何年も待つくらい遅くてあきらめました。

数万件のセンサーデータからのグラフ描画が速い

まずElasticsearchが全文検索エンジンなので、溜め込んだデータの中から特定の条件にマッチするデータの抽出が非常に速いです。さらに、すべての時系列データを描画するのではなく、細かい範囲ごとに最大最小や平均などでデータを間引きしてから描画するので、長期間の動きをサクッと確かめることができます。

データの追加について

今手元で生成され続けているデータは、コマンド出力結果そのままのテキストだったりバイナリ生データだったりするので、Elasticsearchに投げ込むには一手間加えてJSONにする必要があります。今この部分はNode.jsを使って変換しています。これはNode.jsが使い慣れているだけで、実際はどの言語を使ってもいいと思います。

ちょっと困っているところ

グラフをディスプレイに表示し続けるとテレメトリーのようでかっこいいのですが、無料枠ではこの表示中も編集可能でロックはできません。ライセンス購入になると一気にいい値段になってしまうようで二の足です。

2019年4月15日月曜日

技術書典6のふりかえり

技術書典6で机をいただいたので、展示とPDFの頒布を行ってきました。どちらかと言えば本を売るよりもMaker Faire気分で、作ったものの自慢に出てました。

被チェック数

前回の2倍以上の数になっていて驚きました。サークルカットにわかりやすい画像を設定したせいかな、と思っていましたが、いくつかのニュースサイトに掲載されていることに気付きました。

それぞれあからさまに「自分で作るゲームボーイのカートリッジ」と書いてくれていました。ありがたい限りです。開催中も「お友達から買ってくるように言われた」という方が3人くらいおられまして、興味を持ってもらえるのは嬉しいけど参考になるだろうか?と若干不安です。

チップチューンのみなさんからの期待

もともとは「できそうだから」という軽い気持ちで作っていた自作カートリッジなんですが、LSDjを動かすためのカートリッジが年々減っているなかのポッと出てきた新作、かつ日本語で対応できるとのことで湧き上がっているとうかがいました。思わぬ方向からの援軍にモチベーションが高まりますね。

今後の課題

  • もう少し展示に気を遣う
  • そろそろ量産できそうかな
  • M3にも出てみようかな
  • ゲームボーイカラーの対応

お持ちいただいたゲームボーイカラーだと、起動ロゴ以降アプリケーションが動作しませんでした。旧ゲームボーイ用カセットということで動いてくれないものか…と期待していたのですが、一筋縄ではいかなさそうです。

2019年2月24日日曜日

ゲームボーイの自作カートリッジでLSDjが動くようになった

ゲームボーイのカートリッジを自分で作り、技術書典に本を出してから、LSDjが動くといいねという話をよく聞いていました。やっと動くようになったのでつまずいていた点を記載します。

マイコンの容量を増やす

今までの基板ではSTM32F407を使っていました。1MBのFlashを持っているのですが、これだと前述の512KBのROMイメージと128KBのRAM領域を確保できなかったので、ROM容量の多いSTM32F427(2MB)/STM32F413(1.5MB)の2種類を試しました。パッケージサイズは同一でピンアサインもほぼ同一です。

STM32F413でもROM/RAMの領域を確保でき、ソフトの起動を確認できました。413は427に比べてQSPIが載っているので、外部Flashを活用するならこちらのほうがいいのかもしれません。でも2MBの427は大して単価もかわらないのに容量がでかいのでもう全部これでいい気がしています。

MBC5の動きに対応したコードを追加する

今までも動いてはいたんですが、上記のように実装を間違えていて、音がぶつぶつと途切れるようにしか鳴らないし全くテンポどおりに動かない(超遅い)動作になっていました。リンク先のドキュメントと、もとのコード(コメントアウトになっているところ)を見てて気付きました。

音が鳴るようになりました

お知らせ

技術書典6に出ます。前回出展時の本に加筆修正を加えて、第2版として出します。値上げするけど、今まで買ってくれた人はそのままダウンロードできるようにする予定です。「い06」でデモ機と見本誌を用意して展示します。

バッテリーバックアップについて

外部Flashに保存かな〜と考えていたのですが、2MBだと容量の余裕がすごいので内蔵Flashに保存でいいのかもしれません。