Go Down

Topic: led strobe without delays help? (Read 6517 times) previous topic - next topic

cubmanky

Mar 10, 2014, 10:20 pm Last Edit: Mar 12, 2014, 10:43 pm by cubmanky Reason: 1
I have the following that works great

Code: [Select]
void wing_strobe() {

  digitalWrite(6, LOW);
  delay(30);           
 
  digitalWrite(6, HIGH);
  delay(120);           
 
  digitalWrite(6, LOW); 
  delay(30);
 
   digitalWrite(6, HIGH);
  delay(2000);
}
void loop() {
  wing_strobe();


I need to change this over to code without delays.   I have played around with millis() but I can not get it to blink in the pattern above.  

cubmanky

#1
Mar 10, 2014, 10:53 pm Last Edit: Mar 12, 2014, 10:44 pm by cubmanky Reason: 1
I came up with this code but it will not work

Code: [Select]
int ledPin9 = 9;  //  White LED connected to digital pin 9

long time = 0, strobetime1, strobetime2, strobetime3, strobetime4, strobetime5;
int periode = 1000;
const unsigned long strobeinterval = 300;  // strobe time.
unsigned long strobetimer;  // time


void setup()   {               
  // initialize outputs:

  pinMode(ledPin9, OUTPUT);
  strobetimer = millis ();
  strobetime1=millis();   // set time as now
  strobetime2=millis()+30; //first strobe duration
  strobetime3=millis()+100;   // short wait
  strobetime4=millis()+150; //second strobe duration
  strobetime5 = 1000; //long wait
}

//void loop()    {                 

void strobeflash ()  {
  {

    // Strobe Sequence :
//   strobetime1=millis();   // set time as now

    if(millis()>strobetime1) // first strobe flash
      digitalWrite(ledPin9, HIGH);   // set the LED on
    if(millis()>strobetime2) // short wait
      digitalWrite(ledPin9, LOW);    // set the LED off
    if(millis()>strobetime3) // second strobe flash
      digitalWrite(ledPin9, HIGH);   // set the LED on
    if(millis()>strobetime4) // end of second flash
      digitalWrite(ledPin9, LOW);    // set the LED off

  }
}
void loop ()
  {
  // Reset strobe
  if ( (millis () - strobetimer) >= strobeinterval)
    strobeflash ();
    }  // end of loop

MAS3

#2
Mar 10, 2014, 11:26 pm Last Edit: Mar 10, 2014, 11:28 pm by MAS3 Reason: 1
Hi.

Posted a lot on your first day (haven't seen the other posts yet).
But still, slow down.

Let me ask you first to read this (click !).
It is on top in every part of the forum, and tells you how to use it.
Don't think you know all that, just read it once or twice and use the information.

So next time you post some code, put it in code tags like this:[code] put it here [/code].

Your code can't be right.
You are trying to work with something that constantly changes (time), but you are assigning constants to it, even though you do not define them as such.

Code: [Select]
void setup()   {              
 // initialize outputs:

 pinMode(ledPin9, OUTPUT);
 strobetimer = millis ();
 strobetime1=millis();   // set time as now
 strobetime2=millis()+30; //first strobe duration
 strobetime3=millis()+100;   // short wait
 strobetime4=millis()+150; //second strobe duration
 strobetime5 = 1000; //long wait
}

This is effectively assigning constants.
Setup is only run once.
Read millis() as "now".
Then you set strobetime1 to now, exaclty like you described.
And strobetime2 to now (a fraction later than the now in strobetime1) + 30 milliseconds
And so on.

Then you are checking to see some things are true, but at least after the first iteration they are always true.
Code: [Select]
void strobeflash ()  {
 {

   // Strobe Sequence :
//   strobetime1=millis();   // set time as now

   if(millis()>strobetime1) // first strobe flash
     digitalWrite(ledPin9, HIGH);   // set the LED on
   if(millis()>strobetime2) // short wait
     digitalWrite(ledPin9, LOW);    // set the LED off
   if(millis()>strobetime3) // second strobe flash
     digitalWrite(ledPin9, HIGH);   // set the LED on
   if(millis()>strobetime4) // end of second flash
     digitalWrite(ledPin9, LOW);    // set the LED off

 }
}

The short wait might be an actual wait only the first iteration, after that millis will for sure always be > strobetime2
So your sketch can't do what you expect it to do.

What you might want to do, is this:
Code: [Select]
 strobetime1=millis();   // set time as now
 const long strobetime2=30;     //first strobe duration
 const long strobetime3=100;   // short wait
 const long strobetime4=150;   //second strobe duration
 const long strobetime5 = 1000; //long wait

And then check to see what timers have elapsed by comparing them to a variable that was set by millis() when strobeinterval lapsed.
Because you are comparing to a long (millis()), you should use a long here too.

Study blink without delay some more.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

cubmanky

ok I can see how your code will work.  but i'm lost on how to fit it into what i have. 

MAS3

Ok.

You need to keep track of what you're doing and have been doing.
You also need to ask yourself if you really need to use that extra function (void strobeflash() ), but in this case that doesn't really matter.

Keeping track of what you're doing requires some extra variables.
This variable is a flag that tells you in what state you are, and this approach is also known as a state machine (you can and should do some research on that).
It will allow you to skip or do some part of your code, depending on a decision that was made earlier.
In this case, the lapse of strobetimer should trigger some flag, and that flag (together with strobetimer itself) should also be reset at some place in your sketch.

There is absolutely no difference to the blink without delay sketch here.
Try to build code and show it.
There will be someone that tells you where you're doing the right thing and where not.
You will only learn by doing, make mistakes and understand those mistakes.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

cubmanky

SO I have this much working
Code: [Select]
/* Blink without Delay

Turns on and off a light emitting diode(LED) connected to a digital 
pin, without using the delay() function.  This means that other code
can run at the same time without being interrupted by the LED code.

The circuit:
* LED attached from pin 13 to ground.
* Note: on most Arduinos, there is already an LED on the board
that's attached to pin 13, so no hardware is needed for this example.


created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen

This example code is in the public domain.


http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

// constants won't change. Used here to
// set pin numbers:
const int strobe1Pin =  9;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)
  const long strobe1time2=30;     //first strobe duration
  const long strobe1time3=100;   // short wait
  const long strobe1time4=150;   //second strobe duration
  const long strobe1time5 = 1800; //long wait
 
void setup() {
  // set the digital pin as output:
  pinMode(strobe1Pin, OUTPUT);     
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.
  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
//unsigned long currentMillis = millis();
unsigned long strobe1time1 = millis();   // set time as now

  if(strobe1time1 - previousMillis > strobe1time2) {
    //     digitalWrite(strobe1Pin, HIGH);   // set the LED on
//  if(strobe1time2 - previousMillis > 30)
//        digitalWrite(strobe1Pin, LOW);   // set the LED on
         
         
         
   
    // save the last time you blinked the LED
    previousMillis = strobe1time1 ; 

    // if the LED is off turn it on and vice-versa:
if (ledState == LOW)
    ledState = HIGH;
  else
    ledState = LOW;

    // set the LED with the ledState of the variable:
  digitalWrite(strobe1Pin, ledState);
  }
}


I know if I change out
Code: [Select]
  if(strobe1time1 - previousMillis > strobe1time2) {
         digitalWrite(strobe1Pin, HIGH);   // set the LED on

that will turn the LED on.
I treid teh second line of code as
Code: [Select]
if(strobe1time1 - previousMillis > strobe1time2) {
         digitalWrite(strobe1Pin, HIGH);   // set the LED on
  if(strobe1time1 - previousMillis > strobe1time3)
        digitalWrite(strobe1Pin, LOW);   // set the LED on

it will not work. 
Time for bed but more work in the moring

cubmanky

This somewhat works.  The LED blinks but then stays dim   
Code: [Select]
/* Blink without Delay


*/

// constants won't change. Used here to
// set pin numbers:
const int ledPin =  9;      // the number of the LED pin

// Variables will change:
//int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval1 = 50;           // interval at which to blink (milliseconds)
long interval2 = 200;           // interval at which to blink (milliseconds)
long interval3 = 400;           // interval at which to blink (milliseconds)
long interval4 = 1000;           // interval at which to blink (milliseconds)


void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);     
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval1) {digitalWrite(ledPin, HIGH);}
  if(currentMillis - previousMillis > interval2) {digitalWrite(ledPin, LOW);}
  if(currentMillis - previousMillis > interval3) {digitalWrite(ledPin, HIGH);}
  if(currentMillis - previousMillis > interval4) {digitalWrite(ledPin, LOW);

    previousMillis = currentMillis; 

   
}}


This works for one quick blink then a long delay
Code: [Select]
/* Blink without Delay


*/

// constants won't change. Used here to
// set pin numbers:
const int ledPin =  9;      // the number of the LED pin

// Variables will change:
//int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval1 = 50;           // interval at which to blink (milliseconds)
long interval2 = 900;           // interval at which to blink (milliseconds)
long interval3 = 400;           // interval at which to blink (milliseconds)
long interval4 = 1000;           // interval at which to blink (milliseconds)


void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);     
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval1) {digitalWrite(ledPin, HIGH);}
  if(currentMillis - previousMillis > interval2) {digitalWrite(ledPin, LOW);
// if(currentMillis - previousMillis > interval3) {digitalWrite(ledPin, HIGH);}
//  if(currentMillis - previousMillis > interval4) {digitalWrite(ledPin, LOW);

    previousMillis = currentMillis; 

   
}}


MAS3

#7
Mar 12, 2014, 11:27 pm Last Edit: Mar 13, 2014, 08:00 am by MAS3 Reason: 1
OK, some progress is made, so well done.
You'll get this done before next weekend if you stay at this rate.

You have now changed blink without delay in such way you think it can handle more than 2 states: on and off for a fixed time.
This is almost true, but you are missing 2 important steps.
The first one is that you forgot to keep track of what interval number you are working on at that moment.
The second one is that you are always, in every iteration, updating previousMillis to currentMillis, you really don't want to do that.
You only should update that if some requirements are met.

Tip: Find out what these curly braces { } are about, and why some people argue about two of them being at the same line.

By the way, i would not check the smallest number first.
If you check the largest number first, if that isn't met the second largest number and so on, you don't need my first step above.
So you don't need to keep track of an interval number and you will save some memory.
Not important at the moment but this will be in future code.


Edit:
Sorry that last part is incorrect.
In this case, one found value doesn't mean the other values are not true.
So when you are looking for interval4, interval3 will trigger in case you have a value of 600.
That would prevent you from ever reaching interval4.
Therefore, you should keep track of at what interval you are working at the moment and create another variable for that..
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

cubmanky

my brain is fried for now.  I just downloaded Beginning Arduino, 2nd Edition so I hop that helps.   Google has been great. 

MAS3

Read my last reply again, i made a mistake yesterday.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

cubmanky

That was the key, along with a few hours of sleep. 
Code: [Select]
/* nav strobe
Written by C Brooks
3-13-14


*/

// constants won't change. Used here to
// set pin numbers:
const int stro1Pin =  9;      // the number of the LED pin

// Variables will change:

int stro1num = 1;             // ledState used to set the LED
long prestro1Millis = 0;        // will store last time LED was updated
long stro1interval1 = 50;           // interval at which to blink on(milliseconds)
long stro1interval2 = 100;           // interval at which to blink off(milliseconds)
long stro1interval3 = 150;           // interval at which to blink on(milliseconds)
long stro1interval4 = 1800;           // interval at which to blink off(milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(stro1Pin, OUTPUT);     
}

void loop()
{
  // check to see what strob count you are on to see what interval is needed
  unsigned long curstro1Millis = millis();  // set time to now
if (stro1num == 1)   //first blink on
  if(curstro1Millis - prestro1Millis > stro1interval1) {digitalWrite(stro1Pin, HIGH); stro1num = 2;}
if (stro1num == 2)  //first blink off
  if(curstro1Millis - prestro1Millis > stro1interval2) {digitalWrite(stro1Pin, LOW); stro1num = 3;}
if (stro1num == 3)  //second blink on
  if(curstro1Millis - prestro1Millis > stro1interval3) {digitalWrite(stro1Pin, HIGH); stro1num = 4;}
if (stro1num == 4 )  //second blink of
  if(curstro1Millis - prestro1Millis > stro1interval4) {digitalWrite(stro1Pin, LOW); stro1num = 1;
 
  prestro1Millis = curstro1Millis;  // set the time to start loop over
  }
}

MAS3

So that is the working code ?
Has the weekend arrived already ? ;)

Instead of doing this:
Code: [Select]
if (stro1num == 1)   //first blink on
  if(curstro1Millis - prestro1Millis > stro1interval1) {digitalWrite(stro1Pin, HIGH); stro1num = 2;}


You should also be able to do this:
Code: [Select]
if (stro1num == 1) && (curstro1Millis - prestro1Millis > stro1interval1) {digitalWrite(stro1Pin, HIGH); stro1num = 2;}
That should optimize your code, because you are not doing 2 if statements, but still you are processing 2 conditions.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

cubmanky

I'll give it a try.   Now to add this code to my other code and finish my rc navigational lights. 

cubmanky

Forgot about && but the correct code for the is
Code: [Select]
if (stro1num == 1 && curstro1Millis - prestro1Millis > stro1interval1) {digitalWrite(stro1Pin, HIGH); stro1num = 2;} // 1st flash on

Go Up