Hello, I need help on my project to implement data markers, parsing, and clearing any leftover data on the serial buffer every single loop. I intend to use this program as a receiver and controller for a ground drone.
Here is a copy of my code:
// Receive with start- and end-markers combined with parsing
const byte maxDataLength = 12;
char receivedData[maxDataLength];
char tempData[maxDataLength]; // temporary array for use by strtok() function
// variables to hold the parsed data
int pin = '\0';
int value = 0;
boolean newData = false;
int pins [] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int pinsize = 11;
//============
void setup() {
for(int a=0; a<pinsize; a++){
pinMode(pins[a], OUTPUT);
}
Serial.begin(9600);
//Serial.setTimeout(20);
Serial.print(F("This program expects 2 pieces of data, the pin number, "));
Serial.print(F("and value (0 to 255 for PWM, 0 and positive integer for digital"));
Serial.println(F(" enter data in this style <pin, value>. PWM Pins are 3, 5, 6, 9, 10, 11"));
Serial.println(F("Ready for command"));
Serial.println();
}
//============
void loop() {
int p;
checkData();
if (newData == true) {
strcpy(tempData, receivedData); //copy the recievedChars to tempChars
// this temporary copy is necessary to protect the original data
// because strtok() replaces the commas with \0
parseData();
showParsedData();
p=pin-2;
if ((p != 1)||(p != 3)||(p != 4)||(p != 7)||(p != 8)||(p != 9)){
if (value != 0){
digitalWrite(pins[p], HIGH);
}
else{
digitalWrite(pins[p], LOW);
}
}
else{
analogWrite(pins[p], value);
}
newData = false;
}
int a = Serial.read();
Serial.flush();
a = '\0';
}
//============
void checkData() {
static boolean receiving = false;
static byte n = 0;
char startMarker = '<';
char endMarker = '>';
char c;
while (Serial.available() > 0 && newData == false) {
c = Serial.read();
if (receiving == true) { // this one is the second
if (c != endMarker) {
receivedData[n] = c;
n++;
if (n >= maxDataLength) {
n = maxDataLength - 1;
}
}
else { //this is the last, notice the while loop loser on the newData=true
receivedData[n] = '\0'; //clear the data that is now unused
receiving = false;
n = 0;
newData = true;
}
}
else if (c == startMarker) { //this one gets executed first, recvInProgress = true, and then the while do the loop, resulting the if(recvInProgress -- true) started
receiving = true;
}
}
}
//============
void parseData() {
// split the data into its parts
char * indx; // this is used by strtok() as an index
indx = strtok(tempData, ","); // get the first part - the pin number
pin = atoi(indx);
indx = strtok(NULL, ","); // this continues where the previous call left off
value = atoi(indx); // convert this part to an integer
}
//============
void showParsedData() {
Serial.print("Pin = ");
Serial.println(pin);
Serial.print("Value = ");
Serial.println(value);
}
// http://forum.arduino.cc/index.php?topic=288234.60 , page 5
// credits to Robin2 http://forum.arduino.cc/index.php?action=profile;u=174714, for the tutorial about parsing and using marker, also the piece of code
Which is an "upgrade" from this code:
// Receive with start- and end-markers combined with parsing
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use by strtok() function
// variables to hold the parsed data
int pin = '\0';
int value = 0;
boolean newData = false;
int pins []={2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int pinsize= 11;
//============
void setup() {
for(int a=0; a<pinsize; a++){
pinMode(pins[a], OUTPUT);
}
Serial.begin(9600);
Serial.println("This operation expects 2 pieces of data, the pin number (PWM), and value (0 to 255)");
Serial.println("Enter data in this style <pin, value>. Only PWM Pins, which is pin 3, 5, 6, 9, 10, 11");
Serial.println();
}
//============
void loop() {
int p;
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars); //copy the recievedChars to tempChars
// this temporary copy is necessary to protect the original data
// because strtok() replaces the commas with \0
parseData();
showParsedData();
p=pin-2;
analogWrite(pins[p], value);
newData = false;
}
}
//============
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) { // this one is the second
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else { //this is the last, notice the while loop loser on the newData=true
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) { //this one gets executed first, recvInProgress = true, and then the while do the loop, resulting the if(recvInProgress -- true) started
recvInProgress = true;
}
}
}
//============
void parseData() {
// split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ","); // get the first part - the pin number
pin = atoi(strtokIndx);
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
value = atoi(strtokIndx); // convert this part to an integer
}
//============
void showParsedData() {
Serial.print("Pin = ");
Serial.println(pin);
Serial.print("Value = ");
Serial.println(value);
}
// http://forum.arduino.cc/index.php?topic=288234.60 , page 5
// credits to Robin2 http://forum.arduino.cc/index.php?action=profile;u=174714, for the tutorial about parsing and using marker, also the piece of code
Sorry a long one
The main point of "upgrading" the code is to extend the control so the digital pins can be used and adding reliability to the serial buffer so it automatically dump every junk/garbled data that is received, so the arduino can stand by for a longer time.
However, there are problems in the "improved" code, that the data is not sent back to the serial monitor, or sent back incorrectly (which means that the program did not do as intended), as the picture in attachment
Picture 1: the data sent is <2, 1>
Picture 2: the data sent is <3, 255> (no reply), <2, 1> (first reply), and <2,1> (second reply). Further sending <2,1>, <3,255> results in no replies).
There is no compiler error, and the LEDs I used for testing did not light up either (obviously).
Will post the build cabling later as I do not have fritzing installed yet.
Any help is greatly appreciated!!