Go Down

Topic: millis() blink != 50/50 (Read 3641 times) previous topic - next topic

lloyddean

Brevity is not clarity.

And stop acting like a child.  This wasn't aimed at you it's a common complaint I have with most programming forums.

Nick Gammon

Right. Let's move on. All of the solutions posted have their merits. Let's not descend into a flame war.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

lloyddean

And to this I agree with!!

GoForSmoke

Here is a user interactive version, it blinks the on-board led on my UNO.
Enter numbers from 0 to 999 through serial and that will be the millisecs/second the led stays on.

Code: [Select]

unsigned long waitUntil = 0UL; // because millis() returns UL
enum whatFlag { led13state, endOfLine, dataBegun };
byte  Flags = 0;

void setup()
{
  pinMode( 13, OUTPUT );
  digitalWrite( 13, bitRead( Flags, led13state )); 
  Serial.begin( 9600 );
  Serial.println( "Blink w/user input. Enter up to 1000 for led-on interval" );
  Serial.println();
}

void loop()
{
  static byte  c; // c for character buffer
//  static byte  endOfLineState = 0;
  static unsigned long timeSinceLastSerialRead = 0UL;
  static int enter = 0; // to get serial-entered number value.
  static int ledMillisOn = 100;  // must be 0-999
 
  // flash led and state changer
  if ( waitUntil - millis() >= 10000UL )  // when millis() passes waitUntil the _unsigned_ subtract
  {                                       // leaves very large positive result
    Flags ^= ( 1 << led13state ); // led13state T/F bit toggle

    if (bitRead( Flags, led13state ))  waitUntil = millis() + (unsigned long)(ledMillisOn);
    else                              waitUntil = millis() + (unsigned long)(999 - ledMillisOn);
    digitalWrite(13, bitRead( Flags, led13state )); 
  }
 
  // serial input
  if (Serial.available())
  {
    c = Serial.read();
//    Serial.print(".");
//    Serial.print( c );
    timeSinceLastSerialRead = millis();
    if ( c >= '0' && c <= '9' )
    {
      enter *= 10;  // decimal shifting whatever is in enter 1 place up
      enter += ( c - '0' ); // ascii 48 is '0'
      bitSet(Flags, dataBegun );  // entry is treated as finished
      if ( enter >= 100 ) // next digit being able to take the total > 999
      {
        bitSet(Flags, endOfLine );  // entry is treated as finished
      }
    }
    else if (( c == 13 || c == 10 ) && bitRead( Flags, dataBegun ))
    {
      bitSet( Flags, endOfLine );  // entry is treated as finished
    }
    else if (( millis() - timeSinceLastSerialRead >= 500 ) && ! bitRead( Flags, endOfLine ))
    {
      bitSet( Flags, endOfLine );  // entry is treated as finished
    }
  }
 
  // serial output
  if ( bitRead( Flags, endOfLine ) && bitRead( Flags, dataBegun )) // should be done and have data
  {
    Serial.print( ">> " );
    Serial.print( enter );
    Serial.println( " <<" );

    ledMillisOn = enter;
    enter = 0;
    bitClear( Flags, endOfLine );
    bitClear( Flags, dataBegun ); // clears bits, endOfLine and dataBegun
  }
}

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy