1

This sketch is supposed to listen for a single character sent to the serial port, as a means of starting and stopping data collection (which in this example is mocked by printing some register values). It reacts to the first character sent (g), and the while loop begins executing. But it doesn't react to a subsequent s character, it seems I can't get Arduino's attention.

Perhaps this is related to this answer but I'm not sure. If that's the problem, I could use some general suggestions about how to work around the limitations. If it's something else, well obviously I need a suggestion for that as well!

// Listen to the Serial Port for Instructions and Print Register Values

volatile boolean start = false;  // flag to start register inspection; global

void setup() {
  Serial.begin(9600);
  if (Serial) {
    Serial.println("Arduino listening...");
    Serial.println("Enter g or s at any time");  // g = go, s = stop
  }
}

void loop() {
  unsigned char data;
  if (Serial.available()) {
    data = Serial.read();
    Serial.println(data); // only for troubleshooting
    if (data == 'g') {
      start = true;
    }
    else  if (data == 's') {
      start = false;
    }
  }
  
  while (start) {
    // print the values of some ADC registers
    Serial.print("ADMUX  register: ");
    print_bin(ADMUX);
    Serial.print("ADCSRA register: ");
    print_bin(ADCSRA);
    Serial.println(" ");
    delay(1000);
  }
}


void print_bin(byte aByte) {
  for (int8_t aBit = 7; aBit >= 0; aBit--) {
    if (aBit == 3) {
      Serial.print(" ");
    }
    Serial.print(bitRead(aByte, aBit) ? '1' : '0');
  }
  Serial.println(" ");
}

Environment: Version: 2.3.0 Date: 2024-02-07T13:40:21.377Z CLI Version: 0.35.2

0

1 Answer 1

2

There is nothing in your while (start) { loop that would allow start to become false.

  while (start) {
    // print the values of some ADC registers
    Serial.print("ADMUX  register: ");
    print_bin(ADMUX);
    Serial.print("ADCSRA register: ");
    print_bin(ADCSRA);
    Serial.println(" ");
    delay(1000);
  }

...and so your loop continues while data is piling up in Serial's input buffer.

loop() is already a functional loop. Changing while (start) { to if (start) { seems to be what you're looking for.

void loop() { // <-- existing loop
  unsigned char data;
  if (Serial.available()) {   
    // stuff that can change start
  }
  
  if (start) {
    // stuff that happens if start is true
  }
}

You may want to look at the blink without delay example for handling your delay(1000) differently.

2
  • 1
    Dang, I set up a loop inside a loop with no escape from the inner loop once it was going! Thanks for the second set of eyes! Just couldn't see that for some reason. Feb 12 at 1:41
  • 1
    And thanks for the link to the blink nuances. I don't actually need that delay in there, but I need to keep learning about Arduino blocking, interrupts etc. Many details are not readily apparent when one is already learning a lot of new stuff. Feb 12 at 1:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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