Categories: 工作・開発

Arduinoで作った自転車の集団走行無線機、孫が祖父のコードを直す

イメージ画像

自転車で列を組んで走るとき、先頭が見つけた路面の穴や急停止を後続へ伝える手段は限られる。手信号は後ろの数人にしか届かず、声は風にかき消される。Outrageous_Rock_4124氏の祖父は、この問題をLoRaの無線機で対処していた。ところが動作が次第に重くなり、不具合も出るようになったため、孫にあたる同氏が中身を書き直した。

装置はArduinoに11個のボタンとロータリーエンコーダー2個、2桁の7セグメント表示器をつないだ形を採る。エンコーダーで0から99までのチャンネルを選び、ボタンを押すと4バイトのパケットが飛ぶ。中身は目印の0xAAとコマンド、チャンネル、通し番号だ。

合図には優先順位があり、完全停止が最も強く、次いで右の危険、左の危険と続く。上位の合図が入るとキューを空にして先頭へ割り込むため、危険を伝える信号が待たされない。送信には250msの錠を掛けて連打を防ぐ。1秒ごとに届くはずの生存確認が途切れたときと、緊急信号を受け取ったときは、装置をオフライン状態にして送信をやめる。

書き直しの中心はキューだった。元の実装は取り出すたびに要素を前へずらしていたうえ、番兵を走査して毎回長さを数え直していた。同氏はこれを、長さを2のべき乗である64に固定したリングバッファへ置き換えた。位置の折り返しは剰余ではなくビット単位のANDで求め、長さは変数で持つ。取り出しにかかる時間は要素数によらず一定になった。

残る2つも同じ方針で削っている。メッセージは文字列で持っていたのを8ビット符号なし整数に変え、送信のたびに文字を扱う処理をなくした。7セグメント表示器の駆動は、エンコーダーから読んだ2進数をその都度手で復号していたのを、0から9までのビットパターンをあらかじめ並べた表の引き当てに変えた。

効果は本人が測っている。Arduino Uno R3で1万回の追加と取り出しを流し、100回の平均を取った結果、1回あたり636マイクロ秒だったものが4マイクロ秒になったとする。ただし比較元となる元のコードは、第三者企業に著作権があるとして公開していない。同氏は新しいコード側は誰でも動かせるとしており、292行のRework.cppがリポジトリに置かれている。

同氏はあわせて、キューの位置を1つ進める処理が配列の外へ出る不具合も直したと書いている。要素を前へずらす実装が配列の末尾で範囲外の番地へ書き込んでいた。動作が重いだけでなく、条件がそろえば壊れる状態だったことになる。

関連情報

Arduino (アルドゥイーノ)
¥5,092 (2026/07/11 19:47時点 | Amazon調べ)

FabScene編集部

FabScene編集部