この記事はドライブレコーダーをジョイスティックで自在に首振りさせようという目論見について詳細に説明している。
先日ラズベリーパイでスマートロックをつくろうとして最終的にスマートスイッチを実現させたが、マイクロコントローラーの分野がこれから面白いのではないかと思う。そこで今回は別のマイコン基板を使ってドライブレコーダーを首振りさせてみようと考えた。
ドライブレコーダーを自在にリモート首振りさせたい願望の発端
ドライブレコーダーの有効活用
ドライブレコーダーって今どきほとんどの車に搭載されている。もちろん我が家の車2台もそれぞれ前後を向いて2個ずつ載せている。
しかも前を向いている方は高画質(2.5Kだったか)で録画できる機能を持っている。だからレンタカーを借りる旅行のときにはそれを持っていくし、普段のドライブでもきれいな景色や面白い風景が撮れたときは見返すのが楽しい。
しかしたまたまドライブレコーダーが向いていた方向に撮っておきたい景色があったときはいいが、少しずれているとうまく残せなくてもったいない。
正面固定というのが基本ではあるが事故を起こさない限りちょっともったいない使い方ではある。
つまり、きれいな景色あるいはちょっと撮りたいものがあったらサクッとそっちに首を向けたいのだ。
できるだけ安全に操作したい
とはいえ運転中に手動でいじったら危険だ。寄せたい方向に画面見ながら右手だか左手だかでクイックイッと寄せるのはなかなか大変だ。だいたいドライブレコーダーの固定のボールジョイントって固めにできているし。
しかも一度方向を目的のところに寄せたとしても、そのあと戻すのも危険だ。そんなにくどく説明する必要ないくらい危険だ。
しかもちゃんと同じ位置に戻るかわからん。
だからやるなら安全なやり方じゃないと無理だなって思う。
趣味と実益兼ねてできる方法
ここ数ヶ月はIoTやらスマートホームやらマイコンやらがマイブームとなっていて最初のうちは出来合いのものを買う(スマートコンセントやらスマートスピーカーやらスマートドアホンやら)ので満足していたがだんだん際どいことをしたいと思うようになってきた。
それで一度スマートスイッチを自作したラズベリーパイで今回の案件も実行しようと考えたが用途が絞られるのでArduinoというマイコンボードがネット上での情報量も豊富でできるのではないか。
しかもその価格は安いっぽく、サーボも先日買ったのと同じものなら安いしかなりお安く実現できそう。そしてなにより電動でドライブレコーダーが操作できれば楽しいしネタになる。
またさらに今後ちがうものを作ろうと思ったときのための知見が蓄積できるというものだ。
ドライブレコーダー電動首振り化の構想
安いジョイスティック
直感的に操作するためにはジョイスティックが良かろう。それも安いのでないとだめだ。お金をかければ良いというものではない。
ふだん使い慣れているPS5とかのジョイスティックならまったく違和感なく操作できるかもしれない。もっともPS5もPS4も持っていないのでまったく個人的には使い慣れてはいないが。
ただそれにしてもジョイスティック以外の操作方法はあまり思いつかない。そりゃハンドルについているような4方向のプッシュボタンという手段もなくはないが指を置き換えるのがダルいじゃない?
それよりはロボットアームを操作するがごとくジョイスティックでやるのが最良の選択だ。
しかも案外お安い価格なのだ。
サーボ2個
ドライブレコーダーの首振りでパンとチルトを実現するためには最低限サーボが2個必要になる。
1個だと横方向の首振りだけでイマイチ面白みに欠ける。どうせなら縦方向にも首を振らせたい。
かといってサーボ3個は要るかというといらないだろうな。どう使うよ?それだったらサーボ2個&スライダーみたいな動きをさせてフロントのガラスの上で左右に無尽に動き回るっていうのが面白いがおそらく車検NGだ。
理由は視界の妨げになるとかなんとかいわれるかもしれんが、ガラスの縁から20%以内におさまっていれば何もいわれないかもね。
専用の関節に装着
ネットで「サーボ ブラケット」とかって探すとうじゃうじゃと出てきた。
これはスマートロックを検討していたときになにかサーボを固定する出来合いのものは無いかしらと思って検索してみて見つけたのだ。その見つけたことによりドライブレコーダーの首振りという着想を得たのでやはりネットはインスピレーションの宝庫だ。
で、この関節というかサーボブラケットというかはこれまた安い。サーボ2個取り付けられる2次元タイプで数十円レベルだ。
ドライブレコーダーの首振り以外の使い道を思わずに3個買った。いずれなにかに使いたい。
ドライブレコーダーを貼り付け
その関節式サーボブラケット(とでも呼んでおく)をフロントガラスにくっつけ、さらにドライブレコーダーもうまく貼り付ける。
この記事を書いている時点でまだここの構造について確固たるアイデアを思いついていないがおおよそ見当はついているのでいけると思う。
きれいな景色見つけたらジョイスティックで軽く操作して首振り
そして運転中に正面ではなく右または左に素敵な景色を見つけたら徐(おもむろ)にジョイスティックを傾けてそちらを撮影するというわけだ。
特にお台場なんかに遊びに行って夜になって帰るときにレインボーブリッジから見る夜景にいつも家族どのは歓声を上げるが運転手である俺は脇目をふれない。
だからドライブレコーダーに脇目をふらせるのだ。フロントピラーとか一緒に写っちゃうかもしれんが。
ジョイスティック押せばホームポジションに戻る
そしてその市販のジョイスティックには真ん中で押し込めばボタンとしての機能も持ち合わせている。
これは首を振ったままの状態のドライブレコーダーを正面の定位置にもどらせるのに使えばよい。
実に合理的なジョイスティックだ。そして俺の頭も合理的にできている。
そんなん普通かもしれんが。
ジョイスティックに連動して2個のサーボを操作
つまりここまで読んで察した方も多いと思うが、ジョイスティックを縦方向に倒せばドライブレコーダーが上を向いたり下を向いたり。
横方向に倒せば右を向いたり左を向いたりという動作をするわけだ。昔風にいえばラジコンのプロポだ。
ちなみにプロポってプロポーショナルの略でプロポーショナルってプロポーションの派生語だけど意味は「均整のとれた」っていうことだ。
つまり「彼女、良いプロポーションしてるな」なんていう軽口は「均整のとれた体つきをしているな」という生々しい表現をぼかしているわけだ。
どうでもいいけどここでいうラジコンのプロポは比例制御のこと。均整のとれた体つきと比例制御が結びつかない。
閑話休題。
実現方法
Raspberry Piでやろうと思ってたがArduinoにする
先日Raspberry Piでスマートスイッチを作った話はすでに述べているが、今回も当初はRaspberry Piで作るつもりだった。
だけどたかだかサーボ2個動かすだけだしWi-FiやらBluetooth機能も必要ないのにRaspberry Piだと高機能すぎてもったいないという気持ちはあった。
それでいろいろ調べているうちにArduinoというのが単機能マイコンでうってつけかなと感じた次第である。もちろんこれでなければ実現不可能などということはまったくなく、なんならIC1個と抵抗数個ぐらいでできるっぽい。
ただ生のICで制御するには俺はあまりにも素人すぎる。
ArduinoぐらいならC言語の知識があれば使えるようなのでこれでいく。
ドラレコ比例制御計画に用意するもの
Arduino UNO
これが簡単で使いやすいらしい。もっと安物で機能を落としたものでも良かったのだがそれだと調査と学習時間が増えるのでトレードオフでここで妥協した。
ELEGOO Arduino用UNO R3コントロールボード ATmega328P +USBケーブル
¥1,399(2021/11/11 21:22時点の価格)
平均評価点:
>>楽天市場で探す
>>Yahoo!ショッピングで探す
なにができるかというと電源を入れるとずーっとループして入力を待っている。
で、監視しているポートがアクティブに(今回の例ではジョイスティックを倒す)なったらあるポートをアクティブに(サーボに作動命令)するということができる。
実際にはこのマイコン基板はもっといろいろできるっぽいが今のところ興味はない。
サーボ2個
▼こんなに買う必要はありませんww。2個あれば事足りるので。
マイクロサーボテスターsg909g,メタルギア,rc 250 450,ヘリコプター,飛行機,車用|Parts & Accessories| – AliExpress
サーボはおそらくSG90でパワーは十分だろう。ドライブレコーダーなんてたかが100gか200gぐらいなもんだろうから。サーボはSG90ではX軸は問題なかったがY軸は持ち上げることができなかった。SG92Rにしたら問題なく持ち上げられた。
サーボブラケット
上記サーボSG90用のサーボブラケットはいくらでも見つかるので問題ないが、これで非力だったとして違うサーボに変えた場合、ブラケットが適当なのがないまたは高価過ぎる。問題でそう。
サーボブラケットptパン/チルトカメラプラットフォーム防振カメラマウント航空機fpv専用のナイロンのptz 9グラムSG90|camera fpv|pan tilt platformfpv camera – AliExpress
アナログジョイスティック1個
これもなぜか3個セットのものを買ったが残りの2個は何に使おうか思案中。
VKLSVAN 3個セット ゲームレバーセンサー ジョイスティック ブレークアウト シールドモジュール ジョイスティック ゲーム コントローラ モジュール PS2 Arduinoに対応
¥499(2021/11/12 11:06時点の価格)
平均評価点:
>>楽天市場で探す
>>Yahoo!ショッピングで探す
これはドライブレコーダー首振りの応用で監視カメラの首振りをインタラクティブにできるかなって思う。
ただしこのジョイスティックはアナログ信号を発するやつなのでRaspberry Piとセットで使う場合にはアナログからデジタルに信号を変換する必要があり少々関門がある。
ちなみに今回のArduinoUNOは最初から基板にアナログ入力端子があるのでなにも考えないで使える。
ジョイスティックへの端子接続は上の画像では不格好すぎるので安いLANケーブルを買って先端にヘッダーピンメスをはんだ付けして作った。▼
ピッチはジョイスティックとヘッダーピンとちゃんと同サイズにできているので素晴らしい。
補助電源基板
Adruino UNOの基板1枚でサーボ2個動かすのは少々負荷が高すぎるらしく持たないだろうということなのでこういう補助の電源基板を買った。これもなぜか2個セットだったがこのあとスマートロックをつくろうと思ったら必要になるので良しとする。
KKHMF 2個 MB102 ブレッドボード 電源 ブレッドボード 電源モジュール 3.3V 5V Arduinoに対応 「国内配送」
¥448(2021/11/11 21:20時点の価格)
平均評価点:
>>楽天市場で探す
>>Yahoo!ショッピングで探す
電源の入力はUSBのほかピンジャックも備えている。ただUSBの口はメスなのでこのあと紹介する両端オスのUSBケーブルが必要になる。
オスオスUSBケーブル
さきほど紹介した補助電源の基板についているUSB電源入力口がメスなのでこういうオスーオスのUSBケーブルが必要になる。
サンワサプライ 両面挿せるUSBケーブル(A-Aタイプ) 0.5m ブラック KU-RAA05
¥460(2021/11/11 21:27時点の価格)
平均評価点:
>>楽天市場で探す
>>Yahoo!ショッピングで探す
俺はたまたま以前買ったノートパソコン冷却ファンについていたケーブルがそのタイプだったので間に合わせたからここで紹介している現物ではないが上記条件さえ満たせばなんでも大丈夫だと思う。
ジャンプワイヤー
写真のものはオスーオスだけど、オスーメスも必要だから買うようにしよう。この程度のものなら自作してもよい。っていうか運転席近くのコンソールからフロントガラス上部まで線を引き伸ばすのにどうしても自作は避けて通れない。
サンハヤト ジャンプワイヤ SPP-70 70ミリ
¥481(2021/11/11 21:28時点の価格)
平均評価点:
>>楽天市場で探す
>>Yahoo!ショッピングで探す
パソコン
パソコンなくてできるかというとできない。
Arduino UNOのフラッシュメモリに書き込むのにMACだろうとウィンドウズだろうとリナックスだろうといずれか必要だ。
なんならRaspberry Piでもできちゃうはず。
ArduinoIDEをインストール
パソコン上にArduinoUNO用に環境を構築する。ダウンロードできる公式サイトは▼こちら。
Software | Arduino
インストールしてから設定もろもろについては長くなるので他のサイトを参考にしてほしい。ざっくり数言でいってしまうと
- パッケージをインストール
- 起動
- メニューのツール→ボード→ArduinoUNOと選択
- ファイルを新規作成してプログラムコードを書き込む
- メニューバーにあるレ点アイコンがコンパイル
- その右にある→アイコンがデバイスへの転送
これくらいである。むき出しのボードを使っての開発だからどんだけ面倒な手続きするのかと思いきやかなり簡単にできてしまうのでくどくど説明するまでもない。
首振りのアルゴリズム
ジョイスティックの動き | 水平サーボ | 垂直サーボ |
上 | ー | 上に1度動かす |
下 | ー | 下に2度動かす |
右 | 右に2度動かす | ー |
左 | 左に2度動かす | ー |
プッシュ | 中央に戻す | 中央に戻す |
動きとしたらこんなもんで至極単純だ。
ただ1度動かすとか2度動かすとかプログラム書いては実際に動かしながら最適な数値を見つけていくので変数にして集中して定義するほうがやりやすい。
それと上方向への移動角度の刻みと下方向への移動角度の刻みも分けて定義しておいたほうがいいかも。下へ行くより上へ持ち上げるほうがパワーが要るので小刻みのほうが確実かなという考え。
配線
他の参考サイトのようにきれいな配線図がかけないので写真と文字による説明のみになってしまうが
ピン番号と対応端子を列挙する
Arduino側PIN番号 | 接続先 |
GND(複数あるがどれでも可?) | 単独サーボならサーボのGND(茶色) |
9 | 縦方向サーボの信号線(黄色または橙色) |
8 | 横方向サーボの信号線(黄色または橙色) |
2 | ジョイスティックSW |
3.3V | 単独サーボならサーボの電源(赤色) |
5V | ジョイスティック+5V |
GND | ジョイスティックGND |
A0 | ジョイスティックVRY |
A1 | ジョイスティックVRX |
複数サーボなら | 補助電源の+、ーを各サーボの赤、茶につなぐ |
プログラム作る
いざ画面でトライアンドエラーをなんども繰り返す。アルゴリズムは単純だが実際にはなかなか思うように動かなくて面白い。
なぜ思うように動かないかというと動かすたびに現在の角度情報を変数に格納していくが、それが初期化のときに入れ残っていたり、縦横の変数を書き間違えたりとプログラマならあるあるな間違いをしでかす。
そんなことを繰り返しながらほぼ理想に近い動きができたのがこれ。
サーボブラケットにサーボを固定して無負荷の状態ではほぼ完璧な動きが実現できたので次はドライブレコーダーをぶら下げて結合テストといきたい。
ArduinoってOSを持ってないから1つのデバイスに1つしかプログラムを入れられない。したがってファイル名も存在しない。
// Arduino入門編⑧ Servoライブラリを使い4台サーボモーターを動かす
// https://burariweb.info
#include // Servoライブラリの読み込み
#define DEBUG 0 //←デバッグ1にするとシリアルモニタにいろいろ数字がでる
Servo myservo_H;
Servo myservo_V; // Servoオブジェクトの宣言
//Servo myservo3;
//Servo myservo4;
const int SV_PIN_H = 8;
const int SV_PIN_V = 9; // サーボモーター接続ピンを指定
//const int SV_PIN3 = 10;
//const int SV_PIN4 = 11;
int V_ANGLE;
int H_ANGLE;
//ここからジョイスティックの初期化
const int H_PIN = A0; // X軸方向の入力をアナログピンA0に
const int V_PIN = A1; // Y軸方向の入力をアナログピンA1に
const int SW_PIN = 2; // センタースイッチの入力をデジタルピンD2に
int V_POS ; // X軸方向の読み取り値の変数を整数型に
int H_POS ; // Y軸方向の読み取り値の変数を整数型に
int SW_POS ; // センタースイッチの読み取り値の変数を整数型に
//ここまでジョイスティック初期化
// 限界角度定義
const int H_min_Limit = 0;
const int H_max_Limit = 180;
const int V_min_Limit = 55;
const int V_max_Limit = 80;
const int H_mov_angle = 4;//1回で動かす角度
const int V_mov_angle = 1;
const int H_Nutral = 90;//それぞれの中立角度
const int V_Nutral = 70;
void debug_proc(int angle){
if(DEBUG){
Serial.print("V_POS:");
Serial.print(V_POS);
Serial.print(" H_POS :");
Serial.print(H_POS);
Serial.print(" SW_POS :");
Serial.println(SW_POS);
Serial.print(" angle :");
Serial.println(angle);
}
}
void setup(){
pinMode(LED_BUILTIN, OUTPUT);
myservo_V.attach(SV_PIN_V, 500, 2400); // サーボの割り当て(パルス幅500~2400msに指定)
myservo_H.attach(SV_PIN_H, 500, 2400);
V_ANGLE = H_Nutral;
H_ANGLE = V_Nutral;
//ジョイスティック
pinMode(H_PIN, INPUT); // A0ピンを入力に(省略可)
pinMode(V_PIN, INPUT); // A1ピンを入力に(省略可)
pinMode(SW_PIN, INPUT_PULLUP); // D2ピンをプルアップして入力に
Serial.begin(9600); // シリアル通信の開始
while (!Serial); // 準備が終わるのを待つ
Serial.println("プログラム開始"); // シリアル通信でメッセージをPCに送信//ジョイスティック
}
//センターボタン押下処理
void servo_n(int pin){
if(pin == 0){
debug_proc(0);
myservo_H.write(H_Nutral);
V_ANGLE = H_Nutral;
delay(50);
myservo_V.write(V_Nutral);
H_ANGLE = V_Nutral;
delay(50);
}
}
//縦方向倒した処理
/* //縦方向も動かすならこれコメント外す
void servo_v(int angle){
if(angle <= 100){
debug_proc(angle);
//ジョイスティックピンを左に見たとき上
if(V_ANGLE <= V_max_Limit - V_mov_angle){ V_ANGLE = V_ANGLE + V_mov_angle; }else{ V_ANGLE = V_max_Limit; } myservo_V.write(V_ANGLE); delay(50); // wait for a second }else if(angle >=923){//中央値は513だが精度誤差吸収のため550以上から検出
debug_proc(angle);
//ジョイスティックピンを左に見たとき下
if(V_ANGLE >= V_min_Limit + V_mov_angle){
V_ANGLE = V_ANGLE - V_mov_angle;
}else{
V_ANGLE = V_min_Limit;
}
myservo_V.write(V_ANGLE);
delay(50); // wait for a second
}
}
*/
//横方向倒した処理
void servo_h(int angle){
if(angle <= 100){//中央は512だが精度誤差を吸収するため適当値以下のみ検出
debug_proc(angle);
if(H_ANGLE >= H_min_Limit + H_mov_angle){
H_ANGLE = H_ANGLE - H_mov_angle;
}else{
H_ANGLE = H_min_Limit;
}
myservo_H.write(H_ANGLE);
delay(50);
}else if(angle >=600){//中央値は513だが精度誤差吸収のため適当値以上から検出
debug_proc(angle);
if(H_ANGLE <= (H_max_Limit - H_mov_angle)){
H_ANGLE = H_ANGLE + H_mov_angle;
}else{
H_ANGLE = H_max_Limit;
}
myservo_H.write(H_ANGLE);
delay(50); // wait for a second
}
}
void loop(){
//ジョイスティック読み取り
//servo_v(analogRead(V_PIN));//縦方向も動かすならこれコメント外す
servo_h(analogRead(H_PIN));
servo_n(digitalRead(SW_PIN));
}
こんなところに自分の書いたプログラムを晒すのは生まれて初めてだから恥ずかしいが、もし突っ込みたかったらツイートしてくれ。
2021年12月4日コード修正しました。ジョイスティックのピンを左に見たときに上が縦0左が横0になるようなのでそれに合わせて修正した。
ジョイスティックでドライブレコーダー首振りの結合テスト
結合テストやってみた。
結果・・・・不適合ww指摘事項として
- 左右はまあまあ回るが、上下とくに上方向への動きがダメダメ。ドライブレコーダーの重みを弱小サーボSG90では持ち上げられない
- さらに致命的なのは静止中にもかかわらずサーボが微細動する。ガタガタ震える。心臓に悪い現象。
ということで1に関してはもっと強いサーボ(SG90→SG92)を現在調達中なのでなんとかなるとして、2が問題だ。
ネットでググっても同じような問題をなんか解決した事例もあるが難しそう。
なので現在サーボ待ち(海外調達なので時間がかかる)であるから今回の記事はここまで。期待しながら読み進めてくださった方には申し訳ないと思う。
【追記】動作テスト完了
サーボSG92Rを取り寄せて再度動作確認してみたら問題なく動いた。
よってケーブルさえしっかり敷設して基板とジョイスティックをケースに収めれば完成になる。
最終的な完成形になったらまた追記する。
最終的な完成にはまだ至っていないが、多少の進展があった。サーボのリード線を長くするためにLANケーブルを流用して加工して長い(3mぐらい)のコードを作った。それの断線を防止しつつ先端のピン加工するのに手間取ってなかなかはかどらなかった。
でもようやく延長ケーブルはできたのでそれをフロントウィンドウに敷設してジョイスティックを手元に持ってくることができた。
あとはArduinoUNOとジョイスティックを適当なケースに入れてハンドルそばまたはシフトレバーそばに固定すれば完了だ。また追記する。
謝辞
最後になるがこの工作をするにあたり参考にさせていただいたサイトを以下に列挙する。
サーボ制御
【Arduino入門編⑧】サーボモーターを動かしてみる。PWM制御についていの解説です! | ぶらり@web走り書き
[電子工作]ジョイスティックをArduinoで使ってみた – YouTube
サーボSG90仕様
SG90サーボ仕様書
書き込み方
Arduino IDEプログラミングの基礎とシリアルモニターの使い方 – Indoor Corgi
電源供給
外形5.5mm/内径2.1mmのセンタープラスタイプまたはUSB-B
【Arduion入門編⑩】Arduinoの主な電源供給方法! | ぶらり@web走り書き
アナログジョイスティックのこと
【Arduino入門編⑦】ジョイスティックの制御方法!デジタル・アナログ入力の解説です! | ぶらり@web走り書き
動画
第一弾
第2弾