Go Down

Topic: Modify the program "Blink without Delay" to count down and up (Read 112 times) previous topic - next topic

mkto

Hello,

I'm sorry if someone has already asked a similar question.

I'm currently working on a strobescope program using the millis() function.
The reason I'm using millis() is because I want to have several LEDs flashing simultaneously in different frequencies(this part wasn't so hard).
The program below is a simplified version of the program I'm working on, which is based on the "Blink without Delay" program introduced as an example in a tutorial. http://arduino.cc/en/Tutorial/BlinkWithoutDelay

What I want to do in the version below is to have the blinking frequency go down(or up) after going up(or down).
This program is partially working, because the frequency goes down once, and then goes back up once, but after that the frequency keeps on going down.

Code: [Select]


/* Modified "Blink without Delay" */

// constants won't change. Used here to
// set pin numbers:
const int ledPin =  13;      // 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 = 100;           // interval at which to blink (milliseconds)

int i = 0;    //using to count
int up = 1;    //using as a flag to indicate if the program to count up or down

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

void loop()
{

 unsigned long currentMillis = millis();

 if(currentMillis - previousMillis > interval && up == 1) {
   // save the last time you blinked the LED
   previousMillis = currentMillis;
   i = i + 5;  
   interval = interval + i;
   
   digitalWrite(ledPin, HIGH);
   if(interval >= 300)up = 0;
 }
 
   if(currentMillis - previousMillis > interval && up == 0) {
   // save the last time you blinked the LED
   previousMillis = currentMillis;
   i = i - 5;  
   interval = interval - i;
   
   digitalWrite(ledPin, HIGH);
    if(interval <= 100)up = 1;
 }
 
 if(currentMillis - previousMillis > 5)digitalWrite(ledPin, LOW);    //turn LED off right after it's turned on
 
}



To have the program decide if it has to count up or down, I'm using the integer "up" and am switching between 1 or 0. If "up" is 1, the code

if(currentMillis - previousMillis > interval && up == 1) {
   // save the last time you blinked the LED
   previousMillis = currentMillis;
   i = i + 5;  
   interval = interval + i;
   
   digitalWrite(ledPin, HIGH);
   if(interval >= 300)up = 0;
 }

is chosen, and if up is 0, the program

if(currentMillis - previousMillis > interval && up == 0) {
   // save the last time you blinked the LED
   previousMillis = currentMillis;
   i = i - 5;  
   interval = interval - i;
   
   digitalWrite(ledPin, HIGH);
    if(interval <= 100)up = 1;
 }

is chosen.

In my understanding, this program should continuously make the frequency go up and down again and again, but for some reason it only does that once and keeps on going down after that.
Can anyone explain why it does so, and are there any ways to solve that problem?

Thank you very much for your attention.

Best,

mkto


Robin2

You don't need to test the time twice. Try something like this (assumes you want to change by 20 each step)
 
Code: [Select]
// at the top of the program
  int i = 20;
  unsigned long interval = 100


// in loop()
  if(currentMillis - previousMillis > interval ) {
    // save the last time you blinked the LED
    previousMillis += interval;  // keeps the timing tighter
   
    interval = interval + i; // if i is negative this will reduce
   
    digitalWrite(ledPin, ! digitalRead(ledPin); // toggles the pin
    if(interval > 300 || interval < 100) {
        i = - i;   // changes the value from + to - etc
    }
  }


...R

UKHeliBob

Code: [Select]
    i = i - 5;   
    interval = interval - i;

What will happen to the value of interval when i goes negative ?

Try printing i and interval just before the test for the value of interval
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

mkto

Ok I understand and fixed the program to

Code: [Select]


if(currentMillis - previousMillis > interval && up == 1) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    interval = interval + 20;
   
    digitalWrite(ledPin, HIGH);
    if(interval >= 300)up = 0;
  }
 
    if(currentMillis - previousMillis > interval && up == 0) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
   
    interval = interval - 20;
   
    digitalWrite(ledPin, HIGH);
     if(interval <= 90)up = 1;
  }



and it seems to be working.

Thanks again!

mkto


Go Up