Pages: 1 [2]   Go Down
Author Topic: Ultrasonic anemometer reading  (Read 2414 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
#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 Online
Brattain Member
*****
Karma: 654
Posts: 50929
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
my goal is to work like this:
if the start of the string = var1 ($IIMWV)
Code:
if(strcmp(data, "$IIMWV") == 0)
{
}

Quote
write var2(225.0) to somewhere, var3(R) somewhere, etc
Code:
data = strtok(NULL, delimiters);
float rVal = atof(data);

data = strtok(NULL, delimiters);
strcpy(var3, data);

Quote
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.

Quote
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 Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, I did just stumbled upon something likewise and tried it:

Code:
#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 smiley-red, srry about that.
Thanks again!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-razz
Code:
#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 Online
Brattain Member
*****
Karma: 654
Posts: 50929
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26632
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
D' - 'A' + 10 = 14)
sp. "13"
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 654
Posts: 50929
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
sp. "13"
It's early...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Haha, Ok. I'll try it that way.

Thanks
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
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:
Code:
/****************************************************************************
* 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 Online
Brattain Member
*****
Karma: 654
Posts: 50929
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
    AnemometerString[index] = '\0';
     
    if ( InputChar == '\n')
      AnemometerString[index] = '\0';
And, if it isn't? What is in AnemoterString[index] then?

Code:
    if (index == 27)
    {
      strcpy(AnemometerString2, AnemometerString);
Suppose a byte got lost/corrupted? Expecting a specific number of values is not a good idea.

Code:
          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

Nantes (FR)
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It will not have to be forgotten that the sonic anemometer CV7 functions at a speed transmission of 4800bds.
Logged

Christophe
CEO lcjcapteurs

Pages: 1 [2]   Go Up
Jump to: