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