Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!



Need help with begi...
 
Share:
Notifications
Clear all

[Solved] Need help with beginning of using interrupts

20 Posts
2 Users
0 Reactions
6,380 Views
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

Hi there,

To this day I always wrote code so it works for me, not very elegant and often not very like it should be written. But I want to progress, so I want to dive deeper into "how it should be done".

For my next project I want to use Neopixels again. Let´s say I want to light them up with a solid color by pushing a button. But every Pixel has its own button. There are 8 Pixels and therefore 8 buttons. At the beginning, nothing shall happen. When I press a button, the corresponding pixel shall light up (Button 3, Pixel 3; Button 1, Pixel 1 and so on). When I press any other button, the lit up Pixel shall go off and the pixel from the button I have pressed shall light up and so on.

I think I have to use interrupts for this, because that´s what I want to do with those buttons. Every button shall interrupt the lit up Pixel from another button and light up it´s corresponding Pixel.

Here is the code I have used for now. There are no interrupts. Because I don´t know where to start. With this code I can light up all Pixels together when pushing all buttons together. This I want to change to the behavier above. And I have to hold the button to have the Pixel on, which is also not wanted for the new code of course.

I have read about a library where you can use every Pin as an interrupt Pin. So I also need that right? Or is there a better solution without interrupts, because there is not complicated pixel animation, just a solid color?!

An extra would be to have an automated animation when no button is pressed for 5 minutes. So after 5 minutes the first Pixel shall light up for 30 seconds, goes off then and the second pixel lights up for 30 seconds, goes off then and the third pixel lights up and so on.

#include <FastLED.h>

#define NUM_LEDS  4
#define LED_PIN   5


#define buttonPin2 10
#define buttonPin3 9
#define buttonPin4 8
#define buttonPin5 7

int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(100);

  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);
}

void loop() {

  
  leds[1] = CRGB(0, 0, 0);
      buttonState2 = digitalRead(buttonPin2);       // read the state of the pushbutton value
  if (buttonState2 == LOW) { 
    leds[1] = CRGB(0, 0, 255);
  }

    leds[2] = CRGB(0, 0, 0);
      buttonState3 = digitalRead(buttonPin3);       // read the state of the pushbutton value
  if (buttonState3 == LOW) { 
    leds[2] = CRGB(255, 0, 255);
  }

      leds[3] = CRGB(0, 0, 0);
      buttonState4 = digitalRead(buttonPin4);       // read the state of the pushbutton value
  if (buttonState4 == LOW) { 
    leds[3] = CRGB(255, 255, 0);
  }

      leds[4] = CRGB(0, 0, 0);
      buttonState5 = digitalRead(buttonPin5);       // read the state of the pushbutton value
  if (buttonState5 == LOW) { 
    leds[4] = CRGB(0, 255, 255);
  }
 
  FastLED.show();

}

   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

Iam half way there....but without interrupts and the lazy road again. I just set all other Pixels to black when pushing a button, except of the one I want to light up.

Iam open for other solutions. Also thought about switch case???

But maybe my solution is fine. Still want to have the automated "playback". Can´t work with delay of course. But how to write the code to make it "after no button is pressed for 5 minutes, light up Pixel 1 for 30 seconds, then light up Pixel 2 for 30 seconds" and so on?

Also....what if I want to have the lit up Pixel go off after 10 seconds after I have pushed its corresponding button?

Here is the code:

#include <FastLED.h>

#define NUM_LEDS  5
#define LED_PIN   5

#define buttonPin2 10
#define buttonPin3 9
#define buttonPin4 8
#define buttonPin5 7

int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;

CRGB leds[NUM_LEDS];


void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(100);

  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);
}

void loop() {


      buttonState2 = digitalRead(buttonPin2);       // read the state of the pushbutton value
  if (buttonState2 == LOW) { 
    leds[1] = CRGB(0, 0, 255);
    leds[2] = CRGB(0, 0, 0);
    leds[3] = CRGB(0, 0, 0);
    leds[4] = CRGB(0, 0, 0);
  }


      buttonState3 = digitalRead(buttonPin3);       // read the state of the pushbutton value
  if (buttonState3 == LOW) { 
    leds[2] = CRGB(255, 0, 255);
    leds[1] = CRGB(0, 0, 0);
    leds[3] = CRGB(0, 0, 0);
    leds[4] = CRGB(0, 0, 0);
  }


      buttonState4 = digitalRead(buttonPin4);       // read the state of the pushbutton value
  if (buttonState4 == LOW) { 
    leds[3] = CRGB(255, 255, 0);
    leds[1] = CRGB(0, 0, 0);
    leds[2] = CRGB(0, 0, 0);
    leds[4] = CRGB(0, 0, 0);
    
  }


      buttonState5 = digitalRead(buttonPin5);       // read the state of the pushbutton value
  if (buttonState5 == LOW) { 
    leds[4] = CRGB(0, 255, 255);
    leds[1] = CRGB(0, 0, 0);
    leds[2] = CRGB(0, 0, 0);
    leds[3] = CRGB(0, 0, 0);
  }
 
  FastLED.show();

}

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2728
 

Hi Trace!

Apologies for the late response ... I started answering the other day and then things went a little sideways here.

Anyhoo ....

I'm not 100% sure interrupts are needed for a project like this.
Also note that you can attach only one interrupt at a time (eg. one switch can have an interrupt attached - but only one at a time). 

So if I understand your project correctly:

All LEDs (5) off when Arduino starts.
Press button X => LED X ON and all others off. ( where X = {1,2,3,4) )

If nothing pressed for 5 minutes: LED1 ON, rest OFF (5 minutes = 300 second = 300.000 milliseconds)
If nothing pressed for 5 minutes and 30 seconds: LED2 ON, rest OFF
If nothing pressed for 6 minutes: LED3 ON, rest OFF
If nothing pressed for 6 minutes and 30 seconds: LED4 ON, rest OFF
If nothing pressed for 7 minutes: All OFF or start the 5 minute cycle again

A few things I kept in mind:

You seemed to be using different colors for the 4 LEDs, so I shoved those in an array, so it will be easier to reference them, instead of a few if-then loops (which is still correct of course).

Additionally I've added a way to keep track of time so we can determine when the 5 minute marker has been passed.
For this I defined a few constants as well (NotPressed1, NotPressed2, etc) so you can easily change the timing for that if needed.

Also note that I wasn't sure what would happen after the last LED was reached (after the 5 minutes no button pressed), so I can up with 2 options:
The first one just starts the 5 minute loop again, where as the second option turns all LEDs dark.

I did write the code without having an Arduino handy ... so it is untested, but it does compile.

In code I'd do something like this - let me know how it works 😊 

#define FASTLED_INTERNAL    // just used to mute the Pragma messages when compiling
#include <FastLED.h>

#define NUM_LEDS  5
#define LED_PIN   5

#define buttonPin2 10
#define buttonPin3 9
#define buttonPin4 8
#define buttonPin5 7

// time slots when nothing was pressed: 5 minutes = 300 seconds = 300,000 milliseconds
#define NotPressed1 300000
#define NotPressed2 330000
#define NotPressed3 360000
#define NotPressed4 390000
#define NotPressed5 420000

unsigned long LastPressed = 0; // 0 = ignore lastPressed

CRGB leds[NUM_LEDS];

CRGB myColors[4] = { CRGB(0,0,255),
                     CRGB(255,0,255),
                     CRGB(255, 255, 0),
                     CRGB(0, 255, 255) }; 

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(100);

  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);
}

void loop() {
  unsigned long SinceLastPressed;  // Store time since last pressed

  int CurrentLED = -1;             // when -1 then no LED selected / button pressed

  // Read buttons until we find one that is pressed (this can be done more elegant)
  if(digitalRead(buttonPin2) == HIGH)      { CurrentLED = 0; }
  else if(digitalRead(buttonPin3) == HIGH) { CurrentLED = 1; }
  else if(digitalRead(buttonPin4) == HIGH) { CurrentLED = 2; }
  else if(digitalRead(buttonPin5) == HIGH) { CurrentLED = 3; }
  
  if (CurrentLED==-1) {
    if(LastPressed>0) {                            // Only do this if a button was ever pressed
    
      SinceLastPressed = millis() - LastPressed;   // milliseconds since last time button was pressed
      
      // If after "NotPressed5" millioseconds, still nothing pressed:
      
      //   option1: start this loop again
      if( SinceLastPressed>NotPressed5 ) { 
        LastPressed = millis - NotPressed1;        
        SinceLastPressed = NotPressed1;
      } 

      // option2: turn all LEDs dark
      // if( SinceLastPressed>NotPressed5 ) { 
      //   FastLED.clear();
      // }
      
      
      if( SinceLastPressed>NotPressed4 ) {
        CurrentLED = 3; }
      else if( SinceLastPressed>NotPressed3 ) {
        CurrentLED = 2; }
      else if( SinceLastPressed>NotPressed2 ) {
        CurrentLED = 2; }
      else if( SinceLastPressed>NotPressed1 ) {
        CurrentLED = 1; }
    }
  } else {   // CurrentLED not equal -1? -> then a button was pressed
    LastPressed = millis();                        // save timestamp 
  }
  
  FastLED.clear();                                // set all LEDs to black
  
  if (CurrentLED>-1) {                            // Set LED color of selected LED
    leds[CurrentLED] = myColors[CurrentLED];       
  }
  
  FastLED.show();                                 // Show LEDs
}

 


   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

@hans Hi Hans, of course you are the first one to respond 🤣  Thank you.

Thanks for your code but I think something got lost in translation. It is way simpler.

Nothing happes when Arduino starts. When I press button X -> LED X ON and all other off (X={1,2,3,4})

This is correct.

Now there are two extra scenarios which are also very simple.

When Arduino starts and no button will be pressed at all, after 5 minutes it shall act like someone is pressing the buttons one after another and wait between each press for 30 seconds -> pressing button 1 wait 30 seconds (so LED1 is lit for 30 seconds {all others off}), then pressing button 2 wait 30 seconds (so LED2 is lit for 30 seconds {all others off}) and so on.

Until someone is really pushing a button, then it shall react to the real button push again.
So it is meant as an automated animation.

The other scenario is almost the same, but this time, someone has pushed a button and is watching LED X lit up. If the person is again not touching any button for 5 minutes, it again shall act like above (the automated behaviour).


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2728
 

Well, there are not many out here participating in discussions unfortunately - and I always try to help when I can 😉 

In that case just a minor modification will do the trick (I think);

Modify void setup to actually set a lastPressed value initially

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(100);

  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);

  LastPressed = millis();
}

 

And the if(LastPressed=0) condition becomes redundant.

All combined, as usual untested, ... 😊 

#define FASTLED_INTERNAL    // just used to mute the Pragma messages when compiling
#include <FastLED.h>

#define NUM_LEDS  5
#define LED_PIN   5

#define buttonPin2 10
#define buttonPin3 9
#define buttonPin4 8
#define buttonPin5 7

// time slots when nothing was pressed: 5 minutes = 300 seconds = 300,000 milliseconds
#define NotPressed1 300000
#define NotPressed2 330000
#define NotPressed3 360000
#define NotPressed4 390000
#define NotPressed5 420000

unsigned long LastPressed = 0; // 0 = ignore lastPressed

CRGB leds[NUM_LEDS];

CRGB myColors[4] = { CRGB(0,0,255),
                     CRGB(255,0,255),
                     CRGB(255, 255, 0),
                     CRGB(0, 255, 255) }; 

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(100);

  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);

  LastPressed = millis();
}

void loop() {
  unsigned long SinceLastPressed;  // Store time since last pressed

  int CurrentLED = -1;             // when -1 then no LED selected / button pressed

  // Read buttons until we find one that is pressed (this can be done more elegant)
  if(digitalRead(buttonPin2) == HIGH)      { CurrentLED = 0; }
  else if(digitalRead(buttonPin3) == HIGH) { CurrentLED = 1; }
  else if(digitalRead(buttonPin4) == HIGH) { CurrentLED = 2; }
  else if(digitalRead(buttonPin5) == HIGH) { CurrentLED = 3; }
  
  if (CurrentLED==-1) {
      SinceLastPressed = millis() - LastPressed;   // milliseconds since last time button was pressed
      
      // If after "NotPressed5" millioseconds, still nothing pressed:
      
      //   option1: start this loop again
      if( SinceLastPressed>NotPressed5 ) { 
        LastPressed = millis - NotPressed1;        
        SinceLastPressed = NotPressed1;
      } 

      // option2: turn all LEDs dark
      // if( SinceLastPressed>NotPressed5 ) { 
      //   FastLED.clear();
      // }
      
      
      if( SinceLastPressed>NotPressed4 ) {
        CurrentLED = 3; }
      else if( SinceLastPressed>NotPressed3 ) {
        CurrentLED = 2; }
      else if( SinceLastPressed>NotPressed2 ) {
        CurrentLED = 2; }
      else if( SinceLastPressed>NotPressed1 ) {
        CurrentLED = 1; }
    }
  } else {   // CurrentLED not equal -1? -> then a button was pressed
    LastPressed = millis();                        // save timestamp 
  }
  
  FastLED.clear();                                // set all LEDs to black
  
  if (CurrentLED>-1) {                            // Set LED color of selected LED
    leds[CurrentLED] = myColors[CurrentLED];       
  }
  
  FastLED.show();                                 // Show LEDs
}

   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

@hans Wow, how is it possible to answer that quick?

There must be a few mistakes in the code I cant figure out.

    }
  } else {   // CurrentLED not equal -1? -> then a button was pressed
    LastPressed = millis();                        // save timestamp 
  }

 

I think I have to remove { before else right?

But then there is still a mistake. The first LED lights up by itself. Pressing the second button will light up the second LED but only as long as I push the button and releasing the button, it jumps back to the first LED. Every other button is without function.
And after 5 Minutes, nothing happens.


   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

@hans And I have found a typo, but correcting it doesn´t do anything:

      if( SinceLastPressed>NotPressed4 ) {
        CurrentLED = 3; }
      else if( SinceLastPressed>NotPressed3 ) {
        CurrentLED = 2; }
      else if( SinceLastPressed>NotPressed2 ) {
        CurrentLED = 2; }
      else if( SinceLastPressed>NotPressed1 ) {
        CurrentLED = 1; }
    }

   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

@hans Oh boy, I have made a double typo:

 

This:

      if( SinceLastPressed>NotPressed4 ) {
        CurrentLED = 3; }
      else if( SinceLastPressed>NotPressed3 ) {
        CurrentLED = 2; }
      else if( SinceLastPressed>NotPressed2 ) {
        CurrentLED = 2; }
      else if( SinceLastPressed>NotPressed1 ) {
        CurrentLED = 1; }

 

Should become this:

      if( SinceLastPressed>NotPressed4 ) {
        CurrentLED = 3; }
      else if( SinceLastPressed>NotPressed3 ) {
        CurrentLED = 2; }
      else if( SinceLastPressed>NotPressed2 ) {
        CurrentLED = 1; }
      else if( SinceLastPressed>NotPressed1 ) {
        CurrentLED = 0; }

 

But it´s still the same mistake as written before.


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2728
 

Hi Trace,

I suppose that is the issue when writing code without having the hardware laying around to do testing 😉 

Posted by: @trace

I think I have to remove { before else right?

I see, you're almost right. You'll need to remove one of the "}" before the else.

And you're right about the other typo as well - that 's what happens when I use copy and paste too quickly while not having had enough coffee yet. 😉 

I do see that I "forgot" to save the previous LED that was lit.

I hope these small changes fixes those issues 😊 

Apologies for the typos.

#define FASTLED_INTERNAL    // just used to mute the Pragma messages when compiling
#include <FastLED.h>

#define NUM_LEDS  5
#define LED_PIN   5

#define buttonPin2 10
#define buttonPin3 9
#define buttonPin4 8
#define buttonPin5 7

// time slots when nothing was pressed: 5 minutes = 300 seconds = 300,000 milliseconds
#define NotPressed1 300000
#define NotPressed2 330000
#define NotPressed3 360000
#define NotPressed4 390000
#define NotPressed5 420000

unsigned long LastPressed = 0; // 0 = ignore lastPressed

CRGB leds[NUM_LEDS];

CRGB myColors[4] = { CRGB(0,0,255),
                     CRGB(255,0,255),
                     CRGB(255, 255, 0),
                     CRGB(0, 255, 255) }; 

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(100);

  pinMode(buttonPin2, INPUT_PULLUP); // switch connected to buttonPin2 and GND
  pinMode(buttonPin3, INPUT_PULLUP); // switch connected to buttonPin3 and GND
  pinMode(buttonPin4, INPUT_PULLUP); // switch connected to buttonPin4 and GND
  pinMode(buttonPin5, INPUT_PULLUP); // switch connected to buttonPin5 and GND

  LastPressed = millis();
}

void loop() {
  unsigned long SinceLastPressed;  // Store time since last pressed
  int CurrentLED = -1;

  // Read buttons until we find one that is pressed (this can be done more elegant)
  if(digitalRead(buttonPin2) == LOW) { // try LOW instead of HIGH
    CurrentLED = 0; 
  } else if(digitalRead(buttonPin3) == LOW) { 
    CurrentLED = 1; 
  } else if(digitalRead(buttonPin4) == LOW) { 
    CurrentLED = 2; 
  } else if(digitalRead(buttonPin5) == LOW) { 
    CurrentLED = 3; 
  } 

  // if a button was pressed set LastPressed
  if(CurrentLED>-1) {                            
    LastPressed = millis();                      
  } else {  // else see if auto loop should run
    SinceLastPressed = millis() - LastPressed;   // milliseconds since last time button was pressed
      
    if( SinceLastPressed>NotPressed5 ) {         // restart auto loop after NorPressed5 milliseconds
      LastPressed = millis - NotPressed1; 
      CurrentLED = 0;
    }       
    else if( SinceLastPressed>NotPressed4 ) {
      CurrentLED = 3; }
    else if( SinceLastPressed>NotPressed3 ) {
      CurrentLED = 2; }
    else if( SinceLastPressed>NotPressed2 ) {
      CurrentLED = 1; }
    else if( SinceLastPressed>NotPressed1 ) {
      CurrentLED = 0; }
  } 

  // only clear LEDs and set LED when a button was pressed or auto-loop is running - otherwise: leave LEDs as is
  if (CurrentLED>-1) {                            // Set LED color of selected LED
    FastLED.clear();                                // set all LEDs to black
    leds[CurrentLED] = myColors[CurrentLED];       
    FastLED.show();                                 // Show LEDs
  } 
}

   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

Hi Hans,

no need for apologies. Fast coding comes with typos, so I think that´s a side effect of your superpower 🤣

 

I still have two little problems. For one of it I think I know where the problem is, but I don´t know how to fix it.
The issue is, that after the 5 minutes, the automated animation starts and runs through. But when the last LED is lit for 30 seconds, it jumps back to the first LED and constantly lights it up instead of keeping the automated animation. Also when waiting for 5 minutes again, nothing happens anymore. But I can still push a button and it reacts to it, like normal. So waiting again for 5 minutes, the autamted animation runs throug, jumps back to the first LED and stays there again forever.  So it does not restart the auto loop.

Am I right that the problem is here, because it is set to the first LED? I just don´t know what to change:

    if( SinceLastPressed>NotPressed5 ) {         // restart auto loop after NorPressed5 milliseconds
      LastPressed = millis - NotPressed1; 
      CurrentLED = 0;

 

The next problem is a hardware problem, but maybe you can help me with your experience. I want to use those programmable single 5mm LED´s  instead of a stripe. And as soon as I power the Arduino, all the LED´s light up blue and stay blue until the 5 minutes are reached or I push a button. This only happes with those 5mm LED´s, not with the stripe. I already have changed from WS2812b to SK6812 in the setup but that doesnt work. Could it be a missing capacitor, like the ones mounted on the stripe? Cause somewhere I have read that the 5mm LED´s doesn´t have the capacitor.


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2728
 

Hi Trace,

thanks for considering the super-powers hahah ... but like you, I'm just a hobbyist 😊 

I haven't tested the code, but the effect you're seeing after the first "after 5 minutes' cycle is not what I would have expected.
The piece of code you are quoting is indeed where the problem may be ... even though at first glance it looks OK to me.

Since I'm not quite sure what is going wrong, a few things we can try.

1. Change "SinceLastPressed" to default to zero. 

  unsigned long SinceLastPressed = 0;  // Store time since last pressed

 

2. Just a stab in the dark that shouldn't make a difference either, is changing the if then to something like this:
(millis() and millis should result in the same thing: calling the "millis" function without passing any parameters)

    if( SinceLastPressed>NotPressed5 ) {         // restart auto loop after NorPressed5 milliseconds
      LastPressed = millis() - NotPressed1; 
    }  
     
    SinceLastPressed = millis() - LastPressed;   // milliseconds since last time button was pressed

    if( SinceLastPressed>NotPressed4 ) {
      CurrentLED = 3; }
    else if( SinceLastPressed>NotPressed3 ) {
      CurrentLED = 2; }
    else if( SinceLastPressed>NotPressed2 ) {
      CurrentLED = 1; }
    else if( SinceLastPressed>NotPressed1 ) {
      CurrentLED = 0; }
  } 

 

3. I've never worked with individual RGB LEDs, but we can set the "color" to black during setup by adding these 2 lines:

  FastLED.clear;
  FastLED.show();

 

Not sure if either will fix the issue, but both combined in code ...

#define FASTLED_INTERNAL    // just used to mute the Pragma messages when compiling
#include <FastLED.h>

#define NUM_LEDS  5
#define LED_PIN   5

#define buttonPin2 10
#define buttonPin3 9
#define buttonPin4 8
#define buttonPin5 7

// time slots when nothing was pressed: 5 minutes = 300 seconds = 300,000 milliseconds
#define NotPressed1 300000
#define NotPressed2 330000
#define NotPressed3 360000
#define NotPressed4 390000
#define NotPressed5 420000

unsigned long LastPressed = 0; // 0 = ignore lastPressed

CRGB leds[NUM_LEDS];

CRGB myColors[4] = { CRGB(0,0,255),
                     CRGB(255,0,255),
                     CRGB(255, 255, 0),
                     CRGB(0, 255, 255) }; 

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(100);
  FastLED.clear;
  FastLED.show();

  pinMode(buttonPin2, INPUT_PULLUP); // switch connected to buttonPin2 and GND
  pinMode(buttonPin3, INPUT_PULLUP); // switch connected to buttonPin3 and GND
  pinMode(buttonPin4, INPUT_PULLUP); // switch connected to buttonPin4 and GND
  pinMode(buttonPin5, INPUT_PULLUP); // switch connected to buttonPin5 and GND

  LastPressed = millis();
}

void loop() {
  unsigned long SinceLastPressed = 0;  // Store time since last pressed
  int CurrentLED = -1;

  // Read buttons until we find one that is pressed (this can be done more elegant)
  if(digitalRead(buttonPin2) == LOW) { // try LOW instead of HIGH
    CurrentLED = 0; 
  } else if(digitalRead(buttonPin3) == LOW) { 
    CurrentLED = 1; 
  } else if(digitalRead(buttonPin4) == LOW) { 
    CurrentLED = 2; 
  } else if(digitalRead(buttonPin5) == LOW) { 
    CurrentLED = 3; 
  } 

  // if a button was pressed set LastPressed
  if(CurrentLED>-1) {                            
    LastPressed = millis();                      
  } else {  // else see if auto loop should run

    if( SinceLastPressed>NotPressed5 ) {         // restart auto loop after NorPressed5 milliseconds
      LastPressed = millis() - NotPressed1; 
    }  

    SinceLastPressed = millis() - LastPressed;   // milliseconds since last time button was pressed

    if( SinceLastPressed>NotPressed4 ) {
      CurrentLED = 3; }
    else if( SinceLastPressed>NotPressed3 ) {
      CurrentLED = 2; }
    else if( SinceLastPressed>NotPressed2 ) {
      CurrentLED = 1; }
    else if( SinceLastPressed>NotPressed1 ) {
      CurrentLED = 0; }
  } 

  // only clear LEDs and set LED when a button was pressed or auto-loop is running - otherwise: leave LEDs as is
  if (CurrentLED>-1) {                            // Set LED color of selected LED
    FastLED.clear();                                // set all LEDs to black
    leds[CurrentLED] = myColors[CurrentLED];       
    FastLED.show();                                 // Show LEDs
  } 
}

 

 


   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

@hans Hi Hans, I don´t think you are just a hobbyist, cause your code works flawlessly. I just had to add a () here:

  FastLED.clear;
  FastLED.show();

 

Now I still have all LED´s light up when powering the Arduino, but it last just for less than a second and I can live with that. I think it has to do with the LED chip or maybe the missing capacitor. I have ordered some 100nF and will try if this will make any difference.

And again I had no clue how to code that and now Im sitting here with a full working code written by you. The more I learn about this, the more I realize how little I know and I still hope it is still like learning a compex new language and some day I will be able to fully understand it. Still having issues to get my head around where, how, when I can use which kind of command like millis and else-if and compare operators 🤣 

This one goes to you:

https://www.youtube.com/watch?v=OvntcIVKnJM

Thank you very much Hans!


   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

And here is the full working code without typos:

#define FASTLED_INTERNAL    // just used to mute the Pragma messages when compiling
#include <FastLED.h>

#define NUM_LEDS  4
#define LED_PIN   5

#define buttonPin2 10
#define buttonPin3 9
#define buttonPin4 8
#define buttonPin5 7

// time slots when nothing was pressed: 5 minutes = 300 seconds = 300,000 milliseconds
#define NotPressed1 300000
#define NotPressed2 330000
#define NotPressed3 360000
#define NotPressed4 390000
#define NotPressed5 420000

unsigned long LastPressed = 0; // 0 = ignore lastPressed

CRGB leds[NUM_LEDS];

CRGB myColors[4] = { CRGB(255,0,0),
                     CRGB(0,255,0),
                     CRGB(0, 0,255),
                     CRGB(255,0, 255) };

void setup() {
  //FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS);
  FastLED.addLeds<SK6812, LED_PIN, RGB>(leds, NUM_LEDS);
  FastLED.setBrightness(20);
  FastLED.clear();
  FastLED.show();
  

  pinMode(buttonPin2, INPUT_PULLUP); // switch connected to buttonPin2 and GND
  pinMode(buttonPin3, INPUT_PULLUP); // switch connected to buttonPin3 and GND
  pinMode(buttonPin4, INPUT_PULLUP); // switch connected to buttonPin4 and GND
  pinMode(buttonPin5, INPUT_PULLUP); // switch connected to buttonPin5 and GND

  LastPressed = millis();
}

void loop() {
  unsigned long SinceLastPressed = 0;  // Store time since last pressed
  int CurrentLED = -1;

  // Read buttons until we find one that is pressed (this can be done more elegant)
  if(digitalRead(buttonPin2) == LOW) { // try LOW instead of HIGH
    CurrentLED = 0; 
  } else if(digitalRead(buttonPin3) == LOW) { 
    CurrentLED = 1; 
  } else if(digitalRead(buttonPin4) == LOW) { 
    CurrentLED = 2; 
  } else if(digitalRead(buttonPin5) == LOW) { 
    CurrentLED = 3; 
  } 

  // if a button was pressed set LastPressed
  if(CurrentLED>-1) {                            
    LastPressed = millis();                      
  } else {  // else see if auto loop should run
    SinceLastPressed = millis() - LastPressed;   // milliseconds since last time button was pressed
      
    if( SinceLastPressed>NotPressed5 ) {         // restart auto loop after NorPressed5 milliseconds
      LastPressed = millis() - NotPressed1; 
    }  
     
    SinceLastPressed = millis() - LastPressed;   // milliseconds since last time button was pressed

    if( SinceLastPressed>NotPressed4 ) {
      CurrentLED = 3; }
    else if( SinceLastPressed>NotPressed3 ) {
      CurrentLED = 2; }
    else if( SinceLastPressed>NotPressed2 ) {
      CurrentLED = 1; }
    else if( SinceLastPressed>NotPressed1 ) {
      CurrentLED = 0; }
  } 
  

  // only clear LEDs and set LED when a button was pressed or auto-loop is running - otherwise: leave LEDs as is
  if (CurrentLED>-1) {                            // Set LED color of selected LED
    FastLED.clear();                                // set all LEDs to black
    leds[CurrentLED] = myColors[CurrentLED];       
    FastLED.show();                                 // Show LEDs
  } 
}

   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

@hans There is still one little thing I had in mind. What do I have to change if I want to have the need to hold the pushbutton to light up the LED instead of pushing once (and it goes of when releasing the button)? Everything else remains the same.

And is it possible to be able to push more than one button and have the corresponding LED´s light up?

This post was modified 3 years ago by Trace

   
ReplyQuote
(@trace)
Estimable Member
Joined: 5 years ago
Posts: 170
Topic starter  

@hans Hey Hans,

Im glad I have found out the first part by myself. But to be honest, I don´t know why it works.

To have the need to hold the push button to lighten up the LED I only had to remove one line:

From this:

  if (CurrentLED>-1) {                            // Set LED color of selected LED
    FastLED.clear();                                // set all LEDs to black
    leds[CurrentLED] = myColors[CurrentLED];       
    FastLED.show();                                 // Show LEDs
  } 

 

To this:

    FastLED.clear();                                // set all LEDs to black
    leds[CurrentLED] = myColors[CurrentLED];       
    FastLED.show();                                 // Show LEDs
   

 

What I don´t get is the function itself. As it is written in the original code, it says "if currentLED is bigger than -1, clear all LEDs". So when I press button X CurrentLED becomes bigger than -1 (0,1,2,3) right? But why does it not clear the LED? Instead I have the LED light up as long as I push another button or the 5 minutes are over.

Now we are just left with the second addition. Being able to push more than one button at a time.


   
ReplyQuote
Page 1 / 2
Share: