Go Down

Topic: LED fading timing (Read 350 times) previous topic - next topic

RAMKARTHIK

I'm newbie to Arduino.
I want LED to blink at 1st click , fade at 2nd click , hold for the period of time pressed at 3rd click/hold.
Everything is working fine.
But I want to adjust the timing of fading.
I want it to Fade Out and Fade In then Wait for 2 seconds to start ease up again.
but it's fading in and out with the same frequency.It's not holding the time for OFF state.
If I use delay() instead of millis() it's working fine.
But I don't want to pause the program.Thanks :) .





Code: [Select]
/*
 This is a sample sketch to show how to use the OneButtonLibrary
 to detect click events on 2 buttons in parallel.
 The library internals are explained at
 http://www.mathertel.de/Arduino/OneButtonLibrary.aspx
 
 Setup a test circuit:
 * Connect a pushbutton to pin A1 (ButtonPin) and ground.
 * Connect a pushbutton to pin A2 (ButtonPin) and ground.
 * The Serial interface is used for output the detected button events.
 
 The Sketch shows how to setup the library and bind 2 buttons to their functions.
 In the loop function the button1.tick and button2.tick functions have to be called as often as you like.
 */

// 01.03.2014 created by Matthias Hertel
// ... and working.

/* Sample output:

Starting TwoButtons...
Button 1 click.
Button 2 click.
Button 1 doubleclick.
Button 2 doubleclick.
Button 1 longPress start
Button 1 longPress...
Button 1 longPress...
Button 1 longPress...
Button 1 longPress stop
Button 2 longPress start
Button 2 longPress...
Button 2 longPress...
Button 2 longPress stop

*/

#include "OneButton.h"

// Setup a new OneButton on pin A1. 
OneButton button1(A1, true);
// Setup a new OneButton on pin A2. 
OneButton button2(A2, true);
int led = 9;
int i=0;
int inc=5;
int clik=0;
int period =2000;
unsigned long current_time = 0;

// setup code here, to run once:
void setup() {
  // Setup the Serial port. see http://arduino.cc/en/Serial/IfSerial
  Serial.begin(9600);
  pinMode(led , OUTPUT);
  Serial.println("Starting TwoButtons...");

  // link the button 1 functions.
  button1.attachClick(click1);
  button1.attachDoubleClick(doubleclick1);
  button1.attachLongPressStart(longPressStart1);
  button1.attachLongPressStop(longPressStop1);
  button1.attachDuringLongPress(longPress1);

  // link the button 2 functions.
  button2.attachClick(click2);
  button2.attachDoubleClick(doubleclick2);
  button2.attachLongPressStart(longPressStart2);
  button2.attachLongPressStop(longPressStop2);
  button2.attachDuringLongPress(longPress2);

} // setup


// main code here, to run repeatedly:
void loop() {
  // keep watching the push buttons:
  unsigned long cms = millis();
  button1.tick();
  button2.tick();
    if (clik ==1){
    analogWrite(led , 255);
    delay(100);
    analogWrite(led , 0);
    delay(100);
  }
  if (clik == 2 ){
    if (i==0){
      analogWrite(led , 0);
     if(millis() > current_time + period){
      current_time = millis();
      analogWrite(led , 0);
     }
      }
//This is where i stuck
   analogWrite(led , i);
   i = i + inc;
   if(i == 0 || i == 255){
    inc = -inc;
   }
   delay(100);
  }
   if (clik == 3) {
    analogWrite(led , 255);
  }
  if (clik == 4){
    analogWrite(led , 0);
  }
 

  // You can implement other code in here or just wait a while
  delay(10);
} // loop


// ----- button 1 callback functions

// This function will be called when the button1 was pressed 1 time (and no 2. button press followed).
void click1() {
  clik = 1;
  Serial.println(clik);
 
} // click1


// This function will be called when the button1 was pressed 2 times in a short timeframe.
void doubleclick1() {
    clik = 2;
    Serial.println(clik);
} // doubleclick1


// This function will be called once, when the button1 is pressed for a long time.
void longPressStart1() {
  Serial.println("Button 1 longPress start");
} // longPressStart1


// This function will be called often, while the button1 is pressed for a long time.
void longPress1() {
    clik =3;
     Serial.println(clik);
} // longPress1


// This function will be called once, when the button1 is released after beeing pressed for a long time.
void longPressStop1() {
  clik = 4;
  Serial.println(clik);
 } // longPressStop1


// ... and the same for button 2:

void click2() {
  Serial.println("Button 2 click.");
} // click2


void doubleclick2() {
  Serial.println("Button 2 doubleclick.");
} // doubleclick2


void longPressStart2() {
  Serial.println("Button 2 longPress start");
} // longPressStart2


void longPress2() {
  Serial.println("Button 2 longPress...");
} // longPress2

void longPressStop2() {
  Serial.println("Button 2 longPress stop");
 
} // longPressStop2


// End






Grumpy_Mike

You need to write your program as a state machine. Each state of the state machine can be given its own repeat time. Thus you can set exactly what your sequence is going to be. The state machine is advanced by push button or in the case of your wait in the next calling of that state. The time for the next state is set when the previous state increments the state variable.

No doubt you will not understand this but read up on state machines and come back and ask about specificity what you don't understand.

RAMKARTHIK

Code: [Select]
#include "OneButton.h"

OneButton button1(A1 , true);
OneButton button2(A2 , true);
OneButton button3(A3 , true);

int led;
int led1 = 9;
int current_led;
int led2 = 10;
int led3 = 11;
int i = 0;
int incriment = 5;
int bc1 = 0;
int bc2 = 0;
int bc3 = 0;
int delayperiod =2000;
unsigned long current_time;
unsigned long previous_time = 0;
int s1 , s2 , s3 ;


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

  //Buttons Link
  button1.attachClick(click1);
  button2.attachClick(click2);
  button3.attachClick(click3);
}

void loop() {
  // put your main code here, to run repeatedly:
  button1.tick();
  button2.tick();
  button3.tick();

  s1 = switch1(led);
  s2 = switch2();
//  s3 = switch3();
 }

void click1() {
   
    bc1 += 1 ;
    if (bc1 > 3) {
      bc1 = 1;
    }
    Serial.println(bc1);
    delay(10);
}

void click2() {
  bc2 += 1;
  if (bc2 > 7) {
    bc2 = 1;
  }
  Serial.println(bc2);
  delay(10);
}

void click3() {
  bc3 += 3;
  if (bc3 > 4) {
    bc3 = 1;
  }
  Serial.println("3");
  delay(10);
}



//Switch
  int switch1(int) {
  switch (bc1) {
  case 1:
  analogWrite(led1 , 255);
  current_led = bc1;
  int led = led1;
  break;
 
  case 2:
  analogWrite(led2 , 255);
  current_led = bc1;
  led = led2;
  break;

  case 3:
  analogWrite(led3 , 255);
  current_led = bc1;
  led = led3;
  break;
}
  return (led);
  }

  int switch2() {
    unsigned long tt = millis();
    switch (bc2) {
      case 1:
     
       Serial.println(led1);
       long ttt = tt - previous_time;
       if(ttt>=4000){
        previous_time = tt;
       }

       if(ttt >= 4000){
       if (digitalRead(9) == HIGH) {
        analogWrite(9 , 0);
       } else{
        analogWrite(9 , 255);
       }
       }
       break;
    }
  }




How to get these values and use it all over the program?
To identify which LED is active currently
-Thanks again.

Grumpy_Mike

Quote
How to get these values and use it all over the program?
What values?

Did you decide to ignore my advice? It looks like it to me.

RAMKARTHIK

so isn't that a state machine ?  :smiley-sad-blue:   i'm really sorry.
I'll try more. and no I never ignore a legend's advice. I'm sorry again. I know programming language a bit but not that deep.

Grumpy_Mike

Quote
so isn't that a state machine ?
No it is not. Any why use that silly library? It only hides simple code from you and leaves you with a black box.

RAMKARTHIK

So how about this? Is this the State Machine right?


Code: [Select]

enum led{ON , OFF};
led led1 = ON;
int ledPin1 = 9;
int ledPin2 = 10;
int off = 1000;
int on = 1000;
unsigned long sec = millis();

void blinkM() {
  switch(led1) {
    case OFF: {
    if (millis() - sec >= off) {
      sec = millis();
      analogWrite(ledPin1 , 255);
      analogWrite(ledPin2 , 255);
      led1 = ON;     
      Serial.println("ON");
    }
    break;
  }
    case ON: {
    if (millis() - sec >= on) {
      sec = millis();
      analogWrite(ledPin1 , 0);
      analogWrite(ledPin2 , 0);
      led1 = OFF;
      Serial.println("OFF");
    }
    break;
}
}
}





void setup() {
  // put your setup code here, to run once
  pinMode(ledPin1 , OUTPUT);
  pinMode(ledPin2 , OUTPUT);
  analogWrite(ledPin1 , 0);
  analogWrite(ledPin2 , 0);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  blinkM();
}

Grumpy_Mike

#7
Oct 12, 2018, 06:04 pm Last Edit: Oct 12, 2018, 06:04 pm by Grumpy_Mike
Sorry but not quite right for a state machine.
You are always calling the blinkM() from the top function and then are running one of two states based on the current time given by the millis and the sec variable.

You should only be running the blinkM function when it is time to.

This is what you need to do, compiled but not tested:-
Code: [Select]
byte state = 0;
int ledPin1 = 9;
int ledPin2 = 10;
unsigned long  timesUp[] = {1000, 1000}; // time for each state
unsigned long lastTime = millis();

void setup() {
  pinMode(ledPin1 , OUTPUT);
  pinMode(ledPin2 , OUTPUT);
  analogWrite(ledPin1 , 0);
  analogWrite(ledPin2 , 0);
  Serial.begin(9600);
}

void loop() {
  if(millis() - lastTime > timesUp[state]) blinkM(); // only call your function when you need to.
// add more state machines / tasks here
}

void blinkM() {
  switch(state) {
    case 0: {
      lastTime = millis();
      analogWrite(ledPin1 , 255);
      analogWrite(ledPin2 , 255);
      state = 1; // change the state    
      Serial.println("ON");
    }
    break;
    case 1: {
      lastTime = millis();
      analogWrite(ledPin1 , 0);
      analogWrite(ledPin2 , 0);
      state = 0; // change the state
      Serial.println("OFF");
   }
 }
}

Go Up