マルチコントローラーMC-8+MR-8をマイコンボードで使用する
8チャンネルのマルチコントローラーMC-8は、ジョイスティックやボタンによる操作で手軽にマシンを無線操縦することができます。近藤科学KOPROPOでは、長年R/Cカー用の無線送信機を開発してきました。MC-8は、KOPROPOの無線技術を採用し、混信しにくく、安定した無線操縦が可能です。イベント会場など2.4GHzが混在する場所でも無線が途切れにくい仕様になっています。今回は、MC-8と対になる受信機MR-8から出力される各チャンネルのPWMを、マイコンボードで読む方法をご紹介します。
この記事では、マイコンボードとしてArduino MKR ZEROを使用しています。
※弊社では他社マインボード、及びプログラムに関するお問い合わせには対応致しかねます。以下の内容は、仕様事例として参考にご一読ください。
【関連記事】
ArduinoからスピードコントローラMD-1を制御する方法を紹介しています。
RaspberryPiからスピードコントローラMD-1を制御する方法を紹介しています。
『スピードコントローラMD-1をRaspberryPiから制御する』
■マルチコントローラーMC-8とは
MC-8は、PWM信号で制御する機器を8CH制御できるマルチコントローラです。RCカーの操縦は元より、工作セットや自作ロボットなどPWM信号で動作するサーボやスピードコントローラを搭載したマシンの無線コントロールにお勧めです。MC-8専用の受信機MR-8と組み合わせてご利用できます。MR-8に接続できる製品については、MC-8の商品ページをご参照ください。
■受信機MR-8のパルス幅
MR-8は、MC-8の各チャンネルに対応した端子から、PWMの信号としてデータを出力します。操作者がMC-8を操作すると、MR-8から出力されるPWMのパルス幅が変化しますので、マイコンボードからPWMを読み込むことでMC-8の操作を知ることができます。
下記の画像のA~Hは、MC-8の各チャンネルA~Hに対応しています。
右端のBAT.端子は電源端子です。3.0~6.6V電源を接続します。
パルス幅の仕様は以下の図のようになっています。
CH-A~Dは、MC-8のスティックです。傾きによってアナログでパルスが変化します。CH-EとFは、スティックを押し込んだときに反応するボタンです。タクトスイッチですので、押したときにパルス幅が変わります。CH-GとHは、片側10段階(計20段階)でパルス幅が変化します。押された状態が保持されますので、例えばアームを上下したいときに、ボタンを押して段階的に角度を変えることができます。
取得したパルスをArduinoIDEで表示すると図と同じ数値が出力されますが、スティックの個体差などで多少の誤差が発生します。ご利用する前に、一度パルス幅を確認し、プログラム上で値をオフセットしてください。
■配線
MR-8のパルス幅(PWM)を読み取るマイコンボードとしてArduino MKR ZEROを使用します。
MR-8の信号線は3.3V仕様ですので、MKR ZEROの端子に適しています。また、割り込みに対応する端子が多いため8チャンネル全てのパルス幅を読みことが可能です。
ArduinoはpulseIn()関数からPWMを取得することができますが、1チャンネルずつしか計測することができません。そのため、今回はpulseIn()関数を使用せず、割り込みを利用して複数のピンから同時(非同期)にパルス幅を取得できるようにします。
MR-8の各チャンネルにある信号端子を、マイコンボードの割り込みに対応する端子に接続してください。マイコンボードによって割り込みを使用できる端子が異なります。MKR ZEROの場合は、0、1、4、5、6、7、8、A1(16) 、A2(17)の端子が対応しています。
配線については、以下の図を参考にしてください。
MKR ZEROの電源
無線コントロールするマシンにMKR ZEROを搭載する場合は、当然ながらMKR ZEROの電源も確保する必要があります。MKR ZEROに対して、VIN端子から電源を給電することができます。しかし、VINの入力は5Vですのでバッテリーから直結すると破損する可能性があります。
そこで、ロボットによってバッテリーの電圧が異なりますが、電源を5Vに降圧するために三端子レギュレータを実装しました。今回は、5V 1Aを出力できるTA4805Sを使用しました。ただし、バッテリーの電圧が6V以上である必要がありますのでご注意ください。
※図の三端子レギュレータの配線は参考です。使用する部品に合わせて配線し、コンデンサなど必要な部品を取り付けてください。
基板を作成するとこのようになります。三端子レギュレータは、MKR ZEROの下に配置しました。MR-8は両面テープで張り付けています。
配線するとこのようになります。極性を間違えないように注意してください。MKR ZEROとMR-8をつなぐケーブルは、接続ケーブル KRS-4024用(100mm)を使用しました。8チャンネル分+電源端子用で合計9本です。画像左端のケーブルは、バッテリーからのケーブルです。
■プログラム
複数のパルス幅を取得するために、割り込みを利用します。8チャンネル分のプログラムを書きますと長くなりますので、以下の例ではCH-Aの1チャンネルのみ掲載します。複数チャンネルを処理したい場合は、以下の例と同じようにCH-B~H用の処理を追加してください。また、以下のサンプルプログラムからダウンロードできる『MR8_twoPulseInMKRZREO』には2つの割り込み処理がプログラムされていますので、そちらを参照してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
const int MR8_A_PIN = 16; //CH-Aに接続している端子番号 volatile unsigned long startPulse[8]; // volatile int getPulse[8]; //取得したパルスを格納する配列 //割り込みで処理する内容 void chAChangeInterupt() { unsigned long nowPulse = micros(); //現在のマイコン内の時間をnowPulseに代入 if(digitalRead(MR8_A_PIN) == HIGH) //端子がHIGHの場合 { startPulse[0]= nowPulse; //現在の時間をstartPulseに代入 } else //端子がLOWの場合 { getPulse[0] = nowPulse - startPulse[0]; //現在の時間(NowPulse)とstartPulseの差を求める=>パルス幅 } } void setup() { Serial.begin(115200); pinMode(MR8_A_PIN,INPUT); //ピンモードを出力に設定 attachInterrupt(MR8_A_PIN,chAChangeInterupt,CHANGE); //端子に変化があった時に割り込み } void loop() { Serial.print("A = "); Serial.println(getPulse[0]); //getPulseの情報を表示 delay(100); } |
割り込み処理の設定
setup()関数内のattachInterrupt(MR8_A_PIN,chAChangeInterupt,CHANGE);で割り込み処理を開始します。
引数の”MR8_A_PIN”は、割り込みのきっかけになる端子を指定します。プログラムの最初に”MR8_A_PIN”に対して16を代入していますので、16番の端子を指定しました。
”MR8_A_PIN,chAChangeInterupt”は、割り込み処理の内容が書かれた関数を指定しています。
”CHANGE”は、端子がどのような変化があった時に割り込みをするかを指定します。”CHANGE”は端子がLOWからHIGH、またはHIGHからLOWのどちらかの変化があった時に、割り込み処理に移ります。他にも”RISING”や”FALLING”の種類があります。
attachInterrupt()関数の詳細は、こちらのリファレンスをご参照ください。
PWMのパルス幅を読む方法
割り込み処理の内容は、「パルスが終わった時間と始まった時間を引いてパルス幅を求める」となっています。関数内は、下記の内容がプログラムされています。
0)端子16番に変化があったら割り込み処理へ
1)micro()でマイコン内の今の時間をnowPulseに代入
2)端子がHIGHだったらnowPulseをstartPulseに代入
3)端子がLOWだったらnowPulseからStartPulseを引いてパルス幅を求め、getPulseに代入
0)は、前述のattachInterrupt()の通り処理が実行されます。端子が「LOWからHIGHになった時」と「HIGHからLOWになった時」で2回割り込みが実行されます。
【1回目の割り込み】
1)のmicro()関数は、Arduinoがプログラムを開始してから自動でカウントされるボード内の時間を返り値として受け取れる関数です。割り込みが発生したときの時間をnowPulse変数に代入します。この解説では、最初に割り込みが発生したときの時間が100μsecだったとします。
2)割り込みに指定した端子がHIGHかLOWかで処理が分岐します。HIGHの場合は、パルスが立ち上がった時です。つまり、パルス幅のスタート地点になります。今の時間(nowPulse = 100μsec)をstartPulseに代入しておきます。この時に1回目の割り込み処理は終了します。
【2回目の割り込み】
1)端子がHIGHからLOWになると改めて割り込み処理に移ります。2回目に割り込みしたときの時間がnowPulseに代入されます。ここでは、1700μsecだったとします。
3)端子が、HIGHからLOWになりましたのでパルスが終了したことを意味します。そこで、nowPulse(1700μsec)から、startPulse(100μsec)を引きます。つまり、終了時間-開始時間になります。この計算で出された答えが、パルス幅の長さになります。
loop()関数内では、getPulse変数に代入されているパルス幅の長さを表示しています。このパルス幅は、割り込みで自動的に入るため非同期で最新の値を取得することができます。
■サンプルプログラム
Arduino用のサンプルプログラムを公開していますので、ご参考ください。
今回解説したMR-8のサンプルプログラムの他に、MD-1と連携した様々なプログラムも用意しています。
・MR-8連携用
『MR8_onePulseIn』
8チャンネル無線コントローラー「MC-8」とペアで使用する受信機「MR-8」のパルスをシリアルに変更するためのサンプルです。
MR-8は、MC-8からの操作情報をPWMで出力します。このPWMをArduinoのpulseIn()関数で取得することで、ArduinoをMC-8から無線コントロールすることが可能です。
『MR8_twoPulseInMKRZREO』
上記と同じくMR-8からパルスを取得するサンプルですが、pluseIn()関数は1chしか使用できないため、割り込みを利用して複数のピンから取得する方法をご紹介しています。
・MC-8とMD-1を組み合わせてタンクを制御するサンプル
『MC8_MD1TankModeMKRZERO』
8チャンネル無線コントローラーMC-8とMR-8、MD-1を組み合わせてArduinoを搭載したクローラ型のロボットや対向2輪型ロボットを制御するための方法をご紹介するサンプルです。
他にも、スピードコントローラMD-1用のサンプルプログラムも同封されています。MD-1のご利用方法については、下記の記事をご参照ください。
MR-8のPWMを読み込む方法は以上です。Arduinoで読み込むことで、センサと組み合わせた無線操縦や、Arduinoを中継してRaspberryPiなどを無線操縦することが可能になります。
ただし、読み込むパルスが増えると割り込み処理も増えますので、姿勢制御など常に処理を実行しているプログラムに対しては、MR-8の処理とロボットの処理でボードを分けることをお勧めします。
組み込むロボットに合わせてご利用ください。
MC-8 2.4GHz MX-F 送受信機セット(MR-8付属)の詳細をみる MC-8 2.4GHz MX-F MAKEセットA(MD-1NB ×2個付属)の詳細をみる MR-8 2.4GHz MX-F(受信機のみ)の詳細をみる の詳細をみる