[戻る]
新着表示

Re^7: USART受信プログラム 投稿者:n 投稿日:2017/03/24(Fri) 21:48:49 No.855

radioさん
nです。

"SS"だけでなく、他の文字も試してください。
("AB"等が透過するか、透過しないコードは何か)

送信側で、間隔をあけて送信してみてください。
(「'A'しばらく待って'B'しばらく待って'C'」等)

USARTの初期設定の情報を教えてください。
例:
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,25 );

Re^6: USART受信プログラム 投稿者:radio 投稿日:2017/03/24(Fri) 09:41:01 No.854

nさま

n様のお陰で、だいぶゴールに近くなりました。
今の状況を説明します。

送信側PICマイコン⇒ 受信側PICマイコン
USART通信(有線)で動作を確認しています。
Bau Rateは、9600bpsに設定しています。
この状態で、送信側からのデータに応じて受信側のマイコンが動作できています。

次の目標として、無線通信を試みています。
2つのデバイスを使用してテストしています。

@AM送受信モジュール
送信側PICマイコン=>AM送信モジュール ⇔ AM受信モジュール=>受信側PICマイコン

AXbee
送信側PICマイコン=>Xbee Coordinator ⇔ Xbee Router=>受信側PICマイコン

@に関しては、データシートやメーカの情報から、2400bpsに設定してテストしています。
しかし、受信側で'S'、'S'受信まで行っているのですが、LCDに5バイトのデータが受信されません。



Aに関しては、まだあまり詳しくテストしていませんが、
9600bpsで動作確認をおおなったところ、連続して5回程データを受信した後、データを受信しなくなってしまいます。
こちらは、「RO Packetization Timeout」の設定が影響しているのではと考えています。


[ご質問]
まずは、@の環境で、有線と同じレベルまで持っていきたいと考えていますが、
5バイトデータが受信できない理由が分かりません。
考えられる原因についてアドバイスいただけると助かります。

Re^5: USART受信プログラム 投稿者:n 投稿日:2017/03/23(Thu) 22:36:57 No.853

radioさん
nです。

質問が明確なので、回答が楽です。

@ 動作にdelay時間を設けてしまうと、受信できないのは何故でしょうか?

 調歩同期式の通信では、受信側がデータを取りこぼすからです。

A Buf1[]内のデータが"ffff"や"ffe8"になってしまうのは何故でしょうか?

 char型データは、sprintf関数へint型に変換されて渡されます。
 char型の"ff"が負の数(-1)として扱われ、"ffff"になります。
 回避するには、unsigned char型へのキャストを行います。
 (unsigned char)Buf1[1]

B LCDにBuf1[]の5バイト分を1行に表示させる場合、どのように記述すれば良いのでしょうか?

 sprintf関数のbuff1へのポインタを2文字進めながら繰り返します。
 buff1のサイズは、11文字以上必要です。

for(i = 0 ; i < 5 ; i++){
sprintf(buff1+2*i,(const far rom char *)"%02x",(unsigned char)Buf1[i]);
}

> nさま
>
> 度々すみません。
> 少しずつ原因らしきものが見えてきました。
>
>
> 原因を解析するために、状態確認用のLEDを点灯させています。
> 最初の'S'を受信: 白色LED点滅
> 次の'S'を受信:  黄色LED点滅
>
> この点滅をわざと、delay時間を設けて行ってみました。
> 50msecに設定して点滅させてみたところ、'S'、'S'の後の、5バイトデータを受信することができませんでした。
> ⇒LCDに何も表示されない + 5バイトデータの一致判定プログラム(Errorなら赤色LED、Errorが無ければ緑色LED)で確認
>
> この時間を5msecに変更したところ、5バイトデータの一致判定プログラムまで進み、
> Errorが無い(緑色LEDが500msecで点滅する)ことを確認することができました。
>
> ただ、データを連続して受信することができません。
> 次の'S'、'S'受信まで行っているのですが、再びLEDに5バイトのデータが受信されません。
>
> そこで、Errorが無いときに確認していた緑色のLEDの点滅周期を5msecに変更しました。
> そしたら、連続してデータを受信することができ、送信側のデータに応じた動作(LED点灯)を行うことができました。
>
>
> 以上を踏まえて、何点か質問をさせてください。
>
> @今の状態では根本的な解決になっておらず、送信側のデータに応じた動作(今はLEDを点灯するだけ)の時間が長くなると、同じような不具合(連続してデータを受信できない)が発生してしまいます。
>  動作にdelay時間を設けてしまうと、受信できないのは何故でしょうか?
>
>
> ABuf1[]内のでーたが"ffff"や"ffe8"になってしまうのは何故でしょうか?
> 先程の投稿でもお伝えしましたが、Xbeeを接続して、XCTUで送信データを確認してみると、送信側は02 00 00 00 00 の5バイトのはずですが、
> LCDに表示されるデータが違ってしまいます。
> (ただ、この表示のデータでも、送信側のデータに応じた動作はできていますので、私のLCD表示プログラムがおかしいのでしょうか。)
> //Buf1[]内の数字を0〜4まで変更してLCDにデータを表示させました。
> //Buf1[0]=02
> //Buf1[1]=ffff
> //Buf1[2]=ffe9 or ffea or ffe8
> //Buf1[3]=00
> //Buf1[4]=17
>
>
> B初歩的な質問ですみません。
>  LCDにBuf1[]の5バイト分を1行に表示させる場合、どのように記述すれば良いのでしょうか?  
> 今は、↓のように[]内の数字を変えて1つずつ確認しています。
> sprintf(buff1,(const far rom char *)"Data=%02x",Buf1[1]);
> lcd_cmd(0x80); //1行目へ移動
> lcd_str(buff1);
>
>
>
> 5バイトデータ受信後のプログラムです。
> 照合一致(3 緑LED点灯、消灯)はコメントアウトしました。
>
>
> void MotorControl(void)
> {
>
>
> /*** 2連送照合比較一致の場合のみ制御実行***/
> Error = 0; // エラーフラグリセット
> for(i=0; i<5; i++){
> if(Buf1[i] != Buf2[i]) // 比較実行
> {
> Error = 0xFF; // エラーフラグオン
> LED_R ^= 1; // 赤LED点滅
> delay_ms(100);
> }
> }
> if((Error == 0) && (RcvData == 'E')) // 照合一致か?
> {
> //LED_G = 1; // 3 緑LED点灯
> //delay_ms(500);
> //LED_G = 0; // 3 緑LED消灯
> //delay_ms(500);
>
>
> Direction = (int)Buf1[0]; // 方向セット
> MLdata = (int)Buf1[1] * 256 + (int)Buf1[2];
> MRdata = (int)Buf1[3] * 256 + (int)Buf1[4];
> // 制御実行
> switch(Direction) // 方向チェック
> {
> case 0:
> //MLReverse(MLdata); // 後進の場合
> //MRReverse(MRdata);
> LED_G=1;
> delay_ms(5);
> //LED_G=0;
> //delay_ms(500);
> break;
> case 1:
> //MLFeed(MLdata); // 前進の場合
> //MRFeed(MRdata);
> LED_W=1;
> delay_ms(5);
> //LED_W=0;
> //delay_ms(500);
> break;
> case 2:
> MLStop(); // 停止の場合
> MRStop();
> LED_R=1; //4 赤LED点灯
> delay_ms(5);
> //LED_R=0; //4 赤LED消灯
> //delay_ms(500);
> break;
> default: break;
> }
> }
> }

Re^4: USART受信プログラム 投稿者:radio 投稿日:2017/03/23(Thu) 11:13:47 No.852

nさま

度々すみません。
少しずつ原因らしきものが見えてきました。


原因を解析するために、状態確認用のLEDを点灯させています。
最初の'S'を受信: 白色LED点滅
次の'S'を受信:  黄色LED点滅

この点滅をわざと、delay時間を設けて行ってみました。
50msecに設定して点滅させてみたところ、'S'、'S'の後の、5バイトデータを受信することができませんでした。
⇒LCDに何も表示されない + 5バイトデータの一致判定プログラム(Errorなら赤色LED、Errorが無ければ緑色LED)で確認

この時間を5msecに変更したところ、5バイトデータの一致判定プログラムまで進み、
Errorが無い(緑色LEDが500msecで点滅する)ことを確認することができました。

ただ、データを連続して受信することができません。
次の'S'、'S'受信まで行っているのですが、再びLEDに5バイトのデータが受信されません。

そこで、Errorが無いときに確認していた緑色のLEDの点滅周期を5msecに変更しました。
そしたら、連続してデータを受信することができ、送信側のデータに応じた動作(LED点灯)を行うことができました。


以上を踏まえて、何点か質問をさせてください。

@今の状態では根本的な解決になっておらず、送信側のデータに応じた動作(今はLEDを点灯するだけ)の時間が長くなると、同じような不具合(連続してデータを受信できない)が発生してしまいます。
 動作にdelay時間を設けてしまうと、受信できないのは何故でしょうか?


ABuf1[]内のでーたが"ffff"や"ffe8"になってしまうのは何故でしょうか?
先程の投稿でもお伝えしましたが、Xbeeを接続して、XCTUで送信データを確認してみると、送信側は02 00 00 00 00 の5バイトのはずですが、
LCDに表示されるデータが違ってしまいます。
(ただ、この表示のデータでも、送信側のデータに応じた動作はできていますので、私のLCD表示プログラムがおかしいのでしょうか。)
//Buf1[]内の数字を0〜4まで変更してLCDにデータを表示させました。
//Buf1[0]=02
//Buf1[1]=ffff
//Buf1[2]=ffe9 or ffea or ffe8
//Buf1[3]=00
//Buf1[4]=17


B初歩的な質問ですみません。
 LCDにBuf1[]の5バイト分を1行に表示させる場合、どのように記述すれば良いのでしょうか?  
今は、↓のように[]内の数字を変えて1つずつ確認しています。
sprintf(buff1,(const far rom char *)"Data=%02x",Buf1[1]);
lcd_cmd(0x80); //1行目へ移動
lcd_str(buff1);



5バイトデータ受信後のプログラムです。
照合一致(3 緑LED点灯、消灯)はコメントアウトしました。


void MotorControl(void)
{


/*** 2連送照合比較一致の場合のみ制御実行***/
Error = 0; // エラーフラグリセット
for(i=0; i<5; i++){
if(Buf1[i] != Buf2[i]) // 比較実行
{
Error = 0xFF; // エラーフラグオン
LED_R ^= 1; // 赤LED点滅
delay_ms(100);
}
}
if((Error == 0) && (RcvData == 'E')) // 照合一致か?
{
//LED_G = 1; // 3 緑LED点灯
//delay_ms(500);
//LED_G = 0; // 3 緑LED消灯
//delay_ms(500);


Direction = (int)Buf1[0]; // 方向セット
MLdata = (int)Buf1[1] * 256 + (int)Buf1[2];
MRdata = (int)Buf1[3] * 256 + (int)Buf1[4];
// 制御実行
switch(Direction) // 方向チェック
{
case 0:
//MLReverse(MLdata); // 後進の場合
//MRReverse(MRdata);
LED_G=1;
delay_ms(5);
//LED_G=0;
//delay_ms(500);
break;
case 1:
//MLFeed(MLdata); // 前進の場合
//MRFeed(MRdata);
LED_W=1;
delay_ms(5);
//LED_W=0;
//delay_ms(500);
break;
case 2:
MLStop(); // 停止の場合
MRStop();
LED_R=1; //4 赤LED点灯
delay_ms(5);
//LED_R=0; //4 赤LED消灯
//delay_ms(500);
break;
default: break;
}
}
}

Re: USART受信プログラム 投稿者:n 投稿日:2017/03/22(Wed) 20:27:12 No.849

radioさん
nです。

受信データが、'S'(文字コード)なら書式に%cを指定します。
RcvData = ReadUSART(); // 1バイト受信
sprintf(buff1,(const far rom char *)"%c",RcvData);

受信データが、文字コードではなく数値だった場合は、
書式に%X(16進)や%d(10進)を指定します。
RcvData = ReadUSART(); // 1バイト受信
sprintf(buff1,(const far rom char *)"%02X",RcvData);
(%Xを%02Xとすると、00が表示できます)

すでにNo.848に投稿されていますが、ReadUSART()を使用する場合、
有効な受信データが到着しているかを確認する必要があります。
以下の、コードでご確認ください。
(getcUSART()は、ReadUSART()の別名ですので統一しました)
(空のループ(while文)を、空の波かっこ{}で表すスタイルです)

void RadioControl(void)
{
while(!DataRdyUSART()){} //必要
RcvData = ReadUSART();
if(RcvData == 'S'){
while(!DataRdyUSART()){} //必要
RcvData = ReadUSART();
if(RcvData == 'S'){
for(i = 0; i < 5; i++){
while(!DataRdyUSART()){}
Buf1[i] = ReadUSART();
}
for(i = 0; i < 5; i++){
while(!DataRdyUSART()){}
Buf2[i] = ~ReadUSART();
}
while(!DataRdyUSART()){}
RcvData = ReadUSART();
delay_ms(100);
MotorControl();
}
}
}

> PIC18F2320 + C18の環境で作成しています。
>
> 下記サイトを参考にさせていただき、無線ラジコンに取り組んでいます。
> 送信側は完成しましたが、受信側のプログラムで躓いています。
>
> [送信側]
> http://www.picfun.com/Sensor/equipj77.html
>
> XCTUで確認した所、受信側で次のデータが受信できていることを確認しました。
>
> 53 53 02 00 00 00 00 FD FF FF FF FF 45
> (S S 方向 右速度H 右速度L 左速度H 左速度L ~方向 ~右速度H ~右速度L ~左速度H ~左速度L E)
>
>
> 続いて、受信側のプログラムに取り掛かりました。
> [受信側]
> http://www.picfun.com/Sensor/equipj78.html
>
> Radio control関数(下記に掲載します)で躓いています。
>
> サイトのコードを参考に、C18環境で書き直して確認していますが、
> (確認の方法は、受信データをLCDに表示させています。)
>
> LCDにデータが何も表示されません。
> カーソルは2マス動くのですが、何も表示されない状態です。
>
> 確認の方法を含めて何かおかしなことをしているのでしょうか。
> 教えていただけると助かります。
>
> void RadioControl(void)
> {
> char buff1[20]; //LCD 1行目表示データ
> char buff2[20]; //LCD 2行目表示データ
>
> // データ受信と受信データ解析
> RcvData = ReadUSART( ); // 1バイト受信
> sprintf(buff1,(const far rom char *)"%2d%",RcvData);
> lcd_cmd(0x80); //1行目へ移動
> lcd_str(buff1);
> lcd_clear(); //LCD全消去
> delay_ms(1000);
>
> if(RcvData == 'S') // 'S'受信待ち
> {
> RcvData = ReadUSART( );
> sprintf(buff1,(const far rom char *)"%2d%",RcvData);
> lcd_cmd(0x80); //1行目へ移動
> lcd_str(buff1);
> lcd_clear(); //LCD全消去
> delay_ms(1000);
> if(RcvData == 'S') // 連続'S'受信待ち
> {
> for(i=0; i<5; i++) // データ受信5バイト
> while (!DataRdyUSART());
> Buf1[i] = getcUSART( );
> for(i=0; i<5; i++) // 反転データ5バイト受信
> while (!DataRdyUSART());
> Buf2[i] = ~getcUSART( );
> RcvData = ReadUSART( ); // 'E'受信
> // データ照合とモータ制御
> //MotorControl();
> }
> }
> }

Re: USART受信プログラム 投稿者:radio 投稿日:2017/03/22(Wed) 15:14:08 No.848

先程の投稿から少し進展しましたので、報告します。
データを正しく受信できていない件については、データ受信前に遅延(5msec)を追加することで、
正しく受信ができるようになりました。

⇒この確認は、状態確認用のLEDを用意して確認しました。
(LCD表示がおかしくなっていしまう件は、未解決です…)


↓のコードの状態で、データ照合の所まで進みました。
データを照合し、一致していたらLEDが点滅するようにして、点滅することを確認しました。

しかし、データを1度しか受信してくれません。
while(1)文の中のMotorTest();のプログラムは、無限ループになるのですが、
RadioControl();のプログラムは、データを1度受信したきりになってしまいます。

何が原因なのか分からず困っております。



while(1)
{
// モード読み込み
if(PORTBbits.RB0 == 0) // DIPSW No1 On
MotorTest(); // モータテストモード
else{
RadioControl(); // 無線ラジコンモード
}
}
CloseUSART();
}

/************************************
* モータテスト関数
* 1秒間隔で正転、逆転
************************************/
void MotorTest(void)
{
LED_R^=1;
delay_ms(500); //0.5sec
LED_G^=1;
delay_ms(500); //0.5sec
LED_Y^=1;
delay_ms(500); //0.5sec
LED_W^=1;
delay_ms(500); //0.5sec
}



/*********************************************
*  無線ラジコン処理関数
* Buf1, Buf2に受信データ格納
**********************************************/
void RadioControl(void)
{

char buff1[20]; //LCD 1行目表示データ
//char buff2[20]; //LCD 2行目表示データ

// データ受信と受信データ解析
while (!DataRdyUSART());
RcvData = ReadUSART(); //1文字受信

if(RcvData == 'S') // 'S'受信待ち
{
//LED_W^=1;
delay_ms(10);
//while (!DataRdyUSART());
RcvData = ReadUSART(); //1文字受信
if(RcvData == 'S') // 連続'S'受信待ち
{
//LED_Y^=1;
delay_ms(10);
for (i = 0; i < 5; i++) {
while (!DataRdyUSART());
Buf1[i] = getcUSART();
}
delay_ms(10);
for (i = 0; i < 5; i++) {
while (!DataRdyUSART());
Buf2[i] = ~getcUSART();
}

delay_ms(10);
while (!DataRdyUSART());
RcvData = ReadUSART( ); // 'E'受信
delay_ms(100);
// データ照合とモータ制御
MotorControl();
}
}
}

/***********************************************
* データ照合とモータ制御実行サブ関数
* (無線と赤外線で共用)
* Buf1,Buf2に受信データあり
* M1data,M2dataがモータ速度データ
***********************************************/
void MotorControl(void)
{


/*** 2連送照合比較一致の場合のみ制御実行***/
Error = 0; // エラーフラグリセット
for(i=0; i<5; i++){
if(Buf1[i] != Buf2[i]) // 比較実行
{
Error = 0xFF; // エラーフラグオン
LED_R ^= 1; // 赤LED点滅

delay_ms(100);
}
}
if((Error == 0) && (RcvData == 'E')) // 照合一致か?
{

LED_G = 1; // 緑LED点滅
delay_ms(500);
LED_G = 0; // 緑LED点滅
delay_ms(500);

Direction = (int)Buf1[0]; // 方向セット
MLdata = (int)Buf1[1] * 256 + (int)Buf1[2];
MRdata = (int)Buf1[3] * 256 + (int)Buf1[4];
// 制御実行
switch(Direction) // 方向チェック
{
case 0: MLReverse(MLdata); // 後進の場合
MRReverse(MRdata);
break;
case 1: MLFeed(MLdata); // 前進の場合
MRFeed(MRdata);
break;
case 2: MLStop(); // 停止の場合
MRStop();
break;
default: break;
}
}
}

USART受信プログラム 投稿者:radio 投稿日:2017/03/22(Wed) 10:47:49 No.847

PIC18F2320 + C18の環境で作成しています。

下記サイトを参考にさせていただき、無線ラジコンに取り組んでいます。
送信側は完成しましたが、受信側のプログラムで躓いています。

[送信側]
http://www.picfun.com/Sensor/equipj77.html

XCTUで確認した所、受信側で次のデータが受信できていることを確認しました。

53 53 02 00 00 00 00 FD FF FF FF FF 45
(S S 方向 右速度H 右速度L 左速度H 左速度L ~方向 ~右速度H ~右速度L ~左速度H ~左速度L E)


続いて、受信側のプログラムに取り掛かりました。
[受信側]
http://www.picfun.com/Sensor/equipj78.html

Radio control関数(下記に掲載します)で躓いています。

サイトのコードを参考に、C18環境で書き直して確認していますが、
(確認の方法は、受信データをLCDに表示させています。)

LCDにデータが何も表示されません。
カーソルは2マス動くのですが、何も表示されない状態です。

確認の方法を含めて何かおかしなことをしているのでしょうか。
教えていただけると助かります。

void RadioControl(void)
{
char buff1[20]; //LCD 1行目表示データ
char buff2[20]; //LCD 2行目表示データ

// データ受信と受信データ解析
RcvData = ReadUSART( ); // 1バイト受信
sprintf(buff1,(const far rom char *)"%2d%",RcvData);
lcd_cmd(0x80); //1行目へ移動
lcd_str(buff1);
lcd_clear(); //LCD全消去
delay_ms(1000);

if(RcvData == 'S') // 'S'受信待ち
{
RcvData = ReadUSART( );
sprintf(buff1,(const far rom char *)"%2d%",RcvData);
lcd_cmd(0x80); //1行目へ移動
lcd_str(buff1);
lcd_clear(); //LCD全消去
delay_ms(1000);
if(RcvData == 'S') // 連続'S'受信待ち
{
for(i=0; i<5; i++) // データ受信5バイト
while (!DataRdyUSART());
Buf1[i] = getcUSART( );
for(i=0; i<5; i++) // 反転データ5バイト受信
while (!DataRdyUSART());
Buf2[i] = ~getcUSART( );
RcvData = ReadUSART( ); // 'E'受信
// データ照合とモータ制御
//MotorControl();
}
}
}

USART送信 ワーニング[解決] 投稿者:radio 投稿日:2017/03/21(Tue) 09:01:16 No.846

n様

情報ありがとうございました。
無事解決できました。

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |

- WebForum -