Code to process UI input messages and verify them with checksum.
Diff: UserInterface.cpp
- Revision:
- 0:6b5a3a0138ad
- Child:
- 1:7795fb7ee3f3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UserInterface.cpp Wed Feb 04 23:53:56 2015 +0000 @@ -0,0 +1,253 @@ +#include "mbed.h" +#include "MODSERIAL.h" +#include "initDatabed.h" +#include "UserInterface.h" + +// UI button variables +//int buttonA = 1; // state of remote button +//int buttonA_prev = 1; + +// push hold vars +//float tHold = .6; // hold time for sit/stand +//float tIdle = 2; // time out to confirm sit or stance (s) +//int SSconfirm = 0; // sit/stand variable for confirmation process +//float tRelease = .3; // time since last transmission to determine button release + + +// various timers +//Timer time_StateChange; +//Timer time_pressA; +//Timer time_pressB; + +//int buttonB = 1; // state of remote button +//int buttonB_prev = 1; +//char __xbeeBuffer[250]; +//int _dataCnt=0; +int UI = 0; + +//float _time_sinceA, _time_sinceB; //time since the button was first pressed + +UserInterface::UserInterface(void): _buttonA(1), _buttonA_prev(1), _tHold(.6), _tIdle(2), _SSconfirm(0), _tRelease(.3), _buttonB(1), _buttonB_prev(1), _dataCnt(0) { +} + +void UserInterface::readBuffer() +{ + while (xbeeUI.readable() && _dataCnt<250) { + _xbeeBuffer[_dataCnt] = xbeeUI.getc(); + _dataCnt++; + } +} + +/** +* This function returns an array of information about the received characters. count[0] is # of data bytes, count[1] is expected length of the message, given the data length bytes and presence +* of escape characters. count[2] is position of the first data byte. +* @param idx char array containing received data, beginning with the start byte 0x7e +* @param count array that will contain the returned values +* @author Michael Ling +* @date 2/2/2015 +*/ +void UserInterface::find_length(char *idx, int *count) +{ + int pos = 0; + short length; + //This segment reads the length bytes (bytes 2-3 of the message) + if (*(idx+1) == 0x7d) { + length = (*(idx+2) ^ 0x20) << 8; + pos = 3; + } else { + length = *(idx+1) << 8; + pos = 2; + } + if (*(idx+pos) == 0x7d) { + length = length | (*(idx+pos+1)^0x20); + pos += 2; + } else { + length = length | *(idx+pos); + pos += 1; + } + count[0] = (int)length; + //Length incremented by 1--we treat the checksum as a data byte, since it can also be escaped + length += 1; + //Checks for escape characters--for every escape char found, the data section gets 1 byte longer + for (short i = 0; i < length; i += 1) { + if (*(idx+i) == 0x7d) { + length += 1; + } + } + count[1] = (int) length + 3; + count[2] = pos; +} + +/** +* This function returns true if calculated checksum matches the checksum at the end of the message. +* @param idx char array containing received data, starting with start byte 0x7e +* @param length number of data bytes in the message +* @author Michael Ling +* @date 2/2/2015 +*/ +bool UserInterface::checksum_check(char *idx, int length) +{ + int pos = 0; + int sum = 0; + for(int i = 0; i < length; i++) { + //In case of an escape character, the true value of the byte is the following byte XOR with 0x20 + if (*(idx+pos) == 0x7d) { + sum += (*(idx+pos+1) ^ 0x20); + pos += 2; + } else { + sum += *(idx+pos); + pos += 1; + } + } + //XBEE checksum: sum all data bytes, truncate the sum to the rightmost 8 bytes, and subtract that from 0xff + sum = sum & 0x0ff; + char calcsum = (char)(0xff - sum); + char checksum; + if (*(idx+pos) == 0x7d) { + checksum = *(idx+pos)^0x20; + } else { + checksum = *(idx+pos); + } + if (checksum != calcsum) { + return false; + } + return true; +} + +void UserInterface::checkUI_XBee() +{ + int sum = 0; + _buttonA_prev = _buttonA; + _buttonB_prev = _buttonB; + char * idx = strchr(_xbeeBuffer,0x7e); + if (idx != NULL) { + int size[3]; + find_length(idx, size); + pc.printf("Size: %d, Datacount: %d\r\n", size[1], _dataCnt); + if(_dataCnt >= size[1]) { + + _buttonA = (_xbeeBuffer[idx-_xbeeBuffer+21]>>1) & 1; // on DIO1 + _buttonB = (_xbeeBuffer[idx-_xbeeBuffer+21]>>2) & 1; // on DIO2 + + if (checksum_check(idx+size[2], size[0])) { + pc.printf("Checksums match\r\n"); + } else { + pc.printf("Checksums don't match\r\n"); + } + _dataCnt = 0; + } + if(sum == 0x79c) { + if (_buttonA == 0 && _buttonA_prev == 1) {//buton was just pressed + _time_pressA.reset(); + _time_pressA.start(); + _time_sinceA = 0; + } + + else if(_buttonA == 0) { + _time_sinceA = _time_pressA; //button is still pressed + } + + if (_buttonB == 0 && _buttonB_prev == 1) {//button was just pressed + _time_pressB.reset(); + _time_pressB.start(); + _time_sinceB = 0; + } else if(_buttonB == 0) { + _time_sinceB = _time_pressB; //button is still pressed + } + } + + if((_time_pressA-_time_sinceA) >= _tRelease) { //button was released + if(_time_pressA-_tRelease >= _tHold) { //if the button was held before released + UI = 3; //UI command is a held A button + } else { + UI = 1; //UI command is a pressed A button + } + _buttonA = 1; //button A is released + _time_pressA.stop(); //reset the button A timer + _time_pressA.reset(); + } + if(_time_pressB-_time_sinceB >= _tRelease) { //button was released + if(_time_pressB-_tRelease >= _tHold) { //if the button was held before released + UI = 4; //UI command is a held B button + } else { + UI = 2; //UI command is a pressed B button + } + _buttonB = 1; //button B is released + _time_pressB.stop(); //reset the button B timer + _time_pressB.reset(); + } + } + memset(_xbeeBuffer,0xFF,250); + _dataCnt = 0; +} + +/*void checkUI_XBee() +{ + + _buttonA_prev = _buttonA; + buttonB_prev = buttonB; + while (xbeeUI.readable() && _dataCnt<250) { + __xbeeBuffer[_dataCnt] = xbeeUI.getc(); + _dataCnt++; + if (__xbeeBuffer[_dataCnt]==0x7e) { + for(int i=0; i<22; i++) { + if(xbeeUI.readable() { + __xbeeBuffer[_dataCnt] = xbeeUI.getc(); + _dataCnt++; + } + } + } + char * idx=strchr(__xbeeBuffer,0x7e); + _buttonA = (_xbeeBuffer[idx-_xbeeBuffer+21]>>1) & 1; // on DIO1 + buttonB = (_xbeeBuffer[idx-_xbeeBuffer+21]>>2) & 1; // on DIO2 + pc.printf("%x\r\n", *(idx+2)); + _dataCnt=0; + if (buttonA == 0 && buttonA_prev==1) {//buton was just pressed + time_pressA.reset(); + time_pressA.start(); + _time_sinceA=0; + } + + else if(buttonA==0) { + _time_sinceA=time_pressA; //button is still pressed + } + + if (buttonB == 0 && buttonB_prev==1) {//button was just pressed + time_pressB.reset(); + time_pressB.start(); + _time_sinceB=0; + } else if(buttonB==0) { + _time_sinceB=time_pressB; //button is still pressed + } + } + if((time_pressA-_time_sinceA)>=tRelease) { //button was released + if(time_pressA-tRelease>=tHold) { //if the button was held before released + UI=3; //UI command is a held A button + } else { + UI=1; //UI command is a pressed A button + } + buttonA=1; //button A is released + time_pressA.stop(); //reset the button A timer + time_pressA.reset(); + } + if(time_pressB-_time_sinceB>=tRelease) { //button was released + if(time_pressB-tRelease>=tHold) { //if the button was held before released + UI=4; //UI command is a held B button + } else { + UI=2; //UI command is a pressed B button + } + buttonB=1; //button B is released + time_pressB.stop(); //reset the button B timer + time_pressB.reset(); + } + + _dataCnt=0; + memset(__xbeeBuffer,0xF,250); +}*/ + +void UserInterface::initializeUI() +{ + xbeeUI.baud(115200); + mainPower = 0; + +}