XbeeApi

Dependents:   XbeeAPI Hybrid_main_FirstEdtion

Committer:
ark777
Date:
Fri Jan 20 08:13:54 2017 +0000
Revision:
0:bca23ad9e6b5
Child:
1:34007fc9235e
Ver1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ark777 0:bca23ad9e6b5 1 #include "mbed.h"
ark777 0:bca23ad9e6b5 2 #include <XbeeApiLib.h>
ark777 0:bca23ad9e6b5 3 #include <string>
ark777 0:bca23ad9e6b5 4
ark777 0:bca23ad9e6b5 5 XbeeApi::XbeeApi(PinName Tx, PinName Rx, int BaudRate) : Xbee(Tx, Rx, BaudRate){
ark777 0:bca23ad9e6b5 6 //Xbee = Serial(Tx, Rx, BaudRate);
ark777 0:bca23ad9e6b5 7 //Xbee.baud(BaudRate);
ark777 0:bca23ad9e6b5 8
ark777 0:bca23ad9e6b5 9 HopLimit = 0;
ark777 0:bca23ad9e6b5 10 for(int i = 0;i < 4;i++){
ark777 0:bca23ad9e6b5 11 address[i].IsAvailable = false;
ark777 0:bca23ad9e6b5 12 }
ark777 0:bca23ad9e6b5 13 IsTransmitting = false;
ark777 0:bca23ad9e6b5 14 }
ark777 0:bca23ad9e6b5 15
ark777 0:bca23ad9e6b5 16 void XbeeApi::SetAddress(int Num, unsigned long HIGH, unsigned long LOW){
ark777 0:bca23ad9e6b5 17 for(int i = 0;i < 4;i++){
ark777 0:bca23ad9e6b5 18 address[Num].ADR[3 - i] = reinterpret_cast<char (&)[sizeof(HIGH)]>(HIGH)[i];
ark777 0:bca23ad9e6b5 19 address[Num].ADR[7 - i] = reinterpret_cast<char (&)[sizeof(LOW)]>(LOW)[i];
ark777 0:bca23ad9e6b5 20 }
ark777 0:bca23ad9e6b5 21 address[Num].IsAvailable = true;
ark777 0:bca23ad9e6b5 22 address[Num].sum = 0;
ark777 0:bca23ad9e6b5 23 //EndPacket()でチェックサムを計算する際、宛先アドレスもチェックサムに含まれる
ark777 0:bca23ad9e6b5 24 //宛先アドレスは頻繁に変更されないので、アドレス分の合計だけを先にまとめて計算しておく
ark777 0:bca23ad9e6b5 25 for(int i = 0;i < 8;i++){
ark777 0:bca23ad9e6b5 26 address[Num].sum += address[Num].ADR[i];
ark777 0:bca23ad9e6b5 27 }
ark777 0:bca23ad9e6b5 28 address[Num].ADR16bit[0] = 0x00;
ark777 0:bca23ad9e6b5 29 address[Num].ADR16bit[1] = 0x00;
ark777 0:bca23ad9e6b5 30 }
ark777 0:bca23ad9e6b5 31
ark777 0:bca23ad9e6b5 32 //
ark777 0:bca23ad9e6b5 33 //char StartWith: 送信されるデータの最初の1バイトに送信内容のタグとしての役割を持たせている
ark777 0:bca23ad9e6b5 34 //これにより、受信側では送信されてきたバイナリデータをどのような形式で読み取ればよいのか判断する
ark777 0:bca23ad9e6b5 35 void XbeeApi::StartPacket(char StartWith){
ark777 0:bca23ad9e6b5 36 CheckSum = 0x12;
ark777 0:bca23ad9e6b5 37 buf[17] = StartWith;
ark777 0:bca23ad9e6b5 38 itr = 18;
ark777 0:bca23ad9e6b5 39 }
ark777 0:bca23ad9e6b5 40
ark777 0:bca23ad9e6b5 41 //文字列を送信バッファに書き込む
ark777 0:bca23ad9e6b5 42 void XbeeApi::Write(string val){
ark777 0:bca23ad9e6b5 43 int length = val.length();
ark777 0:bca23ad9e6b5 44 if(length < 128 - itr){ //送信バッファの空きよりも文字列が長い場合は何もしない
ark777 0:bca23ad9e6b5 45 for(int i = 0;i < length;i++){
ark777 0:bca23ad9e6b5 46 buf[itr + i] = val.c_str()[i];
ark777 0:bca23ad9e6b5 47 }
ark777 0:bca23ad9e6b5 48 itr += length;
ark777 0:bca23ad9e6b5 49 }else{
ark777 0:bca23ad9e6b5 50 buf[17] = 0x00;
ark777 0:bca23ad9e6b5 51 EndPacket();
ark777 0:bca23ad9e6b5 52 }
ark777 0:bca23ad9e6b5 53 }
ark777 0:bca23ad9e6b5 54
ark777 0:bca23ad9e6b5 55 //int型の数値をバイト列として書き込む
ark777 0:bca23ad9e6b5 56 //リトルエンディアン(位の大きい数字ほどバイト列では後ろになる)であることに注意
ark777 0:bca23ad9e6b5 57 void XbeeApi::Write(int val){
ark777 0:bca23ad9e6b5 58 if(sizeof(val) < 128 - itr){
ark777 0:bca23ad9e6b5 59 for(int i = 0;i < sizeof(val);i++){
ark777 0:bca23ad9e6b5 60 buf[itr + i] = reinterpret_cast<char (&)[sizeof(val)]>(val)[i];
ark777 0:bca23ad9e6b5 61 }
ark777 0:bca23ad9e6b5 62 itr += sizeof(val);
ark777 0:bca23ad9e6b5 63 }else{
ark777 0:bca23ad9e6b5 64 buf[17] = 0x00;
ark777 0:bca23ad9e6b5 65 EndPacket();
ark777 0:bca23ad9e6b5 66 }
ark777 0:bca23ad9e6b5 67 }
ark777 0:bca23ad9e6b5 68
ark777 0:bca23ad9e6b5 69 //double型の数値をバイト列として書き込む
ark777 0:bca23ad9e6b5 70 //リトルエンディアン(位の大きい数字ほどバイト列では後ろになる)であることに注意
ark777 0:bca23ad9e6b5 71 void XbeeApi::Write(double val){
ark777 0:bca23ad9e6b5 72 if(sizeof(val) < 128 - itr){
ark777 0:bca23ad9e6b5 73 for(int i = 0;i < sizeof(val);i++){
ark777 0:bca23ad9e6b5 74 buf[itr + i] = reinterpret_cast<char (&)[sizeof(val)]>(val)[i];
ark777 0:bca23ad9e6b5 75 }
ark777 0:bca23ad9e6b5 76 itr += sizeof(val);
ark777 0:bca23ad9e6b5 77 }else{
ark777 0:bca23ad9e6b5 78 buf[17] = 0x00;
ark777 0:bca23ad9e6b5 79 EndPacket();
ark777 0:bca23ad9e6b5 80 }
ark777 0:bca23ad9e6b5 81 }
ark777 0:bca23ad9e6b5 82
ark777 0:bca23ad9e6b5 83 //float型の数値をバイト列として書き込む
ark777 0:bca23ad9e6b5 84 //リトルエンディアン(位の大きい数字ほどバイト列では後ろになる)であることに注意
ark777 0:bca23ad9e6b5 85 void XbeeApi::Write(float val){
ark777 0:bca23ad9e6b5 86 if(sizeof(val) < 128 - itr){
ark777 0:bca23ad9e6b5 87 for(int i = 0;i < sizeof(val);i++){
ark777 0:bca23ad9e6b5 88 buf[itr + i] = reinterpret_cast<char (&)[sizeof(val)]>(val)[i];
ark777 0:bca23ad9e6b5 89 }
ark777 0:bca23ad9e6b5 90 itr += sizeof(val);
ark777 0:bca23ad9e6b5 91 }else{
ark777 0:bca23ad9e6b5 92 buf[17] = 0x00;
ark777 0:bca23ad9e6b5 93 EndPacket();
ark777 0:bca23ad9e6b5 94 }
ark777 0:bca23ad9e6b5 95 }
ark777 0:bca23ad9e6b5 96
ark777 0:bca23ad9e6b5 97 /*void XbeeApi::EndPacket(){
ark777 0:bca23ad9e6b5 98 if(itr != 0){
ark777 0:bca23ad9e6b5 99 CheckSum += 0x12;
ark777 0:bca23ad9e6b5 100 for(int i = 0;i < itr;i++){
ark777 0:bca23ad9e6b5 101 CheckSum += buf[i];
ark777 0:bca23ad9e6b5 102 }
ark777 0:bca23ad9e6b5 103 for(int i = 0; i < 4;i++){
ark777 0:bca23ad9e6b5 104 if(address[i].IsAvailable == true){
ark777 0:bca23ad9e6b5 105 Xbee.putc(0x7E); //パケットの先頭を表す
ark777 0:bca23ad9e6b5 106 WriteWithEsc((char)(itr + 14) >> 8);
ark777 0:bca23ad9e6b5 107 WriteWithEsc((char)(itr + 14) & 0x00FF);
ark777 0:bca23ad9e6b5 108 WriteWithEsc(0x10);
ark777 0:bca23ad9e6b5 109 WriteWithEsc(0x00); //ここを01にするとxbeeは送信の成否の判定を行うようになる(クソ重い)
ark777 0:bca23ad9e6b5 110 //宛先アドレスを書き込む
ark777 0:bca23ad9e6b5 111 for(int j = 0;j < 8;j++){
ark777 0:bca23ad9e6b5 112 WriteWithEsc(address[i].ADR[j]);
ark777 0:bca23ad9e6b5 113 }
ark777 0:bca23ad9e6b5 114 WriteWithEsc(address[i].ADR16bit[0]);
ark777 0:bca23ad9e6b5 115 WriteWithEsc(address[i].ADR16bit[1]);
ark777 0:bca23ad9e6b5 116 WriteWithEsc(0x01);
ark777 0:bca23ad9e6b5 117 WriteWithEsc(0x01);
ark777 0:bca23ad9e6b5 118 //データを書き込む
ark777 0:bca23ad9e6b5 119 for(int j = 0;j < itr;j++){
ark777 0:bca23ad9e6b5 120 WriteWithEsc(buf[j]);
ark777 0:bca23ad9e6b5 121 }
ark777 0:bca23ad9e6b5 122 //チェックサムを書き込む
ark777 0:bca23ad9e6b5 123 WriteWithEsc((char)(0xFF - (CheckSum + address[i].sum + address[i].ADR16bit[0] + address[i].ADR16bit[1]) & 0xFF));
ark777 0:bca23ad9e6b5 124 }
ark777 0:bca23ad9e6b5 125 }
ark777 0:bca23ad9e6b5 126 CheckSum = 0;
ark777 0:bca23ad9e6b5 127 itr = 0;
ark777 0:bca23ad9e6b5 128 }
ark777 0:bca23ad9e6b5 129 }*/
ark777 0:bca23ad9e6b5 130
ark777 0:bca23ad9e6b5 131 void XbeeApi::EndPacket(){
ark777 0:bca23ad9e6b5 132 if(itr != 0){
ark777 0:bca23ad9e6b5 133 buf[0] = 0x7E; //パケットの先頭を表す
ark777 0:bca23ad9e6b5 134 buf[1] = (char)(itr - 3) >> 8;
ark777 0:bca23ad9e6b5 135 buf[2] = (char)(itr - 3) & 0x00FF;
ark777 0:bca23ad9e6b5 136 buf[3] = 0x10;
ark777 0:bca23ad9e6b5 137 buf[4] = 0x00; //ここを01にするとxbeeは送信の成否の判定を行うようになる(クソ重い)
ark777 0:bca23ad9e6b5 138 buf[15] = 0x01;
ark777 0:bca23ad9e6b5 139 buf[16] = 0x01; //0x01:送りっぱなし
ark777 0:bca23ad9e6b5 140 for(int i = 17;i < itr; i++){
ark777 0:bca23ad9e6b5 141 CheckSum += buf[i];
ark777 0:bca23ad9e6b5 142 }
ark777 0:bca23ad9e6b5 143 BytesToTransmit = itr + 1;
ark777 0:bca23ad9e6b5 144 NextTransmitIndex = BytesToTransmit;
ark777 0:bca23ad9e6b5 145 TransmittingAddrNum = -1;
ark777 0:bca23ad9e6b5 146 itr = 0;
ark777 0:bca23ad9e6b5 147 IsTransmitting = true;
ark777 0:bca23ad9e6b5 148 OnTransmitEnabled();
ark777 0:bca23ad9e6b5 149 }
ark777 0:bca23ad9e6b5 150 }
ark777 0:bca23ad9e6b5 151
ark777 0:bca23ad9e6b5 152 void XbeeApi::OnTransmitEnabled(){
ark777 0:bca23ad9e6b5 153 if(IsTransmitting == true){
ark777 0:bca23ad9e6b5 154 if(NextTransmitIndex < BytesToTransmit){
ark777 0:bca23ad9e6b5 155 WriteWithEsc(buf[NextTransmitIndex]);
ark777 0:bca23ad9e6b5 156 NextTransmitIndex++;
ark777 0:bca23ad9e6b5 157 }else{
ark777 0:bca23ad9e6b5 158 NextTransmitIndex = 0;
ark777 0:bca23ad9e6b5 159 //次の送信先に切り替える
ark777 0:bca23ad9e6b5 160 while(true){
ark777 0:bca23ad9e6b5 161 if(TransmittingAddrNum < 4){
ark777 0:bca23ad9e6b5 162 TransmittingAddrNum++;
ark777 0:bca23ad9e6b5 163 if(address[TransmittingAddrNum].IsAvailable == true){
ark777 0:bca23ad9e6b5 164 //次の送信先に送るためのバッファの準備
ark777 0:bca23ad9e6b5 165 for(int i = 0; i < 8; i++){
ark777 0:bca23ad9e6b5 166 buf[i + 5] = address[TransmittingAddrNum].ADR[i];
ark777 0:bca23ad9e6b5 167 }
ark777 0:bca23ad9e6b5 168 buf[13] = address[TransmittingAddrNum].ADR16bit[0];
ark777 0:bca23ad9e6b5 169 buf[14] = address[TransmittingAddrNum].ADR16bit[1];
ark777 0:bca23ad9e6b5 170 buf[BytesToTransmit - 1] = (char)(0xFF - (CheckSum + address[TransmittingAddrNum].sum + address[TransmittingAddrNum].ADR16bit[0] + address[TransmittingAddrNum].ADR16bit[1]) & 0xFF);
ark777 0:bca23ad9e6b5 171 Xbee.putc(buf[0]);
ark777 0:bca23ad9e6b5 172 NextTransmitIndex++;
ark777 0:bca23ad9e6b5 173 break;
ark777 0:bca23ad9e6b5 174 }
ark777 0:bca23ad9e6b5 175 }else{
ark777 0:bca23ad9e6b5 176 //送信完了
ark777 0:bca23ad9e6b5 177 IsTransmitting = false;
ark777 0:bca23ad9e6b5 178 break;
ark777 0:bca23ad9e6b5 179 }
ark777 0:bca23ad9e6b5 180 }
ark777 0:bca23ad9e6b5 181 }
ark777 0:bca23ad9e6b5 182 }
ark777 0:bca23ad9e6b5 183 }
ark777 0:bca23ad9e6b5 184
ark777 0:bca23ad9e6b5 185 void XbeeApi::WriteWithEsc(char c){
ark777 0:bca23ad9e6b5 186 if(c == 0x7E){
ark777 0:bca23ad9e6b5 187 Xbee.putc(0x7D);
ark777 0:bca23ad9e6b5 188 Xbee.putc(0x5E);
ark777 0:bca23ad9e6b5 189 }else if(c == 0x7D){
ark777 0:bca23ad9e6b5 190 Xbee.putc(0x7D);
ark777 0:bca23ad9e6b5 191 Xbee.putc(0x5D);
ark777 0:bca23ad9e6b5 192 }else{
ark777 0:bca23ad9e6b5 193 Xbee.putc(c);
ark777 0:bca23ad9e6b5 194 }
ark777 0:bca23ad9e6b5 195 }
ark777 0:bca23ad9e6b5 196
ark777 0:bca23ad9e6b5 197 void XbeeApi::ClearPacket(){
ark777 0:bca23ad9e6b5 198 CheckSum = 0;
ark777 0:bca23ad9e6b5 199 itr = 0;
ark777 0:bca23ad9e6b5 200 }
ark777 0:bca23ad9e6b5 201
ark777 0:bca23ad9e6b5 202
ark777 0:bca23ad9e6b5 203 //データ受信時の処理 1バイトごとに呼び出される必要がある
ark777 0:bca23ad9e6b5 204 void XbeeApi::OnDataReceived(){
ark777 0:bca23ad9e6b5 205 static DigitalOut LED(LED1);
ark777 0:bca23ad9e6b5 206 static bool EscFlag = false;
ark777 0:bca23ad9e6b5 207 static int PacketLength = 0;
ark777 0:bca23ad9e6b5 208 static bool IsReceivingPacket = false;
ark777 0:bca23ad9e6b5 209
ark777 0:bca23ad9e6b5 210 char message;
ark777 0:bca23ad9e6b5 211 message = Xbee.getc();
ark777 0:bca23ad9e6b5 212 if(message == 0x7E){ //パケットの先頭バイトは0x7E
ark777 0:bca23ad9e6b5 213 ReceivedBytesCounter = 0;
ark777 0:bca23ad9e6b5 214 PacketLength = 0;
ark777 0:bca23ad9e6b5 215 IsReceivingPacket = true;
ark777 0:bca23ad9e6b5 216 EscFlag = false;
ark777 0:bca23ad9e6b5 217 }
ark777 0:bca23ad9e6b5 218 if(IsReceivingPacket == true){
ark777 0:bca23ad9e6b5 219 if(message == 0x7D){
ark777 0:bca23ad9e6b5 220 EscFlag = true;
ark777 0:bca23ad9e6b5 221 }else{
ark777 0:bca23ad9e6b5 222 if(EscFlag == true){
ark777 0:bca23ad9e6b5 223 RxBuf[ReceivedBytesCounter] = message ^ 0x20;
ark777 0:bca23ad9e6b5 224 EscFlag = false;
ark777 0:bca23ad9e6b5 225 }else{
ark777 0:bca23ad9e6b5 226 RxBuf[ReceivedBytesCounter] = message;
ark777 0:bca23ad9e6b5 227 }
ark777 0:bca23ad9e6b5 228 ReceivedBytesCounter++;
ark777 0:bca23ad9e6b5 229 }
ark777 0:bca23ad9e6b5 230 //この時点でReceivedBytesCounterには受信したデータのバイト数が入っている
ark777 0:bca23ad9e6b5 231 //2バイト目と3バイト目はパケットの長さを表している
ark777 0:bca23ad9e6b5 232 if(RxBuf[0] == 0x7E){
ark777 0:bca23ad9e6b5 233 if(ReceivedBytesCounter == 3){
ark777 0:bca23ad9e6b5 234 PacketLength = 255 * RxBuf[1] + RxBuf[2];
ark777 0:bca23ad9e6b5 235 }
ark777 0:bca23ad9e6b5 236 if(ReceivedBytesCounter > 3 && ReceivedBytesCounter == PacketLength + 4){
ark777 0:bca23ad9e6b5 237 int sum = 0;
ark777 0:bca23ad9e6b5 238 for(int i = 3; i < ReceivedBytesCounter - 1; i++){ //先頭3バイトとチェックサム以外のすべてのバイトを合計
ark777 0:bca23ad9e6b5 239 sum += RxBuf[i];
ark777 0:bca23ad9e6b5 240 }
ark777 0:bca23ad9e6b5 241 if((char)(0xFF - sum & 0xFF) == RxBuf[ReceivedBytesCounter - 1]){
ark777 0:bca23ad9e6b5 242 //ここにデータ受信時の処理を書く
ark777 0:bca23ad9e6b5 243 //パケット受信直後なので、多少時間のかかる処理でも問題ないはず
ark777 0:bca23ad9e6b5 244 if(RxBuf[3] == 0x90){
ark777 0:bca23ad9e6b5 245 int DataLength = PacketLength - 12;
ark777 0:bca23ad9e6b5 246 //パケットタイプ0x90は地上局から送信されたデータが16バイト目 すなわち RxBuf[15] から格納されている
ark777 0:bca23ad9e6b5 247 if(DataLength == 2 && RxBuf[15] == 0x59 && RxBuf[16] == 0x4D){
ark777 0:bca23ad9e6b5 248 LED = !LED;
ark777 0:bca23ad9e6b5 249 address[0].ADR16bit[0] = RxBuf[12];
ark777 0:bca23ad9e6b5 250 address[0].ADR16bit[1] = RxBuf[13];
ark777 0:bca23ad9e6b5 251 }
ark777 0:bca23ad9e6b5 252 if(DataLength == 2 && RxBuf[15] == 0x5E){
ark777 0:bca23ad9e6b5 253
ark777 0:bca23ad9e6b5 254 }
ark777 0:bca23ad9e6b5 255 }
ark777 0:bca23ad9e6b5 256 }
ark777 0:bca23ad9e6b5 257 IsReceivingPacket = false;
ark777 0:bca23ad9e6b5 258 }
ark777 0:bca23ad9e6b5 259 }
ark777 0:bca23ad9e6b5 260 }
ark777 0:bca23ad9e6b5 261 }
ark777 0:bca23ad9e6b5 262
ark777 0:bca23ad9e6b5 263 void XbeeApi::SetInterrupt(bool val){
ark777 0:bca23ad9e6b5 264 if(val == true){
ark777 0:bca23ad9e6b5 265 Xbee.attach(callback(this, &XbeeApi::OnDataReceived), Serial::RxIrq);
ark777 0:bca23ad9e6b5 266 Xbee.attach(callback(this, &XbeeApi::OnTransmitEnabled), Serial::TxIrq);
ark777 0:bca23ad9e6b5 267 }else{
ark777 0:bca23ad9e6b5 268 }
ark777 0:bca23ad9e6b5 269 }
ark777 0:bca23ad9e6b5 270