Problems with the JLED Library

Hello together,

I have a Problem regarding the usage of the JLED Library with an Arduino NANO. The example program (LED breathing) works fine with my Hardware.

In a second step i tried to connect a switch to my Arduino Nano. With this switch I want to start and stop the “breathing effect”. But I cant get this working.

Unfortunately I’m still a beginner regarding programming. Maybe one of you can help me. Thanks in advance.

Here my code:

#include <jled.h>

const int Switch = 7;
auto led = JLed(9);

void setup() {
 pinMode(Switch, INPUT_PULLUP);
 }

void loop() {
 
led.Update();
     if (digitalRead(Switch) == LOW){
      led.Breathe(2000).DelayAfter(1000).Forever();
       }
     else{
      led.Stop();
     }
}
led.Breathe(2000).DelayAfter(1000).Forever();

I am not familiar with the library but what does the Forever() function do ?

Try printing the value of your digitalRead(). What do you see and how often ?

The Forever() methods sets to repeat the effect forever.

I changed my code to ensure my Hardware switch is working. The following code works fine. I can switch the onboard LED ON and OFF…

#include <jled.h>

const int Switch = 7;
auto led = JLed(9);

void setup() {
  pinMode(Switch, INPUT_PULLUP);
  }


void loop() {
  
 //led.Update();
      if (digitalRead(Switch)==LOW){
         digitalWrite(LED_BUILTIN, HIGH);
        }
        
      else{
       digitalWrite(LED_BUILTIN, LOW);
      }
}

It works but does it work in your main program ?

Do as I suggested and print the value returned by digitalRead()
This

led.Breathe(2000).DelayAfter(1000).Forever();

leads me to believe that there will be at least 3 seconds between each digitalRead()

If you are aiming to use the switch as an on/off toggle for the effect then you are doing ig incorrectly. If, however, you want the effect only to run when the button is held down then it could work. Which is it ?

Try this

void loop()
{
  led.Update();
  if (digitalRead(Switch) == LOW)
  {
    if (led.IsRunning() == false)  //start again only if the sequence is not currently running
    {
      led.Breathe(2000).DelayAfter(1000);
    }
  }
  else
  {
    led.Stop();
  }
}

Hi,

thank you very much. Your code works fine. Now I added a second switch to start different effects. Each of the two if-loops works fine.

But they don`t work together. Any Idea? Thanks in advance!

#include <jled.h>
const int SwitchA = 7;
const int SwitchB = 6;
auto led = JLed(9);
int ledpin=9;

void setup() {
  pinMode(SwitchA, INPUT_PULLUP);
  pinMode(SwitchB, INPUT_PULLUP);
  }

void loop()
{
  led.Update();

  
  if (digitalRead(SwitchA) == LOW && digitalRead(SwitchB) == HIGH)
  {
    if (led.IsRunning() == false)  //start again only if the sequence is not currently running
    {
      led.Breathe(2000).DelayAfter(1000).Forever();
    }
  }
  else
  {
    led.Stop();
  }

  if (digitalRead(SwitchA) == HIGH && digitalRead(SwitchB) == LOW)
  {
    if (led.IsRunning() == false)  //start again only if the sequence is not currently running
    {
      led.FadeOn(2000).DelayBefore(500);
    }
  }
  else
  {
    led.Stop();
  }
}

Try this

void loop()
{
  led.Update();
  if (digitalRead(SwitchA) == LOW && digitalRead(SwitchB) == HIGH)
  {
    if (led.IsRunning() == false)  //start again only if the sequence is not currently running
    {
      led.Breathe(2000).DelayAfter(1000).Forever();
    }
  }
  else if (digitalRead(SwitchA) == HIGH && digitalRead(SwitchB) == LOW)
  {
    if (led.IsRunning() == false)  //start again only if the sequence is not currently running
    {
      led.FadeOn(2000).DelayBefore(500);
    }
  }
  else
  {
    led.Stop();
  }
}

Your code was always falling through to one or other of the led.Stop() calls

Ok understand and I tried your code and it works fine.
Now I want that the "else if" Argument executed only one time per toggle of switchB

else if (digitalRead(SwitchA) == HIGH && digitalRead(SwitchB) == LOW)
  {
    if (led.IsRunning() == false)  //start again only if the sequence is not currently running
    {
      led.FadeOn(2000).DelayBefore(500);
    }
  }

Can I realize this with an variable in the loop which is reset in/outside the loop or is there a better way to realize this?

Now I want that the "else if" Argument executed only one time per toggle of switchB

You need to detect when the button changes state rather than its current state. There is an example of this in the IDE. Look at the StateChangeDetection example

Thanks a lot…a very good Tip!

The following code is working fine…

#include <jled.h>
const int SwitchA = 7;
const int SwitchB = 6;
auto led = JLed(9);
int ledpin=9;
int SWB_old = 1;
int SWB_state = 1;
//static boolean Durchlauf = true;

void setup() {
  pinMode(SwitchA, INPUT_PULLUP);
  pinMode(SwitchB, INPUT_PULLUP);
  }
  
void loop()
{
  led.Update();
   
  if (digitalRead(SwitchA) == LOW && digitalRead(SwitchB) == HIGH)
  {
    if (led.IsRunning() == false)  //start again only if the sequence is not currently running
    {
      led.Breathe(5000).Forever();
    }
  }
  else if (digitalRead(SwitchA) == HIGH && digitalRead(SwitchB) == LOW)
  {
    delay (200);
    SWB_state = digitalRead(SwitchB);
    if (led.IsRunning() == false && SWB_state != SWB_old)  //start again only if the sequence is not currently running
    {
      led.FadeOn(5000).Repeat(1);
      SWB_old = SWB_state;
    }
  }
  else
  {
    led.Stop();
  }
}

Good news that you got it working

Personally I would rearrange the code like this

//https://forum.arduino.cc/index.php?topic=671518.0
#include <jled.h>
const int SwitchA = 7;
const int SwitchB = 6;
auto led = JLed(9);
int ledpin = 9;

void setup()
{
  Serial.begin(115200);
  pinMode(SwitchA, INPUT_PULLUP);
  pinMode(SwitchB, INPUT_PULLUP);
  led.Stop();
}

void loop()
{
  led.Update();
  if (led.IsRunning() == false)
  {
    byte stateA = digitalRead(SwitchA);
    byte stateB = digitalRead(SwitchB);
    if (stateA == LOW && stateB == HIGH)
    {
      led.Breathe(2000).DelayAfter(1000);
    }
    else if (stateA == HIGH)
    {
      if (stateB == LOW)
      {
        led.FadeOn(2000).DelayBefore(500);
      }
    }
    else
    {
      led.Stop();
    }
  }
}

The digitalRead()s are only done once and only then if the led sequence is not running. I have split the second input test into two stages rather than having a compound test to make it easier to change the code to detect the input becoming LOW

As you have got it working feel free to ignore the suggested changes

Thank you.

Your solution looks much more professional than mine ;-)!

But it is not working in the same way. Maybe I can combine your solution with mine.......!

I will have a look

it is not working in the same way

It won't. It is based on your first 2 button requirement but you can add the state change detection to it

Ok…now i added the third and the last switch to my code…!
Now it looks like this and its working! Thank you for your great help. In the next step I try to clean up the code a bit…

#include <jled.h>
const int SwitchA = 7;
const int SwitchB = 6;
const int SwitchC = 5;
auto led = JLed(9);
int ledpin=9;
int SWB_old = 1;
int SWB_state = 1;

void setup() {
  pinMode(SwitchA, INPUT_PULLUP);
  pinMode(SwitchB, INPUT_PULLUP);
  pinMode(SwitchC, INPUT_PULLUP);
  }
  
void loop()
{
  led.Update();
   
  if (digitalRead(SwitchA) == LOW && digitalRead(SwitchB) == HIGH && digitalRead(SwitchC) == HIGH)
  {
    if (led.IsRunning() == false)  //start again only if the sequence is not currently running
    {
      led.Breathe(5000).Forever();
    }
  }

  else if (digitalRead(SwitchA) == HIGH && digitalRead(SwitchB) == HIGH && digitalRead(SwitchC) == LOW)
  {
    if (led.IsRunning() == false)  //start again only if the sequence is not currently running
    {
      led.Blink(1000, 1000).Forever();
    }
  }
  
  else if (digitalRead(SwitchA) == HIGH && digitalRead(SwitchB) == LOW && digitalRead(SwitchC) == HIGH)
  {
    delay (200);
    SWB_state = digitalRead(SwitchB);
    if (led.IsRunning() == false && SWB_state != SWB_old)  //start again only if the sequence is not currently running
    {
      led.FadeOn(10000).Repeat(1);
      SWB_old = SWB_state;
    }
  }
  else
  {
    led.Stop();
  }
}

.now i added the third and the last switch to my code.

The process is very familiar to me from working with customers

Customer says "I want the program to do this"
The program is written, delivered and tested

Customer says "I have had another idea"
The revised program is written and delivered and tested

Customer says "That's great, but can you just add ..."
The program now requires a rewrite and would have been written in a different way in the first place if the full specification had been known at the start.

The program is rewritten, delivered and the customer says "Why is the project running late ?"

In the commercial world we often spent as much time finalising the specification as we did writing the program and the customer was expected to sign off the specification and pay heavily for later changes, so it was not always bad news for the software house and programs would often be written with future possible changes in mind.