Library for XBee API targeted toward functions with specific use in conjunction with the Pololu 3pi Robot. Work in Progress
XBee_Robot.cpp@6:fb0316cafaa6, 2016-01-06 (annotated)
- Committer:
- sleighton
- Date:
- Wed Jan 06 17:37:09 2016 +0000
- Revision:
- 6:fb0316cafaa6
- Parent:
- 4:af08c7749f9d
- Child:
- 7:c3acafdb70c0
Log of address now uses 16 bit network address, includes AT request function and constructor now calls AT request to log it's own network address
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sleighton | 2:5040ec01dba1 | 1 | #include "XBee_Robot.h" |
sleighton | 2:5040ec01dba1 | 2 | #include <vector> |
sleighton | 3:cf539cfd3d59 | 3 | #include <algorithm> |
sleighton | 3:cf539cfd3d59 | 4 | #include <list> |
sleighton | 2:5040ec01dba1 | 5 | |
sleighton | 4:af08c7749f9d | 6 | //NETWORK CLASS METHODS |
sleighton | 4:af08c7749f9d | 7 | NetworkNode::NetworkNode(std::vector<uint8_t> & addrIn, int indexIn){ |
sleighton | 4:af08c7749f9d | 8 | addr = addrIn; |
sleighton | 4:af08c7749f9d | 9 | nodeNum = indexIn; |
sleighton | 4:af08c7749f9d | 10 | } |
sleighton | 4:af08c7749f9d | 11 | |
sleighton | 4:af08c7749f9d | 12 | std::vector<uint8_t> NetworkNode::getAddr(){ //returns address of node |
sleighton | 4:af08c7749f9d | 13 | return addr; |
sleighton | 2:5040ec01dba1 | 14 | } |
sleighton | 2:5040ec01dba1 | 15 | |
sleighton | 4:af08c7749f9d | 16 | int NetworkNode::getIndex(){ //returns index of node |
sleighton | 4:af08c7749f9d | 17 | return nodeNum; |
sleighton | 4:af08c7749f9d | 18 | } |
sleighton | 4:af08c7749f9d | 19 | |
sleighton | 4:af08c7749f9d | 20 | void NetworkNode::setIndex(int indexIn){ //sets index of node |
sleighton | 4:af08c7749f9d | 21 | nodeNum = indexIn; |
sleighton | 4:af08c7749f9d | 22 | } |
sleighton | 4:af08c7749f9d | 23 | |
sleighton | 4:af08c7749f9d | 24 | void NetworkNode::setAddr(std::vector<uint8_t> & addrIn){ //sets address of node |
sleighton | 4:af08c7749f9d | 25 | addr = addrIn; |
sleighton | 4:af08c7749f9d | 26 | } |
sleighton | 4:af08c7749f9d | 27 | |
sleighton | 6:fb0316cafaa6 | 28 | /**************************************************************************************************/ |
sleighton | 6:fb0316cafaa6 | 29 | |
sleighton | 4:af08c7749f9d | 30 | //XBEE ROBOT CLASS METHODS |
sleighton | 6:fb0316cafaa6 | 31 | XBee_Robot::XBee_Robot(PinName _txIn, PinName _rxIn): dataLink(_txIn,_rxIn){ |
sleighton | 6:fb0316cafaa6 | 32 | ATQuery(0x4D,0x59); //create AT query with AT command MY to query own 16 bit network address |
sleighton | 6:fb0316cafaa6 | 33 | } |
sleighton | 4:af08c7749f9d | 34 | |
sleighton | 2:5040ec01dba1 | 35 | void XBee_Robot::setRxInterrupt() |
sleighton | 2:5040ec01dba1 | 36 | { |
sleighton | 2:5040ec01dba1 | 37 | dataLink.attach(this,&XBee_Robot::Rx_interrupt, Serial::RxIrq); |
sleighton | 2:5040ec01dba1 | 38 | } |
sleighton | 2:5040ec01dba1 | 39 | |
sleighton | 2:5040ec01dba1 | 40 | void XBee_Robot::Rx_interrupt() |
sleighton | 2:5040ec01dba1 | 41 | { |
sleighton | 3:cf539cfd3d59 | 42 | std::vector<uint8_t> Rx_buffer; |
sleighton | 2:5040ec01dba1 | 43 | while(dataLink.readable()){ |
sleighton | 3:cf539cfd3d59 | 44 | Rx_buffer.push_back(dataLink.getc());//add each incoming byte to buffer |
sleighton | 6:fb0316cafaa6 | 45 | wait(0.00107); //wait for long enough so the next digit is recognised in the same stream (updated from 0.0011 to accomodate for 2 bytes of data) |
sleighton | 2:5040ec01dba1 | 46 | } |
sleighton | 3:cf539cfd3d59 | 47 | |
sleighton | 3:cf539cfd3d59 | 48 | //Check valid packet delimeter and checksum |
sleighton | 3:cf539cfd3d59 | 49 | if((Rx_buffer[0] == 0x7E) && (Rx_buffer[Rx_buffer.size()] == calculateChecksum(Rx_buffer))) |
sleighton | 3:cf539cfd3d59 | 50 | RxPacketControl(Rx_buffer); //call packet control function |
sleighton | 2:5040ec01dba1 | 51 | } |
sleighton | 2:5040ec01dba1 | 52 | |
sleighton | 2:5040ec01dba1 | 53 | void XBee_Robot::transmitRequest(uint8_t *BitAddress64, uint8_t *BitAddress16, uint8_t broadcastRadius, uint8_t options, uint8_t *data,size_t dataLength) |
sleighton | 2:5040ec01dba1 | 54 | { |
sleighton | 2:5040ec01dba1 | 55 | //calculate checksum |
sleighton | 2:5040ec01dba1 | 56 | uint16_t length = 0x0E + dataLength; //calculate length of packet (14 + data length) |
sleighton | 2:5040ec01dba1 | 57 | uint8_t lengthu = length >>8; //upper 8 bits |
sleighton | 2:5040ec01dba1 | 58 | uint8_t lengthl = length & 0xFF; //lower 8 bits |
sleighton | 2:5040ec01dba1 | 59 | |
sleighton | 2:5040ec01dba1 | 60 | |
sleighton | 2:5040ec01dba1 | 61 | std::vector<uint8_t> transmitRequestPacket; //create new vector packet |
sleighton | 2:5040ec01dba1 | 62 | //populate packet |
sleighton | 2:5040ec01dba1 | 63 | transmitRequestPacket.push_back(0x7E); //start delimeter |
sleighton | 2:5040ec01dba1 | 64 | transmitRequestPacket.push_back(lengthu); //upper byte of length |
sleighton | 2:5040ec01dba1 | 65 | transmitRequestPacket.push_back(lengthl); //lower byte of length |
sleighton | 2:5040ec01dba1 | 66 | transmitRequestPacket.push_back(0x10); //API ID (transmit request) |
sleighton | 2:5040ec01dba1 | 67 | transmitRequestPacket.push_back(0x01); //channel ID |
sleighton | 2:5040ec01dba1 | 68 | transmitRequestPacket.insert(transmitRequestPacket.end(), BitAddress64, BitAddress64+8); //64 bit destination address |
sleighton | 2:5040ec01dba1 | 69 | transmitRequestPacket.insert(transmitRequestPacket.end(), BitAddress16, BitAddress16+2); //16 bit network address |
sleighton | 2:5040ec01dba1 | 70 | transmitRequestPacket.push_back(broadcastRadius); //broadcast radius (0 = max hops) |
sleighton | 2:5040ec01dba1 | 71 | transmitRequestPacket.push_back(options); //additional options for packet |
sleighton | 2:5040ec01dba1 | 72 | transmitRequestPacket.insert(transmitRequestPacket.end(), data, data+dataLength); //data |
sleighton | 2:5040ec01dba1 | 73 | uint8_t checksum = calculateChecksum(transmitRequestPacket); |
sleighton | 2:5040ec01dba1 | 74 | transmitRequestPacket.push_back(checksum); //calculate and add checksum |
sleighton | 2:5040ec01dba1 | 75 | |
sleighton | 2:5040ec01dba1 | 76 | for (int i = 0; i < transmitRequestPacket.size(); i++){ |
sleighton | 2:5040ec01dba1 | 77 | dataLink.printf("%c",transmitRequestPacket[i]); //send packet |
sleighton | 2:5040ec01dba1 | 78 | printf("%c",transmitRequestPacket[i]); |
sleighton | 2:5040ec01dba1 | 79 | } |
sleighton | 2:5040ec01dba1 | 80 | } |
sleighton | 2:5040ec01dba1 | 81 | |
sleighton | 6:fb0316cafaa6 | 82 | void XBee_Robot::ATQuery(uint8_t ATu, uint8_t ATl) |
sleighton | 6:fb0316cafaa6 | 83 | { |
sleighton | 6:fb0316cafaa6 | 84 | //calculate checksum |
sleighton | 6:fb0316cafaa6 | 85 | uint8_t lengthu = 0; //upper 8 bits of length |
sleighton | 6:fb0316cafaa6 | 86 | uint8_t lengthl = 0x04; //lower 8 bits of length |
sleighton | 6:fb0316cafaa6 | 87 | |
sleighton | 6:fb0316cafaa6 | 88 | |
sleighton | 6:fb0316cafaa6 | 89 | std::vector<uint8_t> ATRequestPacket; //create new vector packet |
sleighton | 6:fb0316cafaa6 | 90 | //populate packet |
sleighton | 6:fb0316cafaa6 | 91 | ATRequestPacket.push_back(0x7E); //start delimeter |
sleighton | 6:fb0316cafaa6 | 92 | ATRequestPacket.push_back(lengthu); //upper byte of length |
sleighton | 6:fb0316cafaa6 | 93 | ATRequestPacket.push_back(lengthl); //lower byte of length |
sleighton | 6:fb0316cafaa6 | 94 | ATRequestPacket.push_back(0x08); //API ID (AT request) |
sleighton | 6:fb0316cafaa6 | 95 | ATRequestPacket.push_back(0x52); //channel ID |
sleighton | 6:fb0316cafaa6 | 96 | ATRequestPacket.push_back(ATu); //AT command (upper byte) |
sleighton | 6:fb0316cafaa6 | 97 | ATRequestPacket.push_back(ATl); //AT command (lower byte) |
sleighton | 6:fb0316cafaa6 | 98 | uint8_t checksum = calculateChecksum(ATRequestPacket); |
sleighton | 6:fb0316cafaa6 | 99 | ATRequestPacket.push_back(checksum); //calculate and add checksum |
sleighton | 6:fb0316cafaa6 | 100 | |
sleighton | 6:fb0316cafaa6 | 101 | for (int i = 0; i < ATRequestPacket.size(); i++){ |
sleighton | 6:fb0316cafaa6 | 102 | dataLink.printf("%c",ATRequestPacket[i]); //send packet |
sleighton | 6:fb0316cafaa6 | 103 | } |
sleighton | 6:fb0316cafaa6 | 104 | } |
sleighton | 6:fb0316cafaa6 | 105 | |
sleighton | 2:5040ec01dba1 | 106 | uint8_t XBee_Robot::calculateChecksum(std::vector<uint8_t> & packet) |
sleighton | 2:5040ec01dba1 | 107 | { |
sleighton | 2:5040ec01dba1 | 108 | uint8_t checksum = 0xFF; //start with FF as last byte of sum is subtracted from FF |
sleighton | 2:5040ec01dba1 | 109 | for (int i = 3; i < packet.size(); i++) |
sleighton | 2:5040ec01dba1 | 110 | checksum -= packet[i]; |
sleighton | 2:5040ec01dba1 | 111 | return checksum; |
sleighton | 2:5040ec01dba1 | 112 | |
sleighton | 3:cf539cfd3d59 | 113 | } |
sleighton | 3:cf539cfd3d59 | 114 | |
sleighton | 3:cf539cfd3d59 | 115 | void XBee_Robot::RxPacketControl(std::vector<uint8_t> & packet) |
sleighton | 6:fb0316cafaa6 | 116 | { |
sleighton | 3:cf539cfd3d59 | 117 | uint8_t command = packet[3]; //take API address |
sleighton | 3:cf539cfd3d59 | 118 | switch (command) { //index for different commands |
sleighton | 3:cf539cfd3d59 | 119 | case 0x90:{ //Receive packet command |
sleighton | 3:cf539cfd3d59 | 120 | |
sleighton | 6:fb0316cafaa6 | 121 | std::vector<uint8_t> source_addr16; //create new vector to store source address |
sleighton | 6:fb0316cafaa6 | 122 | source_addr16.insert(source_addr16.end(), packet.begin() + 13, packet.begin() + 15); //insert source address part of packet into new vector |
sleighton | 6:fb0316cafaa6 | 123 | checkSourceAddr(source_addr16); |
sleighton | 3:cf539cfd3d59 | 124 | |
sleighton | 3:cf539cfd3d59 | 125 | std::vector<uint8_t> data; //create new vector to store data |
sleighton | 3:cf539cfd3d59 | 126 | data.insert(data.end(), packet.begin() + 15, packet.end() -1); //insert data part of packet into new vector |
sleighton | 3:cf539cfd3d59 | 127 | for(int i = 0; i<data.size();i++){ |
sleighton | 3:cf539cfd3d59 | 128 | printf("Data: %d\n",(int)data[i]); //display data from packet |
sleighton | 3:cf539cfd3d59 | 129 | } |
sleighton | 3:cf539cfd3d59 | 130 | |
sleighton | 3:cf539cfd3d59 | 131 | break; |
sleighton | 3:cf539cfd3d59 | 132 | } |
sleighton | 6:fb0316cafaa6 | 133 | case 0x88:{ //AT response packet command |
sleighton | 6:fb0316cafaa6 | 134 | if(packet[7] == 0x00){ //if packet command status is ok |
sleighton | 6:fb0316cafaa6 | 135 | std::vector<uint8_t> data; //create new vector to store data |
sleighton | 6:fb0316cafaa6 | 136 | data.insert(data.end(), packet.begin() + 8, packet.end() -1); //insert data part of packet into new vector |
sleighton | 6:fb0316cafaa6 | 137 | if((packet[5] == 0x4D) & (packet[6] == 0x59)){ //if AT command is MY |
sleighton | 6:fb0316cafaa6 | 138 | checkSourceAddr(data); |
sleighton | 6:fb0316cafaa6 | 139 | } |
sleighton | 6:fb0316cafaa6 | 140 | } |
sleighton | 6:fb0316cafaa6 | 141 | break; |
sleighton | 6:fb0316cafaa6 | 142 | } |
sleighton | 3:cf539cfd3d59 | 143 | default: |
sleighton | 3:cf539cfd3d59 | 144 | printf("Received API address not recognised: %c",command); |
sleighton | 3:cf539cfd3d59 | 145 | } |
sleighton | 3:cf539cfd3d59 | 146 | } |
sleighton | 3:cf539cfd3d59 | 147 | |
sleighton | 3:cf539cfd3d59 | 148 | void XBee_Robot::checkSourceAddr(std::vector<uint8_t> & addr) |
sleighton | 3:cf539cfd3d59 | 149 | { |
sleighton | 4:af08c7749f9d | 150 | bool exists = false; |
sleighton | 4:af08c7749f9d | 151 | for (int i = 0; i<node_list.size();i++){ //search each entry in node_list for matching address |
sleighton | 4:af08c7749f9d | 152 | if(node_list[i].getAddr() == addr){ |
sleighton | 4:af08c7749f9d | 153 | exists = true; |
sleighton | 4:af08c7749f9d | 154 | printf("Recognised node %d\n",node_list[i].getIndex()); //print node number |
sleighton | 4:af08c7749f9d | 155 | } |
sleighton | 4:af08c7749f9d | 156 | } |
sleighton | 4:af08c7749f9d | 157 | if (exists == false){ //add new address to list if no match found |
sleighton | 4:af08c7749f9d | 158 | NetworkNode newNode(addr,node_list.size());//create new node |
sleighton | 4:af08c7749f9d | 159 | node_list.push_back(newNode); //add new node to list |
sleighton | 6:fb0316cafaa6 | 160 | printf("New address added: Node %d\n",(int)node_list.size()-1); |
sleighton | 3:cf539cfd3d59 | 161 | } |
sleighton | 3:cf539cfd3d59 | 162 | |
sleighton | 4:af08c7749f9d | 163 | } |
sleighton | 4:af08c7749f9d | 164 |