Go Down

Topic: I need help with two similar Functions. Testing an Int for text result (Read 472 times) previous topic - next topic

cyclegadget


  I have two functions that are very similar and both have the same problems.

I start by getting a number from the serial buffer then, I send that number to a function. I want the function to produce a result such as the text "TRUE" or "False" for one function, and "In" or "Out" for the other function. I will then be saving the result to variable to later be saved to a SD card.

My SD card results will need to look like this when done.
Code: [Select]
Log Time RPM TPS IAP HO2 HO2 Wideband IGN STP GEAR CLUTCH NT
00:00.0         1130 56 44 47 65535         38 26 0 Out TRUE
00:00.2         1180 56 50 47 65535         38 26 0 Out TRUE


Below are both the functions that I am having trouble with. I have trouble initializing them properly and my array size does not work with 2 different text results that have different amount of letters. I hope I have provided enough information, I am struggling to use the proper terms for asking the question. I added comments in the code to help follow my line of thinking.

Could some one help me please?

Code: [Select]
/////////////////////////////////Parts for function #1/////////////////////////
//Get the variable Clutch from the buffer (buf)

Clutch = buf[CLUTCH] & 0x10;  //clutch must = IN OR OUT, if clutch = 0 it is "out", if clutch = 1 it is "in"

//Send vairable Clutch to function CLUTCHCHECK() and make a "TRUE" or "False" result
char clutchStr[4] = CLUTCHCHECK(Clutch);

///////////////Function#1/////////////////////////////////////////////
//Receive Clutch becomes ClutchState, then test for 0 or 1
char CLUTCHCHECK(int ClutchState)
{
  char C[4];
  if (ClutchState == 0)
  {
    C = "Out";
  }
  else  // ClutchState should be 1 if it is not 0
  {
    C = "In";
  }
  return C; //return "In" or "Out"
}

////////////////////////////////////Part for function #2///////////////////////////////////////
//Get the variable Nt from the buffer (buf)

Nt = buf[NEUTRAL] & 0x02;  //neutral    MUST = TRUE OR FALSE (2 = false) (0 = true)

//Send vairable Nt to function NEUTRALCHECK() and make a "TRUE" or "False" result
char neutralStr[6] = NEUTRALCHECK(Nt);


/////////////////////FUNCTION #2/////////////////////////////
//Receive Nt becomes NeutralState, then test for 0 or 2
char NEUTRALCHECK(int NeutralState)
{
  char N[6];
  if (NeutralState == 0)
  {
    N = "TRUE";
  }
  else  // if not 0, NeutralState should be 2
  {
    N = "FALSE";
  }
  return N;  // return "TRUE" or "FALSE"
}

Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

johnwasser

The problem is:
Code: [Select]

char C[4];
    C = "Out";

does NOT copy the string constant to the character buffer.

You could use character pointers:
Code: [Select]

char *clutchStr = CLUTCHCHECK(Clutch);

char *CLUTCHCHECK(int ClutchState)
{
  char *C;
  if (ClutchState == 0)
  {
    C = "Out";
  }
  else  // ClutchState should be 1 if it is not 0
  {
    C = "In";
  }
  return C; //return "In" or "Out"
}


or you could copy the strings around which will use more memory and more time:

Code: [Select]

char clutchStr[4];
strcpy(clutchStr, CLUTCHCHECK(Clutch));

char *CLUTCHCHECK(int ClutchState)
{
  char C[4];
  if (ClutchState == 0)
  {
    strcpy(C,"Out");
  }
  else  // ClutchState should be 1 if it is not 0
  {
    strcpy(C, "In");
  }
  return C; //return "In" or "Out"
}


Or you could use the ternary operator and eliminate the functions:
Code: [Select]
char *clutchStr = Clutch ? "In" : "Out";
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

lloyddean

Code: [Select]

#define CLUTCHCHECK(N) ((0 == (N)) ? "Out" : "In")
#define NEUTRALCHECK(N) ((0 == (N)) ? "TRUE" : "FALSE")


cyclegadget



Thank you both for the excellent answers! I will use the ternary operator and eliminate the functions, I like how that really cleans up the code!
Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

cyclegadget


I wrote a small sketch to test the Ternary operator method but, I am doing somethings wrong. I am posting the sketch and my errors.
I must not be understanding the proper use of a Ternary operator.

Code: [Select]
#define CLUTCHCHECK(Clutch) ((0 == (Clutch)) ? "Out" : "In")
#define NEUTRALCHECK(Nt) ((0 == (Nt)) ? "TRUE" : "FALSE")
int Clutch = 0;
int Nt = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
//Clutch = buf[CLUTCH] & 0x10;       //clutch     must = IN OR OUT   if clutch = 0 it is out if clutch = 1 it is in

  CLUTCHCHECK(Clutch);
  Serial.println(Clutch).
  Serial.println(CLUTCHCHECK);
  Serial.println();
 
  if (Clutch == 0)
  {
    Clutch = 1;
  }
  else
  {
    Clutch = 0;
  }

// Nt = buf[NEUTRAL] & 0x02;          //neutral    MUST = TRUE OR FALSE (2 = false) (0 = true)

  NEUTRALCHECK(Nt);
  Serial.println(Nt);
  Serial.println(NEUTRALCHECK);
  Serial.println();
 
  if (Nt == 0)
  {
    Nt = 2;
  }
  else
  {
    Nt = 0;
  }
}


errors
Code: [Select]

sketch_dec30c.ino: In function 'void loop()':
sketch_dec30c:15: error: request for member 'Serial' in 'Serial.HardwareSerial::<anonymous>.Stream::<anonymous>.Print::println(Clutch, 10)', which is of non-class type 'size_t'
sketch_dec30c:15: error: 'CLUTCHCHECK' was not declared in this scope
sketch_dec30c:31: error: 'NEUTRALCHECK' was not declared in this scope
Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

cyclegadget


By the way my sketch just alters the variables back and forth to and prints the results. I hope to see the variable tested and then the result printed on the screen.
Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

johncc



I wrote a small sketch to test the Ternary operator method but, I am doing somethings wrong. I am posting the sketch and my errors.
I must not be understanding the proper use of a Ternary operator.



  CLUTCHCHECK(Clutch);           <<< CLUTCHCHECK only produces a value "Out" or "In", which is then discarded
  Serial.println(Clutch).              <<< The line should end with ;   , not  .   Also, Clutch is still 0 or 1, not "Out" or "In"
  Serial.println(CLUTCHCHECK);  <<< CLUTCHCHECK needs a parameter


I think what you want is (replace all three lines above with this):
  Serial.println( CLUTCHCHECK(Clutch) );  // CLUTCHCHECK produces the value "Out" or "In", and println prints the resulting value

There is another issue with how you believe CLUTCHCHECK works, but start with trying to fix this first.

Cheers,
John

lloyddean

Code: [Select]

#define CLUTCHCHECK(N)  ((0 == (N)) ? "Out" : "In")
#define NEUTRALCHECK(N) ((0 == (N)) ? "TRUE" : "FALSE")

int Clutch  = 0;
int Nt      = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
// Clutch = buf[CLUTCH] & 0x10;       //clutch     must = IN OR OUT   if clutch = 0 it is out if clutch = 1 it is in

  const char*   szClutch = CLUTCHCHECK(Clutch);
  Serial.println(Clutch);
  Serial.println(szClutch);
  Serial.println();
 
  Clutch = ((Clutch == 0) ? 1 : 0);


// Nt = buf[NEUTRAL] & 0x02;          //neutral    MUST = TRUE OR FALSE (2 = false) (0 = true)

  const char*   szNeutral = NEUTRALCHECK(Nt);
  Serial.println(Nt);
  Serial.println(szNeutral);
  Serial.println();
 
  Nt = ((Nt == 0) ? 2 : 0);
}


lloyddean

The macro version expands inline using more memory with each expansion thus the following may be of preference.

Code: [Select]

inline char* CLUTCHCHECK(int state) {
    static char* szOUT = "Out";
    static char* szIN  = "In";

    return ((0 == (state)) ? szOUT : szIN);
}

inline char* NEUTRALCHECK(int state) {
    static char* szTRUE   = "TRUE";
    static char* szFALSE  = "FALSE";
   
    return ((0 == (state)) ? szTRUE : szFALSE);
}


lloyddean

Then again perhaps you don't really want a C-string pointer returned as the result of either of these functions.

cyclegadget


Thank you lloyddean!  I adjusted your sketch for testing. It shows the integer being tested and the result. I think it will work nicely!

My next step is to add it to my logging sketch and see how it looks on the SD card.

I am grateful for your efforts building he macro which shows how the ternary operator works!

Thanks,
Mark

Code: [Select]
#define CLUTCHCHECK(N)  ((0 == (N)) ? "Out" : "In")
#define NEUTRALCHECK(N) ((0 == (N)) ? "TRUE" : "FALSE")

int Clutch  = 0;
int Nt      = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  // Clutch = buf[CLUTCH] & 0x10;       //clutch     must = IN OR OUT   if clutch = 0 it is out if clutch = 1 it is in

  const char*   szClutch = CLUTCHCHECK(Clutch);
  Serial.println("clutch");
  Serial.println(Clutch);    // show the int used
  Serial.write(szClutch);    //print the result
  Serial.println();

  Clutch = ((Clutch == 0) ? 1 : 0);

  Serial.println("**************");

  // Nt = buf[NEUTRAL] & 0x02;          //neutral    MUST = TRUE OR FALSE (2 = false) (0 = true)

  const char*   szNeutral = NEUTRALCHECK(Nt);
  Serial.println("Neutral");
  Serial.println(Nt);           //show the variable used
  Serial.write(szNeutral);      //print the result
  Serial.println();

  Nt = ((Nt == 0) ? 2 : 0);

  Serial.println("**************");

  delay(800);
}
Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

Go Up