「455kHzマルチチャンネル化検証」のための受信機プログラムのとりあえずデバッグが終わったレベルのものです。
PIC10F222等で「20kbpsの赤外線信号受信とPWM制御が同時に可能かどうか」を検証することを目的としていましたが、結局のところ無理でした。(私の技術では)下記に掲載したプログラムは赤外線信号受信とPWM制御を交互に行い、極力PWM制御が停止する期間を短くするようにしたものです。
具体的には下記のシーケンスで動作しています。PWM制御は設定したチャンネルと受信した信号のチャンネルが合っていない場合は行いません。このような場合は”3”、”4”をスキップして再度”1”の赤外線信号待ちの状態となります。
38ビット目がONの場合、受信した信号のチャンネル情報を自分が設定されたチャンネルとして記憶します。(このままだと何回でも再設定できてしまうので、要修正です。・・・今、気がついた)
1. 赤外線信号待ち(この時はPWM制御しない)
2.赤外線信号受信(2ms、この時はPWM制御しない)
3.PWM制御(2ms×8サイクル=16ms、この間は赤外線信号を受信しない)
4.次の赤外線信号受信までPWM制御を継続する
5.赤外線信号の先頭を受信したら"2"ヘ
以下、プログラムのソースリストです。ソースリストの下に信号波形を掲載しています。
~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// IRRX455 (PIC10F222) 3CH PCM IR Remote Control Receiver
// for CC5X
//
// Ver 0.10 09.02.05 T.Kojima マルチチャンネル化検証用
// Ver 0.20 09.02.09 T.Kojima 赤外線受信動作とPWM制御動作を交互に実行するように修正
//
// SOT23 DIP
#define signal GPIO.3 // Pin6 Pin8
#define rud1 GPIO.0 // Pin1 Pin5
#define rud2 GPIO.1 // Pin3 Pin4
#define motor GPIO.2 // Pin4 Pin3
#define TMR0_50us 6
#define TMR0_half 2
unsigned char stat; // 信号受信ステータス
unsigned char Bits_cnt; // ビットカウンタ
bit rud_pol_1; // ラダーを振る方向1 どっちが右なのかは回路次第
bit rud_pol_2; // ラダーを振る方向2
bit chsel; // ペアリング要求1
bit resv2; // ペアリング要求2
bit parity;
bit error_f;
bit next_seq;
unsigned char rud_wid;
unsigned char th_wid;
unsigned char TMR0ck; // 受信した信号をチェックするタイミング
unsigned char chnum;
unsigned char ch;
unsigned char ch0;
unsigned char ch1;
unsigned char ch2;
unsigned char work;
unsigned char TMR0_1;
unsigned char TMR0_2;
unsigned char i;
void main(void)
{
// Hard config
OPTION = 0xc3; // TMR0は16分周モードで使用する (TMR0が1回オーバーフローするごとに約2ms)
TRISGPIO = 0x08; // GPIO3は入力, 他は出力
ADCON0 = 0x00; // 全ピンデジタル指定
OSCCAL = 0xc14; // 要調整
// IO Pin Initial
// rud1 = 1;
// rud2 = 1;
// motor = 1;
// for(i=0;i<50000;i++);
rud1 = 0;
rud2 = 0;
motor = 0;
// WORK Initial
stat = 0;
chnum = 0;
ch = 7;
ch0 = 0;
ch1 = 0x80;
ch2 = 0x80;
work = 1;
rud_pol_1 = 0;
rud_pol_2 = 0;
rud_wid = 0;
th_wid = 0;
error_f = 0;
while (1){
error_f = 0;
// STARTビットの先頭を探す
while(signal == 1){
};
TMR0ck = TMR0 + TMR0_half;
// STARTビットのチェック
// 半サイクル後から1サイクルごとにSTARTビットのチェックを9回繰り返す
Bits_cnt = 0;
while ((error_f == 0) && (Bits_cnt < 9)){
if (TMR0ck == TMR0){
// 信号はONか?
if (signal == 0){
Bits_cnt++;
}
else {
error_f = 1;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
// "0"のチェック
next_seq = 0;
while ((error_f == 0) && (next_seq == 0)){
if (TMR0ck == TMR0){
// 信号はONか?
if (signal == 1){
next_seq = 1;
}
else {
error_f = 1;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
// chnum受信
if (error_f == 0){
Bits_cnt = 0;
while (Bits_cnt < 3){
if (TMR0ck == TMR0){
// 信号はONか?
Bits_cnt++;
chnum = chnum * 2;
if (signal == 0){
chnum++;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
// "0"のチェック
next_seq = 0;
while ((error_f == 0) && (next_seq == 0)){
if (TMR0ck == TMR0){
// 信号はONか?
if (signal == 1){
next_seq = 1;
}
else {
error_f = 1;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
};
// data1受信
if (error_f == 0){
Bits_cnt = 0;
ch0 = 0;
while (Bits_cnt < 7){
if (TMR0ck == TMR0){
// 信号はONか?
Bits_cnt++;
ch0 = ch0 * 2;
if (signal == 0){
ch0++;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
// "0"のチェック
next_seq = 0;
while ((error_f == 0) && (next_seq == 0)){
if (TMR0ck == TMR0){
// 信号はONか?
if (signal == 1){
next_seq = 1;
}
else {
error_f = 1;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
};
// data2受信
if (error_f == 0){
Bits_cnt = 0;
ch1 = 0;
while (Bits_cnt < 7){
if (TMR0ck == TMR0){
// 信号はONか?
Bits_cnt++;
ch1 = ch1 * 2;
if (signal == 0){
ch1++;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
// "0"のチェック
next_seq = 0;
while ((error_f == 0) && (next_seq == 0)){
if (TMR0ck == TMR0){
// 信号はONか?
if (signal == 1){
next_seq = 1;
}
else {
error_f = 1;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
};
// data3受信
if (error_f == 0){
Bits_cnt = 0;
ch2 = 0;
while (Bits_cnt < 7){
if (TMR0ck == TMR0){
// 信号はONか?
Bits_cnt++;
ch2 = ch2 * 2;
if (signal == 0){
ch2++;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
// "0"のチェック
next_seq = 0;
while ((error_f == 0) && (next_seq == 0)){
if (TMR0ck == TMR0){
// 信号はONか?
if (signal == 1){
next_seq = 1;
}
else {
error_f = 1;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
// resv1受信
next_seq = 0;
while (next_seq == 0){
if (TMR0ck == TMR0){
// 信号はONか?
next_seq = 1;
if (signal == 0){
chsel = 1;
}
else {
chsel = 0;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
// resv2受信
next_seq = 0;
while (next_seq == 0){
if (TMR0ck == TMR0){
// 信号はONか?
next_seq = 1;
if (signal == 0){
resv2 = 1;
}
else {
resv2 = 0;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
// parity受信
next_seq = 0;
while (next_seq == 0){
if (TMR0ck == TMR0){
// 信号はONか?
next_seq = 1;
if (signal == 0){
parity = 1;
}
else {
parity = 0;
};
TMR0ck = TMR0ck + TMR0_50us;
};
};
};
// チャンネル設定要求?
if (chsel){ch = chnum;};
// パリティチェック(略)
if ((error_f == 0) && (chnum == ch)){
// 制御量計算
th_wid = ch0 * 2;
rud_pol_1 = 0;
rud_pol_2 = 0;
rud_wid = 0;
if (ch1 > 0x40){
rud_pol_1 = 1;
rud_wid = ch1 - 0x40;
}
else if (ch1 < 0x40){
rud_pol_2 = 1;
rud_wid = 0x40 - ch1;
};
rud_wid = rud_wid * 4;
// RUD,TH PWM制御
// 信号受信成功後0~16msの間は信号を受信しても無視してPWM制御を行う
for(i=0;i<8;i++){
// RUD,TH ON/OFFタイミング設定
TMR0ck = TMR0;
TMR0_1 = TMR0ck + rud_wid;
TMR0_2 = TMR0ck + th_wid;
// RUD,TH ON
while ((TMR0 != TMR0ck) && (TMR0 != (TMR0ck+1)));
if (rud_wid > 5){
if (rud_pol_1 == 1){
rud1 = 1;
rud2 = 0;
} else if(rud_pol_2 == 1){
rud1 = 0;
rud2 = 1;
};
};
if (th_wid > 5){
motor = 1;
};
// RUD,TH OFF
while ((rud1 == 1) || (rud2 == 1) || (motor == 1)){
if ((TMR0 == TMR0_1) || (TMR0 == (TMR0_1+1))){
rud1 = 0;
rud2 = 0;
};
if ((TMR0 == TMR0_2) || (TMR0 == (TMR0_2+1))){
motor = 0;
};
};
};
// 信号受信成功後18ms以降は信号を受信するまでPWM制御する。信号受信したらPWM制御は終了する
while(1){
// RUD,TH ON/OFFタイミング設定
if (signal==0){break;};
TMR0ck = TMR0;
TMR0_1 = TMR0ck + rud_wid;
TMR0_2 = TMR0ck + th_wid;
// RUD,TH ON
while ((TMR0 != TMR0ck) && (TMR0 != TMR0ck+1)){if (signal==0){break;};};
if (rud_wid > 5){
if (rud_pol_1 == 1){
rud1 = 1;
rud2 = 0;
} else if(rud_pol_2 == 1){
rud1 = 0;
rud2 = 1;
};
};
if (th_wid > 5){
motor = 1;
};
// RUD,TH OFF
while ((rud1 == 1) || (rud2 == 1) || (motor == 1)){
if (signal==0){break;};
if ((TMR0 == TMR0_1) || (TMR0 == (TMR0_1+1))){
rud1 = 0;
rud2 = 0;
};
if ((TMR0 == TMR0_2) || (TMR0 == (TMR0_2+1))){
motor = 0;
};
};
};
};
motor = 0;
rud1 = 0;
rud2 = 0;
};
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~
送信機側の出力信号です。20ms周期のトリガ信号を入力していないため、25msごとに勝手に信号を出しています。
一回の信号を拡大しました。PICの内部タイマの都合のため、信号1ビットあたり48μsとしています。
受信機のPWM出力波形です。25msごとの信号受信中はPWM出力がOFFになっています。
(フルスロットル時)
(ハーフスロットル時)
<2009.2.18追記>
スペックについて追記します。
・バンド数 8バンド
・チャンネル数 2チャンネル
・PWM周期 2ms
・分解能 128(送受信データは7ビット、ただし0~4はOFFとする)
・送受信周期 約20ms(同期信号に依存、同期信号未使用時は25ms)
・送受信データサイズ 40ビット
・1ビットあたりの時間 48μs
最近のコメント