Code to process UI input messages and verify them with checksum.
UserInterface.cpp@0:6b5a3a0138ad, 2015-02-04 (annotated)
- Committer:
- mzling
- Date:
- Wed Feb 04 23:53:56 2015 +0000
- Revision:
- 0:6b5a3a0138ad
- Child:
- 1:7795fb7ee3f3
UserInterface code--correct checksum behavior and reformatted
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mzling | 0:6b5a3a0138ad | 1 | #include "mbed.h" |
mzling | 0:6b5a3a0138ad | 2 | #include "MODSERIAL.h" |
mzling | 0:6b5a3a0138ad | 3 | #include "initDatabed.h" |
mzling | 0:6b5a3a0138ad | 4 | #include "UserInterface.h" |
mzling | 0:6b5a3a0138ad | 5 | |
mzling | 0:6b5a3a0138ad | 6 | // UI button variables |
mzling | 0:6b5a3a0138ad | 7 | //int buttonA = 1; // state of remote button |
mzling | 0:6b5a3a0138ad | 8 | //int buttonA_prev = 1; |
mzling | 0:6b5a3a0138ad | 9 | |
mzling | 0:6b5a3a0138ad | 10 | // push hold vars |
mzling | 0:6b5a3a0138ad | 11 | //float tHold = .6; // hold time for sit/stand |
mzling | 0:6b5a3a0138ad | 12 | //float tIdle = 2; // time out to confirm sit or stance (s) |
mzling | 0:6b5a3a0138ad | 13 | //int SSconfirm = 0; // sit/stand variable for confirmation process |
mzling | 0:6b5a3a0138ad | 14 | //float tRelease = .3; // time since last transmission to determine button release |
mzling | 0:6b5a3a0138ad | 15 | |
mzling | 0:6b5a3a0138ad | 16 | |
mzling | 0:6b5a3a0138ad | 17 | // various timers |
mzling | 0:6b5a3a0138ad | 18 | //Timer time_StateChange; |
mzling | 0:6b5a3a0138ad | 19 | //Timer time_pressA; |
mzling | 0:6b5a3a0138ad | 20 | //Timer time_pressB; |
mzling | 0:6b5a3a0138ad | 21 | |
mzling | 0:6b5a3a0138ad | 22 | //int buttonB = 1; // state of remote button |
mzling | 0:6b5a3a0138ad | 23 | //int buttonB_prev = 1; |
mzling | 0:6b5a3a0138ad | 24 | //char __xbeeBuffer[250]; |
mzling | 0:6b5a3a0138ad | 25 | //int _dataCnt=0; |
mzling | 0:6b5a3a0138ad | 26 | int UI = 0; |
mzling | 0:6b5a3a0138ad | 27 | |
mzling | 0:6b5a3a0138ad | 28 | //float _time_sinceA, _time_sinceB; //time since the button was first pressed |
mzling | 0:6b5a3a0138ad | 29 | |
mzling | 0:6b5a3a0138ad | 30 | UserInterface::UserInterface(void): _buttonA(1), _buttonA_prev(1), _tHold(.6), _tIdle(2), _SSconfirm(0), _tRelease(.3), _buttonB(1), _buttonB_prev(1), _dataCnt(0) { |
mzling | 0:6b5a3a0138ad | 31 | } |
mzling | 0:6b5a3a0138ad | 32 | |
mzling | 0:6b5a3a0138ad | 33 | void UserInterface::readBuffer() |
mzling | 0:6b5a3a0138ad | 34 | { |
mzling | 0:6b5a3a0138ad | 35 | while (xbeeUI.readable() && _dataCnt<250) { |
mzling | 0:6b5a3a0138ad | 36 | _xbeeBuffer[_dataCnt] = xbeeUI.getc(); |
mzling | 0:6b5a3a0138ad | 37 | _dataCnt++; |
mzling | 0:6b5a3a0138ad | 38 | } |
mzling | 0:6b5a3a0138ad | 39 | } |
mzling | 0:6b5a3a0138ad | 40 | |
mzling | 0:6b5a3a0138ad | 41 | /** |
mzling | 0:6b5a3a0138ad | 42 | * 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 |
mzling | 0:6b5a3a0138ad | 43 | * of escape characters. count[2] is position of the first data byte. |
mzling | 0:6b5a3a0138ad | 44 | * @param idx char array containing received data, beginning with the start byte 0x7e |
mzling | 0:6b5a3a0138ad | 45 | * @param count array that will contain the returned values |
mzling | 0:6b5a3a0138ad | 46 | * @author Michael Ling |
mzling | 0:6b5a3a0138ad | 47 | * @date 2/2/2015 |
mzling | 0:6b5a3a0138ad | 48 | */ |
mzling | 0:6b5a3a0138ad | 49 | void UserInterface::find_length(char *idx, int *count) |
mzling | 0:6b5a3a0138ad | 50 | { |
mzling | 0:6b5a3a0138ad | 51 | int pos = 0; |
mzling | 0:6b5a3a0138ad | 52 | short length; |
mzling | 0:6b5a3a0138ad | 53 | //This segment reads the length bytes (bytes 2-3 of the message) |
mzling | 0:6b5a3a0138ad | 54 | if (*(idx+1) == 0x7d) { |
mzling | 0:6b5a3a0138ad | 55 | length = (*(idx+2) ^ 0x20) << 8; |
mzling | 0:6b5a3a0138ad | 56 | pos = 3; |
mzling | 0:6b5a3a0138ad | 57 | } else { |
mzling | 0:6b5a3a0138ad | 58 | length = *(idx+1) << 8; |
mzling | 0:6b5a3a0138ad | 59 | pos = 2; |
mzling | 0:6b5a3a0138ad | 60 | } |
mzling | 0:6b5a3a0138ad | 61 | if (*(idx+pos) == 0x7d) { |
mzling | 0:6b5a3a0138ad | 62 | length = length | (*(idx+pos+1)^0x20); |
mzling | 0:6b5a3a0138ad | 63 | pos += 2; |
mzling | 0:6b5a3a0138ad | 64 | } else { |
mzling | 0:6b5a3a0138ad | 65 | length = length | *(idx+pos); |
mzling | 0:6b5a3a0138ad | 66 | pos += 1; |
mzling | 0:6b5a3a0138ad | 67 | } |
mzling | 0:6b5a3a0138ad | 68 | count[0] = (int)length; |
mzling | 0:6b5a3a0138ad | 69 | //Length incremented by 1--we treat the checksum as a data byte, since it can also be escaped |
mzling | 0:6b5a3a0138ad | 70 | length += 1; |
mzling | 0:6b5a3a0138ad | 71 | //Checks for escape characters--for every escape char found, the data section gets 1 byte longer |
mzling | 0:6b5a3a0138ad | 72 | for (short i = 0; i < length; i += 1) { |
mzling | 0:6b5a3a0138ad | 73 | if (*(idx+i) == 0x7d) { |
mzling | 0:6b5a3a0138ad | 74 | length += 1; |
mzling | 0:6b5a3a0138ad | 75 | } |
mzling | 0:6b5a3a0138ad | 76 | } |
mzling | 0:6b5a3a0138ad | 77 | count[1] = (int) length + 3; |
mzling | 0:6b5a3a0138ad | 78 | count[2] = pos; |
mzling | 0:6b5a3a0138ad | 79 | } |
mzling | 0:6b5a3a0138ad | 80 | |
mzling | 0:6b5a3a0138ad | 81 | /** |
mzling | 0:6b5a3a0138ad | 82 | * This function returns true if calculated checksum matches the checksum at the end of the message. |
mzling | 0:6b5a3a0138ad | 83 | * @param idx char array containing received data, starting with start byte 0x7e |
mzling | 0:6b5a3a0138ad | 84 | * @param length number of data bytes in the message |
mzling | 0:6b5a3a0138ad | 85 | * @author Michael Ling |
mzling | 0:6b5a3a0138ad | 86 | * @date 2/2/2015 |
mzling | 0:6b5a3a0138ad | 87 | */ |
mzling | 0:6b5a3a0138ad | 88 | bool UserInterface::checksum_check(char *idx, int length) |
mzling | 0:6b5a3a0138ad | 89 | { |
mzling | 0:6b5a3a0138ad | 90 | int pos = 0; |
mzling | 0:6b5a3a0138ad | 91 | int sum = 0; |
mzling | 0:6b5a3a0138ad | 92 | for(int i = 0; i < length; i++) { |
mzling | 0:6b5a3a0138ad | 93 | //In case of an escape character, the true value of the byte is the following byte XOR with 0x20 |
mzling | 0:6b5a3a0138ad | 94 | if (*(idx+pos) == 0x7d) { |
mzling | 0:6b5a3a0138ad | 95 | sum += (*(idx+pos+1) ^ 0x20); |
mzling | 0:6b5a3a0138ad | 96 | pos += 2; |
mzling | 0:6b5a3a0138ad | 97 | } else { |
mzling | 0:6b5a3a0138ad | 98 | sum += *(idx+pos); |
mzling | 0:6b5a3a0138ad | 99 | pos += 1; |
mzling | 0:6b5a3a0138ad | 100 | } |
mzling | 0:6b5a3a0138ad | 101 | } |
mzling | 0:6b5a3a0138ad | 102 | //XBEE checksum: sum all data bytes, truncate the sum to the rightmost 8 bytes, and subtract that from 0xff |
mzling | 0:6b5a3a0138ad | 103 | sum = sum & 0x0ff; |
mzling | 0:6b5a3a0138ad | 104 | char calcsum = (char)(0xff - sum); |
mzling | 0:6b5a3a0138ad | 105 | char checksum; |
mzling | 0:6b5a3a0138ad | 106 | if (*(idx+pos) == 0x7d) { |
mzling | 0:6b5a3a0138ad | 107 | checksum = *(idx+pos)^0x20; |
mzling | 0:6b5a3a0138ad | 108 | } else { |
mzling | 0:6b5a3a0138ad | 109 | checksum = *(idx+pos); |
mzling | 0:6b5a3a0138ad | 110 | } |
mzling | 0:6b5a3a0138ad | 111 | if (checksum != calcsum) { |
mzling | 0:6b5a3a0138ad | 112 | return false; |
mzling | 0:6b5a3a0138ad | 113 | } |
mzling | 0:6b5a3a0138ad | 114 | return true; |
mzling | 0:6b5a3a0138ad | 115 | } |
mzling | 0:6b5a3a0138ad | 116 | |
mzling | 0:6b5a3a0138ad | 117 | void UserInterface::checkUI_XBee() |
mzling | 0:6b5a3a0138ad | 118 | { |
mzling | 0:6b5a3a0138ad | 119 | int sum = 0; |
mzling | 0:6b5a3a0138ad | 120 | _buttonA_prev = _buttonA; |
mzling | 0:6b5a3a0138ad | 121 | _buttonB_prev = _buttonB; |
mzling | 0:6b5a3a0138ad | 122 | char * idx = strchr(_xbeeBuffer,0x7e); |
mzling | 0:6b5a3a0138ad | 123 | if (idx != NULL) { |
mzling | 0:6b5a3a0138ad | 124 | int size[3]; |
mzling | 0:6b5a3a0138ad | 125 | find_length(idx, size); |
mzling | 0:6b5a3a0138ad | 126 | pc.printf("Size: %d, Datacount: %d\r\n", size[1], _dataCnt); |
mzling | 0:6b5a3a0138ad | 127 | if(_dataCnt >= size[1]) { |
mzling | 0:6b5a3a0138ad | 128 | |
mzling | 0:6b5a3a0138ad | 129 | _buttonA = (_xbeeBuffer[idx-_xbeeBuffer+21]>>1) & 1; // on DIO1 |
mzling | 0:6b5a3a0138ad | 130 | _buttonB = (_xbeeBuffer[idx-_xbeeBuffer+21]>>2) & 1; // on DIO2 |
mzling | 0:6b5a3a0138ad | 131 | |
mzling | 0:6b5a3a0138ad | 132 | if (checksum_check(idx+size[2], size[0])) { |
mzling | 0:6b5a3a0138ad | 133 | pc.printf("Checksums match\r\n"); |
mzling | 0:6b5a3a0138ad | 134 | } else { |
mzling | 0:6b5a3a0138ad | 135 | pc.printf("Checksums don't match\r\n"); |
mzling | 0:6b5a3a0138ad | 136 | } |
mzling | 0:6b5a3a0138ad | 137 | _dataCnt = 0; |
mzling | 0:6b5a3a0138ad | 138 | } |
mzling | 0:6b5a3a0138ad | 139 | if(sum == 0x79c) { |
mzling | 0:6b5a3a0138ad | 140 | if (_buttonA == 0 && _buttonA_prev == 1) {//buton was just pressed |
mzling | 0:6b5a3a0138ad | 141 | _time_pressA.reset(); |
mzling | 0:6b5a3a0138ad | 142 | _time_pressA.start(); |
mzling | 0:6b5a3a0138ad | 143 | _time_sinceA = 0; |
mzling | 0:6b5a3a0138ad | 144 | } |
mzling | 0:6b5a3a0138ad | 145 | |
mzling | 0:6b5a3a0138ad | 146 | else if(_buttonA == 0) { |
mzling | 0:6b5a3a0138ad | 147 | _time_sinceA = _time_pressA; //button is still pressed |
mzling | 0:6b5a3a0138ad | 148 | } |
mzling | 0:6b5a3a0138ad | 149 | |
mzling | 0:6b5a3a0138ad | 150 | if (_buttonB == 0 && _buttonB_prev == 1) {//button was just pressed |
mzling | 0:6b5a3a0138ad | 151 | _time_pressB.reset(); |
mzling | 0:6b5a3a0138ad | 152 | _time_pressB.start(); |
mzling | 0:6b5a3a0138ad | 153 | _time_sinceB = 0; |
mzling | 0:6b5a3a0138ad | 154 | } else if(_buttonB == 0) { |
mzling | 0:6b5a3a0138ad | 155 | _time_sinceB = _time_pressB; //button is still pressed |
mzling | 0:6b5a3a0138ad | 156 | } |
mzling | 0:6b5a3a0138ad | 157 | } |
mzling | 0:6b5a3a0138ad | 158 | |
mzling | 0:6b5a3a0138ad | 159 | if((_time_pressA-_time_sinceA) >= _tRelease) { //button was released |
mzling | 0:6b5a3a0138ad | 160 | if(_time_pressA-_tRelease >= _tHold) { //if the button was held before released |
mzling | 0:6b5a3a0138ad | 161 | UI = 3; //UI command is a held A button |
mzling | 0:6b5a3a0138ad | 162 | } else { |
mzling | 0:6b5a3a0138ad | 163 | UI = 1; //UI command is a pressed A button |
mzling | 0:6b5a3a0138ad | 164 | } |
mzling | 0:6b5a3a0138ad | 165 | _buttonA = 1; //button A is released |
mzling | 0:6b5a3a0138ad | 166 | _time_pressA.stop(); //reset the button A timer |
mzling | 0:6b5a3a0138ad | 167 | _time_pressA.reset(); |
mzling | 0:6b5a3a0138ad | 168 | } |
mzling | 0:6b5a3a0138ad | 169 | if(_time_pressB-_time_sinceB >= _tRelease) { //button was released |
mzling | 0:6b5a3a0138ad | 170 | if(_time_pressB-_tRelease >= _tHold) { //if the button was held before released |
mzling | 0:6b5a3a0138ad | 171 | UI = 4; //UI command is a held B button |
mzling | 0:6b5a3a0138ad | 172 | } else { |
mzling | 0:6b5a3a0138ad | 173 | UI = 2; //UI command is a pressed B button |
mzling | 0:6b5a3a0138ad | 174 | } |
mzling | 0:6b5a3a0138ad | 175 | _buttonB = 1; //button B is released |
mzling | 0:6b5a3a0138ad | 176 | _time_pressB.stop(); //reset the button B timer |
mzling | 0:6b5a3a0138ad | 177 | _time_pressB.reset(); |
mzling | 0:6b5a3a0138ad | 178 | } |
mzling | 0:6b5a3a0138ad | 179 | } |
mzling | 0:6b5a3a0138ad | 180 | memset(_xbeeBuffer,0xFF,250); |
mzling | 0:6b5a3a0138ad | 181 | _dataCnt = 0; |
mzling | 0:6b5a3a0138ad | 182 | } |
mzling | 0:6b5a3a0138ad | 183 | |
mzling | 0:6b5a3a0138ad | 184 | /*void checkUI_XBee() |
mzling | 0:6b5a3a0138ad | 185 | { |
mzling | 0:6b5a3a0138ad | 186 | |
mzling | 0:6b5a3a0138ad | 187 | _buttonA_prev = _buttonA; |
mzling | 0:6b5a3a0138ad | 188 | buttonB_prev = buttonB; |
mzling | 0:6b5a3a0138ad | 189 | while (xbeeUI.readable() && _dataCnt<250) { |
mzling | 0:6b5a3a0138ad | 190 | __xbeeBuffer[_dataCnt] = xbeeUI.getc(); |
mzling | 0:6b5a3a0138ad | 191 | _dataCnt++; |
mzling | 0:6b5a3a0138ad | 192 | if (__xbeeBuffer[_dataCnt]==0x7e) { |
mzling | 0:6b5a3a0138ad | 193 | for(int i=0; i<22; i++) { |
mzling | 0:6b5a3a0138ad | 194 | if(xbeeUI.readable() { |
mzling | 0:6b5a3a0138ad | 195 | __xbeeBuffer[_dataCnt] = xbeeUI.getc(); |
mzling | 0:6b5a3a0138ad | 196 | _dataCnt++; |
mzling | 0:6b5a3a0138ad | 197 | } |
mzling | 0:6b5a3a0138ad | 198 | } |
mzling | 0:6b5a3a0138ad | 199 | } |
mzling | 0:6b5a3a0138ad | 200 | char * idx=strchr(__xbeeBuffer,0x7e); |
mzling | 0:6b5a3a0138ad | 201 | _buttonA = (_xbeeBuffer[idx-_xbeeBuffer+21]>>1) & 1; // on DIO1 |
mzling | 0:6b5a3a0138ad | 202 | buttonB = (_xbeeBuffer[idx-_xbeeBuffer+21]>>2) & 1; // on DIO2 |
mzling | 0:6b5a3a0138ad | 203 | pc.printf("%x\r\n", *(idx+2)); |
mzling | 0:6b5a3a0138ad | 204 | _dataCnt=0; |
mzling | 0:6b5a3a0138ad | 205 | if (buttonA == 0 && buttonA_prev==1) {//buton was just pressed |
mzling | 0:6b5a3a0138ad | 206 | time_pressA.reset(); |
mzling | 0:6b5a3a0138ad | 207 | time_pressA.start(); |
mzling | 0:6b5a3a0138ad | 208 | _time_sinceA=0; |
mzling | 0:6b5a3a0138ad | 209 | } |
mzling | 0:6b5a3a0138ad | 210 | |
mzling | 0:6b5a3a0138ad | 211 | else if(buttonA==0) { |
mzling | 0:6b5a3a0138ad | 212 | _time_sinceA=time_pressA; //button is still pressed |
mzling | 0:6b5a3a0138ad | 213 | } |
mzling | 0:6b5a3a0138ad | 214 | |
mzling | 0:6b5a3a0138ad | 215 | if (buttonB == 0 && buttonB_prev==1) {//button was just pressed |
mzling | 0:6b5a3a0138ad | 216 | time_pressB.reset(); |
mzling | 0:6b5a3a0138ad | 217 | time_pressB.start(); |
mzling | 0:6b5a3a0138ad | 218 | _time_sinceB=0; |
mzling | 0:6b5a3a0138ad | 219 | } else if(buttonB==0) { |
mzling | 0:6b5a3a0138ad | 220 | _time_sinceB=time_pressB; //button is still pressed |
mzling | 0:6b5a3a0138ad | 221 | } |
mzling | 0:6b5a3a0138ad | 222 | } |
mzling | 0:6b5a3a0138ad | 223 | if((time_pressA-_time_sinceA)>=tRelease) { //button was released |
mzling | 0:6b5a3a0138ad | 224 | if(time_pressA-tRelease>=tHold) { //if the button was held before released |
mzling | 0:6b5a3a0138ad | 225 | UI=3; //UI command is a held A button |
mzling | 0:6b5a3a0138ad | 226 | } else { |
mzling | 0:6b5a3a0138ad | 227 | UI=1; //UI command is a pressed A button |
mzling | 0:6b5a3a0138ad | 228 | } |
mzling | 0:6b5a3a0138ad | 229 | buttonA=1; //button A is released |
mzling | 0:6b5a3a0138ad | 230 | time_pressA.stop(); //reset the button A timer |
mzling | 0:6b5a3a0138ad | 231 | time_pressA.reset(); |
mzling | 0:6b5a3a0138ad | 232 | } |
mzling | 0:6b5a3a0138ad | 233 | if(time_pressB-_time_sinceB>=tRelease) { //button was released |
mzling | 0:6b5a3a0138ad | 234 | if(time_pressB-tRelease>=tHold) { //if the button was held before released |
mzling | 0:6b5a3a0138ad | 235 | UI=4; //UI command is a held B button |
mzling | 0:6b5a3a0138ad | 236 | } else { |
mzling | 0:6b5a3a0138ad | 237 | UI=2; //UI command is a pressed B button |
mzling | 0:6b5a3a0138ad | 238 | } |
mzling | 0:6b5a3a0138ad | 239 | buttonB=1; //button B is released |
mzling | 0:6b5a3a0138ad | 240 | time_pressB.stop(); //reset the button B timer |
mzling | 0:6b5a3a0138ad | 241 | time_pressB.reset(); |
mzling | 0:6b5a3a0138ad | 242 | } |
mzling | 0:6b5a3a0138ad | 243 | |
mzling | 0:6b5a3a0138ad | 244 | _dataCnt=0; |
mzling | 0:6b5a3a0138ad | 245 | memset(__xbeeBuffer,0xF,250); |
mzling | 0:6b5a3a0138ad | 246 | }*/ |
mzling | 0:6b5a3a0138ad | 247 | |
mzling | 0:6b5a3a0138ad | 248 | void UserInterface::initializeUI() |
mzling | 0:6b5a3a0138ad | 249 | { |
mzling | 0:6b5a3a0138ad | 250 | xbeeUI.baud(115200); |
mzling | 0:6b5a3a0138ad | 251 | mainPower = 0; |
mzling | 0:6b5a3a0138ad | 252 | |
mzling | 0:6b5a3a0138ad | 253 | } |