Code to process UI input messages and verify them with checksum.

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;
+
+}