Loop() question

I made this code for testing purposes, so I have one question about its working... I have HC-05 module connected on Arduino, and I'm sending text from my Android app to it.

String command; 
int RedLed = 9;

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

Serial.begin(9600);
} 
void loop() {
   
    while (Serial.available())
  { 
  delay(10); 
  char c = Serial.read(); 
  command += c; 
  }    
  if (command.length() > 0)
  {
    Serial.println(command);  
      
     if ( command == "blink") 
  {
digitalWrite ( BlueLed, HIGH);
delay(300);
digitalWrite ( BlueLed, LOW);
delay(300);
  }
  
command="";
} }

I wanted that LED blinks always when I send "blink" to Serial, but it does it just once.
It looks like I put if statement in setuo()...

Any help, please?

I'll bet if you sort out indentation, you'll see your problem

Use to format your sketch.

.

Do you want it to blink forever, or be able to send a "stop blink" command?

RedLed became a BlueLed along the way.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R

larryd:
Use to format your sketch.

Didn't knew that, thanks for the tip! :slight_smile:

jbellavance:
Do you want it to blink forever, or be able to send a "stop blink" command?

RedLed became a BlueLed along the way.

My bad, I have in my code multiple colors, so I made mistake while I copied code.
Yes, I wanted to blink forever...

Robin2:
Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R

Thank you, I will write here after I read all examples...

Cheers to all

Robin,

I tried your first example to combine with simple example 'blink without delay', using for instead of while, but still no luck.
Led just blink once (goes on or off).

const int ledPin =  9;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000;
char receivedChar;
boolean newData = false;

void setup() {
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
}

void loop() {
  recvOneChar();
  showNewData();
}

void recvOneChar() {
  if (Serial.available() > 0) {
    receivedChar = Serial.read();
    newData = true;
  }
}

void showNewData() {
  unsigned long currentMillis = millis();

  if (newData == true && receivedChar == 'q') {

    Serial.println(receivedChar);
    newData = false;

    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;

      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }

      digitalWrite(ledPin, ledState);
    }
  }
}

This code works fine on my NANO.

How is your serial monitor configured? No End of Line, CR only, LF only, CR/LF?

Is it running at 9600 baud?

I'm also testing it on Nano.
Baud is 9600, No line ending...

Then it should work.

Each time I send 'q' from the monitor, the led toggles fine.

Jacques

Don't know why, but I tried almost all digital pins, and all I get is that led goes ON (if it was OFF) and vice versa.
No blinking...

What actually do you mean by blinking? At what rate?

The code says that it toggles the led only when it recieves the letter 'q' from the serial monitor.

Jacques

I mean that it should(?) goes on and off every 1s (using millis istead of delay() )...

I would suggest that you put your blinking code in it's own function:

void blink() {Your blinking code}

Use a global variable

bool blinking = false;

In your showNewData(), replace your blinking code with:

if (recievedChar == 'q') blinking = true;

EDIT: And add the folowing line in the loop()if (blinking) blink();

Try this version:

const int ledPin    =  9;
const long interval = 1000;
byte ledState       = LOW;
unsigned long previousMillis = 0;
char receivedChar;
boolean newData   = false;
boolean flashFlag = false;

//************************************************************************
void setup()
{
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
  pinMode(ledPin, OUTPUT);    //<-----<<<<<
  digitalWrite(ledPin, HIGH); //HIGH = LED OFF
}

//************************************************************************
void loop()
{
  unsigned long currentMillis = millis();

  if (flashFlag == true && currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
  recvOneChar();
  showNewData();
}

//************************************************************************
void recvOneChar()
{
  if (Serial.available() > 0)
  {
    receivedChar = Serial.read();
    newData = true;
  }
}

//************************************************************************
void showNewData()
{
  if (newData == true && receivedChar == 'q')
  {
    Serial.println(receivedChar);
    newData = false;
    flashFlag = true;
  }
  else if (newData == true)
  {
    Serial.println(receivedChar);
    newData = false;
    flashFlag = false;
    digitalWrite(ledPin, HIGH); //HIGH = LED OFF
  }
}
//************************************************************************

EDIT:
Updated code for LED off at start up and !=q received.

Hi Larry,

I did'nt see the missing pinMode().

Flashing the LED in the loop is another way of going about it. I just prefer to create new functions for code that has a particular functionnality.

It then can be easily changed to:void blink(byte pin) {...}or even:void blink(byte pin, int blinkRate) {...}

Jacques

Hi Jacques
2'C here and you are having +30'C, go figure.

I just prefer to create new functions for code that has a particular functionnality.

Yes that can make things neat.

I place all timing stuff in loop() so I can see at a glance what is checked each time through loop(), personal preference I guess.

.

Hi Jacques, hi larryd...

I tried your version of code, but all I'm getting is that LED is always HIGH, no react on command 'q'...

I just tried the sketch, it works fine.

Set up your serial monitor to 'no line ending' characters.

A lower case q will turn on the LED (flashes), any other character will turn it off.

.

And so does this:

const int ledPin =  13;
int ledState = LOW;
unsigned long previousMillis;
const long interval = 1000;
char receivedChar;
boolean newData = false;
boolean blinking =  false;

void setup() {
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
  pinMode(ledPin, OUTPUT);
}

void loop() {
  recvOneChar();
  showNewData();
  if (blinking) blink();
}
void blink() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}

void recvOneChar() {
  if (Serial.available() > 0) {
    receivedChar = Serial.read();
    newData = true;
  }
}

void showNewData() {
  if (newData == true) {
    Serial.println(receivedChar);
    newData = false;
    if (receivedChar == 'q') blinking = true;
  }
}