xbee communication for UWB quadcopter project
com.cpp@11:d1f488302d06, 2014-04-25 (annotated)
- Committer:
- oprospero
- Date:
- Fri Apr 25 06:21:19 2014 +0000
- Revision:
- 11:d1f488302d06
- Parent:
- 10:ec36e1b59a39
small updates;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
oprospero | 0:26a151d2c6db | 1 | /****************************** com.cpp **********************************/ |
oprospero | 0:26a151d2c6db | 2 | /* Version: 1.0 */ |
oprospero | 0:26a151d2c6db | 3 | /* Last Updated: June 1, 2013 */ |
oprospero | 0:26a151d2c6db | 4 | /* */ |
oprospero | 0:26a151d2c6db | 5 | /* The com class implements reliable data transfer between two nodes */ |
oprospero | 0:26a151d2c6db | 6 | /*using a checksum and a sequence number for guaranteed message delivery */ |
oprospero | 0:26a151d2c6db | 7 | /*over an xbee modem connected to the passed in tx and rx pins. Messages */ |
oprospero | 0:26a151d2c6db | 8 | /*are received and placed in the rxBuffer to be read when convenient. */ |
oprospero | 0:26a151d2c6db | 9 | /*Messages are encoded by sending a byte with the value of the command */ |
oprospero | 0:26a151d2c6db | 10 | /*then and int of the command. */ |
oprospero | 0:26a151d2c6db | 11 | /* */ |
oprospero | 0:26a151d2c6db | 12 | /* Commands: 0 -> Ack, does not get placed in rxQueue. */ |
oprospero | 0:26a151d2c6db | 13 | /* 1 -> Throttle */ |
oprospero | 0:26a151d2c6db | 14 | /* 2 -> Pitch */ |
oprospero | 0:26a151d2c6db | 15 | /* 3 -> Roll */ |
oprospero | 0:26a151d2c6db | 16 | /* 4 -> Yaw */ |
oprospero | 0:26a151d2c6db | 17 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 18 | |
oprospero | 0:26a151d2c6db | 19 | #include "mbed.h" |
oprospero | 0:26a151d2c6db | 20 | #include "com.h" |
oprospero | 0:26a151d2c6db | 21 | |
oprospero | 1:4f53de75bc96 | 22 | |
oprospero | 0:26a151d2c6db | 23 | /*********************** com( PinName, PinName ) *************************/ |
oprospero | 0:26a151d2c6db | 24 | /* */ |
oprospero | 0:26a151d2c6db | 25 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 26 | |
oprospero | 2:bd1621102cad | 27 | com::com( PinName tx, PinName rx , PinName rssipin) : xbeeTx( tx, NC), xbeeRx( NC, rx), rssi(rssipin) |
oprospero | 0:26a151d2c6db | 28 | { |
oprospero | 0:26a151d2c6db | 29 | bLength = 0; // How many bytes are in the buffer. |
oprospero | 2:bd1621102cad | 30 | api_mode = false; // Xbee is in transparent mode. |
oprospero | 1:4f53de75bc96 | 31 | xbeeTx.baud(BAUDRATE); // Setup the serial baud rate. |
oprospero | 0:26a151d2c6db | 32 | xbeeRx.baud(BAUDRATE); // Setup the serial baud rate. |
oprospero | 0:26a151d2c6db | 33 | rxBuffer = new queue(); // Point to the rxQueue. |
oprospero | 4:7cdf299ea7a4 | 34 | txBuffer = new queue(); |
oprospero | 0:26a151d2c6db | 35 | signalStrength = 0; |
oprospero | 0:26a151d2c6db | 36 | xbeeRx.attach( this, &com::callback ); // Set callback as the interrupt handler. |
oprospero | 1:4f53de75bc96 | 37 | #ifdef DEBUG |
oprospero | 0:26a151d2c6db | 38 | xbeeTx.printf("Communication.....Done\n\r"); |
oprospero | 1:4f53de75bc96 | 39 | #endif |
oprospero | 0:26a151d2c6db | 40 | } |
oprospero | 0:26a151d2c6db | 41 | |
oprospero | 0:26a151d2c6db | 42 | /************************* bool isData() ********************************/ |
oprospero | 0:26a151d2c6db | 43 | /* */ |
oprospero | 0:26a151d2c6db | 44 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 45 | |
oprospero | 0:26a151d2c6db | 46 | bool com::isData() |
oprospero | 0:26a151d2c6db | 47 | { |
oprospero | 2:bd1621102cad | 48 | |
oprospero | 1:4f53de75bc96 | 49 | return !rxBuffer->isEmpty(); |
oprospero | 0:26a151d2c6db | 50 | } |
oprospero | 0:26a151d2c6db | 51 | |
oprospero | 0:26a151d2c6db | 52 | /************************ void write( char ) *****************************/ |
oprospero | 0:26a151d2c6db | 53 | /* Write a packet out the xbee com port. */ |
oprospero | 0:26a151d2c6db | 54 | /* */ |
oprospero | 0:26a151d2c6db | 55 | /* Data format byte[] */ |
oprospero | 0:26a151d2c6db | 56 | /* byte[0] = command. */ |
oprospero | 0:26a151d2c6db | 57 | /* byte[1] = upper 8 bits of value. */ |
oprospero | 0:26a151d2c6db | 58 | /* byte[2] = lower 8 bits of value. */ |
oprospero | 0:26a151d2c6db | 59 | /* byte[3] = Checksum byte[0] + byte[2]. */ |
oprospero | 0:26a151d2c6db | 60 | /* byte[4] = Sequence Number. */ |
oprospero | 0:26a151d2c6db | 61 | /* byte[5] = 255 End of message. */ |
oprospero | 0:26a151d2c6db | 62 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 63 | |
oprospero | 0:26a151d2c6db | 64 | void com::write( short command, short value ) |
oprospero | 0:26a151d2c6db | 65 | { |
oprospero | 2:bd1621102cad | 66 | if (api_mode) |
oprospero | 2:bd1621102cad | 67 | { |
oprospero | 2:bd1621102cad | 68 | short hvalue = value / 128; |
oprospero | 2:bd1621102cad | 69 | short lvalue = (value % 128); |
oprospero | 2:bd1621102cad | 70 | short sum = (2*command + hvalue + 2*lvalue + value); |
oprospero | 2:bd1621102cad | 71 | short check = sum % 256; |
oprospero | 2:bd1621102cad | 72 | xbeeTx.putc( (char) 127); //Start Delimiter |
oprospero | 2:bd1621102cad | 73 | |
oprospero | 2:bd1621102cad | 74 | xbeeTx.putc( (char) 0); //Frame Data Length MSB |
oprospero | 2:bd1621102cad | 75 | xbeeTx.putc( (char) 6); //Frame Data Length LSB |
oprospero | 2:bd1621102cad | 76 | //Frame Data |
oprospero | 2:bd1621102cad | 77 | xbeeTx.putc( (char) command); // Command |
oprospero | 2:bd1621102cad | 78 | xbeeTx.putc( (char) hvalue); // First 8 bits in array. |
oprospero | 2:bd1621102cad | 79 | xbeeTx.putc( (char) lvalue); // Second 8 bits in array. |
oprospero | 2:bd1621102cad | 80 | xbeeTx.putc( command + lvalue ); // Checksum array[0] + array[1]. |
oprospero | 2:bd1621102cad | 81 | xbeeTx.putc( (char) value); // Sequence number. |
oprospero | 2:bd1621102cad | 82 | xbeeTx.putc( 255 ); // End of message. |
oprospero | 2:bd1621102cad | 83 | |
oprospero | 2:bd1621102cad | 84 | xbeeTx.putc( (char) 255 - check); //Checksum |
oprospero | 2:bd1621102cad | 85 | |
oprospero | 2:bd1621102cad | 86 | } |
oprospero | 2:bd1621102cad | 87 | else |
oprospero | 2:bd1621102cad | 88 | { |
oprospero | 2:bd1621102cad | 89 | short lvalue = (value % 128); |
oprospero | 2:bd1621102cad | 90 | xbeeTx.putc( (char)command ); // Command |
oprospero | 2:bd1621102cad | 91 | xbeeTx.putc( (char) value / 128 ); // First 8 bits in array. |
oprospero | 2:bd1621102cad | 92 | xbeeTx.putc( (char) lvalue); // Second 8 bits in array. |
oprospero | 2:bd1621102cad | 93 | xbeeTx.putc( command + lvalue ); // Checksum array[0] + array[1]. |
oprospero | 2:bd1621102cad | 94 | xbeeTx.putc( (char)value ); // Sequence number. |
oprospero | 2:bd1621102cad | 95 | xbeeTx.putc( 255 ); // End of message. |
oprospero | 2:bd1621102cad | 96 | } |
oprospero | 0:26a151d2c6db | 97 | } |
oprospero | 0:26a151d2c6db | 98 | |
oprospero | 4:7cdf299ea7a4 | 99 | /*************************** char ackCheck() ********************************/ |
oprospero | 0:26a151d2c6db | 100 | /* */ |
oprospero | 0:26a151d2c6db | 101 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 102 | |
oprospero | 3:f8e953201251 | 103 | void com::ackCheck() |
oprospero | 3:f8e953201251 | 104 | { |
oprospero | 4:7cdf299ea7a4 | 105 | if( !txBuffer->isEmpty() && xbeeTx.writeable()) |
oprospero | 3:f8e953201251 | 106 | { |
oprospero | 11:d1f488302d06 | 107 | __disable_irq(); |
oprospero | 4:7cdf299ea7a4 | 108 | short * pkt = txBuffer->pop(); |
oprospero | 4:7cdf299ea7a4 | 109 | write(pkt[0],pkt[1]); //may need to disable interrupt |
oprospero | 4:7cdf299ea7a4 | 110 | delete[] pkt; |
oprospero | 11:d1f488302d06 | 111 | __enable_irq(); |
oprospero | 3:f8e953201251 | 112 | } |
oprospero | 3:f8e953201251 | 113 | } |
oprospero | 3:f8e953201251 | 114 | |
oprospero | 4:7cdf299ea7a4 | 115 | bool com::rdy2ack() |
oprospero | 4:7cdf299ea7a4 | 116 | { |
oprospero | 4:7cdf299ea7a4 | 117 | return !txBuffer->isEmpty(); |
oprospero | 4:7cdf299ea7a4 | 118 | } |
oprospero | 3:f8e953201251 | 119 | |
oprospero | 3:f8e953201251 | 120 | /*************************** char read() ********************************/ |
oprospero | 3:f8e953201251 | 121 | /* */ |
oprospero | 3:f8e953201251 | 122 | /*************************************************************************/ |
oprospero | 3:f8e953201251 | 123 | |
oprospero | 0:26a151d2c6db | 124 | short * com::read() |
oprospero | 0:26a151d2c6db | 125 | { |
oprospero | 0:26a151d2c6db | 126 | if( !rxBuffer->isEmpty()) |
oprospero | 0:26a151d2c6db | 127 | return rxBuffer->pop(); |
oprospero | 0:26a151d2c6db | 128 | |
oprospero | 0:26a151d2c6db | 129 | return NULL; |
oprospero | 0:26a151d2c6db | 130 | } |
oprospero | 0:26a151d2c6db | 131 | |
oprospero | 0:26a151d2c6db | 132 | /************************ void callback() ********************************/ |
oprospero | 0:26a151d2c6db | 133 | /* */ |
oprospero | 0:26a151d2c6db | 134 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 135 | |
oprospero | 0:26a151d2c6db | 136 | void com::callback() |
oprospero | 0:26a151d2c6db | 137 | { |
oprospero | 3:f8e953201251 | 138 | __disable_irq(); |
oprospero | 0:26a151d2c6db | 139 | while( xbeeRx.readable() ) |
oprospero | 0:26a151d2c6db | 140 | { |
oprospero | 0:26a151d2c6db | 141 | char data = xbeeRx.getc(); |
oprospero | 0:26a151d2c6db | 142 | // xbeeTx.printf("data: %d\n\r", data); |
oprospero | 2:bd1621102cad | 143 | // xbeeTx.printf("%d %d", data,(char) 255); |
oprospero | 2:bd1621102cad | 144 | // xbeeTx.putc( data ); |
oprospero | 0:26a151d2c6db | 145 | if( bLength++ < BUFFERSIZE ) |
oprospero | 0:26a151d2c6db | 146 | buffer[bLength] = data; |
oprospero | 3:f8e953201251 | 147 | // |
oprospero | 3:f8e953201251 | 148 | // xbeeTx.putc( bLength ); |
oprospero | 3:f8e953201251 | 149 | // xbeeTx.putc( bLength ); |
oprospero | 3:f8e953201251 | 150 | // xbeeTx.putc( 255 ); |
oprospero | 10:ec36e1b59a39 | 151 | //2nd condition ensure that we have a full size packet before building |
oprospero | 10:ec36e1b59a39 | 152 | if( data == 255 && bLength > 5) |
oprospero | 0:26a151d2c6db | 153 | packetBuilder(); |
oprospero | 0:26a151d2c6db | 154 | } |
oprospero | 3:f8e953201251 | 155 | __enable_irq(); |
oprospero | 0:26a151d2c6db | 156 | } |
oprospero | 0:26a151d2c6db | 157 | |
oprospero | 2:bd1621102cad | 158 | //void com::api_callback() |
oprospero | 2:bd1621102cad | 159 | //{ |
oprospero | 2:bd1621102cad | 160 | // while( xbeeRx.readable() ) |
oprospero | 2:bd1621102cad | 161 | // { |
oprospero | 2:bd1621102cad | 162 | // buffer[bLength++] = xbeeRx.getc(); |
oprospero | 2:bd1621102cad | 163 | // } |
oprospero | 2:bd1621102cad | 164 | //} |
oprospero | 2:bd1621102cad | 165 | |
oprospero | 2:bd1621102cad | 166 | |
oprospero | 0:26a151d2c6db | 167 | /********************** void packetBuilder() *****************************/ |
oprospero | 0:26a151d2c6db | 168 | /* Creates a packet from the buffered data and places it in the rxBuffer */ |
oprospero | 0:26a151d2c6db | 169 | /* queue to be read whenever convenient. Max value of +/- 8063. */ |
oprospero | 0:26a151d2c6db | 170 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 171 | |
oprospero | 0:26a151d2c6db | 172 | void com::packetBuilder() |
oprospero | 0:26a151d2c6db | 173 | { |
oprospero | 0:26a151d2c6db | 174 | char * commandData = new char[bLength]; |
oprospero | 0:26a151d2c6db | 175 | commandData[4] = buffer[--bLength]; // Sequence Number. |
oprospero | 0:26a151d2c6db | 176 | commandData[3] = buffer[--bLength]; // CheckSum value. |
oprospero | 0:26a151d2c6db | 177 | commandData[2] = buffer[--bLength]; // Second 7 bits. |
oprospero | 0:26a151d2c6db | 178 | commandData[1] = buffer[--bLength]; // Fisrt 7 bits. |
oprospero | 0:26a151d2c6db | 179 | commandData[0] = buffer[--bLength]; // Command. |
oprospero | 0:26a151d2c6db | 180 | |
oprospero | 0:26a151d2c6db | 181 | |
oprospero | 0:26a151d2c6db | 182 | if( commandData[0] + commandData[2] == commandData[3] ) // Validate checksum. |
oprospero | 0:26a151d2c6db | 183 | { |
oprospero | 0:26a151d2c6db | 184 | short * array = new short[2]; |
oprospero | 0:26a151d2c6db | 185 | |
oprospero | 0:26a151d2c6db | 186 | array[0] = (short)commandData[0]; |
oprospero | 0:26a151d2c6db | 187 | |
oprospero | 0:26a151d2c6db | 188 | short value = (short)(commandData[1] * 128 + commandData[2]); |
oprospero | 0:26a151d2c6db | 189 | |
oprospero | 0:26a151d2c6db | 190 | if( value > 8062 ) |
oprospero | 0:26a151d2c6db | 191 | value = (short)value + 57344; |
oprospero | 0:26a151d2c6db | 192 | |
oprospero | 0:26a151d2c6db | 193 | array[1] = value; |
oprospero | 0:26a151d2c6db | 194 | // xbeeTx.printf("Cmd: %d,\tVal: %d\n\r,",array[0],array[1]); |
oprospero | 0:26a151d2c6db | 195 | rxBuffer->add( array ); // Add to read buffer. |
oprospero | 2:bd1621102cad | 196 | // xbeeTx.putc( 255 ); |
oprospero | 2:bd1621102cad | 197 | // xbeeTx.putc( 255 ); |
oprospero | 5:4d96c8776442 | 198 | if ( commandData[0] != 0) |
oprospero | 3:f8e953201251 | 199 | { |
oprospero | 3:f8e953201251 | 200 | short * ackPacket = new short[2]; |
oprospero | 5:4d96c8776442 | 201 | ackPacket[0] = commandData[0]; |
oprospero | 3:f8e953201251 | 202 | ackPacket[1] = commandData[4]; |
oprospero | 3:f8e953201251 | 203 | txBuffer->add( ackPacket ); // Ack the packet with sequence nuber. |
oprospero | 3:f8e953201251 | 204 | } |
oprospero | 0:26a151d2c6db | 205 | } |
oprospero | 0:26a151d2c6db | 206 | delete[] commandData; |
oprospero | 0:26a151d2c6db | 207 | bLength = 0; // Reset the buffer length. |
oprospero | 0:26a151d2c6db | 208 | } |
oprospero | 2:bd1621102cad | 209 | // |
oprospero | 2:bd1621102cad | 210 | //void com::api_packetBuilder() |
oprospero | 2:bd1621102cad | 211 | //{ |
oprospero | 2:bd1621102cad | 212 | // |
oprospero | 2:bd1621102cad | 213 | //} |
oprospero | 0:26a151d2c6db | 214 | |
oprospero | 0:26a151d2c6db | 215 | |
oprospero | 0:26a151d2c6db | 216 | /********************** bool isSignalGood() ******************************/ |
oprospero | 0:26a151d2c6db | 217 | /* For future use */ |
oprospero | 0:26a151d2c6db | 218 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 219 | bool com::isSignalGood() |
oprospero | 0:26a151d2c6db | 220 | { |
oprospero | 0:26a151d2c6db | 221 | signalStrength = rssi.dutycycle(); |
oprospero | 0:26a151d2c6db | 222 | if (signalStrength > RSSI_THRES) return true; |
oprospero | 0:26a151d2c6db | 223 | else return false; |
oprospero | 0:26a151d2c6db | 224 | } |
oprospero | 0:26a151d2c6db | 225 | |
oprospero | 2:bd1621102cad | 226 | void com::setAPImode(bool mode) |
oprospero | 2:bd1621102cad | 227 | { |
oprospero | 2:bd1621102cad | 228 | api_mode = mode; |
oprospero | 2:bd1621102cad | 229 | } |
oprospero | 2:bd1621102cad | 230 |