0

I encountered to me inexplicable behavior on an arduino uno. I'm serial reading a string from the serial monitor/python serial. This string is the conditional on several if/else if statements. The crazy thing is, some strings just get ignored, but if I print out the read string after reading it, the ignored statements then get executed and the script works the way it's supposed to. This is the code:

// power outlet 1
# define OUT_1_1 2 // relay #4
# define OUT_1_2 3 // relay #3

// power outlet 2
# define OUT_2_1 4 // relay #2
# define OUT_2_2 5 // relay #1


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  // power outlet 1
  pinMode(OUT_1_1, OUTPUT);
  pinMode(OUT_1_2, OUTPUT);

  // power outlet 2
  pinMode(OUT_2_1, OUTPUT);
  pinMode(OUT_2_2, OUTPUT);

  // init outputs to HIGH
  digitalWrite(OUT_1_1, HIGH);
  digitalWrite(OUT_1_2, HIGH);
  digitalWrite(OUT_2_1, HIGH);
  digitalWrite(OUT_2_2, HIGH);
  
  Serial.begin(9600);
}

void loop() {
  String str = "";
    
  // checking for bytes in the buffer
  if (Serial.available() > 0) {
    str = Serial.readStringUntil("\n");
  }
  // Serial.println(str); // if this line is uncommented serial input "2_ON\n" and "2_OFF\n" is recognized and outled 2 is successfully switched


  // identity
  if (str == "IDN\n") {
    Serial.println("Serial Power Outlet");
  }

  // controlling power outlet 1
  else if (str == "1_ON\n") {
    digitalWrite(OUT_1_1, LOW);
    digitalWrite(OUT_1_2, LOW);
  }
  else if (str == "1_OFF\n") {
    digitalWrite(OUT_1_1, HIGH);
    digitalWrite(OUT_1_2, HIGH);
  }
  
  // controlling power outlet 2
  else if (str == "2_ON\n") {
    digitalWrite(OUT_2_1, LOW);
    digitalWrite(OUT_2_2, LOW);
  }
  else if (str == "2_OFF\n") {
    digitalWrite(OUT_2_1, HIGH);
    digitalWrite(OUT_2_2, HIGH);
  }
  delay(1000);
}

If I serial input 2_ON\n or 2_OFF\n the according else if blocks are just ignored (all other inputs work correctly).

But after I've uncommented // Serial.println(str); these blocks are executed the way they are supposed to and all works just fine.

Where is my mistake, what am I getting wrong here? These blocks also get executed if I Serial.println any random output. Why do I have to Serial.println something first so my script works according to plan? What am I missing?

EDIT: added all of the code.

  • Post the whole code. I bet you have a memory overrun somewhere. – Delta_G Jul 30 at 22:58
  • Tank you for reading, I've just added all of the code. Even though that was just the setup() and 4 defines. – XIII_ Jul 31 at 7:42
  • I've just found out that the character '2' literally is dropped, when I print out 'str' at the end of loop(). This only happens to '2', not any other character. So I will go with 'A_ON/OFF' and 'B_ON/OFF' as control strings and continue with my project. Still, this is no clean solution and I'd still like to know why this behavior is observed. – XIII_ Jul 31 at 8:47
0

Even though you read until \n, that just controls the ending of your buffered string. It does not control it's start. There may be some garbage before the command that you have not cut out. In other words, I suggest you check if the string endsWith as opposed to == the command string.

As for what noise could be causing garbage or why activity on the tx side of the serial cleaned it up, i do not know. Heck something might just be weird enough in the wiring that '2' is just the set of bits needed to aggravate it.

| improve this answer | |
  • That's interesting, thanks for the input! I'll try tomorrow and check if endsWith() works. – XIII_ Aug 2 at 11:15
  • Reality has no duty to conform to our theories, but often we do have jobs that require us to make our theories conform to reality. I'd like to think there's more going on here than a ghost in the machine that hates 2 but likes B. – Abel Aug 6 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.