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

Need help with beginning of using interrupts

Page 2 / 2

 Hans
(@hans)
Noble Member Admin
Joined: 8 years ago
Posts: 2018
 
Posted by: @trace

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

 

Well, in the original code we only clear all LEDs and set the selected LED color, only IF a button was pressed (or we went beyond the 5 minute marker).
The selected LED is stored in CurrentLED, which is -1 if nothing was selected.

By the way the more correct method would be:

FastLED.clear();                                // set all LEDs to black

if (CurrentLED>-1) {                         // Set LED color of selected LED
  leds[CurrentLED] = myColors[CurrentLED];       
}

FastLED.show();                               // Show LEDs
 

 

This to avoid that we are going to use a negative index for the "leds[]" and "myColors[]" arrays (which theoretically could cause errors, since we'd be addressing an invalid memory location, even though the Arduino doesn't seem to be bothered by it).

I'm not sure if I understood your explanation of what happens though.

 

As for pressing multiple buttons at the same time: This would mean we'd need to redo some of the coding.

Right now we save one button press only in CurrentLED, which would not work as expected when pressing multiple buttons.

In the (untested) code below, I'm still using CurrentLED, so I can see if a button was pressed and/or to set the LEDs after the 5 minute marker.
For this to work I needed to move the FastLED.clear more to the front, and test each button and set it's LED if applicable.

I hope this works and makes sense 😉 

#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() {
  FastLED.clear(); // set all LEDs to black

  // Read buttons until we find one that is pressed (this can be done more elegant)
  if (digitalRead(buttonPin2) == LOW) { // try LOW instead of HIGH
    leds[0] = myColors[0];
    CurrentLED = 0;
  }

  if (digitalRead(buttonPin3) == LOW) {
    leds[1] = myColors[1];
    CurrentLED = 1;
  }

  if (digitalRead(buttonPin4) == LOW) {
    leds[2] = myColors[2];
    CurrentLED = 2;
  }

  if (digitalRead(buttonPin5) == LOW) {
    leds[3] = myColors[3];
    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;
    }

    if (CurrentLED > -1) {
      leds[CurrentLED] = myColors[CurrentLED];
    }
  }

  FastLED.show(); // Show LEDs
}

 

 


ReplyQuote
(@trace)
Estimable Member
Joined: 2 years ago
Posts: 115
Topic starter  

Hi Hans,

with your more correct part of code I undestand it now. FastLED.clear had nothing to do with the selected LED stored in CurrentLED when >-1. Thanks for your explanation.

Yesterday I have already tried to rewrite the code to test each button and it looked like your code now, but it had to fail cause I didn´t know I needed to move the FastLED.clear earlier in the code. This is what still confuses me all the time. Not knowing when to put pieces of code in the right place. And it is easier to understand a code when it´s working instead of understanding why it is not working. 🤣 

But to be honest I don´t get it, why moving FastLED.clear makes such a big difference to be able to use multiple buttons at a time 🤔 

In your code I just had to add unsigned long SinceLastPressed=0; and int CurrentLED = -1; because both were not declared.

void loop() {
  FastLED.clear(); // set all LEDs to black
  unsigned long SinceLastPressed = 0;  // Store time since last pressed
  int CurrentLED = -1;

 

And now it works without any problems. Great work from you again Hans. Thanks a lot.
Here is the full working and tested Code:

#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() {
  FastLED.clear(); // set all LEDs to black
  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
    leds[0] = myColors[0];
    CurrentLED = 0;
  }

  if (digitalRead(buttonPin3) == LOW) {
    leds[1] = myColors[1];
    CurrentLED = 1;
  }

  if (digitalRead(buttonPin4) == LOW) {
    leds[2] = myColors[2];
    CurrentLED = 2;
  }

  if (digitalRead(buttonPin5) == LOW) {
    leds[3] = myColors[3];
    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;
    }

    if (CurrentLED > -1) {
      leds[CurrentLED] = myColors[CurrentLED];
    }
  }

  FastLED.show(); // Show LEDs
}

ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 8 years ago
Posts: 2018
 
Posted by: @trace

But to be honest I don´t get it, why moving FastLED.clear makes such a big difference to be able to use multiple buttons at a time

The FastLE.clear function simply sets all LEDs to black (off), so any colors we would have set before calling that function would be lost.
For example: We press the buttons 1 and 3.

First we set all LEDs to black.
Next we detect that button1 is pressed and set LED 1 to color 1. (saved in leds[0])
Next we detect that button3 is pressed and set LED 3 to color 3. (saved in leds[2])
And finally we make the changes visible (FastLED.show).

Here we store the pressed buttons as colors in the leds array.

However when we used just 1 button, we store that button in a separate variable (CurrentLED), cleared all LEDs and after that set the proper led to the proper color.
This was easier that way, since we only had to deal with one LED.

I hope that made sense 😊 

Nice catch on the code that I had forgotten to paste 😜 
And good to hear it works now - enjoy and see ya next time! 👍 


ReplyQuote
(@trace)
Estimable Member
Joined: 2 years ago
Posts: 115
Topic starter  

@hans I think I know understand it a bit better. There is a lot more to learn. Thanks for your explanation and have a nice sunday 👍 


ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 8 years ago
Posts: 2018
 

Thanks Trace and you're most welcome! Hope you had a good weekend as well 😉 


ReplyQuote


Page 2 / 2

Like what you see and you'd like to help out? 

The best way to help is of course by assisting others with their questions here in the forum, but you can also help us out in other ways:

- Do your shopping at Amazon, it will not cost you anything extra but may generate a small commission for us,
- send a cup of coffee through PayPal ($5, $10, $20, or custom amount),
- become a Patreon,
- donate BitCoin (BTC), or BitCoinCash (BCH).

Share: