xbee communication for UWB quadcopter project
com.cpp@2:bd1621102cad, 2014-04-20 (annotated)
- Committer:
- oprospero
- Date:
- Sun Apr 20 02:27:39 2014 +0000
- Revision:
- 2:bd1621102cad
- Parent:
- 1:4f53de75bc96
- Child:
- 3:f8e953201251
- Child:
- 8:42e37cdab039
clean ups
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 | 0:26a151d2c6db | 34 | signalStrength = 0; |
oprospero | 0:26a151d2c6db | 35 | xbeeRx.attach( this, &com::callback ); // Set callback as the interrupt handler. |
oprospero | 1:4f53de75bc96 | 36 | #ifdef DEBUG |
oprospero | 0:26a151d2c6db | 37 | xbeeTx.printf("Communication.....Done\n\r"); |
oprospero | 1:4f53de75bc96 | 38 | #endif |
oprospero | 0:26a151d2c6db | 39 | } |
oprospero | 0:26a151d2c6db | 40 | |
oprospero | 0:26a151d2c6db | 41 | /************************* bool isData() ********************************/ |
oprospero | 0:26a151d2c6db | 42 | /* */ |
oprospero | 0:26a151d2c6db | 43 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 44 | |
oprospero | 0:26a151d2c6db | 45 | bool com::isData() |
oprospero | 0:26a151d2c6db | 46 | { |
oprospero | 2:bd1621102cad | 47 | |
oprospero | 1:4f53de75bc96 | 48 | return !rxBuffer->isEmpty(); |
oprospero | 0:26a151d2c6db | 49 | } |
oprospero | 0:26a151d2c6db | 50 | |
oprospero | 0:26a151d2c6db | 51 | /************************ void write( char ) *****************************/ |
oprospero | 0:26a151d2c6db | 52 | /* Write a packet out the xbee com port. */ |
oprospero | 0:26a151d2c6db | 53 | /* */ |
oprospero | 0:26a151d2c6db | 54 | /* Data format byte[] */ |
oprospero | 0:26a151d2c6db | 55 | /* byte[0] = command. */ |
oprospero | 0:26a151d2c6db | 56 | /* byte[1] = upper 8 bits of value. */ |
oprospero | 0:26a151d2c6db | 57 | /* byte[2] = lower 8 bits of value. */ |
oprospero | 0:26a151d2c6db | 58 | /* byte[3] = Checksum byte[0] + byte[2]. */ |
oprospero | 0:26a151d2c6db | 59 | /* byte[4] = Sequence Number. */ |
oprospero | 0:26a151d2c6db | 60 | /* byte[5] = 255 End of message. */ |
oprospero | 0:26a151d2c6db | 61 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 62 | |
oprospero | 0:26a151d2c6db | 63 | void com::write( short command, short value ) |
oprospero | 0:26a151d2c6db | 64 | { |
oprospero | 2:bd1621102cad | 65 | if (api_mode) |
oprospero | 2:bd1621102cad | 66 | { |
oprospero | 2:bd1621102cad | 67 | short hvalue = value / 128; |
oprospero | 2:bd1621102cad | 68 | short lvalue = (value % 128); |
oprospero | 2:bd1621102cad | 69 | short sum = (2*command + hvalue + 2*lvalue + value); |
oprospero | 2:bd1621102cad | 70 | short check = sum % 256; |
oprospero | 2:bd1621102cad | 71 | xbeeTx.putc( (char) 127); //Start Delimiter |
oprospero | 2:bd1621102cad | 72 | |
oprospero | 2:bd1621102cad | 73 | xbeeTx.putc( (char) 0); //Frame Data Length MSB |
oprospero | 2:bd1621102cad | 74 | xbeeTx.putc( (char) 6); //Frame Data Length LSB |
oprospero | 2:bd1621102cad | 75 | //Frame Data |
oprospero | 2:bd1621102cad | 76 | xbeeTx.putc( (char) command); // Command |
oprospero | 2:bd1621102cad | 77 | xbeeTx.putc( (char) hvalue); // First 8 bits in array. |
oprospero | 2:bd1621102cad | 78 | xbeeTx.putc( (char) lvalue); // Second 8 bits in array. |
oprospero | 2:bd1621102cad | 79 | xbeeTx.putc( command + lvalue ); // Checksum array[0] + array[1]. |
oprospero | 2:bd1621102cad | 80 | xbeeTx.putc( (char) value); // Sequence number. |
oprospero | 2:bd1621102cad | 81 | xbeeTx.putc( 255 ); // End of message. |
oprospero | 2:bd1621102cad | 82 | |
oprospero | 2:bd1621102cad | 83 | xbeeTx.putc( (char) 255 - check); //Checksum |
oprospero | 2:bd1621102cad | 84 | |
oprospero | 2:bd1621102cad | 85 | } |
oprospero | 2:bd1621102cad | 86 | else |
oprospero | 2:bd1621102cad | 87 | { |
oprospero | 2:bd1621102cad | 88 | short lvalue = (value % 128); |
oprospero | 2:bd1621102cad | 89 | xbeeTx.putc( (char)command ); // Command |
oprospero | 2:bd1621102cad | 90 | xbeeTx.putc( (char) value / 128 ); // First 8 bits in array. |
oprospero | 2:bd1621102cad | 91 | xbeeTx.putc( (char) lvalue); // Second 8 bits in array. |
oprospero | 2:bd1621102cad | 92 | xbeeTx.putc( command + lvalue ); // Checksum array[0] + array[1]. |
oprospero | 2:bd1621102cad | 93 | xbeeTx.putc( (char)value ); // Sequence number. |
oprospero | 2:bd1621102cad | 94 | xbeeTx.putc( 255 ); // End of message. |
oprospero | 2:bd1621102cad | 95 | } |
oprospero | 0:26a151d2c6db | 96 | } |
oprospero | 0:26a151d2c6db | 97 | |
oprospero | 0:26a151d2c6db | 98 | /*************************** char read() ********************************/ |
oprospero | 0:26a151d2c6db | 99 | /* */ |
oprospero | 0:26a151d2c6db | 100 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 101 | |
oprospero | 0:26a151d2c6db | 102 | short * com::read() |
oprospero | 0:26a151d2c6db | 103 | { |
oprospero | 0:26a151d2c6db | 104 | if( !rxBuffer->isEmpty()) |
oprospero | 0:26a151d2c6db | 105 | return rxBuffer->pop(); |
oprospero | 0:26a151d2c6db | 106 | |
oprospero | 0:26a151d2c6db | 107 | return NULL; |
oprospero | 0:26a151d2c6db | 108 | } |
oprospero | 0:26a151d2c6db | 109 | |
oprospero | 0:26a151d2c6db | 110 | /************************ void callback() ********************************/ |
oprospero | 0:26a151d2c6db | 111 | /* */ |
oprospero | 0:26a151d2c6db | 112 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 113 | |
oprospero | 0:26a151d2c6db | 114 | void com::callback() |
oprospero | 0:26a151d2c6db | 115 | { |
oprospero | 0:26a151d2c6db | 116 | while( xbeeRx.readable() ) |
oprospero | 0:26a151d2c6db | 117 | { |
oprospero | 0:26a151d2c6db | 118 | char data = xbeeRx.getc(); |
oprospero | 0:26a151d2c6db | 119 | // xbeeTx.printf("data: %d\n\r", data); |
oprospero | 2:bd1621102cad | 120 | // xbeeTx.printf("%d %d", data,(char) 255); |
oprospero | 2:bd1621102cad | 121 | // xbeeTx.putc( data ); |
oprospero | 0:26a151d2c6db | 122 | if( bLength++ < BUFFERSIZE ) |
oprospero | 0:26a151d2c6db | 123 | buffer[bLength] = data; |
oprospero | 0:26a151d2c6db | 124 | |
oprospero | 0:26a151d2c6db | 125 | if( data == 255 ) |
oprospero | 0:26a151d2c6db | 126 | packetBuilder(); |
oprospero | 0:26a151d2c6db | 127 | } |
oprospero | 0:26a151d2c6db | 128 | } |
oprospero | 0:26a151d2c6db | 129 | |
oprospero | 2:bd1621102cad | 130 | //void com::api_callback() |
oprospero | 2:bd1621102cad | 131 | //{ |
oprospero | 2:bd1621102cad | 132 | // while( xbeeRx.readable() ) |
oprospero | 2:bd1621102cad | 133 | // { |
oprospero | 2:bd1621102cad | 134 | // buffer[bLength++] = xbeeRx.getc(); |
oprospero | 2:bd1621102cad | 135 | // } |
oprospero | 2:bd1621102cad | 136 | //} |
oprospero | 2:bd1621102cad | 137 | |
oprospero | 2:bd1621102cad | 138 | |
oprospero | 0:26a151d2c6db | 139 | /********************** void packetBuilder() *****************************/ |
oprospero | 0:26a151d2c6db | 140 | /* Creates a packet from the buffered data and places it in the rxBuffer */ |
oprospero | 0:26a151d2c6db | 141 | /* queue to be read whenever convenient. Max value of +/- 8063. */ |
oprospero | 0:26a151d2c6db | 142 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 143 | |
oprospero | 0:26a151d2c6db | 144 | void com::packetBuilder() |
oprospero | 0:26a151d2c6db | 145 | { |
oprospero | 0:26a151d2c6db | 146 | char * commandData = new char[bLength]; |
oprospero | 0:26a151d2c6db | 147 | commandData[4] = buffer[--bLength]; // Sequence Number. |
oprospero | 0:26a151d2c6db | 148 | commandData[3] = buffer[--bLength]; // CheckSum value. |
oprospero | 0:26a151d2c6db | 149 | commandData[2] = buffer[--bLength]; // Second 7 bits. |
oprospero | 0:26a151d2c6db | 150 | commandData[1] = buffer[--bLength]; // Fisrt 7 bits. |
oprospero | 0:26a151d2c6db | 151 | commandData[0] = buffer[--bLength]; // Command. |
oprospero | 0:26a151d2c6db | 152 | |
oprospero | 0:26a151d2c6db | 153 | |
oprospero | 0:26a151d2c6db | 154 | if( commandData[0] + commandData[2] == commandData[3] ) // Validate checksum. |
oprospero | 0:26a151d2c6db | 155 | { |
oprospero | 0:26a151d2c6db | 156 | short * array = new short[2]; |
oprospero | 0:26a151d2c6db | 157 | |
oprospero | 0:26a151d2c6db | 158 | array[0] = (short)commandData[0]; |
oprospero | 0:26a151d2c6db | 159 | |
oprospero | 0:26a151d2c6db | 160 | short value = (short)(commandData[1] * 128 + commandData[2]); |
oprospero | 0:26a151d2c6db | 161 | |
oprospero | 0:26a151d2c6db | 162 | if( value > 8062 ) |
oprospero | 0:26a151d2c6db | 163 | value = (short)value + 57344; |
oprospero | 0:26a151d2c6db | 164 | |
oprospero | 0:26a151d2c6db | 165 | array[1] = value; |
oprospero | 0:26a151d2c6db | 166 | // xbeeTx.printf("Cmd: %d,\tVal: %d\n\r,",array[0],array[1]); |
oprospero | 0:26a151d2c6db | 167 | rxBuffer->add( array ); // Add to read buffer. |
oprospero | 2:bd1621102cad | 168 | // xbeeTx.putc( 255 ); |
oprospero | 2:bd1621102cad | 169 | // xbeeTx.putc( 255 ); |
oprospero | 0:26a151d2c6db | 170 | write( (short)commandData[0], (short)commandData[4]); // Ack the packet with sequence nuber. |
oprospero | 0:26a151d2c6db | 171 | } |
oprospero | 0:26a151d2c6db | 172 | delete[] commandData; |
oprospero | 0:26a151d2c6db | 173 | bLength = 0; // Reset the buffer length. |
oprospero | 0:26a151d2c6db | 174 | } |
oprospero | 2:bd1621102cad | 175 | // |
oprospero | 2:bd1621102cad | 176 | //void com::api_packetBuilder() |
oprospero | 2:bd1621102cad | 177 | //{ |
oprospero | 2:bd1621102cad | 178 | // |
oprospero | 2:bd1621102cad | 179 | //} |
oprospero | 0:26a151d2c6db | 180 | |
oprospero | 0:26a151d2c6db | 181 | |
oprospero | 0:26a151d2c6db | 182 | /********************** bool isSignalGood() ******************************/ |
oprospero | 0:26a151d2c6db | 183 | /* For future use */ |
oprospero | 0:26a151d2c6db | 184 | /*************************************************************************/ |
oprospero | 0:26a151d2c6db | 185 | bool com::isSignalGood() |
oprospero | 0:26a151d2c6db | 186 | { |
oprospero | 0:26a151d2c6db | 187 | signalStrength = rssi.dutycycle(); |
oprospero | 0:26a151d2c6db | 188 | if (signalStrength > RSSI_THRES) return true; |
oprospero | 0:26a151d2c6db | 189 | else return false; |
oprospero | 0:26a151d2c6db | 190 | } |
oprospero | 0:26a151d2c6db | 191 | |
oprospero | 2:bd1621102cad | 192 | void com::setAPImode(bool mode) |
oprospero | 2:bd1621102cad | 193 | { |
oprospero | 2:bd1621102cad | 194 | api_mode = mode; |
oprospero | 2:bd1621102cad | 195 | } |
oprospero | 2:bd1621102cad | 196 |