Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: XbeeAPI Hybrid_main_FirstEdtion
XbeeApiLib.cpp
00001 #include "mbed.h" 00002 #include <XbeeApiLib.h> 00003 #include <string> 00004 00005 XbeeApi::XbeeApi(PinName Tx, PinName Rx, int BaudRate, void (*onPacketReceived)(int, char*)) : Xbee(Tx, Rx, BaudRate){ 00006 //Xbee = Serial(Tx, Rx, BaudRate); 00007 //Xbee.baud(BaudRate); 00008 00009 HopLimit = 0; 00010 for(int i = 0;i < 4;i++){ 00011 address[i].IsAvailable = false; 00012 } 00013 IsTransmitting = false; 00014 SetInterrupt(true); 00015 OnPacketReceived = onPacketReceived; 00016 } 00017 00018 void XbeeApi::SetAddress(int Num, unsigned long HIGH, unsigned long LOW){ 00019 for(int i = 0;i < 4;i++){ 00020 address[Num].ADR[3 - i] = reinterpret_cast<char (&)[sizeof(HIGH)]>(HIGH)[i]; 00021 address[Num].ADR[7 - i] = reinterpret_cast<char (&)[sizeof(LOW)]>(LOW)[i]; 00022 } 00023 address[Num].IsAvailable = false; 00024 address[Num].sum = 0; 00025 //EndPacket()でチェックサムを計算する際、宛先アドレスもチェックサムに含まれる 00026 //宛先アドレスは頻繁に変更されないので、アドレス分の合計だけを先にまとめて計算しておく 00027 for(int i = 0;i < 8;i++){ 00028 address[Num].sum += address[Num].ADR[i]; 00029 } 00030 address[Num].ADR16bit[0] = 0x00; 00031 address[Num].ADR16bit[1] = 0x00; 00032 } 00033 00034 // 00035 //char StartWith: 送信されるデータの最初の1バイトに送信内容のタグとしての役割を持たせている 00036 //これにより、受信側では送信されてきたバイナリデータをどのような形式で読み取ればよいのか判断する 00037 void XbeeApi::StartPacket(char StartWith){ 00038 CheckSum = 0x12; 00039 buf[17] = StartWith; 00040 itr = 18; 00041 } 00042 00043 //文字列を送信バッファに書き込む 00044 void XbeeApi::Write(string val){ 00045 int length = val.length(); 00046 if(length < 128 - itr){ //送信バッファの空きよりも文字列が長い場合は何もしない 00047 for(int i = 0;i < length;i++){ 00048 buf[itr + i] = val.c_str()[i]; 00049 } 00050 itr += length; 00051 }else{ 00052 buf[17] = 0x00; 00053 EndPacket(); 00054 } 00055 } 00056 00057 //int型の数値をバイト列として書き込む 00058 //リトルエンディアン(位の大きい数字ほどバイト列では後ろになる)であることに注意 00059 void XbeeApi::Write(int val){ 00060 if(sizeof(val) < 128 - itr){ 00061 for(int i = 0;i < sizeof(val);i++){ 00062 buf[itr + i] = reinterpret_cast<char (&)[sizeof(val)]>(val)[i]; 00063 } 00064 itr += sizeof(val); 00065 }else{ 00066 buf[17] = 0x00; 00067 EndPacket(); 00068 } 00069 } 00070 00071 //long型の数値をバイト列として書き込む 00072 //リトルエンディアン(位の大きい数字ほどバイト列では後ろになる)であることに注意 00073 void XbeeApi::Write(long long val){ 00074 if(sizeof(val) < 128 - itr){ 00075 for(int i = 0;i < sizeof(val);i++){ 00076 buf[itr + i] = reinterpret_cast<char (&)[sizeof(val)]>(val)[i]; 00077 } 00078 itr += sizeof(val); 00079 }else{ 00080 buf[17] = 0x00; 00081 EndPacket(); 00082 } 00083 } 00084 00085 //double型の数値をバイト列として書き込む 00086 //リトルエンディアン(位の大きい数字ほどバイト列では後ろになる)であることに注意 00087 void XbeeApi::Write(double val){ 00088 if(sizeof(val) < 128 - itr){ 00089 for(int i = 0;i < sizeof(val);i++){ 00090 buf[itr + i] = reinterpret_cast<char (&)[sizeof(val)]>(val)[i]; 00091 } 00092 itr += sizeof(val); 00093 }else{ 00094 buf[17] = 0x00; 00095 EndPacket(); 00096 } 00097 } 00098 00099 //float型の数値をバイト列として書き込む 00100 //リトルエンディアン(位の大きい数字ほどバイト列では後ろになる)であることに注意 00101 void XbeeApi::Write(float val){ 00102 if(sizeof(val) < 128 - itr){ 00103 for(int i = 0;i < sizeof(val);i++){ 00104 buf[itr + i] = reinterpret_cast<char (&)[sizeof(val)]>(val)[i]; 00105 } 00106 itr += sizeof(val); 00107 }else{ 00108 buf[17] = 0x00; 00109 EndPacket(); 00110 } 00111 } 00112 00113 void XbeeApi::EndPacket(){ 00114 if(itr != 0){ 00115 buf[0] = 0x7E; //パケットの先頭を表す 00116 buf[1] = (char)(itr - 3) >> 8; 00117 buf[2] = (char)(itr - 3) & 0x00FF; 00118 buf[3] = 0x10; 00119 buf[4] = 0x00; //ここを01にするとxbeeは送信の成否の判定を行うようになる(クソ重い) 00120 buf[15] = 0x01; 00121 buf[16] = 0x01; //0x01:送りっぱなし 00122 for(int i = 17;i < itr; i++){ 00123 CheckSum += buf[i]; 00124 } 00125 BytesToTransmit = itr + 1; 00126 NextTransmitIndex = BytesToTransmit; 00127 TransmittingAddrNum = -1; 00128 itr = 0; 00129 IsTransmitting = true; 00130 OnTransmitEnabled(); 00131 } 00132 } 00133 00134 void XbeeApi::OnTransmitEnabled(){ 00135 if(IsTransmitting == true){ 00136 if(NextTransmitIndex < BytesToTransmit){ 00137 WriteWithEsc(buf[NextTransmitIndex]); 00138 NextTransmitIndex++; 00139 }else{ 00140 NextTransmitIndex = 0; 00141 //次の送信先に切り替える 00142 while(true){ 00143 if(TransmittingAddrNum < 4){ 00144 TransmittingAddrNum++; 00145 if(address[TransmittingAddrNum].IsAvailable == true){ 00146 //次の送信先に送るためのバッファの準備 00147 for(int i = 0; i < 8; i++){ 00148 buf[i + 5] = address[TransmittingAddrNum].ADR[i]; 00149 } 00150 buf[13] = address[TransmittingAddrNum].ADR16bit[0]; 00151 buf[14] = address[TransmittingAddrNum].ADR16bit[1]; 00152 buf[BytesToTransmit - 1] = (char)(0xFF - (CheckSum + address[TransmittingAddrNum].sum + address[TransmittingAddrNum].ADR16bit[0] + address[TransmittingAddrNum].ADR16bit[1]) & 0xFF); 00153 Xbee.putc(buf[0]); 00154 NextTransmitIndex++; 00155 break; 00156 } 00157 }else{ 00158 //送信完了 00159 IsTransmitting = false; 00160 break; 00161 } 00162 } 00163 } 00164 } 00165 } 00166 00167 void XbeeApi::WriteWithEsc(char c){ 00168 if(c == 0x7E){ 00169 Xbee.putc(0x7D); 00170 Xbee.putc(0x5E); 00171 }else if(c == 0x7D){ 00172 Xbee.putc(0x7D); 00173 Xbee.putc(0x5D); 00174 }else{ 00175 Xbee.putc(c); 00176 } 00177 } 00178 00179 void XbeeApi::ClearPacket(){ 00180 CheckSum = 0; 00181 itr = 0; 00182 } 00183 00184 00185 //データ受信時の処理 1バイトごとに呼び出される必要がある 00186 void XbeeApi::OnDataReceived(){ 00187 static bool EscFlag = false; 00188 static int PacketLength = 0; 00189 static bool IsReceivingPacket = false; 00190 00191 char message; 00192 message = Xbee.getc(); 00193 if(message == 0x7E){ //パケットの先頭バイトは0x7E 00194 ReceivedBytesCounter = 0; 00195 PacketLength = 0; 00196 IsReceivingPacket = true; 00197 EscFlag = false; 00198 } 00199 if(IsReceivingPacket == true){ 00200 if(message == 0x7D){ 00201 EscFlag = true; 00202 }else{ 00203 if(EscFlag == true){ 00204 RxBuf[ReceivedBytesCounter] = message ^ 0x20; 00205 EscFlag = false; 00206 }else{ 00207 RxBuf[ReceivedBytesCounter] = message; 00208 } 00209 ReceivedBytesCounter++; 00210 if(ReceivedBytesCounter >= 256){ 00211 IsReceivingPacket = false; //受信バッファを溢れる場合は、パケットの読み込みを中止する 次に0x7Eを受信するまで再開されない 00212 } 00213 } 00214 //この時点でReceivedBytesCounterには受信したデータのバイト数が入っている 00215 //2バイト目と3バイト目はパケットの長さを表している 00216 if(RxBuf[0] == 0x7E){ 00217 if(ReceivedBytesCounter == 3){ //パケットの3バイト目までを受信した時点で、パケットの長さを計算できる 00218 PacketLength = 255 * RxBuf[1] + RxBuf[2]; 00219 } 00220 if(ReceivedBytesCounter > 3 && ReceivedBytesCounter == PacketLength + 4){ //パケットの長さと同じだけのデータを受信したら 00221 int sum = 0; 00222 for(int i = 3; i < ReceivedBytesCounter - 1; i++){ //先頭3バイトとチェックサム以外のすべてのバイトを合計 00223 sum += RxBuf[i]; 00224 } 00225 if((char)(0xFF - sum & 0xFF) == RxBuf[ReceivedBytesCounter - 1]){ //チェックサムが一致するならば 00226 //ここにデータ受信時の処理を書く 00227 //パケット受信直後なので、多少時間のかかる処理でも問題ないはず 00228 if(RxBuf[3] == 0x90){ // パケットタイプ0x90は他のXbeeから送信されたデータを表す 00229 int DataLength = PacketLength - 12; //データ本体の長さは パケットの長さ - 12 ここでいう「パケットの長さ」に、最初の3バイトとチェックサムは含まない 00230 OnPacketReceived(DataLength, &RxBuf[15]); //パケットタイプ0x90は地上局から送信されたデータが16バイト目 すなわち RxBuf[15] から格納されている 00231 //OnPacketReceived(DataLength + 16, RxBuf); //デバッグ用 パケットすべてを渡す場合 00232 if(DataLength == 2 && RxBuf[15] == 0x59 && RxBuf[16] == 0x4D){ //0x594Dが送られて来たら、送信元の64bitアドレスをチェックする 00233 for(int i = 0; i < 4; i++){ 00234 bool IsMatchAddr = true; 00235 for(int j = 0; j < 8; j++){ 00236 if(address[i].ADR[j] != RxBuf[j + 4]){ 00237 IsMatchAddr = false; //16bitアドレスを調べる 1つでも一致しなければ終了するし 00238 break; 00239 } 00240 } 00241 if(IsMatchAddr == true){ //0x594Dを送信してきた地上局の64bitアドレスがaddress[i]と一致した場合 00242 address[i].ADR16bit[0] = RxBuf[12]; //address[i]の16bitアドレスを地上局側に合わせる 00243 address[i].ADR16bit[1] = RxBuf[13]; 00244 address[i].IsAvailable = true; 00245 break; 00246 } 00247 } 00248 } 00249 } 00250 } 00251 IsReceivingPacket = false; 00252 } 00253 } 00254 } 00255 } 00256 00257 void XbeeApi::SetInterrupt(bool val){ 00258 if(val == true){ 00259 Xbee.attach(callback(this, &XbeeApi::OnDataReceived), Serial::RxIrq); 00260 Xbee.attach(callback(this, &XbeeApi::OnTransmitEnabled), Serial::TxIrq); 00261 }else{ 00262 Xbee.attach(NULL, Serial::RxIrq); 00263 Xbee.attach(NULL, Serial::TxIrq); 00264 } 00265 } 00266
Generated on Sat Jul 16 2022 00:59:51 by
1.7.2