Holding a button/relay

Hi Guys,

I can't thank you enough for your help but I'm useless at explaining what I'm trying to achieve.

I think Evan hit the nail on the head and Cattledog, it might be worth showing a vid of my current setup:

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

As I explained before, because of my intention to combine the green with the red (and the need for the red to jump into the sequence at any time), my 'indicatorSweep()' function addresses each led in turn with each loop (instead of creating the sweep in a single loop) This means that when the button is released, the strip resets.

I simply can't work out how to make the green sweep reach the end of the strip with a single button press while still allowing the red to jump into the sequence at any time.

This is where millis() comes in hopefully and Evan summed it up perfectly:

If the button is pressed (for an instant or longer), set indicatorPintimerRunning to 1. Keep indicatorPintimerRunning (aka, buttonPressed) set for one second. While buttonPressed ==1, do whatever needs to happen while it looks like the button was held.

I'm just not sure how to implement this yet but I'm going to give it a go now.

Thanks again guys, sorry I'm having so much trouble getting my head round this!

Kyle

I can’t imagine how wrong this is but how’s this?

#include "FastLED.h"


#define NUM_LEDS 15

CRGB leds[NUM_LEDS];

const int indicatorPin = 2;    
unsigned long currentMillis;
byte indicatorPintimerRunning = 0;
unsigned long indicatorPinstartTime;
unsigned long indicatorPinelapsedTime;
unsigned long indicatorPinonDuration = 1000;
int currentIndicatorLED = 0;


void setup() {   
  
  FastLED.addLeds<WS2812B, 6, RGB>(leds, NUM_LEDS);
  pinMode (indicatorPin, INPUT_PULLUP); // wire pinX to connect to Gnd when button is pressed
}

void indicatorSweep()
 
{
  if (currentIndicatorLED < NUM_LEDS)
  {
    
    leds[currentIndicatorLED] = CRGB(255, 0, 0);
    FastLED.show();
    
    currentIndicatorLED++;
  }
  else
  {
    
    FastLED.clear();
    FastLED.show();                           
    delay(100);        

    currentIndicatorLED = 0;
  }

  delay(35);
 
}

void loop(){
currentMillis = millis();
indicatorPinstartTime = millis(); //how does this code know what this variable does?
// check if button pin has been pressed for 'an instant or longer'
if (digitalRead(indicatorPin) == indicatorPinstartTime){ //if button pin has been pressed for millis or longer?
indicatorPintimerRunning = 1;

if (indicatorPintimerRunning = 1) {
indicatorSweep();

// Nothing to stop the sweep yet since I need to work out how to hold it for 1 second first (walk before I can run)
 }

}

From the look of this, can I remove some of the variables or do I need them all still?

Sorry for the lack of understanding but thanks again!

Kyle

I think I understand that you want your indicator sweep to finish the pattern when you remove your finger from the button.

Try to shift your thinking around a bit.

When you press the button you will set a global boolean variable callIndicatorSweep = true

In loop you have a conditional test

if(callIndicatorSweep == true)
{
 indicatorSweep();
}

You then cancel the callIndicatorSweep within indicatorSweep() when it is finished.

void indicatorSweep()
 
{
  if (currentIndicatorLED < NUM_LEDS)
  {
    
    leds[currentIndicatorLED] = CRGB(255, 0, 0);
    FastLED.show();
    
    currentIndicatorLED++;
  }
  else
  {
    
    FastLED.clear();
    FastLED.show();                           
    delay(100);        

    currentIndicatorLED = 0;

    callIndicatorSweep = false;
  }

  delay(35);
 
}

kylefoster:
The terminology used on a lot of the Arduino pages is still beyond me so the Unsigned Long page doesn’t make much sense to me nor does it help me understand it’s purpose unfortunately. I really wish I could understand all this so a lot of the simpler things would makes sense too.

It might help to pt the arduino to one side for an hour or two and do a tutorial on the C++ language itself. There’s one here: C++ Language - C++ Tutorials . Don’t know if it’s any good - I learned out of the brown book. You only need the first few chapters, and anything it says about main() or about input and output isn’t really relevant for the arduino environment. But it has the basics that you are missing.

Hi Guys,

Thanks very much for taking the time to reply on a weekend and sorry for my late one,

Cattledog, this makes a lot of sense and like you said, I need to change my thinking for this. It didn't occur to me that you could separate the button state from the state of the function on the strip. If I've understood correctly, I need to add a 'middleman' between the button state and function.

I'll read up on some examples of Boolean variables.

Paul, thanks for your comments too, I am definitely missing the basics and like learning any new skill, it's very difficult to know where to start. I simply saw some leds hooked up to an arduino one day and went from there so thanks for pointing out a specific place to learn from. I'll start looking at that now.

Thanks again guys,

Kyle

Hi Guys,

Thanks for your recent advice. I’ve spent some time trying to learn about boolean variables and state changes. I’ve worked though a few examples:

Using a Button to Change State

State Change Detection

I also saw this which sounds like what I need but I can’t decipher the parts I might need:

How to Make a Variable Stay True

I’ve made a few attempts and the code is ‘functioning’ but certainly not the in the way that I’d like:

#include "FastLED.h"


#define NUM_LEDS 15

CRGB leds[NUM_LEDS];

int currentIndicatorLED = 0;
int brakeState = 0;
const int LED = 9;
const int BUTTON = 2;
const int BUTTONB = 1;
boolean lastButton = LOW;
boolean currentButton = LOW;
boolean ledOn = false;

void setup() {
  
  FastLED.addLeds<WS2812B, 6, RGB>(leds, NUM_LEDS);
  pinMode(BUTTON,INPUT);
  pinMode(BUTTONB,INPUT);
}
boolean debounce(boolean last)
{
  boolean current = digitalRead(BUTTON);
  if(last != current)
{
  delay(5);
  current = digitalRead(BUTTON);
  }
  return current;
}

void indicatorSweep() 
 
{
  if (currentIndicatorLED < NUM_LEDS)
  {
    
    leds[currentIndicatorLED] = CRGB(255, 0, 0);
    FastLED.show();
    
    currentIndicatorLED++;
    
  for (int led = currentIndicatorLED; led < NUM_LEDS; led++)
    { 
      // Are the brakes on ?
      if (brakeState == HIGH)
      {
         // Light the led as a brake
         leds[led] = CRGB(0, 255, 0);        
      }
      
      else
      
      {
         // Blank the led as there is no brake
         leds[led] = CRGB(0, 0, 0);
    }

    
    FastLED.show(); 
       
    }
  }
  
  else 
  
  {

    
    currentIndicatorLED = 0;

  }

  delay(40);
 
}

void loop() {

   brakeState = digitalRead(BUTTONB);
   currentButton = debounce(lastButton);
   if(lastButton == LOW && currentButton == HIGH)
   {
    indicatorSweep();
   }
   lastButton = currentButton;

   
   
}

I’ve added a debounce to help me out a bit (don’t know if this is right either).

I think a lot of my confusion is coming from the fact that these examples (and anything else I can find) don’t have ‘complex’ led strip functions and so I think my code is simply causing the ‘currentIndicatorLED’ to stay on until I call the next loop by pressing the button again rather than saying

‘if (button == HIGH); repeat loop’

Again, here’s the vid of the code functioning as it should (apart from the button release):

Brake and Indicator/Turn Signal Led Strip

Cattledog, thanks again for your advice, it makes a lot of sense and I can understand the logic of it (compared to before). I just can’t work out how and where to implement it.

Also, to show that I’m doing to my best to figure this out I have a question about the code you wrote.

If at the end of my indicatorSweep() function, you say callIndicatorSweep = false; (to cease the ‘state’), would this not call for a cease after each loop if I let go of the button? Bearing in mind my function doesn’t create the sweep in one loop, each loop adds an led to the strip.

I’m not sure if what I thinks going on here is right either!

Also, at the point, I’m wondering if it would be worth trying the FRM 01 timer relay but I’m not sure if it has the functionality I need. After looking at examples of what it does, it seems it would be able to physically hold the button on for a desired time.

Sorry I’m struggling with this so much but thanks again,

Kyle