Comparing of values of the same Array

Hi arduino family,

have the problem that i have a array of values:

LedState[2] = {0,0};
LedState[2] = {1,0};
LedState[2] = {0,1};

And i have 2 buttons and i have 2 Led - one left and one right.
Now i want to compare the values of the array for the condition if the left or the right Led is blinking. The reason is that its only on the left side blinking if there is no blinking on the right side and vice versa.

For example like this.

if(BlinkButton[i] == 2 && LedStat[2] == 1) {  
          BlinkLedState[i] = millis() % (650*2) >= 650; 
      }

if(BlinkButton[i] == 2 && LedStat[1] == 1) {  
          BlinkLedState[i] = millis() % (650*2) >= 650; 
      }

But its not running. I tried to debug it with a seriel.print() but it wasnt running with that condition. Why?

The whole code for understanding of the small learning project:

#include "ClickButton.h"

// Button Array
const int BlinkButtons = 2;
const int LichtButtons = 2;
const int HupeButton = 1;

// LED
const int BlinkLedPin[BlinkButtons] = { 7, 11 }; // Arduino pins to the LEDs
int BlinkLedState[BlinkButtons]     = { 0, 0 };
int BlinkLEDfunction[BlinkButtons]  = { 0, 0 };
unsigned long lastActionMillis[BlinkButtons] = { 0,0 };

// Input Pin
const int BlinkButtonPin1 = 14;
const int BlinkButtonPin2 = 19;

//Intervalle
const long Interval2 = 5000;

/*Marker
int ActionStateLinks = 0;
int ActionStateRechts = 0;
int ActionStateFront1 = 0;
int ActionStateFront2 = 0;
*/

// Instantiate ClickButton objects in an array
ClickButton BlinkButton[BlinkButtons] = {
  ClickButton (BlinkButtonPin1, LOW, CLICKBTN_PULLUP), // HABEN ALLE PULLUPS AM NANO?
  ClickButton (BlinkButtonPin2, LOW, CLICKBTN_PULLUP),
};

//----------------------------------------

void setup()
{
  Serial.begin(9600);
  
  //Blinkersektion
  
  for (int i=0; i<BlinkButtons; i++)
  {
    pinMode(BlinkLedPin[i],OUTPUT);  

    BlinkButton[i].debounceTime   = 20;   // Debounce timer in ms
    BlinkButton[i].multiclickTime = 250;  // Time limit for multi clicks
    BlinkButton[i].longClickTime  = 1000; // Time until long clicks register
  }
}

//----------------------------------------

void loop()
{

//Blinksection
  for (int i=0; i<BlinkButtons; i++) {
      BlinkButton[i].Update();
  
      if (BlinkButton[i].clicks != 0) {    
        BlinkLEDfunction[i] = BlinkButton[i].clicks;
        lastActionMillis[i] = millis();
        
      }
      
//1 click

      if(BlinkLEDfunction[i] == 1) {   
          if(millis() - lastActionMillis[i] < Interval2) {
            Serial.println("eins funzt");
              BlinkLedState[i] = millis() % (650*2) >= 650; 
              }
                  else { BlinkLedState[i] = 0;
                  }
      }
     
//2 clicks

      if(BlinkLEDfunction[i] == 2) {  
        Serial.println("links funzt");
          BlinkLedState[i] = millis() % (650*2) >= 650; 
      }
         
//3 long click

      if(BlinkLEDfunction[i] == -3) {   
        Serial.println("lang funzt");
          BlinkLedState[i] = millis() % (650*2) >= 650;
      }
  }
  
//----------------------------------------
// update the LEDs

      for (int i=0; i<BlinkButtons; i++) {
          digitalWrite(BlinkLedPin[i],BlinkLedState[i]);
      }

}

I am not sure would be correct to make this comparison unless the clickButton object can be converted to integer in your class.
if(BlinkButton == 2

how about just adding a bool bBlinktJemand and if one is requested to start blinking, they first check if it's false, so they can start and setting it to true so no other blinker can claim it. when they are requested to stop they just change it back to false. that way you also can add as many blinkers as you want without changing that part of the code

@abdelhmimas
thanks for your thoughts and help. "2" is an integer value and without "&& LedStat[2] == 1" everything is fine. so it should be okay and work - or am i wrong? did i missunderstand you?

@frozenrat
i dont get it. Maybe i had the ides as plan B. i wanted to try "ActionMarker" if there is still some action. Is this what you mean?

@OP
Sorry for the confusion,
BlinkButton is declared as an object of clickButton type.
Unless clickButton can return somehow an integer you cannot make a test like
If BlinkButton == 2
Have a look to the .h library, you may need to compare it with a member of BliknButton that returns the value to compare.

a declared object cant be compared? do i understand right? is it always like this? Is that the reason why the value is stored in another array?

BlinkLEDfunction[i] = BlinkButton[i].clicks;

I don't see the need for the BlinkLEDfunction array

You should be able to read BlinkButton_.clicks whenever you need to know its value as long as you do a BlinkButton*.Update() at the start of loop()*_

Okay thanks so i understand that i also could replace “BlinkLEDfunction_” with “[/color]BlinkButton*.clicks” and everything will be the same?![/color]*_
But the origin of the post was the question how i can compare the values of the array?
Now i can push several buttons and several Led can blink. But i wanna do the rule:
Left Led can only blink when right is not blinking - and of course the other way - right blinks when left is not blinking.
I tried several things but nothing worked.

gnom:
Left Led can only blink when right is not blinking - and of course the other way - right blinks when left is not blinking.

If one of the LEDs is blinking, do you want to disable the ability to make the other blink, or stop the one that is currently blinking and blink the other LED? In other words, if the right LED is blinking and you press the button to blink the left LED, do you want to continue blinking the right LED, or stop the right LED from blinking and start blinking the left LED?
Do you want to do this only with two LEDs, or add more LEDs later?

UKHeliBob:
You should be able to read BlinkButton_.clicks whenever you need to know its value as long as you do a BlinkButton*.Update() at the start of loop()[/quote]_
My guess is that Update() sets .clicks to 0 if the state has not changed. That would explain why the sketch stores the value (.clicks=0, 1, 2, -3 for NoChange, Click, DoubleClick, and LongPress) and records the time each time .clicks is non-zero. They need to remember the click state and the time it last changed.
I would define constants for Left and Right and use those when noting a new state:
_
```*_
*const int Left = 0;
const int Right = 1;
 if (BlinkButton[i].clicks != 0)
   {
     switch (i)
     {
       case Left:
         BlinkLEDfunction[Left] = BlinkButton[Left].clicks;
         BlinkLEDfunction[Right] = 0;  // Tell the other LED to stop
         BlinkLedState[Right] = 0;
         lastActionMillis[Left] = millis();
         break;

case Right:
         BlinkLEDfunction[Right] = BlinkButton[Right].clicks;
         BlinkLEDfunction[Left] = 0;  // Tell the other LED to stop
         BlinkLedState[Left] = 0;
         lastActionMillis[Right] = millis();
         break;
     }
   }*

```

thanks for your thoughts!

@david_2018
left is blinking, i push the button for right --> left stops and right is blinking. and of course in the other direction as well only switched. Should be a little project for my motorbike to learn some more programming.

right now the blinking is only for the two led sides but there will be also added the light switch and so on ... later

@johnwasser
the .clicks value will be stored and not be resetted - i did a serial.print() and it was stored and repeated every loop.But its a interesting thought with the switch..case() stuff! thanks a lot! I'll try and will be back with more questions for sure!

This is a bit more complex than a simple if statement, because you will need to set one LED to blink, and also turn off the blinking for all the other LEDs. Extending to more than two buttons/LEDs would make it even more complex.

I have not tested this with actual hardware, but it will compile, and should give you some ideas:

#include "ClickButton.h"

// Button Array
const int BlinkButtons = 2;
const int LichtButtons = 2;
const int HupeButton = 1;

// LED
const int BlinkLedPin[BlinkButtons] = { 7, 11 }; // Arduino pins to the LEDs
bool BlinkLedState[BlinkButtons] = { false, false };
int BlinkLEDfunction[BlinkButtons]  = { 0, 0 };
unsigned long lastActionMillis[BlinkButtons] = { 0, 0 };

bool LEDBlinking[BlinkButtons] = { false, false };
bool LEDBlinkingPrevious[BlinkButtons] = { false, false };
unsigned long blinkTimer;
//set active state of LED output pins, active state will depend on your actual wiring
const byte LEDon = LOW;
const byte LEDoff = HIGH;

// Input Pin
const int BlinkButtonPin1 = 14;
const int BlinkButtonPin2 = 19;

//Intervalle
const long Interval2 = 5000;

/*Marker
  int ActionStateLinks = 0;
  int ActionStateRechts = 0;
  int ActionStateFront1 = 0;
  int ActionStateFront2 = 0;
*/

// Instantiate ClickButton objects in an array
ClickButton BlinkButton[BlinkButtons] = {
  ClickButton (BlinkButtonPin1, LOW, CLICKBTN_PULLUP), // HABEN ALLE PULLUPS AM NANO?
  ClickButton (BlinkButtonPin2, LOW, CLICKBTN_PULLUP),
};

//----------------------------------------

void setup()
{
  Serial.begin(9600);

  //Blinkersektion

  for (int i = 0; i < BlinkButtons; i++)
  {
    pinMode(BlinkLedPin[i], OUTPUT);

    BlinkButton[i].debounceTime   = 20;   // Debounce timer in ms
    BlinkButton[i].multiclickTime = 250;  // Time limit for multi clicks
    BlinkButton[i].longClickTime  = 1000; // Time until long clicks register
  }
}

//----------------------------------------

void loop()
{

  //Blinksection
  for (int i = 0; i < BlinkButtons; i++) {
    BlinkButton[i].Update();

    if (BlinkButton[i].clicks != 0) {
      BlinkLEDfunction[i] = BlinkButton[i].clicks;
      lastActionMillis[i] = millis();

    }

    //1 click

    if (BlinkLEDfunction[i] == 1) {
      if (millis() - lastActionMillis[i] < Interval2) {
        Serial.println("eins funzt");
        //BlinkLedState[i] = millis() % (650 * 2) >= 650;
        BlinkLedState[i] = true;
      }
      else {
        BlinkLedState[i] = false;
      }
    }

    //2 clicks

    if (BlinkLEDfunction[i] == 2) {
      Serial.println("links funzt");
      //BlinkLedState[i] = millis() % (650 * 2) >= 650;
      BlinkLedState[i] = true;
    }

    //3 long click

    if (BlinkLEDfunction[i] == -3) {
      Serial.println("lang funzt");
      //BlinkLedState[i] = millis() % (650 * 2) >= 650;
      BlinkLedState[i] = true;
    }
  }

  //----------------------------------------
  //determine which LED should be blinking
  //  note that higher number BlinkButtons have priority, so two cannot be turned on simultaneously
  for (int i = 0; i < BlinkButtons; i++) {
    if (BlinkLedState[i] == true) {
      for (int j = 0; j < BlinkButtons; j++) {
        if (i == j) {
          LEDBlinking[j] = true; //turns on blinking for current button
        } else {
          LEDBlinking[j] = false; //turns off blinking for all other buttons
        }
      }
    } else { //(BlinkLEDState[i] == false)
      LEDBlinking[i] = false;
    }
  }

  //initialize blinking on LED that was not previously blinking
  //  and turn off any LED that is blinking but needs to stop
  for (int i = 0; i < BlinkButtons; i++) {
    if (LEDBlinking[i] != LEDBlinkingPrevious[i]) {
      blinkTimer = millis(); //reset start of blink cycle
      if (LEDBlinking[i] == true) {
        digitalWrite(BlinkLedPin[i], LEDon);
      } else {
        digitalWrite(BlinkLedPin[i], LEDoff);
      }
    }
    LEDBlinkingPrevious[i] = LEDBlinking[i];
  }
  
  if ((millis() - blinkTimer) >= 650ul) {
    blinkTimer = millis();
    for (int i = 0; i < BlinkButtons; i++) {
      if (LEDBlinking[i] == true) {
        digitalWrite(BlinkLedPin[i], (digitalRead(BlinkLedPin[i]) == LOW) ? HIGH : LOW); //change state of LED output
      }
    }
  }

}

Something else that will cause you problems, your code does not appear to have a way to clear a value from BlinkLedFunction once it is set to something other than 0. If you only want a single LED blinking at a time, you would probably want to clear the value in BlinkLedFunction for the buttons of the non-blinking LEDs.

@david_2018

yeah that is what i found out. Was a lot of information for a newbie at the weekend and now i try get everything in order in my mind :smiley: @johnwasser and you helped my a lot to get new ideas for a solution. I wanted to think about the case() process from @johnwasser and your determining of the buttons/Led - its really useful!

but one question to a part of your code:

if ((millis() - blinkTimer) >= 650ul) {
    blinkTimer = millis();
    for (int i = 0; i < BlinkButtons; i++) {
      if (LEDBlinking[i] == true) {
        digitalWrite(BlinkLedPin[i], (digitalRead(BlinkLedPin[i]) == LOW) ? HIGH : LOW); //change state of LED output
      }

is the 650ul only a little keyboard misfortune or do you wanted to write “ul”?

and i can’t find a explanation to the syntax of

digitalWrite(BlinkLedPin[i], (digitalRead(BlinkLedPin[i]) == LOW) ? HIGH : LOW);

what is the "? HIGH : LOW? doing?

is the 650ul only a little keyboard misfortune or do you wanted to write "ul"?

That tells the compiler that the number is unsigned long. Not really needed here, but just being consistent since millis() is an unsigned long.

what is the "? HIGH : LOW? doing?

That is the c++ unary operator, the equivalent of

if (digitalRead(BlinkLedPin[i]) == LOW) {
  digitalWrite(BlinkLedPin[i], HIGH);
} else {
  digitalWrite(BlinkLedPin[i], LOW);
}

That statement is often written as follows, but because of some changes in the IDE this doesn't always work on some of the newer boards.

digitalWrite(BlinkLedPin[i], !digitalRead(BlinkLedPin[i]) );

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.