Serial Packet Handler
Dependencies: mbed MbedJSONValue
main.cpp@3:632a7590a341, 2018-01-15 (annotated)
- Committer:
- Arkadi
- Date:
- Mon Jan 15 12:46:23 2018 +0000
- Revision:
- 3:632a7590a341
- Parent:
- 2:c887a1b1b762
minor changes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Arkadi | 0:6080c5029b3f | 1 | //////////////////////////////////////// |
Arkadi | 2:c887a1b1b762 | 2 | // Serial Packet - MbedJsonValue // |
Arkadi | 2:c887a1b1b762 | 3 | // Arkadiraf@gmail.com - 15/06/2017 // |
Arkadi | 0:6080c5029b3f | 4 | //////////////////////////////////////// |
Arkadi | 0:6080c5029b3f | 5 | /* |
Arkadi | 0:6080c5029b3f | 6 | Construct packet from uart and parse with json format |
Arkadi | 0:6080c5029b3f | 7 | json:<PACKET>\r\n |
Arkadi | 3:632a7590a341 | 8 | test with |
Arkadi | 3:632a7590a341 | 9 | json:{"my_array": ["demo_string", 10], "my_boolean": true} |
Arkadi | 0:6080c5029b3f | 10 | */ |
Arkadi | 0:6080c5029b3f | 11 | |
Arkadi | 0:6080c5029b3f | 12 | /* |
Arkadi | 0:6080c5029b3f | 13 | Board : Nucleo STM32F446RE |
Arkadi | 0:6080c5029b3f | 14 | */ |
Arkadi | 0:6080c5029b3f | 15 | |
Arkadi | 0:6080c5029b3f | 16 | /* |
Arkadi | 0:6080c5029b3f | 17 | Pinout: |
Arkadi | 0:6080c5029b3f | 18 | PC - Serial 2 |
Arkadi | 0:6080c5029b3f | 19 | PA_2 (Tx) --> STLINK |
Arkadi | 0:6080c5029b3f | 20 | PA_3 (Rx) --> STLINK |
Arkadi | 0:6080c5029b3f | 21 | */ |
Arkadi | 0:6080c5029b3f | 22 | |
Arkadi | 1:711a27baa42d | 23 | |
Arkadi | 0:6080c5029b3f | 24 | /////////////// |
Arkadi | 0:6080c5029b3f | 25 | // Libraries // |
Arkadi | 0:6080c5029b3f | 26 | /////////////// |
Arkadi | 0:6080c5029b3f | 27 | #include "mbed.h" |
Arkadi | 1:711a27baa42d | 28 | #include "MbedJSONValue.h" |
Arkadi | 1:711a27baa42d | 29 | #include <string> |
Arkadi | 1:711a27baa42d | 30 | |
Arkadi | 0:6080c5029b3f | 31 | //#include "BufferedSerial.h" // uart handler library |
Arkadi | 0:6080c5029b3f | 32 | /////////////// |
Arkadi | 0:6080c5029b3f | 33 | // #defines // |
Arkadi | 0:6080c5029b3f | 34 | /////////////// |
Arkadi | 0:6080c5029b3f | 35 | |
Arkadi | 0:6080c5029b3f | 36 | #define DEBUG_MOD1 |
Arkadi | 0:6080c5029b3f | 37 | #define MSG_BUFFER_SIZE 512 |
Arkadi | 0:6080c5029b3f | 38 | #define HEADER_SIZE 5 |
Arkadi | 0:6080c5029b3f | 39 | #define FOOTER_SIZE 2 |
Arkadi | 0:6080c5029b3f | 40 | |
Arkadi | 0:6080c5029b3f | 41 | ///////////// |
Arkadi | 0:6080c5029b3f | 42 | // Objects // |
Arkadi | 0:6080c5029b3f | 43 | ///////////// |
Arkadi | 0:6080c5029b3f | 44 | |
Arkadi | 0:6080c5029b3f | 45 | // uart |
Arkadi | 0:6080c5029b3f | 46 | Serial pc(USBTX, USBRX); |
Arkadi | 0:6080c5029b3f | 47 | |
Arkadi | 0:6080c5029b3f | 48 | // digital output |
Arkadi | 0:6080c5029b3f | 49 | DigitalOut led(PA_5); |
Arkadi | 0:6080c5029b3f | 50 | /////////////// |
Arkadi | 0:6080c5029b3f | 51 | // variables // |
Arkadi | 0:6080c5029b3f | 52 | /////////////// |
Arkadi | 0:6080c5029b3f | 53 | |
Arkadi | 0:6080c5029b3f | 54 | // json buffer |
Arkadi | 0:6080c5029b3f | 55 | char json[MSG_BUFFER_SIZE]; |
Arkadi | 0:6080c5029b3f | 56 | |
Arkadi | 0:6080c5029b3f | 57 | // packet variables |
Arkadi | 0:6080c5029b3f | 58 | struct packetMSG_struct { |
Arkadi | 0:6080c5029b3f | 59 | // recieve message variables |
Arkadi | 0:6080c5029b3f | 60 | uint8_t header[HEADER_SIZE]; |
Arkadi | 0:6080c5029b3f | 61 | uint8_t footer[FOOTER_SIZE]; |
Arkadi | 0:6080c5029b3f | 62 | uint8_t syncIndex; // sync index for header / footer |
Arkadi | 0:6080c5029b3f | 63 | uint8_t syncFlag; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer |
Arkadi | 0:6080c5029b3f | 64 | // buffer |
Arkadi | 0:6080c5029b3f | 65 | uint16_t bufferIndex; // buffer index |
Arkadi | 0:6080c5029b3f | 66 | uint8_t buffer[MSG_BUFFER_SIZE]; |
Arkadi | 0:6080c5029b3f | 67 | } ; |
Arkadi | 0:6080c5029b3f | 68 | packetMSG_struct packetMSG; |
Arkadi | 0:6080c5029b3f | 69 | /////////////// |
Arkadi | 0:6080c5029b3f | 70 | // Functions // |
Arkadi | 0:6080c5029b3f | 71 | /////////////// |
Arkadi | 0:6080c5029b3f | 72 | |
Arkadi | 0:6080c5029b3f | 73 | // Serial Event function |
Arkadi | 0:6080c5029b3f | 74 | void rxCallback(void); |
Arkadi | 0:6080c5029b3f | 75 | |
Arkadi | 0:6080c5029b3f | 76 | // initialize packet struct |
Arkadi | 0:6080c5029b3f | 77 | void initPacket(void); |
Arkadi | 1:711a27baa42d | 78 | |
Arkadi | 1:711a27baa42d | 79 | // Packet Parser |
Arkadi | 1:711a27baa42d | 80 | void parsePacket(void); |
Arkadi | 0:6080c5029b3f | 81 | //////////////////////// |
Arkadi | 0:6080c5029b3f | 82 | // Main Code Setup : // |
Arkadi | 0:6080c5029b3f | 83 | //////////////////////// |
Arkadi | 0:6080c5029b3f | 84 | int main() |
Arkadi | 0:6080c5029b3f | 85 | { |
Arkadi | 0:6080c5029b3f | 86 | // init packet: |
Arkadi | 0:6080c5029b3f | 87 | initPacket(); |
Arkadi | 0:6080c5029b3f | 88 | // init uart |
Arkadi | 0:6080c5029b3f | 89 | pc.baud(57600); |
Arkadi | 0:6080c5029b3f | 90 | // attach serial event interrupt |
Arkadi | 0:6080c5029b3f | 91 | pc.attach(&rxCallback, Serial::RxIrq); |
Arkadi | 0:6080c5029b3f | 92 | |
Arkadi | 0:6080c5029b3f | 93 | #ifdef DEBUG_MOD1 |
Arkadi | 0:6080c5029b3f | 94 | pc.printf("UART Test \r\n"); |
Arkadi | 0:6080c5029b3f | 95 | #endif |
Arkadi | 0:6080c5029b3f | 96 | /////////////////////// |
Arkadi | 0:6080c5029b3f | 97 | // Main Code Loop : // |
Arkadi | 0:6080c5029b3f | 98 | /////////////////////// |
Arkadi | 0:6080c5029b3f | 99 | while(1) { |
Arkadi | 0:6080c5029b3f | 100 | //sleep(); |
Arkadi | 0:6080c5029b3f | 101 | }// end main loop |
Arkadi | 0:6080c5029b3f | 102 | }// end main |
Arkadi | 1:711a27baa42d | 103 | |
Arkadi | 1:711a27baa42d | 104 | |
Arkadi | 1:711a27baa42d | 105 | |
Arkadi | 0:6080c5029b3f | 106 | /////////////// |
Arkadi | 0:6080c5029b3f | 107 | // Functions // |
Arkadi | 0:6080c5029b3f | 108 | /////////////// |
Arkadi | 0:6080c5029b3f | 109 | |
Arkadi | 0:6080c5029b3f | 110 | // Serial Event function |
Arkadi | 0:6080c5029b3f | 111 | void rxCallback(void) |
Arkadi | 0:6080c5029b3f | 112 | { |
Arkadi | 0:6080c5029b3f | 113 | while (pc.readable()) { |
Arkadi | 0:6080c5029b3f | 114 | // read icoming |
Arkadi | 0:6080c5029b3f | 115 | led = !led; |
Arkadi | 0:6080c5029b3f | 116 | uint8_t in_byte = pc.getc(); |
Arkadi | 0:6080c5029b3f | 117 | #ifdef DEBUG_MOD1 |
Arkadi | 0:6080c5029b3f | 118 | pc.putc(in_byte); |
Arkadi | 0:6080c5029b3f | 119 | #endif |
Arkadi | 0:6080c5029b3f | 120 | // detect start message , end message |
Arkadi | 0:6080c5029b3f | 121 | switch (packetMSG.syncFlag) { |
Arkadi | 0:6080c5029b3f | 122 | // waiting for header |
Arkadi | 0:6080c5029b3f | 123 | case 0: { |
Arkadi | 0:6080c5029b3f | 124 | if (packetMSG.header[packetMSG.syncIndex] == in_byte) { |
Arkadi | 0:6080c5029b3f | 125 | packetMSG.syncIndex++; |
Arkadi | 0:6080c5029b3f | 126 | if (packetMSG.syncIndex == HEADER_SIZE) { // finish header SYNC |
Arkadi | 0:6080c5029b3f | 127 | packetMSG.syncFlag = 1; // start collecting data, wait for footer |
Arkadi | 0:6080c5029b3f | 128 | packetMSG.bufferIndex = 0; |
Arkadi | 0:6080c5029b3f | 129 | packetMSG.syncIndex=0; |
Arkadi | 0:6080c5029b3f | 130 | } |
Arkadi | 0:6080c5029b3f | 131 | } else { // reinit sync |
Arkadi | 0:6080c5029b3f | 132 | packetMSG.syncIndex=0; |
Arkadi | 0:6080c5029b3f | 133 | } |
Arkadi | 0:6080c5029b3f | 134 | //pc.printf("case 0 , %d \r\n",packetMSG.syncIndex); |
Arkadi | 0:6080c5029b3f | 135 | break; |
Arkadi | 1:711a27baa42d | 136 | } |
Arkadi | 0:6080c5029b3f | 137 | // waiting for footer |
Arkadi | 0:6080c5029b3f | 138 | case 1: { |
Arkadi | 0:6080c5029b3f | 139 | // add byte to buffer |
Arkadi | 0:6080c5029b3f | 140 | packetMSG.buffer[packetMSG.bufferIndex] = in_byte; |
Arkadi | 0:6080c5029b3f | 141 | packetMSG.bufferIndex++; |
Arkadi | 0:6080c5029b3f | 142 | if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow |
Arkadi | 0:6080c5029b3f | 143 | // reset buffer |
Arkadi | 0:6080c5029b3f | 144 | packetMSG.bufferIndex = 0; |
Arkadi | 0:6080c5029b3f | 145 | packetMSG.syncIndex = 0; |
Arkadi | 0:6080c5029b3f | 146 | packetMSG.syncFlag = 0; |
Arkadi | 0:6080c5029b3f | 147 | } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved |
Arkadi | 0:6080c5029b3f | 148 | packetMSG.syncIndex++; |
Arkadi | 0:6080c5029b3f | 149 | packetMSG.syncFlag=2; // move to verify footer |
Arkadi | 0:6080c5029b3f | 150 | } |
Arkadi | 0:6080c5029b3f | 151 | //pc.printf("case 2 , %d \r\n",packetMSG.syncIndex); |
Arkadi | 0:6080c5029b3f | 152 | break; |
Arkadi | 1:711a27baa42d | 153 | } |
Arkadi | 0:6080c5029b3f | 154 | // verify footer |
Arkadi | 0:6080c5029b3f | 155 | case 2: { |
Arkadi | 0:6080c5029b3f | 156 | // add byte to buffer |
Arkadi | 0:6080c5029b3f | 157 | packetMSG.buffer[packetMSG.bufferIndex] = in_byte; |
Arkadi | 0:6080c5029b3f | 158 | packetMSG.bufferIndex++; |
Arkadi | 0:6080c5029b3f | 159 | if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow |
Arkadi | 0:6080c5029b3f | 160 | // reset buffer |
Arkadi | 0:6080c5029b3f | 161 | packetMSG.bufferIndex = 0; |
Arkadi | 0:6080c5029b3f | 162 | packetMSG.syncIndex = 0; |
Arkadi | 0:6080c5029b3f | 163 | packetMSG.syncFlag = 0; |
Arkadi | 0:6080c5029b3f | 164 | } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved |
Arkadi | 0:6080c5029b3f | 165 | packetMSG.syncIndex++; |
Arkadi | 0:6080c5029b3f | 166 | if (packetMSG.syncIndex == FOOTER_SIZE) { // finish footer SYNC |
Arkadi | 0:6080c5029b3f | 167 | packetMSG.syncFlag = 3; |
Arkadi | 1:711a27baa42d | 168 | // copy packet to json buffer |
Arkadi | 0:6080c5029b3f | 169 | memcpy (&json, &packetMSG.buffer, packetMSG.bufferIndex); |
Arkadi | 1:711a27baa42d | 170 | json[packetMSG.bufferIndex]=NULL; // end with NULL to indicate end of string |
Arkadi | 0:6080c5029b3f | 171 | // copy packet to json buffer with sprintf |
Arkadi | 0:6080c5029b3f | 172 | //sprintf(json, "%.*s", packetMSG.bufferIndex, packetMSG.buffer ); |
Arkadi | 0:6080c5029b3f | 173 | // send msg to parse. |
Arkadi | 1:711a27baa42d | 174 | parsePacket(); |
Arkadi | 0:6080c5029b3f | 175 | // reset buffer |
Arkadi | 0:6080c5029b3f | 176 | packetMSG.bufferIndex = 0; |
Arkadi | 0:6080c5029b3f | 177 | packetMSG.syncIndex = 0; |
Arkadi | 0:6080c5029b3f | 178 | packetMSG.syncFlag = 0; |
Arkadi | 0:6080c5029b3f | 179 | } |
Arkadi | 0:6080c5029b3f | 180 | } else { // footer broke restart wait for footer |
Arkadi | 0:6080c5029b3f | 181 | packetMSG.syncFlag=1; |
Arkadi | 0:6080c5029b3f | 182 | // verify that it didnt broke on first footer char |
Arkadi | 0:6080c5029b3f | 183 | if (packetMSG.footer[0] == in_byte) { |
Arkadi | 0:6080c5029b3f | 184 | packetMSG.syncIndex=1; |
Arkadi | 0:6080c5029b3f | 185 | } else { |
Arkadi | 0:6080c5029b3f | 186 | packetMSG.syncIndex=0; |
Arkadi | 0:6080c5029b3f | 187 | } |
Arkadi | 0:6080c5029b3f | 188 | } |
Arkadi | 0:6080c5029b3f | 189 | break; |
Arkadi | 1:711a27baa42d | 190 | } |
Arkadi | 0:6080c5029b3f | 191 | default: { |
Arkadi | 0:6080c5029b3f | 192 | pc.printf("Sonmething went wrong \r\n"); |
Arkadi | 0:6080c5029b3f | 193 | break; |
Arkadi | 0:6080c5029b3f | 194 | } |
Arkadi | 0:6080c5029b3f | 195 | } // end switch |
Arkadi | 0:6080c5029b3f | 196 | }// end uart readable |
Arkadi | 0:6080c5029b3f | 197 | } // end rxCallback |
Arkadi | 0:6080c5029b3f | 198 | |
Arkadi | 0:6080c5029b3f | 199 | |
Arkadi | 0:6080c5029b3f | 200 | // initialize packet struct |
Arkadi | 0:6080c5029b3f | 201 | void initPacket(void) |
Arkadi | 0:6080c5029b3f | 202 | { |
Arkadi | 0:6080c5029b3f | 203 | // init variables to default: |
Arkadi | 0:6080c5029b3f | 204 | packetMSG.header[0] = 'j'; |
Arkadi | 0:6080c5029b3f | 205 | packetMSG.header[1] = 's'; |
Arkadi | 0:6080c5029b3f | 206 | packetMSG.header[2] = 'o'; |
Arkadi | 0:6080c5029b3f | 207 | packetMSG.header[3] = 'n'; |
Arkadi | 0:6080c5029b3f | 208 | packetMSG.header[4] = ':'; |
Arkadi | 0:6080c5029b3f | 209 | |
Arkadi | 0:6080c5029b3f | 210 | packetMSG.footer[0]= 13; // /r |
Arkadi | 0:6080c5029b3f | 211 | packetMSG.footer[1]= 10; // /n |
Arkadi | 0:6080c5029b3f | 212 | |
Arkadi | 0:6080c5029b3f | 213 | packetMSG.syncIndex=0; // sync index for header / footer |
Arkadi | 0:6080c5029b3f | 214 | packetMSG.syncFlag=0; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer |
Arkadi | 0:6080c5029b3f | 215 | packetMSG.bufferIndex=0; // buffer index |
Arkadi | 1:711a27baa42d | 216 | } |
Arkadi | 1:711a27baa42d | 217 | |
Arkadi | 1:711a27baa42d | 218 | // Packet Parser |
Arkadi | 1:711a27baa42d | 219 | void parsePacket(void) |
Arkadi | 1:711a27baa42d | 220 | { |
Arkadi | 1:711a27baa42d | 221 | #ifdef DEBUG_MOD1 |
Arkadi | 1:711a27baa42d | 222 | // write buffer to screen |
Arkadi | 1:711a27baa42d | 223 | //pc.printf("%d, %.*s", packetMSG.bufferIndex ,packetMSG.bufferIndex, packetMSG.buffer ); |
Arkadi | 1:711a27baa42d | 224 | pc.printf("%s", json); |
Arkadi | 1:711a27baa42d | 225 | #endif |
Arkadi | 1:711a27baa42d | 226 | |
Arkadi | 3:632a7590a341 | 227 | MbedJSONValue demo; |
Arkadi | 1:711a27baa42d | 228 | |
Arkadi | 3:632a7590a341 | 229 | //const char * json = "{\"my_array\": [\"demo_string\", 10], \"my_boolean\": true}"; |
Arkadi | 3:632a7590a341 | 230 | // json:{"my_array": ["demo_string", 10], "my_boolean": true} |
Arkadi | 3:632a7590a341 | 231 | //parse the previous string and fill the object demo |
Arkadi | 3:632a7590a341 | 232 | parse(demo, json); |
Arkadi | 1:711a27baa42d | 233 | |
Arkadi | 3:632a7590a341 | 234 | std::string my_str; |
Arkadi | 3:632a7590a341 | 235 | int my_int; |
Arkadi | 3:632a7590a341 | 236 | bool my_bool; |
Arkadi | 1:711a27baa42d | 237 | |
Arkadi | 3:632a7590a341 | 238 | my_str = demo["my_array"][0].get<std::string>(); |
Arkadi | 3:632a7590a341 | 239 | my_int = demo["my_array"][1].get<int>(); |
Arkadi | 3:632a7590a341 | 240 | my_bool = demo["my_boolean"].get<bool>(); |
Arkadi | 3:632a7590a341 | 241 | |
Arkadi | 3:632a7590a341 | 242 | printf("my_str: %s\r\n", my_str.c_str()); |
Arkadi | 3:632a7590a341 | 243 | printf("my_int: %d\r\n", my_int); |
Arkadi | 3:632a7590a341 | 244 | printf("my_bool: %s\r\n", my_bool ? "true" : "false"); |
Arkadi | 3:632a7590a341 | 245 | |
Arkadi | 0:6080c5029b3f | 246 | } |