Timer for illuminating one LED for 1 time only

Hello all,

I need big help, this is so simple yet I cannot get it working.
I am not so good in writing code...

I want to switch a led on for 3 seconds if it my attiny sees a high input on a pin.
As long as the input is high nothing happens.

If the inpot is low and then back high the led will go on for 3 seconds.

so infact the led will only be on for 3 seconds wen input is high.

Thanks for the help!!!!

the code

int ledPin = 4;
int contactaan = 1; // analogRead(1) takes place at P2
#define HIGH 0x1

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

void loop() {
if(analogRead(contactaan)>0){
digitalWrite(ledPin, HIGH);
delay(3000);
}
// else{
//digitalWrite(ledPin, LOW);
//}
}

The answer is in the code as usual. The code you have that we don't.

1 Like

Welcome, Check line 9 through 20 of your code that I cannot see. Posting your code using code tags along with a simple schematic will probably get your problem(s) solved in short order.

1 Like

What had this post got to do with education? You are simply asking for help with a project. Therefore I have moved your post here.

You might want to look at this How to get the best out of this forum before you proceed any further.
We only know what you tell us, and without knowing what you have, we don't stand a chance.

This sounds you have a homework assignment, we get several of these a day at the moment. Your teacher wants you to learn about the millis() timer. Look at the blink without delay example in the IDE, along with the dosens of attempts users have tried to explain the functioning of of a state machine.

Sorry forgot to insert the code. :innocent:

And the schematic remember.
Oh you altered the first post, and did not post it correctly.

Take time to read and understand that link I sent. Then post the code correctly.

1 Like

The pusbutton is just for testing purpuse, in real its a 12v constant after a switch.
The purpuse is for a car, once you switch on the ignition the led (pump) go's on for 3 seconds
but the input stays high as long as ignitionj is on

So in real you are going to destroy your Arduino are you?

Sorry, that is NOT my intention???

Oh Oh now i understand what you mean.... of course not ther will be a voltage divider after the ignition so that it is safe for the attiny.

I am not that stupid ...

We see all levels of not that stupid here. Take nothing personally!

If the HIGH that made the LED start its three seconds goes LOW during that period, what should happens?

If the HIGH that made the LED start its three seconds goes LOW during that period, and goes HIGH again during the period, what should happen?

If you get something to work with a signal that stays HIGH beyond the three seconds stab on the LED, the LED turns off and we ready for next time.

The other two questions will have answers - no matter you think ahead of time what to code, something will happen, so it is better to plan for all possibilities, don't just say "that will never happen" and then not care about why if it did.

But the key here is in a thing called "state change (or edge) detection", there is an example in the IDE and a decent enough article here:

https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection/

So when you see the transition from LOW to HIGH on the input, turn on the LED and note the time.

And also in the loop(), check to see if the LED has been turned on, and then check to see if it has been on for three seconds. If so, turn it off.

You may not yet have learned the way to do simple timing stuff, the basic tools are presented in "blink without delay", another necessary example available in the IDE to become familiar with.

HTH

a7

Well Thank You for the effort!

I don't take anything personal, oh no.

I am very bad in coding, in act i am a zero, really.

In my head it is so simple but wrinting the code is hell cause i am not experienced and also
i just don't know wher to start.

when the ignition is switched on , the led (pump) wil start for a very brief time "3seconds" yet to determined, it could be also 30 seconds. but for now 3 seconds is ok.
This occours while ignition is switched on (high) for all the time.

As of now the code above works perfectly except if ignition is still high the led also stays on .
I don't understand how to switch it off after the given time.

I thought tha someone here can give me a clue how to do it.

thanks in advance

Here's more to the clues not buried in other words.

To start a timer, set variable to the current system time. Use unsigned long variables whenever you are doing a timing task

   ledWentOnAt = millis();

millis() is the time in milliseconds since reset or power up.

To see if a timer has expired, that is to say if the desired elapsed time has passed, check it against what millis() has become

  if (millis() - ledWentOnAt > 3000) {

// it's been 3000 milliseconds since (3 seconds) so do whatever to turn off the LED

  }

Just like figuring out elapsed times in real left. What time is it now, subtract the start time and that is the elapsed time. Only no messing with days, hours and minutes maths.

There really isn't much more to it. Here it does not matter if you turn off the LED thousands of times, so you don't even need to know if it is on.

Not yet code, but the loop will have two sections

  did the button get pressed?
     turn on the LED
     start the timer (again, start is just noting the time now)


  is the timer expired?
    turn off the LED
     

Real code will cost you. I take PayPal, or maybe someone will just scratch this out for you. Or you could look at the examples I mentioned earlier, and see it is easy after it was so hard. :expressionless:

a7

Unthink this. Consider every project unknown. Apply what you know. Learn as you proceed.

You must record if the pin changed from HIGH to LOW, then changed LOW to HIGH.
But, if the pin remains HIGH, or only goes from HIGH to LOW (and remains LOW), do nothing.

After you record the HIGH to LOW and LOW to HIGH transitions, start a 3 seconds timer.

But first... this is not used, discard it:

Your pin definitions are not easy to read. Try ATtiny85 definitions:

byte ledPin = PB4;
byte contactaan = PB2;

You must define the direction for EVERY used pin (not just the LED):

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

Try simulating your project on WOKWI.COM. This sketch only waits for a button press to simulate your HIGH/LOW/HIGH transitions. You can work on the timer.

byte ledPin = PB4;
byte contactaan = PB2;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(contactaan, INPUT); // tied LOW when not pressed. HIGH when pressed
}

void loop() {
  if (digitalRead(contactaan)) { // if button is pressed (HIGH)
    digitalWrite(ledPin, HIGH); // turn LED ON
  }
  else
    digitalWrite(ledPin, LOW); // if button is released, turn LED OFF
}

Use this file on the diagram.json tab to set up the hardware:

{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-attiny85", "id": "tiny", "top": -1.2, "left": -13.6, "attrs": {} },
    {
      "type": "wokwi-led",
      "id": "led1",
      "top": -13.2,
      "left": 80.6,
      "attrs": { "color": "red", "flip": "" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": 42.65,
      "left": 27.4,
      "rotate": 180,
      "attrs": { "value": "500" }
    },
    {
      "type": "wokwi-pushbutton-6mm",
      "id": "btn1",
      "top": -47,
      "left": 61.6,
      "rotate": 90,
      "attrs": { "color": "green" }
    },
    { "type": "wokwi-vcc", "id": "vcc1", "top": -66.44, "left": -19.2, "attrs": {} },
    {
      "type": "wokwi-resistor",
      "id": "r2",
      "top": 33.05,
      "left": 27.4,
      "rotate": 180,
      "attrs": { "value": "10000" }
    }
  ],
  "connections": [
    [ "led1:C", "r1:1", "green", [ "h0.4", "v18.35" ] ],
    [ "tiny:GND", "r1:2", "black", [ "v0" ] ],
    [ "tiny:VCC", "vcc1:VCC", "red", [ "v0" ] ],
    [ "tiny:PB4", "led1:A", "green", [ "v28.8", "h95.2" ] ],
    [ "tiny:GND", "r2:2", "black", [ "v0" ] ],
    [ "vcc1:VCC", "btn1:2.r", "red", [ "v0" ] ],
    [ "btn1:1.r", "r2:1", "green", [ "v0" ] ],
    [ "r2:1", "tiny:PB2", "green", [ "v-48", "h-86" ] ]
  ],
  "dependencies": {}
}

Well THANK YOU,

This is help, well explained, i could follow it very easy.

The problem is yhat i am a car mecanic, i could fragment a car in 10.000 pieces but i realy dont know how to start here and i love to learn.

Thank you "xfpd"

Now for the script, it douse the same as the one i made prevously, yours is more refined.
but i wanted the led to go out after 3 seconds or X time even if the button is still pressed.

That is what i am looking for.

The function is for priming a pump in the first seconds after the status "HIGH"

This status keeps being HIGH for probably several hours, but the priming function is only

needed every time the status changes from HIGH to Low and then back HIGH then it wil

prime only for the dedicated X time which could be 3 seconds or 30 seconds etc...

I tried the "delay" function for "contactaan" but this would not work, as long i keep pressing

the leds stays on.

Again a big thank you for your effort; WOW

@tech111
1. If you are using Digispark ATtiny85 Dev Board, then I would suggest to make your hardware setup as per Fig-1 as PB3 (D-) and PB4 (D+) are used to capture data from USB Port.


Figure-1:

2. This is the Flow Chart (Fig-2) that describes (hope fully!) the solution to your LED2-K1 problem.


Figure-2:

3. Let us convert the Flow Chart of Fig-2 into sketch and then upload the sketch into Digispark ATtiny85 Dev Board and then observe the result.

Sketch: (tested on UNO and ATtiny85)
(I have used goto statements for quick development of codes. In Step-4, goto statement free sketch will be presented if I can!)

#define ledPin  1 // UNO 13
#define Button 2 //UNO 2
unsigned long int presentMillis;

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

void loop()
{
L1:
  if (digitalRead(Button) == HIGH) //Button is closed
  {
L2: delay(100); //wait for bouncing period of Button
L3: if (digitalRead(Button) == HIGH) //Is Button still close
    {
L4:   digitalWrite(ledPin, HIGH);
      presentMillis = millis();
L5:   if (millis() - presentMillis >= 3000) //test interval
      {
L6:     digitalWrite(ledPin, LOW);
L7:     while (digitalRead(Button) == HIGH)
        {
          ; //wait until Button is opened
        }
        goto L1; //Button is Opened
      }
      else
      {
L8:     if (digitalRead(Button) == LOW)
        {
          goto L6; // Button is opened
        }
        else
        {
          goto L5;
        }
      }
    }
  }
}

4. Re-write sketch of Step-3 excluding the goto statements.
... pending

#define ledPin  1 //UNO = 13
#define Button 2 //UNO = 2
unsigned long int presentMillis;

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

void loop()
{
  if (digitalRead(Button) == HIGH) //Button is closed L1:
  {
    delay(100); //wait for bouncing period of Button L2:
    if (digitalRead(Button) == HIGH) //Is Button still close L3:
    {
      digitalWrite(ledPin, HIGH); //L4:
      presentMillis = millis(); 
      while (millis() - presentMillis < 3000)  //test interval  L5:
      {
        if (digitalRead(Button) == LOW) //L8:
        {
          break;
        }
      }
      digitalWrite(ledPin, LOW);  //LED2 is turned Off L6:
      while (digitalRead(Button) == HIGH) //L7:
      {
        ; //wait
      }
    }
  }
}

5. Draw State Machine Digram for the Flow Chart of Fig-2 of this post.
... pending

6. Create sketch for the State Macine Diagram of Step-5.
... prnding

@GolamMostafa please! if you are going to write code for people, avoid don't use goto.

goto may have its place, here for this task it is totally unnecessary.

I'm not even going to look at your code anymore to see if your use of it was in away way proper, it is certainly not justified. Bad enough in the hands of experts, dangerous for noobs. I wouldn't even mention it.

Goto Considered Harmful


@tech111 take stretch and add what you can glean from @xfpd #16 and @alto777 #15 above.

A single boolean variable says whether the LED is on or off

bool ledIsOn = false;

In the loop() function, repeatedly check and adjust.

If the LED is off, see if the signal is present and turn the LED on. Here turning on takes two steps

    digitalWrite(ledPin, HIGH);
    ledIsOn = true;

At the same point start a timer.

If the LED is on, see if the timer has expired and turn the LED off. Again, turn off the LED and set the variable we have to track the status

    digitalWrite(ledPin, LOW);
    ledIsOn = false;

When you post your code, please use the <CODE/> button in the message composition window, and paste your code where it says, so it ends up looking like code

void setup() {
  pinMode(ledPin, OUTPUT);
// whatever
}

I see this

if(analogRead(contactaan)>0){

and ask you to say what values you expect, and what you've connected to the input. It is likely that a digitalRead() is usable, and it is usually a digital matter if something else is on or off or HIGH or LOW. If you are reading a voltage, perhaps requiring that the value be above some threshold other than zero is appropriate

if (analogRead(contactaan) > 512) {  // voltage over 2.5 volts

If you had a voltage divider. Be careful of automotive voltages, I'm too too lazy read back to see where your external signal is coming from, for now a pushbutton can be substituted until you are ready to hook this up IRL.

HTH

a7

2 Likes

Use of goto statements in programming is not much encouraged. However, they can be used for learning the process of converting sequence of events into programming codes and that's what I have tried to do in respect of the above quote of OP.

Teaching something students should not use until maybe never is bad pedagogy. I could compare it to interrupts - teach it too early and you will derail your students. Worse is if students discover it for themselves and start trying to exploit it. goto is the same.

I realize I am almost alone in holding this view, nevertheless it is the conclusion I have arrived at.

a7

3 Likes