Anything inside of this if-statement will not run when reading from serial

Hello I have this code I am trying to run alongside a python script and it sort of does what I want it to do but anything inside of the if data = 'x' statement will not run and the beeps continue as soon as the value is no longer being printed to the serial.

const int buzzerOne = 9;
const int buzzerTwo = 10;
bool inChair = false;
bool personFound = false;
int buzzTone1 = 1500;
int buzzTone2 = 3000;

void setup() {
  Serial.begin(9600);
  pinMode(buzzerOne, OUTPUT);
  pinMode(buzzerTwo, OUTPUT);

}

void loop() {


  while (personFound == false) {
    int val;
    val = analogRead(0);

    if (Serial.available() > 0) {
      String data = Serial.readString();

      if (data == 'x') {
        val = 0;
        personFound = true;

      }
    }

    if (val >= 1) {
      tone(buzzerOne, buzzTone1);
      delay(500);
      noTone(buzzerOne);
      tone(buzzerTwo, buzzTone2);
      delay(500);
      noTone(buzzerTwo);
    }
  }

}

Could you please help me figure out why this if statement isn't running at all?

if (data == 'x') {
        val = 0;
        personFound = true;

      }

I'm not an expert on the serial port but my guess is you are reading more than one byte from the serial port. Without knowing the source of the "x" I cannot comment on what might be at the serial port.

If you made:

if (Serial.available() > 0)
to
if (Serial.available() = 1)

You would read a byte as soon as the program got around to the serial part of the code.
Do you know what else might be coming in on the serial port? i.e. can you strip all but the 1st character?

C++ doesn't like strings, you should change "String" to an array of char. A quick google of "array of char" will give you much more info.

1 Like

There is only one character coming through so it would probably be smarter to change to an array of char anyway. I will try your fix and see if it helps, thank you!

What board are you using? If it has another serial port you could send the data out the port to the IDE serial monitor.

I use a 128 X 32 OLED for trouble shooting when I cannot access the Serial port. THe oled displays are about $5 to $7 on ebay.

I am using an Arduino Uno

I tried your fix but I still am having no luck

The String class has no problem although many are convinced to the contrary.

It is your sketch that contains several errors:

  • you are comparing a pointer to char with a char variable type: you should use double quotes and not single quotes.
  • BUT, the string is received from the serial line, so in addition to the character 'x' there will also be line terminators '\n' and '\r' (based on how you configured the terminal software).
  • the variable val will be different from 0 only in the case in which the potentiometer is completely closed (and it may not be so even in that case if the cursor is not precise) because you are reading again A0 just after some micorseconds.
    Therefore the two buzzers will always be in operation by introducing a total delay of 1000 milliseconds which affects on receiving data in a heavy way. You should use a non-blocking approach (millis ()) for handling buzzers.

I am not having issues with buzzers or my vibration sensor, only issues with serial communication, but thank you.

Try this, but anyway this is not the best way to read a command from serial in my opinion.

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

void loop() {
  if (Serial.available() > 0) {
    String data = Serial.readString();

    if (data == "x\n") {
      Serial.println("I've found \"x\"");
    }
  }
}

Thank you for your answer but that was not successful either

Have you tried the simulator? It works.

If don't work on your real hardware is because, as I stated, it depends of which type of line endings you selected. This is the reason why this way is not the best.

serial-monitor-newline

Well part of the problem is that I can't have the serial monitor open and run a pyserial script at the same time

The default line termination of pySerial could be with both carriage return (\r) and newline (\n).

Try this if (data == "x\r\n") or change the pySerial script for using only one terminator character
I've updated also the example.

Ok so I have them communicating now but when i try to terminate the while loop running the buzzers it still continues

Because probably the value of A0 is still > 0 so in the next loop you read againg and val variable will be >= 1.
Try with a higher threshold

I changed my code to this earlier I was testing without the buzzer code in but ever since I put it in the scripts won't communicate

const int buzzerOne = 9;
const int buzzerTwo = 10;
bool inChair = false;
bool sawyerFound = false;

void setup() {
  Serial.begin(9600);
  pinMode(buzzerOne, OUTPUT);
  pinMode(buzzerOne, OUTPUT);
}

void loop() {
  int val;
  val = analogRead(0);

  if (val > 1) {
    inChair = true;
  }

  while (inChair == true) {
    tone(buzzerOne, 1500);
    delay(500);
    noTone(buzzerOne);
    tone(buzzerTwo, 3000);
    delay(500);
    noTone(buzzerTwo);
    if (Serial.available() == 1) {
      char data = Serial.read();

      if (data == 'x') {
        Serial.println('a');
        sawyerFound = true
        inChair = false;
      }
    }



  }
}

Actually its what i put in with the if data == x code that is causing the issue

Please stop writing random lines of code and focus on what you are doing.

Once you understand the concept, everything will be easier: when you send some text from a serial connection (terminal or python script, is the same), one or two additional characters will be added as line ending.

Serial.available() return the numbers of total bytes you can read from the serial buffer.

When you add the buzzers piece of code, you will never be able to process the single byte because the delay introduced!
Indeed in the mean time, the \r and the \n characters will be fitted in buffer, so Serial.available() will be != 1

Check again the same simulated example, I've added the buzzers and a pot

This is char it can NEVER equate to String not in a million years. It is like saying I have a box of apples, why when I pick up one apple and compare it to oranges

if (apple == orange)

never runs?