0

we want to have a LED turn on with the press of a button, and become brigther and brighter as times go by (whithin a defined time frame), and when it reaches maximum brightness to turn off for a couple of seconds and then start again. in addition to that, we are trying to add a motor that will start spinning 720 degrees when the button has been pressed. Our main problem is the fact that when we let go of the button the led turns off. How do we set the button so that when it is pressed once it turns everything on, and the led runs in a loop, but the motor doesn't; and when we press it again the whole led turns off completely and the motor runs 720 degrees in the opposite spinning direction than the previous.

Here is what we have managed so far (we didn't get to introduce the motor yet as we got stuck along the way):

const int switchPin = 11;
const int motorPin = 6;
int led = 9;
int switchState = LOW;
int previous = LOW;
int i = 0;
int fadeAmount = 5;

void setup() 
{
  pinMode(led, OUTPUT);
  pinMode(motorPin, OUTPUT);
  pinMode(switchPin, INPUT);
}

void loop() 
{
  int switchState = digitalRead(switchPin);

  for (int i = 0; i <= 255; i++) 
  {
    analogWrite(led, i);
  }

  if (switchState == HIGH && previous == LOW) 
  {
    if (i == 0) 
    {
      digitalWrite (led, HIGH);
      i = i + fadeAmount;
      delay(1000);
    }

    analogWrite(led, i);

    for (int i = 255; i <= 255; i--)
    {
      digitalWrite (led, LOW);
      i = 0;
    }
  }
  else 
  { 
    //toggle off
    digitalWrite(led, LOW);
    i = 0;
  }
}

PS. WE are beginers. Thanks for the help and understanding!

  • you are getting distracted by the fading lights and by the motor .... the motor action and the fading lights action are completely separate from the button press action .... the motor and light could be triggered by a timer, by voltage level or by a number of other events ....... the lights should be controlled by a boolean variable ... name it lights_on for example ... the button should set the value of lights_on variable .... the value should be set only by the switch at the transition from button not-pressed state to button pressed state, not by the "pressed` state alone – jsotola Nov 29 '19 at 18:57
  • start by writing button code that controls a single led ... button sets a variable .... LED responds to variable – jsotola Nov 29 '19 at 18:58
0

Here is a program that should fade the LED as you specified. Initially the LED is off. If you press the button the LED starts fading within the time frame to its maximum. Then it switches to zero waits a couple of seconds and starts fading from new. If you press the button a second time the LED stops fading and is set to darkness. ;-) This happens emediately, but of cause, you can only see it if the LED is in the fading phase.

I used interrupts in order to have a well defined state transition I can work with.

Aquiring the button pin in the loop, would be more complex to handle. That would require a state variable and some state transition rules. And I was too lazy to work that out. If interupts can't be used for any reason, I would change the answer. (No Mum I don't want to ...)

I removed the motor pin as it makes no sense for the answer. I also think that one pin would not be enough if your motor (stepper, dc with feedback or a servo) should spin a certain amount of degrees.

I tested the program on a Arduino UNO. The button I used is of low quality so I had to debounce it.

If there is something not clear to you, please ask within a comment.

// Attache the LED to a PWM pin UNO -> 3,5,6,9,10,11
const byte ledPin       = 9;

// UNO -> only pin 2 or pin 3 are interrupt pins
// as we use pullups the button should be connected to GND 
const byte interruptPin = 2; 

// in milli seconds - The time the LED needs to fully light up
const int timeFrame  = 5000;

// in milli seconds 
const int aCoupleOfSeconds = 2000;

const int fadeAmount =    5;

volatile boolean fadeOn = false;
volatile long debounceTime = 800;
volatile long actTime = 0;

int brightness =   0;

int stepCount = 256       / fadeAmount;
int stepDelay = timeFrame /  stepCount;

void setup() 
{
  pinMode( ledPin,       OUTPUT       );
  pinMode( interruptPin, INPUT_PULLUP );

  attachInterrupt( digitalPinToInterrupt( interruptPin ), pressed, CHANGE );
}

void loop() 
{
  if ( fadeOn )
  {
    delay( stepDelay );
    brightness += fadeAmount;
    if ( brightness >= 255 )
    {
       brightness = 0;
       analogWrite( ledPin, brightness );
       delay( aCoupleOfSeconds );
    }
    analogWrite( ledPin, brightness );
  }
  else 
  { 
    brightness = 0;
    analogWrite( ledPin, brightness );
  }
}

void pressed() 
{
  // the debouncing does not work perfectly

  if ( digitalRead( interruptPin ) == LOW )
  {
    if ( millis() - actTime > debounceTime )
    {
      fadeOn = !fadeOn;
    }
  }
  else
  {
    actTime = millis();
  }
}
| improve this answer | |
  • 1
    "Our main problem is the fact that when we let go of the button the led turns off" – Juraj Nov 29 '19 at 16:25
  • @Juraj Ahhhh, noo, I completely misread the question. Thank you for giving me the hint. – Peter Paul Kiefer Nov 29 '19 at 16:34
  • just change a boolean when button is pressed and from there build the code... if(switchstate == HIGH){bool1 = 1;} if(bool1 == 1){...} – ElectronSurf Nov 29 '19 at 16:48
  • @Hamed I have to synchronize the button if it is pressed longer. The OP does not want to hold the button. They press the button than the fading starts, if the LED is complete on, it should be switched off, waits a while and start again fading. If I press the button a second time I switch the LED and fading off. Just holding a boolean state would toggle if I press the button for a longer time. I plan to use interrupts. – Peter Paul Kiefer Nov 29 '19 at 17:17
  • millis() in cli()? it is incremented by a timer interrupt – Juraj Nov 30 '19 at 18:13
0

Have a look at some code inside the forum from marcello.romani. He posted it on jan 1st, 2013. The topic on subject is called : "button pressed more than 2 seconds do somethingelse" Marcello's code is so KISS (Keep It Simple Stupid) and efficient that it deserves a Nobel prize. The goals is to handle the different signals that come from a button or switch action : keyPress, keyRelease, longKeyPress etc.. as you can find in the original sketch.

| improve this answer | |
  • The OP has no problem with longer or shorter key presses. She only wants to toggle a state by pressing the key. So the code might be good, but it does not answer the question. BTW: that code is for demonstration, and it is not KISS. "Do only the things that must be done". But for demonstration he uses methods with only one statement in it. I had to follow the execution path to find out what happens. No, that is not KISS, although IMHO it is perfect for demonstration purposes as he gives us the places where we can extend it. – Peter Paul Kiefer Dec 1 '19 at 17:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.