I fixed leaving Serial.available() by mistake

Hello everyone,

I tried the whole day to leave Serial.available() but it doesn't work.

Then I tried something by mistake and it works.

( (I create a lable called done: )) then I put it in other if statement, and it done I left,

I tried other if statement but it doesn't work, just where I put it at the beginning.

What I want now is, someone expert to explain what had I done to leave success leave Serial.available().

Here is the whole code.

unsigned long T1=0;
unsigned long T2=0;
int interval1 = 1000;
int interval2 = 2000;

unsigned long c=0;
int s=0;
int m=0;
int h=0;
int cmd2;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  
  unsigned long mT = millis();

  while(Serial.available()>0){
   String cmd = Serial.readStringUntil("/n");
    cmd.trim();
    //char cr[3];
    //cmd.toCharArray(cr, 3);
 //Serial.println(cmd2);
    if(cmd.indexOf("m")>=0){
      
      ask:
      cmd2 = Serial.parseInt();
      
      if(cmd2 != 0){
        Serial.println(cmd2);
      m = cmd2;
      s= 0;
      mT = millis();
      T1 = mT;
      T2 = mT;
      Serial.println("done");
       goto done;
      
      }else{
        Serial.println("Enter Time minute : ");
        goto ask;
      }
    }
 if(cmd.indexOf("h")>=0){
      
      ask2:
      cmd2 = Serial.parseInt();
      
      if(cmd2 != 0){
        Serial.println(cmd2);
      h = cmd2;
      s= 0;
      mT = millis();
      T1 = mT;
      T2 = mT;
      Serial.println("done");
       goto done;
      
      }else{
        Serial.println("Enter Time hour : ");
        goto ask2;
      }
    }
  }



if(mT - T1 == interval1 && mT - T2 != interval2){
  digitalWrite(13, 1);
  T1 = mT; 
}

if(mT - T2 == interval2){
  digitalWrite(13, 0);
  T1 = mT;
  T2 = mT;
}

if(mT - c == 1000){done:
  c = mT;
  s++; 
  if(s >= 60){
  m++;
  s=0;
}

if(m >= 60){
  h++;
  m=0;
}

if(h >= 24){
  h=0;
}

  Serial.print(h);
Serial.print(":");
Serial.print(m);
Serial.print(":");
Serial.println(s);
}

}

goto

:scream: :scream: :scream: :scream: :scream: :scream: :scream: :scream:

you probably meant '\n' , didn't you ?? :innocent:

your code is flawed with timeout issues due to the functions you are using. I would suggest to study Serial Input Basics to handle this

3 Likes
    while (Serial.available ()>0){
        String cmd = Serial.readStringUntil ("/n");
        cmd.trim ();
        //char cr[3];
        //cmd.toCharArray (cr, 3);
        //Serial.println (cmd2);
        if (cmd.indexOf ("m")>=0){
ask:
            cmd2 = Serial.parseInt ();

            if (cmd2 != 0){
                Serial.println (cmd2);
                m = cmd2;
                s= 0;
                mT = millis ();
                T1 = mT;
                T2 = mT;
                Serial.println ("done");
                goto done;

            }else{
                Serial.println ("Enter Time minute : ");
                goto ask;
            }
        }

is the above code really doing what you think?

it looks like it waits for a \n. if there's a non-zero value, it sets T1 and T2 to the value. but of there's no value, it prints "Enter Time minute".

i assume you want to enter a value after the prompt. but there isn't a prompt until there is an empty line entered. And i think similar for the hour prompt

    if (mT - c == 1000){
done:

not sure why done: is inside the conditional.
one reason my college professor said he would fail anyone for using gotos is that it makes the code harder to follow. (there are very good reasons to use gotos, exception handling)

looks like the following is what you want to do

    if (mT - T1 == interval1 && mT - T2 != interval2){
        digitalWrite (13, 1);
        T1 = mT;
    }

    if (mT - T2 == interval2){
        digitalWrite (13, 0);
        T1 = mT;
        T2 = mT;
    }

why not make that code conditional when the T1 and T2 values are set.

a prompt can be generated in setup() and after reading input and have another piece of code check for input which is a single line containing the hours and minutes and sets T1 and T2 accordingly

    if (Serial.available()) {
         ...

The code is working very well

Guys The code is just for fun, I am testing waiting without delays ( I create flashing arduino led ) and I create a clock, and I could change minutes and hours from Serial monitor by enter m then number to change minutes and h then number to change hours

Check done: here

let's say that It miraculously functions may be ...

video for the code using arduino nano

Good evening
Yes it is,
but if you are expert I want suggest from you
I am here because I want to learn, I am beginner
Thank you

hahahah
it did the same work

So what do you think "/n" is ?

Mistake, I changed it :saluting_face:

Hope you like spaghettis :slight_smile:

1 Like

look this over
keep it simple

// simple clock

unsigned long c=0;
int s=0;
int m=0;
int h=0;

const byte PinLed = LED_BUILTIN;
char t [80];

void loop ()
{
    unsigned long mT = millis ();

    if (Serial.available ()) {
        int n = Serial.readBytesUntil ('\n', t, sizeof(t)-1);
        t [n] = '\0';
        sscanf (t, "%d:%d", &h, &m);
    }

    // display time
    if (mT - c >= 1000) {
        c = mT;

        digitalWrite (PinLed, ! digitalRead (PinLed));

        s++;
        if (s >= 60) {
            m++;
            s=0;
        }

        if (m >= 60) {
            h++;
            m=0;
        }

        if (h >= 24) {
            h=0;
        }

        sprintf (t, "%2d:%02d:%02d", h, m, s);
        Serial.println (t);
    }
}

void setup () {
    Serial.begin (9600);
    pinMode (PinLed, OUTPUT);
    Serial.println ("Enter Time as hh:mm");
}
1 Like

Thank you, I will keep it
And I will learn many new things from this code
I am excited :grin:

But you have not yet answered to the following question of post #12?

he did

I thought that that was a question to OP instead of correcting that.

I am not sure I meant to take any order after click enter in the serial