Boolean question

Is have some code that reads code from my serial port (PC). using a boolean I want to be able to enable/disable printing of the read input back to my PC (it should be disabled default)

On top of my sketch I've declared:

//GamePadSerialFeedback variables declaration
boolean GamepadSerialFeedback = false;
const char SerialFeedbackOn[] = "~SerialFeedbackOn#";
const char SerialFeedbackOff[] = "~SerialFeedbackOff#";

After reading the serial code (the code has to include the following header and footer) the input is saved inside an array (StringIn):

Header: ~
Footer: #

based on a certain command the printing function is enabled or disabled:

//Enables or disables the feedback (print) from the arduino to the interface software.
            if (strcmp(SerialFeedbackOff,StringIn) == 0){
              Serial.print("~GamepadSerialFeedbackOff#");
              GamepadSerialFeedback = false;
            }
            else if (strcmp(SerialFeedbackOn,StringIn) == 0){
              Serial.print("~GamepadSerialFeedbackOn#");
              GamepadSerialFeedback = true;
            }

            if (GamepadSerialFeedback == true){

              // Print the array. Debugging code
              for(int j=0; j < (i-1) ; j++){
                Serial.print(StringIn[j]);
              }
            }

But the GamepadSerialFeedback variable is not changed and keeps the value as declared ont top of my sketch?

Is it not possible to change the state/value of a variable at runtime?

Thanks in advance,

Cheers /me

The more likely problem is that you are not populating the StringIn array correctly, so neither strcmp function is returning that a match occurred.

We'd need to see more of the code, and some output from the sketch.

Hi PaulS,

This is a continuation of my serial read code (You've helped my out before on this piece of code :))

Here is the whole sketch. Please do not mind my complex programming skills, I am trying to simplify the code but without success at the moment.

/*This example reads serial data. 
 The serial data should contain a one character header and a  one character footer.
 */

// Header and Footer declaration
const char HEADER = '~';
const char FOOTER = '#';

//GamePadSerialFeedback variables declaration
boolean GamepadSerialFeedback;
const char SerialFeedbackOn[] = "~SerialFeedbackOn#";
const char SerialFeedbackOff[] = "~SerialFeedbackOff#";

// Maximum number of elements allowed in StringIn
const int MAX_ARRAY_ELEMENTS = 120;

//Serial read variables
char StringIn[MAX_ARRAY_ELEMENTS] = {
  '\0'};

void setup()
{
  Serial.begin(115200);
  Serial.print("~SetupOK#");
  GamepadSerialFeedback = false;
  delay(1000);
}

void loop(){

  if(Serial.available() > 0) {

    // Read the first byte in the buffer
    byte IncomingByte = Serial.read();

    //Debugging code
    //Serial.println(IncomingByte);

    // Check if first char is header
    if (IncomingByte == HEADER) { 

      //Serial.print("~Header found!!#"); //Debugging code

      delay(10); //Has to be inserted or else no code will be recognized??

      int i = 0;//index of char array

      StringIn[i++] = HEADER; //add the header to the char array

      // This loop reads the remaining bytes based on certain criteria.
      while(Serial.available() > 0)

      {
        //Check if String in still has elements available. If not array will be termindated
        if (i != (MAX_ARRAY_ELEMENTS - 1)){

          //If serial data is in buffer read the next char
          byte IncomingByte = Serial.read();

          //Serial.println(IncomingByte);

          // Check if read char is footer, if yes add to array and add NULL
          if (IncomingByte == FOOTER) {

            //Serial.print("~Footer found!!#");

            StringIn[i++] = FOOTER; //add footer to the char array
            StringIn[i++] = '/0'; // add NULL

            //Serial.println(i); // print the amount of elemnts in array. Debugging code.

            //Enables or disables the feedback (print) from the arduino to the interface software.
            if (strcmp(SerialFeedbackOff,StringIn) == 0){
              Serial.print("~GamepadSerialFeedbackOff#");
              GamepadSerialFeedback = false;
            }
            else if (strcmp(SerialFeedbackOn,StringIn) == 0){
              Serial.print("~GamepadSerialFeedbackOn#");
              GamepadSerialFeedback = true;
            }

            if (GamepadSerialFeedback == true){

              // Print the array. Debugging code
              for(int j=0; j < (i-1) ; j++){
                Serial.print(StringIn[j]);
              }
            }

            break; // stop the while loop
          }

          // No footer found yet but character in between. It will be added to the array.
          else
          {
            //Serial.println("Other char added to array!!"); //Debugging code
            StringIn[i++] = IncomingByte;
          }
        }

        // Array full. Probably no footer found.
        else
        {
          StringIn[i++] = '/0'; // add NULL
          Serial.print("~Warning: Array overflow, no footer found!!#");
          //Serial.flush();
          break; // Break the loop.
        }
      }
    }
  }
}

Do you see these responses:

              Serial.print("~GamepadSerialFeedbackOff#");
              Serial.print("~GamepadSerialFeedbackOn#");

when the appropriate input is sent?

Is have some code that reads code from my serial port (PC). using a boolean I want to be able to enable/disable printing of the read input back to my PC (it should be disabled default)

boolean GamepadSerialFeedback;

The default value for a boolean is true.

some strange thing going on......

if I set GamepadSerialFeedback = false; (in the setup), the print function in the strcmp does not work. If I change this to

GamepadSerialFeedback = true;

the printing function starts to work. (after I send ~SerialFeedbackOn# or ~SerialFeedbackOff# from my PC to the Arduino)??

const char SerialFeedbackOn[] = "~SerialFeedbackOn#";
const char SerialFeedbackOff[] = "[glow]~SerialFeedbackOff#[/glow]";
if (strcmp(SerialFeedbackOff,StringIn) == 0){
              Serial.print("[glow]~GamepadSerialFeedbackOff#[/glow]");
              GamepadSerialFeedback = false;
            }
            else if (strcmp(SerialFeedbackOn,StringIn) == 0){
              Serial.print("~GamepadSerialFeedbackOn#");
              GamepadSerialFeedback = true;
            }

The messages being printed do not match the initial values. Is this intentional?

Yes.

I think something goes wrong in building StringIn or the strcmp function.

I did not include the string.h library but I assume dis does not matter?

Is it possible to check if the string contains a part of another string? (so not using strcmp). So not really a 1:1 comparison.

I have to do some serious debugging...............

I think something goes wrong in building StringIn or the strcmp function.

I just noticed this.

            StringIn[i[glow]++[/glow]] = '/0'; // add NULL

You should not be incrementing i when adding the NULL. Your StringIn array looks like this, when ~Hi# is received:

'~', 'H', NULL, 'i', NULL, '#', NULL.

Passing this to strcmp will compare "~H" to the specified string.

The logic of the code is to always do

if (GamepadSerialFeedback == true){

              // Print the array. Debugging code
              for(int j=0; j < (i-1) ; j++){
                Serial.print(StringIn[j]);
              }
            }

when GamepadSerialFeedback is true.

So, if it's true in setup, it will always be true unless

if (strcmp(SerialFeedbackOff,StringIn) == 0){
              Serial.print("~GamepadSerialFeedbackOff#");
              GamepadSerialFeedback = false;
            }

ever matches.

So, if neither strcmp(SerialFeedbackOff,StringIn), nor (strcmp(SerialFeedbackOn,StringIn) ever matches, the value of GamepadSerialFeedback will never ever change.
That's likely what is happening.

For some reason, the strings are never matched, maybe because they are never sent or read properly.

[edit]Ooops - 2nd edit
That is may be because the test while(Serial.available() > 0) {
is failing before the end of string, '#', is read.[/edit]

It might help with debugging if

            if (GamepadSerialFeedback == true){
              // Print the array. Debugging code
              for(int j=0; j < (i-1) ; j++){
                Serial.print(StringIn[j]);
              }
            }

became something like:
Serial.print("got a #, read ");
Serial.print(i);
Serial.print(" characters, StringIn=<");
Serial.print(StringIn);
Serial.println('>');
so that it is very easy to see what was read.
Make sure to count the characters printed, in case there is a control (invisible) character in there.

Small point; there is a test:
if (i != (MAX_ARRAY_ELEMENTS - 1)){ ...
A more robust test is:
if (i <MAX_ARRAY_ELEMENTS-1){
I don't think it is a cause of failure, but as code is changed, it may change in other ways, so < is a bit more robust. Just a suggestion

HTH
GB

PaulS -

StringIn[i++] = '/0'; // add NULL

'/0' is a mistake, but it isn't a '\0'.
I'm not sure what the gnu C++ compiler will do with it.
I would expect it is a weird two byte thing, a '/' and a '0'.

It needs changing (everywhere) to a '\0'

Further, if it were a null byte, '\0', I can't see where it would cause the problem you describe. Would you point out the specific line please?

HTH
GB

Hi PaulS and gbulmer,

Based on your suggestions I've modified the code a bit:

Major changes:

  • The array is printed using the Serial.print(StringIn); instead of the for...next loop.
  • The Array terminator is changed to : '\0'
  • if (i <MAX_ARRAY_ELEMENTS-1){ is changes instead of if (i != MAX_ARRAY_ELEMENTS-1){

It basically works but, it looks like the boolean is changed back to its declared value every time the loop starts a new cycle.

A test-case:

  • When I send "~SerialFeedbackOff#" using the Arduino's serial monitor I get "~FeedbackOff#" back from the Arduino (so no problem yet!!). The boolean "GamepadSerialFeedback" value should be set to "false".
  • When I send ~test# to the Arduino no text is supposed to be printed but ~test# is printed back?? This should not happen? because I want to disable every loop() cycle until I send "~SerialFeedbackOn#"

Should the new value of the boolean be stored in a special way? :-?

/*This example reads serial data. 
 The serial data should contain a one character header and a  one character footer.
 */

// Header and Footer declaration
const char HEADER = '~';
const char FOOTER = '#';

//GamePadSerialFeedback variables declaration
const char SerialFeedbackOn[] = "~SerialFeedbackOn#";
const char SerialFeedbackOff[] = "~SerialFeedbackOff#";
boolean GamepadSerialFeedback = true;

// Maximum number of elements allowed in StringIn
const int MAX_ARRAY_ELEMENTS = 120;

//Serial read variables
char StringIn[MAX_ARRAY_ELEMENTS] = {
  '\0'};

void setup()
{
  Serial.begin(115200);
  Serial.print("~SetupOK#");
}

void loop(){

  if(Serial.available() > 0) {

    // Read the first byte in the buffer
    byte IncomingByte = Serial.read();

    //Debugging code
    //Serial.println(IncomingByte);

    // Check if first char is header
    if (IncomingByte == HEADER) { 

      //Serial.print("~Header found!!#"); //Debugging code

      delay(10); //Has to be inserted or else no code will be recognized??

      int i = 0;//index of char array

      StringIn[i++] = HEADER; //add the header to the char array

      // This loop reads the remaining bytes based on certain criteria.
      while(Serial.available() > 0)

      {
        //Check if String in still has elements available. If not array will be termindated
        if (i != (MAX_ARRAY_ELEMENTS - 1)){

          //If serial data is in buffer read the next char
          byte IncomingByte = Serial.read();

          //Serial.println(IncomingByte);

          // Check if read char is footer, if yes add to array and add NULL
          if (IncomingByte == FOOTER) {

            //Serial.print("~Footer found!!#"); //Debugging code

            StringIn[i++] = FOOTER; //add footer to the char array

            StringIn[i] = '\0'; // add NULL

            //Serial.print(strlen(StringIn)); // print the amount of elemnts in array. Debugging code.

            //Enables or disables the feedback (print) from the arduino to the interface software.
            if (strcmp(StringIn,SerialFeedbackOff) == 0){
              Serial.print("~FeedbackOff#");
              GamepadSerialFeedback = false;
            }

            if (strcmp(StringIn,SerialFeedbackOn) == 0){
              Serial.print("~FeedbackOn#");
              GamepadSerialFeedback = true;
            } 

            if (GamepadSerialFeedback == true){
              Serial.print(StringIn);
            }
            break; // stop the while loop
          }

          // No footer found yet but character in between. It will be added to the array.
          else
          {
            //Serial.println("Other char added to array!!"); //Debugging code
            StringIn[i++] = IncomingByte;

          }
        }

        // Array full. Probably no footer found.
        else
        {
          StringIn[i++] = '/0'; // add NULL
          Serial.print("~Warning: Array overflow, no footer found!!#");
          //Serial.flush();
          break; // Break the loop.
        }
      }
    }
  }
}

@ gbulmer: I always use the same procedure you mentioned for debugging purposes (print each step of the process) :slight_smile:

@ gbulmer: I always use the same procedure you mentioned for debugging purposes (print each step of the process)

Please don't get me wrong, I am very impressed that you are so methodical. You have a good way to "squeeze the bugs out" :slight_smile:

My main point is, StringIn is being used as a valid string in things like strcmp(), but code like

              // Print the array. Debugging code
              for(int j=0; j < (i-1) ; j++){
                Serial.print(StringIn[j]);
              }

treats it as a known length array of characters.
If the program logic relies on it being a valid string, then it is good to let the system treat it as a valid string all the time.

In retrospect, maybe the '/0' would have shown up.

Let me have a cup of tea, and read the code.

HTH
GB

Ooops - noticed there is still, at least, one StringIn[i++] = '/0';
which needs to become StringIn[i++] = '\0';

Is the posted code the right version?

It still has if (i != (MAX_ARRAY_ELEMENTS - 1)){
and not if (i <MAX_ARRAY_ELEMENTS-1){

What happens when
boolean GamepadSerialFeedback = true;
is changed to
boolean GamepadSerialFeedback = false;
and the program run again?

Do we agree, that it shouldn't make any difference?
So if it does, there is something odd happening.

GB

          // No footer found yet but character in between. It will be added to the array.
          else
          {
            //Serial.println("Other char added to array!!"); //Debugging code
            StringIn[i++] = IncomingByte;

          }

StringIn needs to be NULL terminated, here, too.

hi im strugaling to get my arduino to type a key on the computer. i am new at using arduinos and i hear there are multaple steps involved but i dont have the slightest idea how to go about doing this. any code, info, tips would be helpfull. thanks.