■ホビーロボット部品の製造・販売 
  モータコントローラ、センサ、音声、画像、無線モジュールなど、
■ホビーロボット制作記事のページ (各種マイコン、PCとの接続事例)
■特殊メイク、特殊材料の販売 ※特殊メイクのコーナーはこちらに移りました。
Top(お知らせ) 製品紹介 使い方とサンプルプログラム 通信販売 リンク ロボット掲示板 会社案内
 Easy Robotics for all enthusiastic people!!!  ---HOBBY ROBOT PARTS SHOP ASAKUSAGIKEN---   Since 2003...

PICとラジコン受信機の接続

はじめに

 ラジコン受信機は浅草ギ研では扱ってませんが、需要が多そうなネタなのでここで簡単に紹介します。以後のネタと組み合わせて操縦系のロボットが作れるようになるかと。


ラジコン受信機

ラジコンについては知らない方はいないと思われますが、一応説明しますと、

 プロポ−>受信機−>RCサーボ

という流れでプロポのスティックを動かすと受信機からある波形が出てRCサーボを回転させるという構成になってます。


これは4チャンネルの受信機で、[1]〜[4]のところにRCサーボをつなぎます。左の灰色の線はアンテナです。
[4]のところだけ「4/B]となってますが、Bは受信機の電源を入れるところです。
機種によっては


[B]
[4]
[3]
[2]
[1]

のようにBが独立しているものもあります。
基本的にラジコン受信機はプロポと無線の周波数が合っていればどれを使っても同じようです。



プロポはこんな感じです。スティックが2本ありますが、各スティック上下/左右で2チャンネルで、上のプロポは4チャンネルというわけです。黄色い81というシールが貼ってるところがクリスタルで、これで周波数を変えます(上の受信機も81のシールが貼ってある)。クリスタルはプロポ、受信機とも交換できるようになってます。
ロボットコンテストなどでは混信を防ぐため、クリスタルを数個もって会場にいく人が多いです。




受信機のピンは各チャンネル3本あります。サーボを見るとこのように3本になってます。上の写真は近藤科学のサーボですが、線の色は一般的なもので、黒はGND,赤は電源、白は信号線になってます。この色から、受信機のピンの真ん中は電源の+であると考えられます。



Bは受信機への電源ですので、上のサーボの線配列からこのように考えられます。
今回はサーボをつなぐのではなく、プロポの動きをこの受信機の信号線の状態を測定して読み取ります。
受信機への電源ですが、通常はサーボに電源も供給するのでBにはサーボ用のバッテリを接続します。サーボ用の電源は4.8V〜6Vなので、前回作った回路の5V電源が使えそうです。



ということで、受信機のピンの真ん中を5V,右をGND、左をPICのGPIOに接続しました。
[1]〜[3]のチャンネルも読み取る場合は、受信機の信号線(左のピン)だけをPICのGPIOのどれかにつなげばよいです。[1]〜[3]の真ん中と右のピンはサーボへ電源を供給するためのもので、今回はサーボを動かすわけではありませんので未接続でOKです。
※ここでは[4]の読み取りしかやりませんので各自実験してみてください。

写真では2550コネクタと線で簡易ケーブルを作ってます。実験の場合、こんな感じでケーブルを何本か作っておくと便利です。いざロボットへ組み込もうというばあいもそこそこ外れないので簡単なロボットであればそのまま使えます。



回路図



PIC関係の回路は上の写真をみてもわかるとおり前回のままですが、この回路図ではMAX232などを省略してます。書いてないところの詳しくは前のページをや前の前のページ参照願います。


受信機からの出力波形

ラジコン受信機(RCサーボの駆動も同じ)のパルス出力についてはインターネットでいろいろと解説されているのでそちらを参照願います。(浅草ギ研で書いている書籍「自作ロボット入門ラジコンロボ編」でも詳しく解説してます。が、PICじゃなくてBASICスタンプを使ってます。)

基本的にはプロポのスティックをまっすくにした状態で1.5mS幅のHighのパルスが20mS周期(この周期はものによって違う場合がある)で出ており、スティックを倒すとプラスマイナス0.5mSぐらいで変化します。

マイコンでこの値を読むには、信号線のHigh/Lowを検知し、Highの時間をタイマで測定すれば解析できます。



プログラム

さてプログラムですが、「なんとなく小さくてADCもついてるから」という理由で選んだPIC12F675ですがこれがなかなかクセモノでした。このページをサクっと終わらせるつもりがハマってしまい、結局データシートをすみからすみまで読む羽目に...寝る前の読書の時間x3日分をつぶしてようやくツボがわかりました。という話はさておき、ポイントは次の2点、

■12F675は電源を入れた瞬間は各端子がADCの設定になっているのでデジタルIOとしては使えない

■内部クロックでタイマを使う場合はクロックが1/4になる。つまり4MHzは1MHz


ほとんどのPIC解説本は16F84などですが、この辺りが違う(16F84は電源を入れた状態では各ピンはデジタルIO)ので、解説本だけではわかりません。こういうのを発見するにはやはりデータシートを見るしかないです。後でインターネットで検索したらやはり同様のところでハマっている人が多いようでした。

まず、最初のはGPIOの説明のところにチョロっと書いてありました。
データシートの 3.0 GPIO Port の初めの方より、

データシートの始めの方から読んでいくと、まだANSELレジスタやCMCONレジスタについては説明されてませんが、GPIOのところにNote:(注)で「(灰色の部分)PIC12F675のばあいはアナログチャンネルをデジタル入力に変えるためにANSELとCMCONを設定する必要があります」とあります。 普通はデジタルIOが初期設定で、(ANSELのような)特殊レジスタを設定してADコンバータとか使うと思うじゃないですか。ここだけ読んでも初期設定がADCになってるとは気がつきにくいです。
その下の例3−1はアセンブラですが設定例が書いてありますのでこれを参考にしました。
ちなみに、デジタル出力はこの設定をしなくても大丈夫なようです。あくまで、デジタル入力として使いたい場合に設定する必要があります。ということで前回やったLEDの点灯は大丈夫だったようです。

つぎのツボの、内部クロックがタイマ使用で1/4になるというところは、タイマのところだけでなく、 9.0 Special Features of the CPU (このCPUの特徴)というところも読んでなんとなくわかりました。

という2点をふまえて作ったプログラムが下記の通りです。



テキストデータはこちら RCV.txt
(取る場合は右クリックで保存)

ようはADCとコンパレータを切ればよいのだと思い、CCS-Cの組み込み関数(SETUP_ADC(ADC_OFF)とか)を使えばよいかと思い色々試しましたが、結局上のデータシートの例の通りにやらないとうまくいきませんでした。よって、特殊レジスタに値を直接書いてます(#byte...やGPIO,CMCON,ANSELに値を代入してるとこ)。これらをすることによりピンをデジタルIOとして使えるようになります。(めんどくさ〜)
どの特殊レジスタが何番のアドレスかはデータシートに書いてあります。(こうゆうのは大体後ろの方にまとめてある)

mainの中のタイマ0の設定ですが、普通に考えると内部クロック4MHzなので、1.5mS前後(1mS〜2mS)を計測しようとすると、クロックの分周値と各パルス幅でのカウント数は次のようになります。

 
1mS
1.5mS
2mS
0分周
4000
6000
8000
8分周
500
750
1000
32分周
125
187.5
250
128分周
31.25
46.875
62.5

タイマ0は8ビットなので0〜255までしかカウントできませんので、ここは一見、32分周がちょうどよいかと思いますが、内部クロックは1/4になるので、上記の32分周と同じカウント結果を出したければその1/4の8分周ということになります。よってタイマの設定の部分は

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_8);

となります。RTCC_INTERNALは内部クロック使用の設定、RTC_DIV_nはクロックをn分周する設定です。nはそのマイコンや、同じマイコンでもタイマの種類によって違いますのでデータシートで確認する必要があります。タイマ0とタイマ1とではできる分周の値が違うということが多いです。

while(1)の中身ですが、GP0ピン(プログラムの設定ではPIN_A0)の状態のHigh/Lowを正確に測定するために、まずパルスの立下りを検出し、パルスの途中からカウントしないようにします。その後は見ての通りです。プログラム中のコメントを参照願います。

結果の出力ですが、printf( ) 文で、C本などの例でよくある %d を使うとマイナスの値が出ますので注意してください。符号なし10進数を出力したい場合は %u になります。\r\nは改行コードです。¥はMPLABではバックスラッシュになりますので注意してください(¥キーを押してもバックスラッシュになる。むきになって¥を出そうとしないように)。
get_timer0( ) 関数はCCS-Cの組み込み関数で、タイマー0の値を返す関数です。


実行結果は次の通り、




プロポの方の電源を入れないと数値が不安定になります。プロポのスイッチを入れるのを忘れないように。(実験中は結構これを忘れる。)

ちょっとわかりづらいですが、はじめの方の187がプロポを 倒さない状態、次にだんだん左へ倒して最小値が132、中心に戻したあと、だんだん右へ倒して最大値が244となりました。ほぼ上の表の通りの結果となった(32分周のところを見る。1/4なので)


2005年8月15日
 
(C)Copylight 2003. 有限会社浅草ギ研 | 通信販売の法規(訪問販売法第8条)に基づく通信販売業者の表示