I'm trying to set up my code for an Arduino UNO so that if 'a' is given in the serial input, the LED will blink until 'b' and ONLY 'b' is input. I've attached my code.
My problem is that anything can turn off the LED because of the while loop that I have setup, but I wasn't sure of any other way that I could make the LED blink indefinitely.
I tried replacing the while condition with (serial.readString().compareTo("b\n") == !0), but then the LED doesn't blink even when 'a' is pressed.
I also have to use strings because I don't want an input like "abc" to trigger anything in the code.
My code:
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
Serial.println("Press 'a' to blink the LEDs. Press 'b' to turn them off."); // prompt user input
}
void loop() {
if (Serial.available() > 0) { // check if serial input is given
String input = Serial.readString(); // read and store the input as a string
// check if the string is a
if (input.compareTo("a\n") == 0) {
Serial.print("\tInput was 'a'.\n");
Serial.print("\tTurning LEDs on.\n");
while (Serial.available() == 0) {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(2000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000);
}
}
// check if the string is b
else if (input.compareTo("b\n") == 0) {
Serial.print("\tInput was 'b'.\n");
Serial.print("\tTurning LEDs off.\n");
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
}
// check if the string is not a or b
else {
Serial.print("\tInput not recognized.\n\tPlease try again.\n");
}
Serial.print("\nPress 'a' to blink the LEDs. Press 'b' to turn them off.\n"); // restate the user prompt
}
}
What you need to do is multiple things at once. When LEDs are not blinking you need to check for an 'a' and when they are you need to check for a 'b'. The easiest way to do that is to not use delays but the millis() function. See the following tutorial: Walk Away from Delay. It is actually has a blinking LED example. Get that working first then add code to check the serial port.
If the source of the input 'a' is the serial monitor the serial input basics tutorial shows how to receive a character. Then us if to see if the serial input is 'a' and set a flag to run the blinking.
Here is the previous example modified to get input from serial monitor to control whether the LED will blink or not. Uses code from the serial input basics tutorial.
const int ledPin = LED_BUILTIN;
int ledState = LOW;
unsigned long previousMillis = 0;
long interval = 500; // ************ removed const
char receivedChar;
boolean newData = false;
boolean runLed = false;
void setup()
{
Serial.begin(115200);
Serial.println("Arduino ready");
pinMode(ledPin, OUTPUT);
}
void loop()
{
recvOneChar();
if (newData == true)
{
if (receivedChar == 'a') //run blink
{
runLed = true;
newData = false;
}
else if (receivedChar == 's') // turn off blink
{
runLed = false;
ledState = LOW; // turn led off
newData = false;
}
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval && runLed == true)
{
previousMillis = currentMillis;
if (ledState == LOW)
{
ledState = HIGH;
interval = 500; // ********** sets on time
}
else
{
ledState = LOW;
interval = 100; // ********** sets off time
}
} //end if
digitalWrite(ledPin, ledState);
}
void recvOneChar()
{
if (Serial.available() > 0)
{
receivedChar = Serial.read();
newData = true;
}
}
Thanks ToddL1962 and groundFungus for your responses and the examples you provided. I'm pretty new to coding so seeing that approach really helped me learn.
I changed the code to Serial.readString() instead of just Serial.read() so that if multiple characters were input, it wouldn't be recognized as just 'a' or 'b'. So in the end the code runs the way I want it to and I learned a little bit about coding.
And if you keep using the String class you will, eventually, learn about chasing weird bugs. Read the evils of String page to see why.
The second example in Robin2's serial input basics tutorial (linked in reply #5) shows how to read multiple characters into a null terminated character array (string) without blocking (readString blocks).