Go Down

Topic: If else statement: Compare pointer with integer (Read 2028 times) previous topic - next topic

0011

The idea:
I have a pressure sensor that feeds the pointer ( I think this is a pointer) "userdata->pressure" with a number between 0 and 1023. Most of the time the sensor is just listening / staying 0. Whenever the sensor is in use (greater than 0), a LED turns on. Otherwise its off.

Testing:
I am trying to compare userdata->pressure with the integer 0 inside an if statement.
Whenever I manually change the comparison operator > like this (userdata->pressure > 0) the tweet is on HIGH. Whenever I change the comparison operator < like this (user->pressure < 0) the tweet is on LOW. So far this testing works.

Problem:
What I want is that the dynamic data (0-1023) inside userdata->pressure turns on and off the LED.
When I run the modified code, not much happens. The print statement shows me only HIGH ((userdata->pressure > 0) ) but the if statement never changes to LOW, no matter how often sensed data is coming in.

I am suspecting that this pointer cannot not be compared with an integer for some reason, but with a string. Yet, I need to compare userdata->pressure with an integer since userdata->pressure holds two conditions (0 and greater than 0) which I need to map on HIGH and LOW.

I am thankful for any hints.


Code: [Select]
void printUserData(const struct UserData* userData) {
  int tweet = LOW;
   
  Serial.print("data = ");
  Serial.println(userData->pressure);
 
  if ((userData->pressure) > 0)
 
  { 
    Serial.println("HIGH");
    tweet = HIGH;
  }
  else
  {
    Serial.println("LOW");
    tweet = LOW;
  }
 
}



About output of userData:
Below you will see incoming data that fills userData anew every second. The tricky part about all this, is to get access to the JSON part ("pressure"). By writing this userData->pressure  I am selecting specifically {"pressure:0"}. In order to get to the "pressure" you can do the following: strcpy(userData->pressure, root["bag"][0]["content"]["pressure"].
   
   The author of ArduinoJson mentions the following about strcpy:

   // Here were copy the strings we're interested in
     // It's not mandatory to make a copy, you could just use the pointers
     // Since, they are pointing inside the "content" buffer, so you need to make
     // sure it's still in memory when you read the string


In context of my project {"pressure:0"} means that the sensor is currently on standby. Otherwise you see a number popping up there. If I do not use this library ArduinoJson,  the serial monitor replaces the requested data with a question mark.

Code: [Select]
{
   "name":"Its me Wario",
   "location":"Wario Land",
   "time":"1995",
   "bag" [{
     "color":"red",
             "created":"2017-01-18",
     "content":{"pressure":0}
   }]
   }



Here this code snippet shows where userdata->pressure comes from:

Code: [Select]
bool readReponseContent(struct UserData* userData) {
  // Compute optimal size of the JSON buffer according to what we need to parse.
  // This is only required if you use StaticJsonBuffer.
const size_t BUFFER_SIZE =
      JSON_OBJECT_SIZE(4)    // the root object has 4 elements     
      + JSON_OBJECT_SIZE(3)  // the "with" object has 3 elements
      + JSON_OBJECT_SIZE(1)  // the "content" object has 1 element
      + MAX_CONTENT_SIZE;    // additional space for strings
     
// Allocate a temporary memory pool
  DynamicJsonBuffer jsonBuffer(BUFFER_SIZE);

  JsonObject& root = jsonBuffer.parseObject(client);

  if (!root.success()) {
    Serial.println("JSON parsing failed!");
    return false;
  }

  // Here were copy the strings we're interested in
  strcpy(userData->pressure, root["with"][0]["content"]["pressure"]);
//  strcpy(userData->company, root["company"]["name"]);
  // It's not mandatory to make a copy, you could just use the pointers
  // Since, they are pointing inside the "content" buffer, so you need to make
  // sure it's still in memory when you read the string

  return true;
}



I am working with code example JsonHttpClient provided by the custom library ArduinoJson:

Code: [Select]
// Sample Arduino Json Web Client
// Downloads and parse http://jsonplaceholder.typicode.com/users/1
//
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!







Code: [Select]

jeffez

#1
Jan 18, 2017, 04:52 am Last Edit: Jan 18, 2017, 05:05 am by jeffez
If pressure is a pointer, and you want the value its pointing to you need to prefix it with the dereference * operator

if (*(userData->pressure) > 0)

Or

If pressure is a string, use something like toInt() to convert it to a integer first.

Delta_G

#2
Jan 18, 2017, 06:00 am Last Edit: Jan 18, 2017, 06:01 am by Delta_G
I doubt pressure is a pointer.  Pressure is more likely a string or an int.  It's userData that is a pointer, that's why you are using the -> operator to get pressure.

Without seeing some of the json where pressure is coming from I can't offer much help.  I can't think of anywhere that pressure is ever negative.  I don't think pressure ever measures negative unless it is in respect to some other pressure.  Even in deep space pressure is positive.  It's very very small, but positive. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

jeffez

Maybe show us some output you get from Serial.println(userData->pressure);

That should tell us exactly what data type pressure actually is.

0011

Thanks for your comments so far, I updated the code with JSON.

@Delta_G
Pressure is more likely a string or an int.. Pressure is made to a string with strcpy  (I think) but outputs later an integer. This confuses me.

I don't think pressure ever measures negative. Pressure outputs 0 or greater.

@jeffez
Maybe show us some output you get from Serial.println(userData->pressure);
Serialprintln(userData->pressure) outputs an integer from 0 to 1023.

if (*(userData->pressure) > 0)
. Thanks, I will give this a shot.

0011

I just tried out jeffez suggestions:

if (*(userData->pressure) > 0) Or
If pressure is a string, use something like toInt() to convert it to a integer first.




When I use the * like this (*(userData->pressure) == number) the following error message
clears up: ISO C++ forbids comparison between pointer and integer [-fpermissive]. Despite of this, the if statement does not jump to else statement. The good thing about this * is that I can compare userData->pressure with integers now.

When I append toInt() like here if (userData->pressure.toInt() == number)
I get the following error message :
exit status 1
request for member 'toInt' in 'userData->UserData::pressure', which is of non-class type 'const char [32]'




 
Code: [Select]
int number = 1023;


  if (*(userData->pressure.toInt()) == number) // !=0 brings LOW and ==0 brings HIGH


    Serial.println("HIGH");
    tweet = HIGH;
  }
  else
  {
    Serial.println("LOW");
    tweet = LOW;
  }
 
}



Would converting of const char into an integer be the next logical step forward? If yes, how would you do that?

Blue Eyes

I think your comparison should look like this:

Code: [Select]

int number = 1023;


if (atoi(userData->pressure) == number) // !=0 brings LOW and ==0 brings HIGH

{
  Serial.println("HIGH");
  tweet = HIGH;
}
else
{
  Serial.println("LOW");
  tweet = LOW;
}



The toInt() method is used with the String class, but you probably have C string, or array of char.  Check out the below demo code.


Code: [Select]



typedef struct  {
              char *str;
              int num;
             
} test;

test info = {"37", 54};


void setup()
{
  Serial.begin(9600);
 
  test *i = &info;
 
  Serial.println(i->str);
  Serial.println(i->num);
 
  if( i->num == 54 ) Serial.println("num success");
 // compile error if( i->str == 37 ) Serial.print("str success");
  if( *(i->str) == '3' ) Serial.println("str deref success");
  if( atoi(i->str) == 37 ) Serial.print("str success");

}

void loop()
{
 
}



0011

Jackpot, Blue Eyes.

The presented atoi() method solved my problem.

Go Up