Pages: [1]   Go Down
Author Topic: Turn on LED with switch using millis (solved)  (Read 1205 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I want to push a button to turn on a LED for 4 seconds using millis. I think I almost got it, but it is not working the way i wanted to. I do not want to use a delay as I will be working with more than one LED.

code:
Code:
const int buttonPin = 41;     // the number of the pushbutton pin
const int ledPin =  39;      // the number of the LED pin
unsigned long time;
// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);  
  digitalWrite(ledPin, LOW);  
}

void loop(){
  time = millis();
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {  
    digitalWrite(ledPin,HIGH);
    {
    if (time >= 1000 && time < 1020){
     digitalWrite(ledPin,HIGH);
   }  // turn it on when its been running for a second
  
   if (time >= 4000 && time < 4020){
     digitalWrite(ledPin,LOW);
   }  // turn it off when its been running for 4seconds  

    
  }
  
}}

When I use the code above, the LED would stay on after I pressed the button.  I want the LED to turn on for 4 seconds after pushing button instead.
Any suggestion?

Code:
if (buttonState == HIGH) {  
   digitalWrite(ledPin,HIGH);  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    {
    if (time >= 1000 && time < 1020){
     digitalWrite(ledPin,HIGH);
   }  // turn it on when its been running for a second
  
   if (time >= 4000 && time < 4020){
     digitalWrite(ledPin,LOW);
   }
I believe this is what keeping the LED on HIGH. If i take that out, LED would not turn on at all.
« Last Edit: April 14, 2011, 03:35:11 pm by faytoceanz3 » Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 439
Posts: 23797
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So you want the LED to come on one second after the button is pressed, like a long debounce?
Then yes, take out the line indicated.
Put in a flag to indice the button was pressed, reset the flag when you turn the LED back off.
You could take out the end time limits also (<1020 & <4020), they are not needed.
If you printed time after the condition was met, I think you would see it it always just barely past 1000 & 4000 and never close to 1020 & 4020.

So basically:
loop:
read time
read button
if button was pressed & set_pressed flag is low, then set_pressed flag = high
if time > 1000 and set_pressed flag is high,  turn on led
if time > 4000, turn set_pressed flag,turn off led
end loop
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your problem is that you're only turning off the LED if the button is pressed. See, if the button was not pressed, it wouldn't even go into the first if statement, and never get to the one asking if it has been four seconds.

What I would do is have the button set the timer variable to the current time. Then I'd have a completely separate if statement asking if millis() - time > 4000. In the no case, I'd put a write high, in the yes case I'd put a write low.

The one problem with that is it would keep the LED on for 4 seconds after the button was released. You could having something where it would compare the current value of the button to the last one, and only if they were different AND the button was pressed (so it was pressed this loop but not last loop) would it set the timer variable.

Does that make sense?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

this is what i have now if im following you right

Code:
void loop(){
  time = millis();
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH && set_pressed == LOW )
    set_pressed == HIGH;
  { 
    if (time >= 1000 && set_pressed == HIGH){
     digitalWrite(ledPin,HIGH);
   }  // turn it on when its been running for a second
   
   if (time >= 4000 && set_pressed == LOW){
     digitalWrite(ledPin,LOW);
   }  // turn it off when its been running for 4seconds 

     
  }
 
}

at the top , do i set the flag  " boolean set_pressed = false"?
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 439
Posts: 23797
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes to setting it low to start.

if time>=4000 & set_pressed == high
{
turn off led
set_pressed = low
}
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

it doesn't turn on the LED on at all after being pressed.

Wiz was right i think.

updated code on loop:

Code:
if (buttonState == HIGH && set_pressed == LOW )
    set_pressed == HIGH;
  {  
    if (time >= 1000 && set_pressed == HIGH){
     digitalWrite(ledPin,HIGH);
   }  // turn it on when its been running for a second
  
   if (time >= 4000 && set_pressed == HIGH){
     set_pressed == LOW;
     digitalWrite(ledPin,LOW);
    
   }  // turn it off when its been running for 4seconds  
« Last Edit: April 14, 2011, 12:10:56 am by faytoceanz3 » Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 439
Posts: 23797
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah, yes - millis() is free running counter, you need to look at the elapsed time, not just the static time.
Make your time variable
unsigned long
and subtract earlier time from current time to see how much has elapsed, resetting when you start over.

if (buttonState == HIGH && set_pressed == LOW )
    set_pressed == HIGH;
time = millis; // start time running
  {
if

Silly of  me to overlook that.
Capture time again just before your if statements, make the if's
current_time  = millis
if ((current_time - time) >=1000 ...
and
current_time  = millis
if ((current_time - time >=4000 ...

Then you can be doing other stuff in your loop while time marches on ...

I'm off to bed, think it thru & good luck.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Im having a hard time getting it to work. It still won't turn on .


updated code;
Code:
const int buttonPin = 41;     // the number of the pushbutton pin
const int ledPin =  39;      // the number of the LED pin
unsigned long time;
unsigned long current_time;
// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int set_pressed = 0;

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);     
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);   
  digitalWrite(ledPin, LOW);

}

void loop(){
 
 
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
 

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH && set_pressed == LOW )
    set_pressed == HIGH;
    time = millis();
   
   
  { 
    current_time = millis();
    if ((current_time - time) >= 1000 && set_pressed == HIGH)
     digitalWrite(ledPin,HIGH);
     
   }  // turn it on when its been running for a second
   
   {
   current_time = millis();
   if ((current_time - time) >= 4000 && set_pressed == HIGH)
     set_pressed == LOW;
     digitalWrite(ledPin,LOW);
     
   }  // turn it off when its been running for 4seconds 

     
  }

What am i missing?

Maybe I'm missing something on the void setup
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 549
Posts: 46128
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
  {
   current_time = millis();
   if ((current_time - time) >= 4000 && set_pressed == HIGH)
     set_pressed == LOW;
     digitalWrite(ledPin,LOW);
    
   }  // turn it off when its been running for 4seconds  
The comment is wrong. The ledPin is set LOW regardless of the time and/or the value in set_pressed. You have curly braces where you don't need them, and you don't have them where you do need them.

And, == is the equality operator. It is not the assignment operator. set_pressed is not being set here.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Finally I got it!!!!!!!!!
Code:
const int buttonPin = 41;     // the number of the pushbutton pin
const int ledPin =  39;      // the number of the LED pin
unsigned long off_time;

boolean ledState=false;

int buttonState = 0;         // variable for reading the pushbutton status


void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);  
  digitalWrite(ledPin, LOW);

}

void loop(){
 
if ((ledState) && (millis()>=off_time)) /* is it on and is it later or equal to off_time */
{
    digitalWrite(ledPin,LOW);
    ledState = false;
}
else if (!ledState) /* is it off? */
{
    buttonState = digitalRead(buttonPin);
    if(buttonState == HIGH)
    {
        digitalWrite(ledPin, HIGH);
        ledState = true;
        off_time = millis() + 5000;
    }
}}

Thanks for the insight guys
« Last Edit: April 14, 2011, 03:36:01 pm by faytoceanz3 » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is somewhat I am looking for. However, I want to use a continuous servo instead, but the problem is that there is gonna be 3 wires on the servo.  The positive(red) wire, the ground black wire, and the control white wire. 

Tried changing up the code a bit with the servos, and so far no luck. Servo doesn't turn on at all.

Code:
#include <Servo.h>
const int servobuttonPin1 = 51;

const int servoPin1 = 35;

unsigned long off_time1;

boolean servoState1 = false;

int servobuttonState1 = 0;

Servo myservo;

void setup()
{
  pinMode(servoPin1, OUTPUT);
  pinMode(servobuttonPin1, INPUT);
  digitalWrite(servoPin1, LOW);
  myservo.attach(23); //set up the servo as usual
}

void loop() {
 
  if ((servoState1) && (millis()>=off_time1)) /* is it on and is it later or equal to off_time */
{
    digitalWrite(servoPin1,LOW);
    servoState1 = false;
}
else if (!servoState1) /* is it off? */
{
    servobuttonState1 = digitalRead(servobuttonPin1);
    if(servobuttonState1 == HIGH)
    {
        digitalWrite(servoPin1, HIGH);
        servoState1 = true;
        off_time1 = millis() + 5000;
    }
}
 
   // on this servo 1500 is stopped, above 1500 is clockwise, below is counter clockwise... 2000 is max I think
   myservo.writeMicroseconds(1000);
   delay(15);
}

unless i can't use this method for my servo...

Any suggestions?
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 549
Posts: 46128
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
However, I want to use a continuous servo instead, but the problem is that there is gonna be 3 wires on the servo.  The positive(red) wire, the ground black wire, and the control white wire. 
These wires go where?

Code:
const int servoPin1 = 35;
  myservo.attach(23); //set up the servo as usual
Is the servo control wire connected to 23 or 35? Why is 23 a constant when everything else uses names?

The code you posted makes me suspect that you are trying to power the servo using a digital pin, turning that pin on or off in the code, and then using servo.writeMicroseconds() to move the servo if it is powered. Is that what you are doing? If so, stop it. Now. Power the servo correctly, and use the appropriate argument to writeMicroseconds() to control the servo motion.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

here you go theonlyone, this should work
Code:
#include <Servo.h>

Servo myservo;  // create servo object to control a servo

#define LED 13   
#define BUTTON 51

int val = 0;                    // variable for reading the pin status
int bounceCheck = 0;            // variable for debouncing
int cw = 0;                     // Servo cw value

void setup() {
  pinMode(BUTTON, INPUT);     // declare pushbutton as input
  pinMode(LED, OUTPUT);     // declare LED as output
}

void loop(){

  val = digitalRead(BUTTON);            //read input value
  delay(20);                              //wait 20ms
  bounceCheck = digitalRead(BUTTON);   //check again

  if(val == bounceCheck){                //if val is the same then not a bounce
    if (val == LOW) {                   //check if the input is LOW
     } else {
  digitalWrite(LED, HIGH);
  myservo.attach(9);               // white wire of servo to pin 9
  myservo.write(cw);
  delay(5000);
  digitalWrite(LED, LOW);
  myservo.detach();
}     
} //End if bounce check
} //end Loop

LED pin 13 just shows whether the servo is running or not running.
Red wire of servo to +5 V, white wire to pin 9, black to ground
Button pin 51

Also note that I am using a delay and not millis. I'll see if I can using millis instead of a delay.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Awesome thx man.

Anyhow , can this be done using millis?
Logged

Pages: [1]   Go Up
Jump to: