MP-101ワイヤレスリモコンの作成
xbeeとarduinoでビデオカメラのLANCと電動雲台をワイヤレスリモコンコントロールさせる機材を自作
MP-101と言う知る人ぞ知るカメラ用の電動雲台があります。
かなり前に発売された装置ですが、現在までそれに取って代わる機種が少ないため配信系の業界ではあちこちでよくお見かけする現役マシンです。これのワイヤレス化は通称「加賀式」と呼ばれる優秀な機材が開発して販売されているのですが、この一年ぐらい販売が停止されているようです。2017年に私は一台購入して使用していたので、追加購入をしたくお願いしてみたのですが、一年待っても販売が再開されないため諦めておりました。
最近音楽のライブ配信をワンマンで実施することが結構あり、2台目のMP-101を使ってやりたくなっておりました。また、なぜか配信中にカメラ側の色温度設定を変更しないといけない現場がありリモートで色温度が変えたくなりました。そこでネットを調べて自分でモドキ的な装置を作成したので、他に困っている方がいれば参考にどうぞという気持ちで公開してみます。自分で考えたと言うより先人の知恵の拝借ばかりですので参考資料をよくご覧ください。
もちろん諸諸細かいところまで考えて作成されている「加賀式」に比べると怪しいので、販売などはしません。電子工作マニアで無い限り手を出せないでしょうし、電子工作マニア的に他に参考になる方がいれば幸いかなという気持ちです。
参考資料1)MP-101 無線リモコンキット 通称「加賀式雲台」 https://shop.project92.com/
とりあえず動く回路を考えてみる
目標は「加賀式」に近づくことですので、目標はMP-101のコントロールとLANCの実装になります。MPー101 の動作原理はワイヤードリモコンの代わりをするだけなので比較的単純で、「加賀式」さんのHPで回路図は公開されてますし、動作回路はネットで数個存在しました2)のでこちらは特に問題は無くできそうな感じでした。問題はLANC回路の方ですがこちらは参考資料の3)や4)を参考にしてまずブレッドボードで実験。特に3)の方が解析された、JVCカメラのショートカットアサインLANCコマンドが発見できなければそもそもこの計画は動きませんでした。感謝します。(配信で使用しているメインのカメラがJVCGY-HM175なので色温度をLANCで変えられるのを発見したときに、この部分だけでも自作しようと思い立ちました)ここまでは特に問題も無くすんなりと。先人の知恵をほとんどそのまま活用させていただいてます。
参考資料3)Arduino による、自作LANCリモコン・製作レポート http://www.next-zero.com/Lib/LANC-RemCon/
arduinoでLANCがコントロール可能なことが分かったので、後は無線化です。以前Blackmagic のATEM用ターリーランプのワイヤレス装置を作成して現場活用してますが、このときは単純にライトのONOFFだけだったのでArduinoEthernet 互換機+TWE-Liteで送信側。受信側はTWE-Liteのみで作成して安定運用してます。しかし今回は受信側にもarduinoが必要となります。雲台に取り付けられるように作成するためにはかなりの小型化が必要となるため(それでも私の実装技術では「加賀式」より大きくなるのは避けられない)TWE-Liteよりも小型の「加賀式」でも採用されているxbeeに初挑戦。
xbeeはTWE-Liteよりもかなり複雑でした。結局シリアル通信の置き換えで使えると言うことが分かったので当初arduinoNANO互換機で設計試作。送信側 受信側2台用意してまずは有線でシリアル通信させて基本的な動作プロトコルを開発。加賀式さんでソースは公開されてないため、ここからは完全に独自に検討。やりたいことは相手側に送信コマンドを送り、受信側でそれを読み取ってLANC送信やMP-101 を動作させれば良いので、単純に送信側でUpボタンを押したら「A}を送ったりDownボタンを押したら「B」送って受信側でそれ読み込んで待って動作すれば良いかなと。結局なんか上手く動作したので最後までこのままで実装。xbeeを間に挟んで動作させた場合どうも本当はAPIモードというのがあってこれじゃないとまずいかもとか考えましたが、APIモードはかなり面倒なので挫折。xbeeはATコマンドでほとんどの動作設定可能なのが判明したので、最終的に複数台の受信側コントロールもATコマンドで送信相手先を書き換えて対応しました。文章で書くと簡単でしたがここ一週間ぐらい試行錯誤してました。特にあまり考えずに新しい方が良いし安かったからと言う判断でxbee3を買ったのですが、これ用の資料が思いのほか少なかった。参考文献6)にかなり支えられました。xbee3とsc2を両方記述していただいてましたので、他の文献を見るときに辞書代わりにもなりました。
つまずいたところ 悩んだ点
趣味での電子工作しかしてませんので色々悩みます。
arduino nanoだと基本5V系なのでxbeeの3.3V系の場合レベル変換が必要?
=>多くの場合直接レベル変換の必要は無いとの記述が各種資料で存在はする。以前作成した上の機材の場合TWI-LITEが3.3V系で直接つなぐと壊れると書いてあったので、秋月の8ビット双方向ロジックレベル変換モジュールを間に入れて動作。
今回は2ビット分しか使用しないので 4ビット双方向ロジックレベル変換モジュール https://akizukidenshi.com/catalog/g/gK-13837/ を当初検討
子機はブレッドボードで作成してそのまま実装できそうだったので、秋月さんの片面ガラス・ユニバーサル基板(ブレッドボード配線パターンタイプ)https://akizukidenshi.com/catalog/g/gP-04303/ と思ったらこの基盤、結構実装密度は上げられないことに途中で気が付きました。基盤面積的には余裕があっても縦一列しか配置できないのでarduinoNANO+レベル変換+xbeeでは無理だと断念。
3.3V系だけで組めばレベル変換が不要になる。Arduino Bootloader書込済(3.3V 内蔵8MHz仕様) ATmega328P https://akizukidenshi.com/catalog/g/gI-12775/ これでならいけそうです。「加賀式」さんの回路図見たらおなじことしてるし正解だなと。
しかし親機の実装上I/Oが足りない!!。 NANOだとシリアル通信分を除いてI/Oで使用できるのは20ピンぶん。ATmega328Pだと18ピン。「加賀式」さんのジョイスティックは2pinでX-Y4方向行けます。最初あれで実験しました。ちゃんと動きました。しかし、私の実装技術であれをきちんとケースに収めるのはおそらく無理。
ちょっと話それますが 回路設計するとき最終的なケースの実装はまず大事。それによって基盤サイズが決まりますので。
親機ケースは電池式で手で持ってコントロールするサイズという点で、タカチのLC-145シリーズを選択。パネル取り付け型押しボタンスィッチの厚さは結構あるため単3電池4本入りのLCS145H-M4では電池の上側のパネルにスィッチが取り付け困難。よく落として私の「加賀式」はすでにパネルのあちこちにヒビや傷が多いため、タカチのLCシリーズのシリコンケースは魅力的。
困った。。。
植え込み式電池ボックで単4式は見つからない。。。これは充電式内蔵電池方式で内部キャパを稼ぐしかないのか。。。
充電系の技術は全く無いのでちょっと心配。あと現場ですぐにどこでも手に入る乾電池式は実際の運用上メリットも大きい。仕方が無いのでLCS145H-F6を選択。単4電池6本のケースだがそのうち3本の使用で後は使わないで直結して4.5V供給で行く。意味も無くレギュレーターに負荷をかける必要も無し。
で最終的に問題はI/Oの数となりました。
先に述べたように、ジョイスティックの使用は諦め(これ結構最後まで悩みました。)
入力系として
- MP-101 Upボタン
- MP-101 Downボタン
- MP-101 Leftボタン
- MP-101 Rightボタン
- MP-101 スピードhi/low
- LANC用 Zoom Far
- LANC用 Zoom Near
- LANC用 ZoomスピードHi
- LANC用 ZoomスピードMid
- LANC用 ZoomスピードLow
- LANC用 Focus Tele
- LANC用 Focus Wide
- LANC用 AF/MF切り替え
- LANC用 ASSIGNボタン
- 子機切り替え1
- 子機切り替え2
- 子機切り替え3
「加賀式」さんではスピードコントロールはジョイスティックの押し込みボタンを利用して切り変えしてますが、直感的にわかりにくかったため独立させたかった。そのため入力系が増えました。
さらに 出力系(LED点灯)
- LINK 状態表示
- LANC 接続状態表示
- LANC用 ZoomスピードHi
- LANC用 ZoomスピードMid
- LANC用 ZoomスピードLow
- MP-101 スピードhi/low
- LANC用 AF/MF切り替え
- LANC用 ASSIGNボタン
- 子機切り替え1
- 子機切り替え2
- 子機切り替え3
- 電源(これはI/Oコントロール不要)
結局I/O系が28本必要になりました。
全然足りません
I/O増設が必要です。
検討したのが
秋月さんの 16bit I2C I/Oエキスパンダー MCP23017
スイッチサイエンスさんの PCAL9555APW I2C GPIOエクスパンダ
機能的には両者ほとんど同じ感じ。スィッチサイエンスさんの方が実装上小型化できるためスィッチサイエンスさんの方で決定。プルアップ抵抗を本体に追加実装できるためさらに小型化可能。(arduino側でプルアップ可能では?次に出てきます非常に癖があるarduino互換機のため最終的に必要となるここも悩んだ箇所です。)
これでI/O16本増えました。制御系で2本減るため NANOだと34ピンぶん。ATmega328Pだと32ピン これで解決した。
スイッチサイエンスさんの PCAL9555APW I2C GPIOエクスパンダ
スイッチサイエンスさんのWIKIが消えていて困りました。スイッチサイエンスWIKIはhttps でないと表示されない仕様になっており、いろいろなところからのリンクが切れているようです。PCAL9555APW I2C GPIOエクスパンダの 使い方 https://trac.switch-science.com/wiki/PCAL9555APW こちらをご覧ください。
スイッチサイエンスさんのHPからリンクの本家のデーターシートサイトも消えていてどうやって使うのか。。。 型番から探した本家のデーターシート と 参考文献7)を参考にして使いやすいようにコードを作成。普段のpinmodeやdigitalwriteと同じように動作するようにしてみました。これでデジタルのIN/OUTは簡単にできそうです。ただ処理速度が遅くて読み落としなどが発生しては嫌ですので測定してみました。
処理速度的に通常のpinmodeが1処理約5マイクロ秒ですが、PIOpinModaでは400マイクロ秒。digitalreadが通常7マイクロ秒ですがPIOread が614マイクロ秒かかってました。この数だけ見ると遅くて使い物にならない気もしますが、いずれも1ミリ秒(0.001秒)以下なので動作的には全く問題にななりませんでした。loop中に結局早すぎてディレイ挟み込んで調整してます。
#include <Wire.h> #define PCAL9555APW_ADDR 0x20 // in 7bit for Arduino #define INPUT_REG 0x00 #define OUTPUT_REG 0x02 #define INVERS_REG 0x04 #define CONFIG_REG 0x06 #define OUTPUT_DRIVE 0x40 #define INPUT_LATCH 0x44 #define PULLUP_EN 0x46 #define PULLUP_SEL 0x48 #define INTRRPT_MASK 0x4A #define INTRRPT_STAT 0x4C #define OUTPUT_CONFIG 0x4F #define NUM_OF_PORT 16 void datasend(int, int, int *, int); void dataread(int, int, int *, int); void PIOWrite(int, int); int port_output[2]; //出力状態変数 int port_config[2]; //port control状態変数 void datasend(int id, int reg, int *data, int datasize) { Wire.beginTransmission(id); Wire.write(reg); for (int i = 0; i < datasize; i++) { Wire.write(data[i]); } Wire.endTransmission(); } void dataread(int id, int reg, int *data, int datasize) { Wire.beginTransmission(id); Wire.write(reg); Wire.endTransmission(false); Wire.requestFrom(id, datasize, false); for (int i = 0; i < datasize; i++) { data[i] = Wire.read(); } Wire.endTransmission(true); } void PIOpinMode(int port, int inout) //portはPORT0とPORT1続けて0から15まで PORT1の0ピン=8 になります 以下同じ { if (inout == INPUT) { //inputはデフオルトでプルアップらしい(データーシート上)(自分では未確認ですが動作は良好) if (port > 7) { port_config[1] = port_config[1] | 1 << (port - 8); } else { port_config[0] = port_config[0] | 1 << (port); } } if (inout == OUTPUT) { if (port > 7) { port_config[1] = port_config[1] & ~1 << (port - 8); } else { port_config[0] = port_config[0] & ~1 << (port); } } datasend(PCAL9555APW_ADDR, CONFIG_REG, port_config, 2); } void PIOWrite(int port, int onoff) { if (onoff == HIGH) { if (port > 7) { port_output[1] = port_output[1] | (1 << (port - 8)); } else { port_output[0] = port_output[0] | (1 << (port)); } } if (onoff == LOW) { if (port > 7) { port_output[1] = port_output[1] & ~(1 << (port - 8)); } else { port_output[0] = port_output[0] & ~(1 << (port)); } } datasend(PCAL9555APW_ADDR, OUTPUT_REG, port_output, 2); } int PIORead(int port) { int port_input[2]; //入力状態を取得する変数 int value; dataread(PCAL9555APW_ADDR, INPUT_REG, port_input, 2); if (port > 7) { value = (port_input[1] >> (port - 8)) & 1; } else { value = (port_input[0] >> (port)) & 1; } return value; }
ケースに採用したLCS145H-F6の推奨基盤サイズは
いやいやなかなかちいさいぞ。これはまず手配線では不可能なので基盤起こすにしてもスイッチやLEDの配線の数もかなりなのでちょっと無理かも。。。 電池の空きスペースにレギュレーターは入れてスペース稼ぐとか色々考えました。
つづく 2021年5月18日現在 子機は手配線で動作済み。 親機動作はブレッドボードですべて子機との動作確認済み。2台目子機の基盤(久々の基盤制作だったための練習用の意味合いが強い)は現在中国からの輸送中 親機基盤も注文済み 分けて頼んだので送料が損してしまった。発注先はseeed Fusion 基盤が問題なければ、回路図やプログラム掲載に取りかかります。 ケースの加工もそろそろ始める予定。
MP-101ワイヤレスリモコンの作成 シリーズ
その1 その2 その3 その4 その5 その6 その7 その8
関連
参考資料
- MP-101 無線リモコンキット 通称「加賀式雲台」 https://shop.project92.com/
- コストパフォーマンスの高い、電動雲台MP-101をAmazonで購入しました。http://www1.plala.or.jp/h-roku/MP-101.html
- Arduino による、自作LANCリモコン・製作レポート http://www.next-zero.com/Lib/LANC-RemCon/
- Arduinoで、SONY LANCプロトコルを調べる http://ichirowo.com/2017/10/arduinosony-lanc/
- How SONY’s LANC(tm) protocol works http://www.boehmel.de/lanc
- XBee(無線通信)の実験 http://zattouka.net/GarageHouse/micon/XBee/XBee1.htm
- Arduino-ESP32 I2C < PCAL9555APW GPIOエクスパンダ > https://qiita.com/T-YOSH/items/882edfa28bcac390b39a