Very simple bytestuffed protocolThe version here is crafted so it can be tested on an Arduino Should be easy portable Jens byteStuff on Ard no 1// JDN oct 2024 // simple byte stuffing protocol // WARNING: no check on timeout in rx as well as tx // // NB tx and RX buf size is 64 on ardino uno and mega // // bytestuff is inserted and removed on the fly so ... // SPECIAL: // In the example we use TX and RX on Serial "1" port - the same port // So for test you have to connect TX and RX pins // On an UNO its pin 0 and 1 // WHEN UPLOADING REMOVE THE CONNECTION OTHERWISE UPLOAD FAIL // //vrs 0.13 // start of frame delimiter - is inserted automaticly #define SOT '[' // end of frame delimiter - is inserted automaticly #define EOT ']' // Byte stuffing value #define STUFFBYTE 'S' // nr of restart in rxPkg if a SOT occurs after forst SOT and before the wanted EOT #define NRRESTART 1 // define rx and tx ports #define TXPORT Serial #define RXPORT Serial //----------------------------------------------- // tx pgk lgt do not include SOF and EOF void txPkg(const char *src, int lgt) { char b; //1. txSOF TXPORT.write(SOT); //2: tx message while (0 < lgt) { b = *src; switch (b) { case SOT: // bytesstuffing now ? case EOT: // just add more chars if needed case STUFFBYTE: b = ~b; TXPORT.write(STUFFBYTE); TXPORT.write(b); break; default: TXPORT.write(b); } lgt--; if (0 < lgt) src++; } //3. tx EOT TXPORT.write(EOT); } //---- void emptyRxBuf() { delay(100); // why ?? dont know ! :-) while (RXPORT.available()) RXPORT.read(); } uint8_t getNextByte() { char b; while (RXPORT.available() < 1) ; b = RXPORT.read(); return (b); } int rxPkg(uint8_t *dest, int maxLgt) { int bytesRcv = 0; uint8_t b, noRestart; uint8_t *p; noRestart = NRRESTART; p = dest; //1. read SOT - start of Frame while (1) { b = getNextByte(); if (b == SOT) break; } //2. assumption EOF is not in tlg - only as EOF // read message and EOT // NB if your buffer fills up before EOT is received length returned is negative while (1) { b = getNextByte(); //hm lost EOT so start on next pkg if (SOT == b) { // start again noRestart--; if (noRestart < 0) { bytesRcv = -9999; goto outhere; } p = dest; bytesRcv = 0; break; } if (EOT == b) { goto outhere; } else { if (b == STUFFBYTE) { b = getNextByte(); // drop stuff Symbol and get next char b = ~b; //destuff// -------------------- } *p = b; p++; bytesRcv++; // rx user buffer full ? if (maxLgt <= bytesRcv) { bytesRcv = -bytesRcv; // negativ value indicates for caller buffer full goto outhere; // before we did get EOT !! } } } // 3. return nr of bytes rcv not including SOF and EOF outhere: return bytesRcv; } uint8_t rcvBuf[100]; char bf[] = "1234S45[]0"; int nrRcv = 0; void setup() { Serial.begin(115200); Serial.println("\n----"); Serial.println(__FILE__); Serial.println(__DATE__); Serial.println(sizeof(bf)); Serial.println("--<>--"); delay(100); // empty buf emptyRxBuf(); delay(500); //test txPkg(bf, sizeof(bf)); delay(500); nrRcv = rxPkg(rcvBuf, 100); delay(100); // results of test Serial.println("\n---after test"); Serial.print("tx: "); Serial.println(sizeof(bf)); Serial.print("rx: "); Serial.println(nrRcv); if (nrRcv == sizeof(bf)) Serial.println("same number of chr received as transmitted"); else Serial.println("did not receive same number as transmitted"); Serial.println((char *)rcvBuf); Serial.println("--eof"); } void loop() {} |