Advertisement
Guest User

Untitled

a guest
Oct 10th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.46 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement