xbee communication for UWB quadcopter project
com.cpp
- Committer:
- oprospero
- Date:
- 2014-04-25
- Revision:
- 11:d1f488302d06
- Parent:
- 10:ec36e1b59a39
File content as of revision 11:d1f488302d06:
/****************************** com.cpp **********************************/ /* Version: 1.0 */ /* Last Updated: June 1, 2013 */ /* */ /* The com class implements reliable data transfer between two nodes */ /*using a checksum and a sequence number for guaranteed message delivery */ /*over an xbee modem connected to the passed in tx and rx pins. Messages */ /*are received and placed in the rxBuffer to be read when convenient. */ /*Messages are encoded by sending a byte with the value of the command */ /*then and int of the command. */ /* */ /* Commands: 0 -> Ack, does not get placed in rxQueue. */ /* 1 -> Throttle */ /* 2 -> Pitch */ /* 3 -> Roll */ /* 4 -> Yaw */ /*************************************************************************/ #include "mbed.h" #include "com.h" /*********************** com( PinName, PinName ) *************************/ /* */ /*************************************************************************/ com::com( PinName tx, PinName rx , PinName rssipin) : xbeeTx( tx, NC), xbeeRx( NC, rx), rssi(rssipin) { bLength = 0; // How many bytes are in the buffer. api_mode = false; // Xbee is in transparent mode. xbeeTx.baud(BAUDRATE); // Setup the serial baud rate. xbeeRx.baud(BAUDRATE); // Setup the serial baud rate. rxBuffer = new queue(); // Point to the rxQueue. txBuffer = new queue(); signalStrength = 0; xbeeRx.attach( this, &com::callback ); // Set callback as the interrupt handler. #ifdef DEBUG xbeeTx.printf("Communication.....Done\n\r"); #endif } /************************* bool isData() ********************************/ /* */ /*************************************************************************/ bool com::isData() { return !rxBuffer->isEmpty(); } /************************ void write( char ) *****************************/ /* Write a packet out the xbee com port. */ /* */ /* Data format byte[] */ /* byte[0] = command. */ /* byte[1] = upper 8 bits of value. */ /* byte[2] = lower 8 bits of value. */ /* byte[3] = Checksum byte[0] + byte[2]. */ /* byte[4] = Sequence Number. */ /* byte[5] = 255 End of message. */ /*************************************************************************/ void com::write( short command, short value ) { if (api_mode) { short hvalue = value / 128; short lvalue = (value % 128); short sum = (2*command + hvalue + 2*lvalue + value); short check = sum % 256; xbeeTx.putc( (char) 127); //Start Delimiter xbeeTx.putc( (char) 0); //Frame Data Length MSB xbeeTx.putc( (char) 6); //Frame Data Length LSB //Frame Data xbeeTx.putc( (char) command); // Command xbeeTx.putc( (char) hvalue); // First 8 bits in array. xbeeTx.putc( (char) lvalue); // Second 8 bits in array. xbeeTx.putc( command + lvalue ); // Checksum array[0] + array[1]. xbeeTx.putc( (char) value); // Sequence number. xbeeTx.putc( 255 ); // End of message. xbeeTx.putc( (char) 255 - check); //Checksum } else { short lvalue = (value % 128); xbeeTx.putc( (char)command ); // Command xbeeTx.putc( (char) value / 128 ); // First 8 bits in array. xbeeTx.putc( (char) lvalue); // Second 8 bits in array. xbeeTx.putc( command + lvalue ); // Checksum array[0] + array[1]. xbeeTx.putc( (char)value ); // Sequence number. xbeeTx.putc( 255 ); // End of message. } } /*************************** char ackCheck() ********************************/ /* */ /*************************************************************************/ void com::ackCheck() { if( !txBuffer->isEmpty() && xbeeTx.writeable()) { __disable_irq(); short * pkt = txBuffer->pop(); write(pkt[0],pkt[1]); //may need to disable interrupt delete[] pkt; __enable_irq(); } } bool com::rdy2ack() { return !txBuffer->isEmpty(); } /*************************** char read() ********************************/ /* */ /*************************************************************************/ short * com::read() { if( !rxBuffer->isEmpty()) return rxBuffer->pop(); return NULL; } /************************ void callback() ********************************/ /* */ /*************************************************************************/ void com::callback() { __disable_irq(); while( xbeeRx.readable() ) { char data = xbeeRx.getc(); // xbeeTx.printf("data: %d\n\r", data); // xbeeTx.printf("%d %d", data,(char) 255); // xbeeTx.putc( data ); if( bLength++ < BUFFERSIZE ) buffer[bLength] = data; // // xbeeTx.putc( bLength ); // xbeeTx.putc( bLength ); // xbeeTx.putc( 255 ); //2nd condition ensure that we have a full size packet before building if( data == 255 && bLength > 5) packetBuilder(); } __enable_irq(); } //void com::api_callback() //{ // while( xbeeRx.readable() ) // { // buffer[bLength++] = xbeeRx.getc(); // } //} /********************** void packetBuilder() *****************************/ /* Creates a packet from the buffered data and places it in the rxBuffer */ /* queue to be read whenever convenient. Max value of +/- 8063. */ /*************************************************************************/ void com::packetBuilder() { char * commandData = new char[bLength]; commandData[4] = buffer[--bLength]; // Sequence Number. commandData[3] = buffer[--bLength]; // CheckSum value. commandData[2] = buffer[--bLength]; // Second 7 bits. commandData[1] = buffer[--bLength]; // Fisrt 7 bits. commandData[0] = buffer[--bLength]; // Command. if( commandData[0] + commandData[2] == commandData[3] ) // Validate checksum. { short * array = new short[2]; array[0] = (short)commandData[0]; short value = (short)(commandData[1] * 128 + commandData[2]); if( value > 8062 ) value = (short)value + 57344; array[1] = value; // xbeeTx.printf("Cmd: %d,\tVal: %d\n\r,",array[0],array[1]); rxBuffer->add( array ); // Add to read buffer. // xbeeTx.putc( 255 ); // xbeeTx.putc( 255 ); if ( commandData[0] != 0) { short * ackPacket = new short[2]; ackPacket[0] = commandData[0]; ackPacket[1] = commandData[4]; txBuffer->add( ackPacket ); // Ack the packet with sequence nuber. } } delete[] commandData; bLength = 0; // Reset the buffer length. } // //void com::api_packetBuilder() //{ // //} /********************** bool isSignalGood() ******************************/ /* For future use */ /*************************************************************************/ bool com::isSignalGood() { signalStrength = rssi.dutycycle(); if (signalStrength > RSSI_THRES) return true; else return false; } void com::setAPImode(bool mode) { api_mode = mode; }