Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #15 on: May 08, 2012, 08:10:19 am » |
Okay, everything works now. Thanks for the advice! Now I have another problem. I would like to seperate the parts, I did it by the strtok() like you guys told me, but how is it possible to get everything like: var1 = $IIMWV var2 = 225.0 var3 = R etc (this is the string: $IIMWV,225.0,R,000.0,N,A*38) I can have it printed this way, but doesn't the data get's overwrited every cycle? This is the program I made to test it, so I don't mess up my main one. #include <string.h>
char *data; char delimiters[] = ",";
void setup() { Serial.begin(9600); }
void loop() { char anemometer[] = "$IIMWV,225.0,R,000.0,N,A*38";
data = strtok(anemometer, delimiters);
while (data != NULL) { delay(500); Serial.println(data); data = strtok(NULL, delimiters); } delay(1000); }
my goal is to work like this: if the start of the string = var1 ($IIMWV) write var2(225.0) to somewhere, var3(R) somewhere, etc This way I can compare the vars, and make decisions whether it is correct, or use them to calculate other things. I also tried out the atoi function to get the int's out of it, but here I have the same problem. How can I write them away so that I can process it? I will post the main program, the one that is working, later when I get back home. Already thanks for all the useful advice! Ben
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35493
Seattle, WA USA
|
 |
« Reply #16 on: May 08, 2012, 08:24:31 am » |
my goal is to work like this: if the start of the string = var1 ($IIMWV) if(strcmp(data, "$IIMWV") == 0) { } write var2(225.0) to somewhere, var3(R) somewhere, etc data = strtok(NULL, delimiters); float rVal = atof(data);
data = strtok(NULL, delimiters); strcpy(var3, data); I also tried out the atoi function to get the int's out of it 225.0 is not an int. It is a float. How can I write them away so that I can process it? That depends on how long you need to persist the values.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #17 on: May 08, 2012, 08:33:51 am » |
Thanks, I did just stumbled upon something likewise and tried it: #include <string.h>
char *data; char delimiters[] = ","; char *a; char *b; char *c; char *d;
void setup() { Serial.begin(9600); }
void loop() { char anemometer[] = "$IIMWV,225.0,R,000.0,N,A*38";
a = strtok(anemometer, delimiters); b = strtok(NULL, delimiters); c = strtok(NULL, delimiters); d = strtok(NULL, delimiters);
{ delay(500); Serial.println(a); Serial.println(b); Serial.println(c); Serial.println(d); data = strtok(NULL, delimiters); } delay(1000); }
But I will try it your way (it looks quite the same). And now I finally understand the strtok function totally. And indeed, I did meant float  , srry about that. Thanks again!
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #18 on: May 10, 2012, 02:41:20 am » |
Okay, atm I have almost whole the program finished for reading in the values and printing out what needs to be visualized. The only problem I still have is the checksum. This is the problem: I have the string: $IIMWV,225.0,R,000.0,N,A*38 The 38 is the bitwise XOR function of every character between $ and * I stored that solution into an int called CheckSum. If I print the the CheckSum like -> Serial.println(CheckSum, HEX); I will get the 38. The real problem is, how can I compare the 38 that I have like 2 characters from the string (With the atoi function I can make it into an int) with the CheckSum which is still an int (HEX 38 = int 56)? Because there isn't an atoh function (I think?), how is it possible to compare these? I hope you understand what I mean. The program: (probably not the best solution to everything, like the bitwise XOR. But it works  #include <string.h>
// Reading String char InputChar = 0; char AnemometerString[27]; int index = 0;
//Dividing String char Delimiters[] = "$,*"; char *StringPart1; char *StringPart2; char *StringPart3; char *StringPart4; char *StringPart5; char *StringPart6; char *StringPart7; int CheckSum = 0;
//Processing String Parts float WindAngle = 0; float WindSpeed = 0; char *RelativeReference = "R"; char *True = "T"; char *Knots = "N"; char *KMH = "K"; char *MPH = "M"; char *Available = "A"; char *Alarm = "V";
void setup() { Serial2.begin(9600); Serial.begin(9600); Serial.println("Power on"); }
void loop() { if (Serial2.available() > 0) // If the serial input gets information => do the next { InputChar = Serial2.read(); AnemometerString[index] = InputChar; index++; AnemometerString[index] = '\0'; if ( InputChar == '\n') { AnemometerString[index] = '\0'; }
if (index == 27) { int CheckSum = AnemometerString[1] ^ AnemometerString[2] ^ AnemometerString[3] ^ AnemometerString[4] ^ AnemometerString[5] ^ AnemometerString[6] ^ AnemometerString[7] ^ AnemometerString[8] ^ AnemometerString[9] ^ AnemometerString[10] ^ AnemometerString[11] ^ AnemometerString[12] ^ AnemometerString[13] ^ AnemometerString[14] ^ AnemometerString[15] ^ AnemometerString[16] ^ AnemometerString[17] ^ AnemometerString[18] ^ AnemometerString[19] ^ AnemometerString[20] ^ AnemometerString[21] ^ AnemometerString[22] ^ AnemometerString[23]; Serial.print("The whole string: \t"); Serial.print(AnemometerString); Serial.println("\n"); StringPart1 = strtok(AnemometerString, Delimiters); StringPart2 = strtok(NULL, Delimiters); StringPart3 = strtok(NULL, Delimiters); StringPart4 = strtok(NULL, Delimiters); StringPart5 = strtok(NULL, Delimiters); StringPart6 = strtok(NULL, Delimiters); StringPart7 = strtok(NULL, Delimiters); int CheckSum2 = atoi(StringPart7); if (CheckSum == CheckSum2) { if (strcmp (StringPart1, "IIMWV") == 0) { Serial.print("The start sentence is: \t"); Serial.println(StringPart1); WindAngle = atof(StringPart2); WindSpeed = atof(StringPart4); if (strcmp(StringPart3, RelativeReference) == 0) { Serial.print("The windangle is: \t"); Serial.print(WindAngle); Serial.println(" Relative"); } else if (strcmp(StringPart3, True) == 0) { Serial.print("The windangle is: \t"); Serial.print(WindAngle); Serial.println(" true"); } else { Serial.println("Wrong windangle signal"); } if (strcmp(StringPart5, Knots) == 0) { Serial.print("The windspeed is: \t"); Serial.print(WindSpeed); Serial.println(" knots"); } else if (strcmp(StringPart5, KMH) == 0) { Serial.print("The windspeed is: \t"); Serial.print(WindSpeed); Serial.println(" km/h"); } else if (strcmp(StringPart5, MPH) == 0) { Serial.print("The windspeed is: \t"); Serial.print(WindSpeed); Serial.println(" mph"); } else { Serial.println("Wrong windspeed signal"); } if (strcmp(StringPart6, Available) == 0) { Serial.print("Total string: \t\t"); Serial.println("Available"); } else if (strcmp(StringPart6, Alarm) == 0) { Serial.print("The total string: \t\t"); Serial.println("Alarm!"); } else { Serial.println("Wrong status!"); } Serial.print("The checksum is: \t"); Serial.println(StringPart7); Serial.println("\n"); } else { Serial.println("Error, wrong input device \n"); } } index = 0; } } }
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35493
Seattle, WA USA
|
 |
« Reply #19 on: May 10, 2012, 05:23:59 am » |
The real problem is, how can I compare the 38 that I have like 2 characters from the string Converting the string "38" to an int, using atoi() won't help because the string is assumed to be in base 10, not base 16. You need to convert each character to a int yourself, knowing that it is base 16. If the character is between '0' and '9', the value is the character minus '0' ('3' - '0' = 3). If the character is between 'A' and 'F', the value is the character minus 'A' plus 10 ('D' - 'A' + 10 = 14). Then, multiply the first value by 16 and add the second value. Then, you can compare that value to the value in CheckSum.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Online
Brattain Member
Karma: 137
Posts: 19045
I don't think you connected the grounds, Dave.
|
 |
« Reply #20 on: May 10, 2012, 05:27:24 am » |
D' - 'A' + 10 = 14) sp. "13"
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35493
Seattle, WA USA
|
 |
« Reply #21 on: May 10, 2012, 05:31:05 am » |
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #22 on: May 10, 2012, 06:06:27 am » |
Haha, Ok. I'll try it that way.
Thanks
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #23 on: May 10, 2012, 07:16:20 am » |
This worked fine! Now I'll try to shorten my XOR function and then I will post the results. Thanks for all the advice! After this I can move on with the next program to use everything I got right now.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #24 on: May 16, 2012, 04:02:23 am » |
At first I wanna thank you guys for all your help! I really learned a lot. Here is my total program just if someone would like to know all the answers. (Don't mind the commentary, I needed to do it that much) Program for simulating the string the anemometer sends: void setup() { Serial.begin(9600); Serial2.begin(9600); }
void loop() { char anemometerString[] = "$IIMWV,225.0,R,000.0,N,A*38"; Serial.println(anemometerString); Serial2.write (anemometerString); delay(500); } Decoding and displaying the retrieved signal: /**************************************************************************** * Decoding the Anemometer string sent by the CV7-V sensor from LCJ capteurs * * This string will look like '$IIMWV,225.0,R,000.0,N,A*38' for example * ****************************************************************************/
//Include a library to use some extra functions #include <string.h>
// Reading String char InputChar = 0; char AnemometerString[50]; int index = 0;
//Dividing String char Delimiters[] = "$,*"; char *StringPart1; char *StringPart2; char *StringPart3; char *StringPart4; char *StringPart5; char *StringPart6; char *StringPart7;
//Checksum char ChecksumCalc = 0; int CharVal1 = 0; int CharVal2 = 0; int Checksum = 0; char AnemometerString2[27]; int index2 = 0;
//Processing String Parts float WindAngle = 0; float WindSpeed = 0; char *RelativeReference = "R"; char *True = "T"; char *Knots = "N"; char *KMH = "K"; char *MPH = "M"; char *Available = "A"; char *Alarm = "V";
// Setup the connection speed and show the monitor the Arduino is on void setup() { Serial2.begin(9600); Serial.begin(9600); Serial.println("Power on"); }
// Start the whole program void loop() { /********************************************************* * If the serial input reads something * * Write it to a char and make a string from these chars * * Null terminate every char and finally the whole string * *********************************************************/ if (Serial2.available() > 0) { InputChar = Serial2.read(); AnemometerString[index] = InputChar; index++; AnemometerString[index] = '\0'; if ( InputChar == '\n') AnemometerString[index] = '\0';
/*********************************************************** * If the string reached 27 chars, this is the whole string * * Print out this string and copy it into an other string * * The second will be used for comparing later on * ***********************************************************/ if (index == 27) { strcpy(AnemometerString2, AnemometerString); Serial.print("The whole string: \t"); Serial.print(AnemometerString); Serial.println("\n"); // Devide the string in 7 different parts StringPart1 = strtok(AnemometerString, Delimiters); StringPart2 = strtok(NULL, Delimiters); StringPart3 = strtok(NULL, Delimiters); StringPart4 = strtok(NULL, Delimiters); StringPart5 = strtok(NULL, Delimiters); StringPart6 = strtok(NULL, Delimiters); StringPart7 = strtok(NULL, Delimiters); /**************************************************** * The last two numbers of the string are a checksum * * This checksum needs to be in HEX * * Convert it to an equal int value * ****************************************************/ if ((StringPart7[0] >= '0') && (StringPart7[0] <= '9')) CharVal1 = StringPart7[0] - '0'; else if ((StringPart7[0] >= 'A') && (StringPart7[0] <= 'F')) CharVal1 = StringPart7[0] - 'A' + 10; if ((StringPart7[1] >= '0') && (StringPart7[1] <= '9')) CharVal2 = StringPart7[1] - '0'; else if ((StringPart7[1] >= 'A') && (StringPart7[1] <= 'F')) CharVal2 = StringPart7[1] - 'A' + 10; Checksum = CharVal1*16 + CharVal2; /********************************************************************************* * Make the check sum by adding every character of the string between '$' and '*' * * evey time the ChecksumCalc needs to be set on 0 again before we calculate it * *********************************************************************************/ ChecksumCalc = 0; for (index2 = 1; index2 <=23 ; index2++) ChecksumCalc = ChecksumCalc ^ AnemometerString2[index2]; Serial.println(StringPart1); /************************************************************************ * If the calculated checksum is equal to the checksum in the string * * And if the first part of the string is the code for anemometer sensor * * Everything can be written to the monitor * ************************************************************************/ if (ChecksumCalc == Checksum) { if (strcmp (StringPart1, "IIMWV") == 0) { Serial.print("The start sentence is: \t"); Serial.println(StringPart1); // Make floats from the chars that presents numbers WindAngle = atof(StringPart2); WindSpeed = atof(StringPart4); /******************************************************** * Print the value of the Windangle * * Say wheter it is the true value or the Relative value * ********************************************************/ if (strcmp(StringPart3, RelativeReference) == 0) { Serial.print("The windangle is: \t"); Serial.print(WindAngle); Serial.println(" Relative"); } else if (strcmp(StringPart3, True) == 0) { Serial.print("The windangle is: \t"); Serial.print(WindAngle); Serial.println(" true"); } else Serial.println("Wrong windangle signal"); /******************************************************** * Print the value of the Windspeed * * Say wheter it is in Knots, Km/h or mph * ********************************************************/ if (strcmp(StringPart5, Knots) == 0) { Serial.print("The windspeed is: \t"); Serial.print(WindSpeed); Serial.println(" knots"); } else if (strcmp(StringPart5, KMH) == 0) { Serial.print("The windspeed is: \t"); Serial.print(WindSpeed); Serial.println(" km/h"); } else if (strcmp(StringPart5, MPH) == 0) { Serial.print("The windspeed is: \t"); Serial.print(WindSpeed); Serial.println(" mph"); } else Serial.println("Wrong windspeed signal"); /************************************************************* * Say wheter the signal is available or if there is an alarm * *************************************************************/ if (strcmp(StringPart6, Available) == 0) { Serial.print("Total string: \t\t"); Serial.println("Available"); } else if (strcmp(StringPart6, Alarm) == 0) { Serial.print("The total string: \t\t"); Serial.println("Alarm!"); } else Serial.println("Wrong status!"); //Print out the checksum to compare it by eye Serial.print("The checksum is: \t"); Serial.print(StringPart7); Serial.println(" HEX"); Serial.println("\n"); }// End of if function for anemometer detection // If the anemometerdevice isn't detected, print it out else Serial.println("Error, wrong input device \n"); }// End of if function where checksum needs to be right // Put the index of you anemometer string back to 0 index = 0; }// End of if function where the string needs to be 27 chars long }// End of if function where serial input needs to be available }// End of void loop
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35493
Seattle, WA USA
|
 |
« Reply #25 on: May 16, 2012, 04:30:58 am » |
AnemometerString[index] = '\0'; if ( InputChar == '\n') AnemometerString[index] = '\0'; And, if it isn't? What is in AnemoterString[index] then? if (index == 27) { strcpy(AnemometerString2, AnemometerString);
Suppose a byte got lost/corrupted? Expecting a specific number of values is not a good idea. WindAngle = atof(StringPart2); WindSpeed = atof(StringPart4); It would be a good idea to make sure that StringPart2 and StringPart4 were valid pointers, first. Ditto for all the other pointers that you assume are valid.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #26 on: May 22, 2012, 05:32:06 am » |
It will not have to be forgotten that the sonic anemometer CV7 functions at a speed transmission of 4800bds.
|
|
|
|
|
Logged
|
|
|
|
|
|