Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Licensed under the GNU General Public License v3.0
- #define START_DELIMITER 0x7E
- #define ESCAPE_FLAG 0x7D
- #define XON 0x11
- #define XOFF 0x13
- #define SUCCESS 0x00
- #define TX_BROADCAST_ADDRESS 0xFFFE
- #define TX_MAX_HOPS 0
- #define TX_UNICAST 0
- #define TX_FRAME_ID 1
- #define TX_API_LENGTH 12
- #define MAX_FRAME_DATA_SIZE 80
- // More details of the API Frame Types at end of code
- #define FRAME_TYPE_TRANSMIT_REQUEST 0x10
- #define FRAME_TYPE_MODEM_STATUS 0x8A
- #define FRAME_TYPE_TRANSMIT_STATUS 0x8B
- #define FRAME_TYPE_RECEIVE_PACKET 0x90
- // Xbee 64-bit address to transmit to
- uint64_t Tx_address64;
- uint8_t Tx_messageLength = 0;
- uint8_t Tx_frameLength = 0;
- // Transmit message buffer
- char Tx_FrameData[MAX_FRAME_DATA_SIZE] = {0};
- // Variables used when receiving a message
- bool Rx_fixIfEscapeChar = false;
- uint8_t Rx_pos = 0;
- uint8_t Rx_nextByte;
- uint8_t Rx_checksum = 0;
- uint8_t Rx_apiId = 0;
- uint8_t Rx_msbLength = 0;
- uint8_t Rx_lsbLength = 0;
- uint8_t Rx_frameLength = 0;
- // Receive message buffer
- uint8_t Rx_FrameData[MAX_FRAME_DATA_SIZE] = {0};
- // Timer
- unsigned long mytime;
- char strbuffer[50];
- void setup() {
- // Update the User
- Serial.begin(9600);
- // LED light
- pinMode(13, OUTPUT);
- // XBee Serial port
- // Note Serial1 hardcoded later in the code
- Serial1.begin(9600);
- }
- void loop() {
- // This loop can be left empty if just receiving messages.
- // Timer
- mytime = millis();
- // XBee destination address
- Tx_address64 = 0x0013a20041894b4a;
- // Payload to send. Don't make larger than MAX_FRAME_DATA_SIZE
- sprintf(Tx_FrameData,"%s %lu","Hello World ",mytime);
- // Transmit message
- sendXbee();
- // Wait a few milliseconds, to stop going wild with transmissions
- delay(1000);
- }
- // ===============================================
- //
- // SEND MESSAGE
- //
- // ===============================================
- void sendXbee() {
- Tx_messageLength = strlenMax();
- Tx_frameLength = TX_API_LENGTH + Tx_messageLength;
- Serial.print("TX message length ");
- Serial.println(Tx_frameLength);
- // Start delimiter 7E
- sendByte(START_DELIMITER, false);
- // Length
- sendByte(((Tx_frameLength + 2) >> 8) & 0xFF, true);
- sendByte((Tx_frameLength + 2) & 0xFF, true);
- // Frame type. This is fixed at 0x10 TX Message
- sendByte(FRAME_TYPE_TRANSMIT_REQUEST, true);
- // Frame ID
- sendByte(TX_FRAME_ID, true);
- // 64-bit destination address
- sendByte((Tx_address64 >> 56) & 0xFF, true);
- sendByte((Tx_address64 >> 48) & 0xFF, true);
- sendByte((Tx_address64 >> 40) & 0xFF, true);
- sendByte((Tx_address64 >> 32) & 0xFF, true);
- sendByte((Tx_address64 >> 24) & 0xFF, true);
- sendByte((Tx_address64 >> 16) & 0xFF, true);
- sendByte((Tx_address64 >> 8) & 0xFF, true);
- sendByte(Tx_address64 & 0xFF, true);
- // 16-bit destination address (2 bytes)
- sendByte((TX_BROADCAST_ADDRESS >> 8) & 0xFF, true);
- sendByte(TX_BROADCAST_ADDRESS & 0xFF, true);
- // Broadcast radius
- sendByte(TX_MAX_HOPS, true);
- // Options
- sendByte(TX_UNICAST, true);
- // Calculate the checksum
- uint8_t checksum = FRAME_TYPE_TRANSMIT_REQUEST;
- checksum += TX_FRAME_ID;
- checksum += (Tx_address64 >> 56) & 0xFF;
- checksum += (Tx_address64 >> 48) & 0xFF;
- checksum += (Tx_address64 >> 40) & 0xFF;
- checksum += (Tx_address64 >> 32) & 0xFF;
- checksum += (Tx_address64 >> 24) & 0xFF;
- checksum += (Tx_address64 >> 16) & 0xFF;
- checksum += (Tx_address64 >> 8) & 0xFF;
- checksum += Tx_address64 & 0xFF;
- checksum += (TX_BROADCAST_ADDRESS >> 8) & 0xFF;
- checksum += TX_BROADCAST_ADDRESS & 0xFF;
- checksum += TX_MAX_HOPS;
- checksum += TX_UNICAST;
- // Response Frame data
- for (int i = 0; i < Tx_messageLength; i++)
- {
- // Transmit the message data
- sendByte(Tx_FrameData[i], true);
- // Update the checksum
- checksum += Tx_FrameData[i];
- }
- // Finalise checksum
- checksum = 0xFF - checksum;
- // Send end of message
- sendByte(checksum, true);
- }
- uint8_t strlenMax()
- {
- uint8_t i=0;
- for (i=0; i<MAX_FRAME_DATA_SIZE; i++)
- {
- if (Tx_FrameData[i] == 0)
- {
- break;
- }
- }
- return i;
- }
- void sendByte(uint8_t thisByte, bool fixIfEscapeChar)
- {
- if ((thisByte == START_DELIMITER || thisByte == ESCAPE_FLAG || thisByte == XON || thisByte == XOFF) && fixIfEscapeChar) {
- // Flag as a special character is going to follow
- Serial1.write(ESCAPE_FLAG);
- Serial1.write(thisByte ^ 0x20);
- return;
- }
- // Just send the byte
- Serial1.write(thisByte);
- }
- // ===============================================
- //
- // RECEIVE MESSAGE
- //
- // ===============================================
- void serialEvent1()
- {
- // Loop over the message coming in
- while (Serial1.available())
- {
- // Read the next byte
- Rx_nextByte = Serial1.read();
- // Process the received message (so far)
- // Message can arrive over several serialEvents
- // Do we have the first 7F start of message flag?
- if (Rx_nextByte == START_DELIMITER)
- {
- // Reset the input buffer
- resetResponse();
- Rx_FrameData[Rx_pos] = Rx_nextByte;
- Rx_pos++;
- }
- else
- {
- // Every other byte of the message we need to check if its an escape character
- if (Rx_nextByte == ESCAPE_FLAG)
- {
- // The next character read needs to be adjusted
- Rx_fixIfEscapeChar = true;
- // We now want the read the next byte from the message.
- }
- else
- {
- // So we have the next byte
- if (Rx_fixIfEscapeChar == true)
- {
- Rx_nextByte = 0x20 ^ Rx_nextByte;
- Rx_fixIfEscapeChar = false;
- }
- // So from here on every byte has been un-escaped. So happy to proceed
- // Store what we see, if we have the space
- if (Rx_pos < MAX_FRAME_DATA_SIZE)
- {
- Rx_FrameData[Rx_pos] = Rx_nextByte;
- }
- else
- {
- Serial.println("Error: Received messsage too large");
- return;
- }
- // Process the message so far
- if (Rx_pos == 1)
- {
- // The next two bytes are the length of the payload
- Rx_msbLength = Rx_nextByte;
- }
- else if (Rx_pos == 2)
- {
- // Second byte of the payload length.
- Rx_lsbLength = Rx_nextByte;
- // So now we know the length of our message coming in.
- // It is the payload, so we need to add 4 (START_DELIMITER + 2 bytes for the length + checksum)
- Rx_frameLength = ((Rx_msbLength << 8) & 0xFF) + (Rx_lsbLength & 0xFF);
- }
- else if (Rx_pos == 3)
- {
- // Read the API ID response code
- Rx_apiId = Rx_nextByte;
- }
- // Update the checksum
- if (Rx_pos >= 3) Rx_checksum += Rx_nextByte;
- // Have we reached the end of the message?
- // Fortunately the 2nd and 3rd byte have told us how long the message will be
- if (Rx_pos == Rx_frameLength + 3)
- {
- // Print the received message - the whole frame
- for (int i=0; i <= Rx_pos; i++){
- sprintf(strbuffer,"%02X ", Rx_FrameData[i] & 0xFF);Serial.print(strbuffer);
- }
- // Check the checksum
- if ((Rx_checksum & 0xFF) == 0xFF)
- {
- Serial.println(" SUCCESS");
- Rx_checksum = Rx_nextByte;
- // Process the memory
- ProcessMessage();
- }
- else
- {
- Serial.println(" FAILED");
- }
- }
- // Increase the position counter
- Rx_pos++;
- }
- }
- }
- }
- void ProcessMessage(){
- // Check for the correct TX response
- if (Rx_apiId == FRAME_TYPE_TRANSMIT_STATUS)
- {
- Serial.print("FRAME_TYPE_TRANSMIT_STATUS");
- // Read the response. Did it succeed?
- if (Rx_FrameData[8] == SUCCESS) {
- Serial.print("\tSUCCESS");
- } else{
- Serial.print("\tFAILED");
- }
- Serial.println("");
- }
- else if (Rx_apiId == FRAME_TYPE_RECEIVE_PACKET)
- {
- // Some XBee has sent us a message
- Serial.print("FRAME_TYPE_RECEIVE_PACKET");
- Serial.print("\tFrom XBee ");
- for (int i=4; i < 12; i++){
- sprintf(strbuffer,"%02X ", Rx_FrameData[i] & 0xFF);Serial.print(strbuffer);
- }
- Serial.print("\t[");
- for (int i=15; i < Rx_frameLength+3; i++){
- sprintf(strbuffer,"%c", Rx_FrameData[i] & 0xFF);Serial.print(strbuffer);
- }
- Serial.println("]");
- }
- else if (Rx_apiId == FRAME_TYPE_MODEM_STATUS)
- {
- Serial.print("ERROR: Check the power supply to the XBee. Perhaps provide it with its own power supply?");
- }
- }
- void resetResponse() {
- // Reset the response variables
- Rx_fixIfEscapeChar = false;
- Rx_pos = 0;
- Rx_apiId = 0;
- Rx_msbLength = 0;
- Rx_lsbLength = 0;
- Rx_frameLength = 0;
- Rx_checksum = 0;
- }
- //
- // API 2 Frame Types
- //
- // 0x00 - Tx (Transmit) Request: 64-bit address
- // 0x01 - Tx (transmit) Request: 16-bit address
- // 0x07 - Remote AT Command (Wi-Fi)
- // 0x08 - AT Command
- // 0x09 - AT Command Queue Register Value
- // 0x10 - Transmit Request <----------------------- Used (send out message)
- // 0x11 - Explicit Addressing Command Frame
- // 0x16 - Metaframe Tx
- // 0x17 - Remote AT Command
- // 0x1F - TX SMS
- // 0x20 - TX IPv4
- // 0x21 - Create Source Route
- // 0x24 - Register Joining Device
- // 0x28 - Send Data Request
- // 0x2A - Device Response
- // 0x80 - RX (Receive) Packet: 64-bit Address
- // 0x81 - RX (Receive) Packet: 16-bit Address
- // 0x82 - RX (Receive) Packet: 64-bit Address IO
- // 0x83 - RX (Receive) Packet: 16-bit Address IO
- // 0x87 - Remote AT Command Response (Wi-Fi)
- // 0x88 - AT Command Response
- // 0x89 - Tx (Transmit) Status
- // 0x8A - Modem Status
- // 0x8B - Transmit Status <------------------------ Used (was sent message successful?)
- // 0x8D - Route Information Packet
- // 0x8E - Aggregate Addressing Update
- // 0x8f - IO Data Sample RX Indicator
- // 0x90 - Receive Packet <------------------------- Used (received message)
- // 0x91 - Explicit RX Indicator
- // 0x92 - IO Data Sample Rx Indicator
- // 0x94 - XBee Sensor Read Indicator
- // 0x95 - Node Identification Indicator
- // 0x97 - Remote AT Command Response
- // 0x98 - Extended Modem Status
- // 0x9F - RX SMS
- // 0xA0 - Over-the-Air Firmware Update Status
- // 0xA1 - Route Record Indicator
- // 0xA2 - Device Authenticated Indicator
- // 0xA3 - Many-to-One Route Request Indicator
- // 0xA4 - Register Joining Device Status
- // 0xA5 - Join Notification Status
- // 0xA6 - Metaframe FX
- // 0xB0 - RX IPv4
- // 0xB8 - Send Data Response
- // 0xB9 - Device Request
- // 0xBA - Device Response Status
- // 0xFE - Frame Error
- // 0xFF - Generic
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement