Go Down

Topic: LED to flash for 3000 millis when button pressed (Read 1 time) previous topic - next topic

sirjorge

I'm trying to get the led to flash for 3000 millis at 250 millis intervals only whenever a button has been pressed (when a thrown object hits the target), and I'm really struggling with the code. I've been able to merge some existing codes together to get the led to flash when the button is depressed (although very dimly) but it goes off when the button is released. I ready the sticky on creating sketches from scratch and gave it a shot, but my brain melted fairly quickly. Can anyone help me get started?
I'm using a Mega 2560

UKHeliBob

Read the button input.  When you detect that it has changed from not pressed to pressed save the time from millis() and set a flag to true to indicate that flashing has started.  In loop() do what the BlinkWithoutDelay example does to turn the LED on and off but only if the flashing flag is true.  Each time through loop subtract the flashing start time from the current time and if it is greater than 3000 milliseconds set the flashing flag to false and turn off the LED.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

gpop1

with out seeing the code you tried its hard to tell whats going on. Most new people make the mistake of setting the button up as a input with out a additional resistor to pull the pin down. The fix is normally done by changing the input to a input pullup which tells the arduino to add a internal resistor. This makes the button seem backwards as LOW is now pressed and HIGH is unpressed.

sirjorge

Thanks UKHeliBob. Here's what I've got so far. I'm not sure how to identify the starting millis
Code: [Select]

const int buttonPin = 2;     
const int ledPin =  5;     

int buttonState = 0;         
int ledState = HIGH;           

unsigned long previousMillis = 0;       


const long interval = 250;         


void setup() {
    pinMode(ledPin, OUTPUT);
    pinMode(buttonPin, INPUT);
}

void loop() {
    buttonState = digitalRead(buttonPin);
    unsigned long currentMillis = millis();

 
  if (buttonState == HIGH) {
      if(currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis; 
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}}


sirjorge

with out seeing the code you tried its hard to tell whats going on. Most new people make the mistake of setting the button up as a input with out a additional resistor to pull the pin down. The fix is normally done by changing the input to a input pullup which tells the arduino to add a internal resistor. This makes the button seem backwards as LOW is now pressed and HIGH is unpressed.
I have the button setup exactly as it was in the button example. If I change 
else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
to digitalWrite(ledPin, HIGH); it is bright, but does not flash

UKHeliBob

Quote
I'm not sure how to identify the starting millis
You need 2 variables to hold the 2 different start times.  One will be the start of the 3 second period and the other will be the start of the 250 millis period. 

I suggest that you start by detecting that the button has become pressed (rather than is pressed (see the StateChangeDetection example in the IDE) and turn on the LED for 3 seconds and test whether the period has passed each time through loop() and turn it off when the period has passed.  Don't worry about flashing the LED for the time being.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

gpop1

I have the button setup exactly as it was in the button example. If I change 
else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
to digitalWrite(ledPin, HIGH); it is bright, but does not flash
digital pins tend to float so when you press a button using input the reading will be 5v dc+ when you let go of the button the reading will float (not be 0v) adding a resistor (10k plus) between the pin and the arduino negative will pull the pin down to 0v or you can use pullup and redo the code to suit and let the arduino add the resistors.

if you don't do this you can get rouge button detection where the arduino will read a HIGH on the input even when the button is not pressed. floating voltage is a pain as its not stable so it might do this every few scans or every few seconds totally random which will drive you nuts



UKHeliBob

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

sirjorge

It seems as if I'm in over my head, considering I need this project functional by the end of next week. I appreciate your help on this one! Where should I go about finding a professional service to complete this project for me?

gpop1

so you want a program that does this?

1/ when button pressed (single press not held)

2/ for 3 seconds make a led flash at a rate of 250ms ?

or

2/ you want a led to flash 3 seconds on, 250ms off repeating until ?


gpop1

I think this is what you want

see notes on wiring button.

quick press of button will make the led flash for 3 seconds at 250ms intervals

(easy to test if you change led to pin 13 and use the onboard led)


Code: [Select]
//one side of button connected to arduino pin 2
//other side of button connected to gnd pin of arduino


const int buttonPin = 2;
const int ledPin =  5;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
unsigned long interval1 = 250;
unsigned long interval2 = 3000;
byte requestFlash = 0;
byte button=0;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  button = digitalRead(buttonPin);
  unsigned long currentMillis = millis();

  if (button == LOW) {
    requestFlash = 1;
    previousMillis2 = currentMillis;
  }

  if ((currentMillis - previousMillis1 >= 250) && (requestFlash == 1)) {
    digitalWrite(ledPin, !digitalRead(ledPin));
    previousMillis1 = currentMillis;
  }
  if ((currentMillis - previousMillis2 >= interval2) && (requestFlash == 1)) {
    requestFlash = 0;
    digitalWrite(ledPin, LOW);
  }
}



sirjorge

I think this is what you want

gpop1 Thanks! It works perfectly. I can't wait to spend some time learning this stuff so I can pay it forward. In the meantime, I'll gladly buy you a beer anytime your in the Dallas, TX area!

gpop1

glad it worked. ukhelibobs code (state change) would have been better at accurate timing but I figured close was good enough for what you said you was using it for. 

sirjorge

So, if I want to use this program to control a lamp or string of traditional christmas lights, I would use a powerswitch tail (http://www.adafruit.com/products/268) and a relay shield?

gpop1

the power switch says its optically isolated so it should be able to run straight from the arduino output pin.
You will need to add gfci protection or use a gfci receptacle.
maybe worth asking if anyone has tried one of these in the general electronics forum

Go Up