ATMELのAT-Tiny26,ATmega,R8Cなどのワンチップマイコン,C言語,JAVAなどのプログラミング言語の入門のためのページです.サンプルプログラムを中心に紹介します.他にもLinixや数学ソフトなどの紹介も行います.

このブログを検索

あなたは 番目のお客様です.

2010年2月16日火曜日

Xbeeを使い無線でシリアル通信を行う










Xbeeを使い無線でシリアル通信を行うためのメモです
Series1とSeries2があって互換性がない.相互通信できない.
アンテナのタイプが3種類ある.室内で簡単な通信を行うなら,whipまたはChipアンテナ.屋外で回路をカバーで保護したい場合は,外付けアンテナが良い.
Xbeeのピンは,2mmピッチなので通常の基板にさせない.テスト用には,上部にリード線を
ハンダ付けるるのが簡単.
Xbeeは20ピンあり,単に通信で使うだけなら,VCC(1),DOUT(2),DIN(3),GND(10)のみ使う.
省電力のため通信時以外は休止(Hibernate)させたい場合,SM=1として,SleepModeとする.この場合,9pinをHighで休止,Lowで活動となる.

Xbeeの供給電源は2.8-3.4V,ちなみにADM3202は3-5.5V.
電池×3(4.5V)でも動く.
XBEEの通信速度はdefaultで9600

(はじめの一歩)
PCとXbeeを接続する方法は,Comポートからレベル変換(ADM3202)で接続する方法と,USBシリアル変換モジュールFT232RLで接続する方法がある.FT232RLで接続する方が,接続も簡単だし,FT232RLから3.3Vの電源も取り出せて便利である.
Xbeeの設定はX-CTUを使う.X-CTUはDigi-MaxStreamのサイトからダウンロードできる.
PCにXbeeを接続した状態でX-CTUを立ち上げ,Modem Configurationで
パラメータをリードして,変更したい設定を書き替えてライトすればよい.

(2台のPCを使ったテストの例)
PC-COM-ADM3202-XBEE-(無線)-XBEE-ADM3202-COM-PC
PC-USB-FT232RL-XBEE-(無線)-XBEE-FT232RL-USB-PC
通信は,Teraterm等の通信ソフトやX-CTUでできる.

(XBEEの設定の例)
Series1で1対1の接続の場合
自分のアドレスMYと相手のアドレスDLを互い違いになるように設定する.
Series1で多対多の接続の場合
自分のアドレスMYをゼロ(0)と相手のアドレスDLもゼロ(0)に設定する.
Series2で多対多の接続の場合
それぞれのXBEEのFunctionSetをZigbee router/End device ATに設定する.
DHをゼロ(0),DLを0X0000FFFFに設定する.
こうするとbroadcastの設定となり全XBEEに信号を送れる.
Series2で1対多の接続の場合
1台のXBEEのFunctionSetをZigbee coordinator ATに設定する.
DHをゼロ(0),DLを0X0000FFFFに設定する.
残りのXBEEのFunctionSetをZigbee router/End device ATに設定する.
DH,DLにはcoordinatorのSerialNumberのHighとLowを入れる.
こうするとcoordinatorは残りの全XBEEに信号を送り(broadcast)
各router/End deviceはcoordinatorにのみ信号を送る.

(ターミナルソフト)
シリアル通信のターミナルソフトとしてはやはりTeraTermが便利である.
お互いに画面に表示を行い通信を行うに場合は,
TeraTermの設定・端末・改行コードを「送信:CR+LF」「受信:CR」とすればよい

(AT-mega88を使ったシリアル通信のテストプログラム)
/*
adcom88.c
mega88p用AD変換,シリアル通信のプログラム
Ext8MHz分周なし
ADC0(PC0)は入力,可変抵抗の電圧を入力する
電源5V
ADCSR=0B11000000でAD変換がスタートし,ADIF=1でAD変換完了
AVCCとVCCを接続,AVGND(22ピン)とGNDを接続,AREFは無接続
AD変換の精度を確保するためにはADPS0-2で
A/D変換クロックを50-200kHzに設定する必要あり
CK=8MHzのときCK/64=125kHz
avrデータシートのUSARTサンプルプログラムでは
データを受信する関数は,データが来るまで待ち続けるので
データが来ないときには'*'を返すように変更した
*/
#include <avr/io.h>

//マイクロ秒単位の待ち(t<256)
void delay(uint8_t t){
TCCR0B=0B00000010;//タイマカウンタ0の分周をセットCK/8
TCNT0=0;
while(TCNT0<t){}
}

void Utx(uint8_t data) //マイコンがデータを送信する
{
while ( !(UCSR0A & (1<<UDRE0)) );
UDR0 = data;
}

uint8_t Urx(void)//マイコンがデータを受信する(修正)
{
if(UCSR0A & (1<<RXC0))return UDR0;
else return '*';
}

int main( void )
{
int16_t i,baud;
uint8_t ad,dat,st=0;
dat='e';

//USART
baud=8000000/16/9600-1;//ボーレートの計算
UBRR0H = (uint8_t)(baud>>8);//ボーレート上位
UBRR0L = (uint8_t)baud; //ボーレート下位
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
UCSR0B = (1<<RXEN0)|(1<<TXEN0);//送受信可

//AD
ADMUX=0B11100000; //基準電圧1.1V Left Adjust ADC0(PC0)
ADCSRA=0B10000110; //CK/64

while((dat = Urx())!='s'){}
while(1){
dat = Urx();
if(dat=='s')st=1;
if(dat=='e')st=0;

if(st==1){
//AD
ADCSRA |= 1<<ADSC; //AD start
while(!(ADCSRA & (1<<ADIF))){} //ADCSRのビット4(ADIF)が1になるまで待つ
ad=ADCH;
//AD to dec, send data
dat=ad/100+'0';
Utx(dat);
ad%=100;
dat=ad/10+'0';
Utx(dat);
ad%=10;
dat=ad+'0';
Utx(dat);
Utx(0x0a); //LF
Utx(0x0d); //CR
}//if(st==1)
for(i=0;i<4000;i++)delay(250);//wait 1s

}//while(1)

}