XBee wifiにはtelnetで接続すると、
受信パケットをエコーバックします。
シリアルのボーレートは57600bpsまでしかうごきませんでした。
とりあえずのコード
(汚い…、。)
/*
XBee WiFi Connected Serial.
XBee works in API Mode.
Receie Serial and Parse API packet,
then echo back by API packet.
*/
/**
* 送信パケットの生成
*/
int makeXBeeApiSendIp(byte* pPacket, unsigned short u16Size,
byte* pbIpAddrDst, byte* pbPortDst, byte* pbPayload, word length)
{
if(u16Size < length + 16)
{
Serial.println("buffer too short");
return -1;
}
// パケット生成
pPacket[0] = 0x7E;
// length
u16Size = length + 12;
pPacket[1] = u16Size >> 8;
pPacket[2] = u16Size & 0x00FF;
// API Cmd
pPacket[3] = 0x20;
// FrameID
pPacket[4] = 0x00;
// IpAddrDst
pPacket[5] = pbIpAddrDst[0];
pPacket[6] = pbIpAddrDst[1];
pPacket[7] = pbIpAddrDst[2];
pPacket[8] = pbIpAddrDst[3];
// PortDst
pPacket[9] = pbPortDst[0];
pPacket[10] = pbPortDst[1];
// PortSrc
pPacket[11] = 0x26;
pPacket[12] = 0x16;
// Packet Type
pPacket[13] = 0x01; //< TCP, Connection Keep
//
pPacket[14] = 0x00;
// Payload
for(int i=0; i<length; i++)
{
pPacket[15 + i] = pbPayload[i];
}
// チェックサム計算
byte sum = 0;
for(int i=0; i<length + 12; i++)
{
sum += pPacket[3 + i];
}
pPacket[length + 15] = 0xFF - sum;
return length + 16;
}
/**
* 受信パケットのダンプ
*/
void printPayload(byte* pPayload, word length)
{
if(0 < length)
{
Serial.println("dump");
for(word i = 0; i<length; i++)
{
Serial.print(pPayload[i], HEX);
Serial.print(",");
}
Serial.println();
}
}
/**
* 受信パケットのパース
*/
byte g_pbIpAddrSrc[4];
byte g_pbPortSrc[2];
byte* g_pbPayload;
int parseXBeeApiReceiveIp(byte* pPacket, unsigned short u16Size,
byte* pbIpAddrSrc, byte* pbPortSrc, byte** ppbPayload) {
// APIコード確認
if (0xB0 != pPacket[3]) {
// Serial.print("wrong api code:");
// Serial.println(pPacket[3]);
return -1;
}
// 送信元IPアドレス取得
pbIpAddrSrc[0] = pPacket[4];
pbIpAddrSrc[1] = pPacket[5];
pbIpAddrSrc[2] = pPacket[6];
pbIpAddrSrc[3] = pPacket[7];
// Serial.write(pbIpAddrSrc, 4);
// Serial.println();
// 送信元ポート取得
pbPortSrc[0] = pPacket[10];
pbPortSrc[1] = pPacket[11];
// Serial.write(pbPortSrc, 2);
// Serial.println();
// ペイロード取得
*ppbPayload = &pPacket[14];
// Serial.println(pPacket[1]);
// Serial.println(pPacket[2]);
return ((int) pPacket[1] << 8) + (int) pPacket[2] - 11;
}
/**
* 受信処理
*/
#define RECEIVE_IP 1
unsigned char u8ReceiveMode = 0;
#define RECEIVE_MODE_IDLE 0
#define RECEIVE_MODE_LEN1 1
#define RECEIVE_MODE_LEN2 2
#define RECEIVE_MODE_DATA 3
#define RECEIVE_MODE_CS 4
#define APIPACKET_SIZE_MAX 1024
byte g_pu8ApiPacket[APIPACKET_SIZE_MAX];
unsigned short g_u16ApiPacketSize;
unsigned short g_u16ApiPacketLength;
int parseChar(byte data) {
// Serial.println(data, HEX);
switch (u8ReceiveMode) {
case RECEIVE_MODE_IDLE:
// wait for "0x7E"
if (0x7E == data) {
g_u16ApiPacketSize = 0;
g_u16ApiPacketLength = 0;
g_pu8ApiPacket[g_u16ApiPacketSize++] = data;
u8ReceiveMode = RECEIVE_MODE_LEN1;
// Serial.println("api start");
}
break;
case RECEIVE_MODE_LEN1:
g_pu8ApiPacket[g_u16ApiPacketSize++] = data;
u8ReceiveMode = RECEIVE_MODE_LEN2;
break;
case RECEIVE_MODE_LEN2:
g_pu8ApiPacket[g_u16ApiPacketSize++] = data;
u8ReceiveMode = RECEIVE_MODE_DATA;
g_u16ApiPacketLength = ((unsigned short) g_pu8ApiPacket[1] << 8)
+ (unsigned short) g_pu8ApiPacket[2];
// Serial.print("get len :");
// Serial.println(g_u16ApiPacketLength);
if (g_u16ApiPacketLength > (APIPACKET_SIZE_MAX - 4)) {
Serial.println("invalid data len");
u8ReceiveMode = RECEIVE_MODE_IDLE;
}
break;
case RECEIVE_MODE_DATA:
g_pu8ApiPacket[g_u16ApiPacketSize++] = data;
if ((g_u16ApiPacketSize - 3) >= g_u16ApiPacketLength) {
u8ReceiveMode = RECEIVE_MODE_CS;
// Serial.println("get data");
}
break;
case RECEIVE_MODE_CS:
g_pu8ApiPacket[g_u16ApiPacketSize++] = data;
u8ReceiveMode = RECEIVE_MODE_IDLE;
// Serial.println("get cs");
return RECEIVE_IP;
break;
default:
break;
}
return 0;
}
byte RXLED = 13;
byte toggle = 0;
void setup() {
pinMode(RXLED, OUTPUT); // Set RX LED as an output
// TX LED is set as an output behind the scenes
Serial.begin(115200); //This pipes to the serial monitor
Serial1.begin(4800); //This is the UART, pipes to sensors attached to board
}
void loop() {
if (0 < Serial.available()) {
byte data = Serial.read();
Serial1.write(g_pu8ApiPacket, makeXBeeApiSendIp(g_pu8ApiPacket, APIPACKET_SIZE_MAX, g_pbIpAddrSrc, g_pbPortSrc, &data, 1));
if (0 == toggle) {
digitalWrite(RXLED, LOW); // set the LED on
TXLED0; //TX LED is not tied to a normally controlled pin
toggle = 1;
} else {
digitalWrite(RXLED, HIGH); // set the LED off
TXLED1;
toggle = 0;
}
}
if (0 < Serial1.available()) {
// Serial.write(parseChar(Serial1.read()));
if (RECEIVE_IP == parseChar(Serial1.read())) {
int len = parseXBeeApiReceiveIp(g_pu8ApiPacket, g_u16ApiPacketSize,
g_pbIpAddrSrc, g_pbPortSrc, &g_pbPayload);
Serial.print("receive ip packet:");
Serial.println(len);
printPayload(g_pbPayload, len);
// echo
byte data = *g_pbPayload;
Serial1.write(g_pu8ApiPacket, makeXBeeApiSendIp(g_pu8ApiPacket, APIPACKET_SIZE_MAX, g_pbIpAddrSrc, g_pbPortSrc, &data, 1));
}
}
}
0 件のコメント:
コメントを投稿