SHARE
TWEET

Untitled

a guest Oct 10th, 2019 57 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Licensed under the GNU General Public License v3.0
  2.  
  3. #define START_DELIMITER       0x7E
  4. #define ESCAPE_FLAG           0x7D
  5. #define XON                   0x11
  6. #define XOFF                  0x13
  7. #define SUCCESS               0x00
  8.  
  9. #define TX_BROADCAST_ADDRESS  0xFFFE
  10. #define TX_MAX_HOPS           0
  11. #define TX_UNICAST            0
  12. #define TX_FRAME_ID           1
  13. #define TX_API_LENGTH         12
  14. #define MAX_FRAME_DATA_SIZE   80
  15.  
  16. // More details of the API Frame Types at end of code
  17. #define FRAME_TYPE_TRANSMIT_REQUEST 0x10
  18. #define FRAME_TYPE_MODEM_STATUS     0x8A
  19. #define FRAME_TYPE_TRANSMIT_STATUS  0x8B
  20. #define FRAME_TYPE_RECEIVE_PACKET   0x90
  21.  
  22. // Xbee 64-bit address to transmit to
  23. uint64_t Tx_address64;
  24. uint8_t Tx_messageLength = 0;
  25. uint8_t Tx_frameLength = 0;
  26.  
  27. // Transmit message buffer
  28. char Tx_FrameData[MAX_FRAME_DATA_SIZE] = {0};
  29.  
  30. // Variables used when receiving a message
  31. bool Rx_fixIfEscapeChar = false;
  32. uint8_t Rx_pos = 0;
  33. uint8_t Rx_nextByte;
  34. uint8_t Rx_checksum = 0;
  35. uint8_t Rx_apiId = 0;
  36. uint8_t Rx_msbLength = 0;
  37. uint8_t Rx_lsbLength = 0;
  38. uint8_t Rx_frameLength = 0;
  39.  
  40. // Receive message buffer
  41. uint8_t Rx_FrameData[MAX_FRAME_DATA_SIZE] = {0};
  42.  
  43. // Timer
  44. unsigned long mytime;
  45.  
  46. char strbuffer[50];
  47.  
  48. void setup() {
  49.  
  50.   // Update the User
  51.   Serial.begin(9600);
  52.  
  53.   // LED light
  54.   pinMode(13, OUTPUT);
  55.  
  56.   // XBee Serial port
  57.   // Note Serial1 hardcoded later in the code
  58.   Serial1.begin(9600);
  59.  
  60. }
  61.  
  62. void loop() {  
  63.  
  64.   // This loop can be left empty if just receiving messages.
  65.  
  66.   // Timer
  67.   mytime = millis();
  68.  
  69.   // XBee destination address
  70.   Tx_address64 = 0x0013a20041894b4a;
  71.  
  72.   // Payload to send. Don't make larger than MAX_FRAME_DATA_SIZE
  73.   sprintf(Tx_FrameData,"%s %lu","Hello World ",mytime);
  74.  
  75.   // Transmit message
  76.   sendXbee();
  77.  
  78.   // Wait a few milliseconds, to stop going wild with transmissions
  79.   delay(1000);
  80. }
  81.  
  82.  
  83. // ===============================================
  84. //
  85. //                   SEND MESSAGE
  86. //
  87. // ===============================================
  88.  
  89. void sendXbee() {
  90.  
  91.   Tx_messageLength = strlenMax();
  92.   Tx_frameLength = TX_API_LENGTH + Tx_messageLength;
  93.  
  94.   Serial.print("TX message length ");
  95.   Serial.println(Tx_frameLength);
  96.  
  97.   // Start delimiter 7E
  98.   sendByte(START_DELIMITER, false);
  99.  
  100.   // Length
  101.   sendByte(((Tx_frameLength + 2) >> 8) & 0xFF, true);
  102.   sendByte((Tx_frameLength + 2) & 0xFF, true);
  103.  
  104.   // Frame type. This is fixed at 0x10 TX Message
  105.   sendByte(FRAME_TYPE_TRANSMIT_REQUEST, true);
  106.  
  107.   // Frame ID
  108.   sendByte(TX_FRAME_ID, true);
  109.  
  110.   // 64-bit destination address
  111.   sendByte((Tx_address64 >> 56) & 0xFF, true);
  112.   sendByte((Tx_address64 >> 48) & 0xFF, true);
  113.   sendByte((Tx_address64 >> 40) & 0xFF, true);
  114.   sendByte((Tx_address64 >> 32) & 0xFF, true);
  115.   sendByte((Tx_address64 >> 24) & 0xFF, true);
  116.   sendByte((Tx_address64 >> 16) & 0xFF, true);
  117.   sendByte((Tx_address64 >> 8) & 0xFF, true);
  118.   sendByte(Tx_address64 & 0xFF, true);
  119.  
  120.   // 16-bit destination address (2 bytes)
  121.   sendByte((TX_BROADCAST_ADDRESS >> 8) & 0xFF, true);
  122.   sendByte(TX_BROADCAST_ADDRESS & 0xFF, true);
  123.  
  124.   // Broadcast radius
  125.   sendByte(TX_MAX_HOPS, true);
  126.  
  127.   // Options
  128.   sendByte(TX_UNICAST, true);
  129.  
  130.   // Calculate the checksum
  131.   uint8_t checksum = FRAME_TYPE_TRANSMIT_REQUEST;
  132.   checksum += TX_FRAME_ID;
  133.   checksum += (Tx_address64 >> 56) & 0xFF;
  134.   checksum += (Tx_address64 >> 48) & 0xFF;
  135.   checksum += (Tx_address64 >> 40) & 0xFF;
  136.   checksum += (Tx_address64 >> 32) & 0xFF;
  137.   checksum += (Tx_address64 >> 24) & 0xFF;
  138.   checksum += (Tx_address64 >> 16) & 0xFF;
  139.   checksum += (Tx_address64 >> 8) & 0xFF;
  140.   checksum += Tx_address64 & 0xFF;
  141.   checksum += (TX_BROADCAST_ADDRESS >> 8) & 0xFF;
  142.   checksum += TX_BROADCAST_ADDRESS & 0xFF;
  143.   checksum += TX_MAX_HOPS;
  144.   checksum += TX_UNICAST;
  145.  
  146.   // Response Frame data
  147.   for (int i = 0; i < Tx_messageLength; i++)
  148.   {
  149.     // Transmit the message data
  150.     sendByte(Tx_FrameData[i], true);
  151.  
  152.     // Update the checksum
  153.     checksum += Tx_FrameData[i];
  154.   }
  155.  
  156.   // Finalise checksum
  157.   checksum = 0xFF - checksum;
  158.  
  159.   // Send end of message
  160.   sendByte(checksum, true);
  161. }
  162.  
  163. uint8_t strlenMax()
  164. {
  165.   uint8_t i=0;
  166.   for (i=0; i<MAX_FRAME_DATA_SIZE; i++)
  167.   {
  168.     if (Tx_FrameData[i] == 0)
  169.     {
  170.       break;
  171.     }
  172.   }
  173.   return i;
  174. }
  175.  
  176. void sendByte(uint8_t thisByte, bool fixIfEscapeChar)
  177. {
  178.   if ((thisByte == START_DELIMITER || thisByte == ESCAPE_FLAG || thisByte == XON || thisByte == XOFF) && fixIfEscapeChar) {
  179.    
  180.     // Flag as a special character is going to follow
  181.     Serial1.write(ESCAPE_FLAG);
  182.     Serial1.write(thisByte ^ 0x20);
  183.     return;
  184.   }
  185.  
  186.   // Just send the byte
  187.   Serial1.write(thisByte);
  188.  
  189. }
  190.  
  191. // ===============================================
  192. //
  193. //               RECEIVE MESSAGE
  194. //
  195. // ===============================================
  196.  
  197. void serialEvent1()
  198. {
  199.   // Loop over the message coming in
  200.   while (Serial1.available())
  201.   {
  202.     // Read the next byte
  203.     Rx_nextByte = Serial1.read();
  204.    
  205.     // Process the received message (so far)
  206.     // Message can arrive over several serialEvents
  207.  
  208.     // Do we have the first 7F start of message flag?
  209.     if (Rx_nextByte == START_DELIMITER)
  210.     {      
  211.       // Reset the input buffer
  212.       resetResponse();      
  213.       Rx_FrameData[Rx_pos] = Rx_nextByte;    
  214.       Rx_pos++;
  215.     }
  216.     else
  217.     {
  218.       // Every other byte of the message we need to check if its an escape character
  219.       if (Rx_nextByte == ESCAPE_FLAG)
  220.       {
  221.         // The next character read needs to be adjusted
  222.         Rx_fixIfEscapeChar = true;
  223.  
  224.         // We now want the read the next byte from the message.
  225.       }
  226.       else
  227.       {
  228.         // So we have the next byte
  229.        
  230.         if (Rx_fixIfEscapeChar == true)
  231.         {
  232.           Rx_nextByte = 0x20 ^ Rx_nextByte;
  233.           Rx_fixIfEscapeChar = false;
  234.         }
  235.  
  236.         // So from here on every byte has been un-escaped. So happy to proceed
  237.         // Store what we see, if we have the space
  238.         if (Rx_pos < MAX_FRAME_DATA_SIZE)
  239.         {
  240.           Rx_FrameData[Rx_pos] = Rx_nextByte;
  241.         }
  242.         else
  243.         {
  244.           Serial.println("Error: Received messsage too large");
  245.           return;
  246.         }
  247.  
  248.         // Process the message so far
  249.         if (Rx_pos == 1)
  250.         {
  251.           // The next two bytes are the length of the payload
  252.           Rx_msbLength = Rx_nextByte;
  253.         }
  254.         else if (Rx_pos == 2)
  255.         {
  256.           // Second byte of the payload length.
  257.           Rx_lsbLength = Rx_nextByte;
  258.  
  259.           // So now we know the length of our message coming in.
  260.           // It is the payload, so we need to add 4 (START_DELIMITER + 2 bytes for the length + checksum)
  261.           Rx_frameLength = ((Rx_msbLength << 8) & 0xFF) + (Rx_lsbLength & 0xFF);
  262.         }
  263.         else if (Rx_pos == 3)
  264.         {
  265.           // Read the API ID response code
  266.           Rx_apiId = Rx_nextByte;
  267.         }
  268.  
  269.         // Update the checksum
  270.         if (Rx_pos >= 3) Rx_checksum += Rx_nextByte;
  271.        
  272.         // Have we reached the end of the message?
  273.         // Fortunately the 2nd and 3rd byte have told us how long the message will be
  274.         if (Rx_pos == Rx_frameLength + 3)
  275.         {
  276.           // Print the received message - the whole frame
  277.           for (int i=0; i <= Rx_pos; i++){
  278.             sprintf(strbuffer,"%02X ", Rx_FrameData[i] & 0xFF);Serial.print(strbuffer);
  279.           }
  280.      
  281.           // Check the checksum
  282.           if ((Rx_checksum & 0xFF) == 0xFF)
  283.           {
  284.             Serial.println(" SUCCESS");
  285.             Rx_checksum = Rx_nextByte;
  286.  
  287.             // Process the memory
  288.             ProcessMessage();
  289.           }
  290.           else
  291.           {
  292.             Serial.println(" FAILED");
  293.           }
  294.         }
  295.  
  296.         // Increase the position counter
  297.         Rx_pos++;        
  298.       }
  299.     }    
  300.   }
  301. }
  302.  
  303. void ProcessMessage(){
  304.  
  305.   // Check for the correct TX response            
  306.   if (Rx_apiId == FRAME_TYPE_TRANSMIT_STATUS)
  307.   {
  308.     Serial.print("FRAME_TYPE_TRANSMIT_STATUS");
  309.     // Read the response. Did it succeed?
  310.     if (Rx_FrameData[8] == SUCCESS) {
  311.       Serial.print("\tSUCCESS");
  312.     } else{
  313.       Serial.print("\tFAILED");
  314.     }
  315.     Serial.println("");
  316.   }
  317.   else if (Rx_apiId == FRAME_TYPE_RECEIVE_PACKET)
  318.   {
  319.     // Some XBee has sent us a message
  320.     Serial.print("FRAME_TYPE_RECEIVE_PACKET");
  321.     Serial.print("\tFrom XBee ");
  322.     for (int i=4; i < 12; i++){
  323.       sprintf(strbuffer,"%02X ", Rx_FrameData[i] & 0xFF);Serial.print(strbuffer);
  324.     }
  325.     Serial.print("\t[");
  326.     for (int i=15; i < Rx_frameLength+3; i++){
  327.       sprintf(strbuffer,"%c", Rx_FrameData[i] & 0xFF);Serial.print(strbuffer);
  328.     }
  329.     Serial.println("]");
  330.   }
  331.   else if (Rx_apiId == FRAME_TYPE_MODEM_STATUS)
  332.   {
  333.     Serial.print("ERROR: Check the power supply to the XBee. Perhaps provide it with its own power supply?");
  334.   }
  335. }
  336.  
  337. void resetResponse() {
  338.  
  339.   // Reset the response variables
  340.   Rx_fixIfEscapeChar = false;
  341.   Rx_pos = 0;
  342.   Rx_apiId = 0;
  343.   Rx_msbLength = 0;
  344.   Rx_lsbLength = 0;
  345.   Rx_frameLength = 0;
  346.   Rx_checksum = 0;
  347. }
  348.  
  349.  
  350. //
  351. // API 2 Frame Types
  352. //
  353. // 0x00 - Tx (Transmit) Request: 64-bit address
  354. // 0x01 - Tx (transmit) Request: 16-bit address
  355. // 0x07 - Remote AT Command (Wi-Fi)
  356. // 0x08 - AT Command
  357. // 0x09 - AT Command Queue Register Value
  358. // 0x10 - Transmit Request <----------------------- Used (send out message)
  359. // 0x11 - Explicit Addressing Command Frame
  360. // 0x16 - Metaframe Tx
  361. // 0x17 - Remote AT Command
  362. // 0x1F - TX SMS
  363. // 0x20 - TX IPv4
  364. // 0x21 - Create Source Route
  365. // 0x24 - Register Joining Device
  366. // 0x28 - Send Data Request
  367. // 0x2A - Device Response
  368. // 0x80 - RX (Receive) Packet: 64-bit Address
  369. // 0x81 - RX (Receive) Packet: 16-bit Address
  370. // 0x82 - RX (Receive) Packet: 64-bit Address IO
  371. // 0x83 - RX (Receive) Packet: 16-bit Address IO
  372. // 0x87 - Remote AT Command Response (Wi-Fi)
  373. // 0x88 - AT Command Response
  374. // 0x89 - Tx (Transmit) Status
  375. // 0x8A - Modem Status
  376. // 0x8B - Transmit Status <------------------------ Used (was sent message successful?)
  377. // 0x8D - Route Information Packet
  378. // 0x8E - Aggregate Addressing Update
  379. // 0x8f - IO Data Sample RX Indicator
  380. // 0x90 - Receive Packet <------------------------- Used (received message)
  381. // 0x91 - Explicit RX Indicator
  382. // 0x92 - IO Data Sample Rx Indicator
  383. // 0x94 - XBee Sensor Read Indicator
  384. // 0x95 - Node Identification Indicator
  385. // 0x97 - Remote AT Command Response
  386. // 0x98 - Extended Modem Status
  387. // 0x9F - RX SMS
  388. // 0xA0 - Over-the-Air Firmware Update Status
  389. // 0xA1 - Route Record Indicator
  390. // 0xA2 - Device Authenticated Indicator
  391. // 0xA3 - Many-to-One Route Request Indicator
  392. // 0xA4 - Register Joining Device Status
  393. // 0xA5 - Join Notification Status
  394. // 0xA6 - Metaframe FX
  395. // 0xB0 - RX IPv4
  396. // 0xB8 - Send Data Response
  397. // 0xB9 - Device Request
  398. // 0xBA - Device Response Status
  399. // 0xFE - Frame Error
  400. // 0xFF - Generic
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top