Best practice for checking

Hi,

Sweltering heat here so my brains probably melted out of my ear.

Whats the best practice for structuring code for this?

Basic priciple.

3x counters counting down to 0.
1st counter is primary. If it reaches 0 all other countdowns are useless.
2nd and 3rd counter must reach 0 and reset to presaved values if 1st counter>0
All counters should when == 0 pass an output to two relay pins

I cant remember what this kind of table is called but its for assessing what should happen if two things happen and what the required output is.

R = 1st Counter
S = 2nd Counter
Y = 3rd Counter (1st Preset)
N = 3rd Counter (2nd Preset)
SY = 2nd Counter + 3rd Counter (1st Preset)
SN = 2nd Counter + 3rd Counter (2nd Preset)

1 = Action 1
2 = Action 2
3 = Action 3 (Not visualised in table as is called but solo Counter)
4 = Action 4 (Not visualised in table as is called but solo Counter)

A rewording of my question helped me work out what i actually need

(R==0 , R!=0) (S==0, S!=0) (Y==0, Y!=0) (N==0, N!=0)

I need a way that cover all possible permutations of these. 48 permutations?
Anything that is inside brackets cannot be in the same permutation as its opposite. IE R==0 cannot be with R!=0.

This is my problem. 48 if statements is alot for something so basic

TLDR:
Do i use multiple nested if statements? State Machines "Can statemachines check for multiple conditions?"or something completely different to check?

This heat is murder on brain capacity...

what causes any counter to decrement?

(stimuli into a state machine)

A state machine can access other state machines, if this is your question.


“This heat is murder on brain capacity...”
What country ? :face_with_thermometer:

I'm not sure I understand the logic; however, in general, if you use a state machine any number of conditions can be checked to define a transition. For example, if you are in state A you may require x=0 and y=1 in order to transition to state B.

Could be many places in Europe, but I'm guessing UK!

Gonna dump my script here incase someone needs to see it.

//20x4 LCD
#include <LiquidCrystal_I2C.h> //SDA = A4, SCL = A5 Arduino https://www.arduino.cc/reference/en/libraries/liquidcrystal-i2c/
LiquidCrystal_I2C lcd(0x27, 20, 4);

///New ROTMETHOD
#define LEFT 2
#define RIGHT 3
#define PUSH 4
///New ROTMETHOD

int menuCounter;

int menu1_Value = 0; //value within menu 1
int menu2_Value = 0; //value within menu 2
int menu2_StoredValue = 0; // STORED VALUE FOR COMPARRISSON
int menu3_Value = 0; //value within menu 3
int menu3_StoredValue = 0; // STORED VALUE FOR COMPARRISSON
char menu4_Value; //value within menu 4

bool menu1_selected = false; //enable/disable to change the value of menu item
bool menu2_selected = false;
bool menu3_selected = false;
bool menu4_selected = false;
//Note: if a menu is selected ">" becomes "X".



bool ColourRepeat = true;
bool refreshLCD = true; //refreshes values
bool refreshSelection = false; //refreshes selection (> / X)

// HE Sensor code
// HE Sensor code
#define DETECT 5 // pin 5 for  sensor (D5)
#define ACTION 8 // pin 8 for action to do someting (A1)

// HE Sensor code
// HE Sensor code
const int redRELAY_PIN = 11;  // relays state = NO = LOW = OFF
const int greyRELAY_PIN = 12;  //

///New ROTMETHOD
uint8_t lrmem = 3;
int lrsum = 0;
int num = 0; //RotEnc Rotation Count.
int8_t res; //RotEnc Movement Detection 
bool buttonPushed = false;
///New ROTMETHOD


bool RUNNINGSTATE = false;
unsigned long previousMillis = 0;  
const long interval = 1000;   

int8_t rotary() ///New ROTMETHOD
{
   static int8_t TRANS[] = {0,-1,1,14,1,0,14,-1,-1,14,0,1,14,1,-1,0};
   int8_t l, r;

   l = digitalRead(LEFT);
   r = digitalRead(RIGHT);

   lrmem = ((lrmem & 0x03) << 2) + 2*l + r;
   lrsum = lrsum + TRANS[lrmem];
   /* encoder not in the neutral state */
   if(lrsum % 4 != 0) return(0);
   /* encoder in the neutral state */
   if (lrsum == 4)  /* encoder in the neutral state - clockwise rotation*/
      {
      lrsum=0;
      return(1);
      }
   if (lrsum == -4) /* encoder in the neutral state - anti-clockwise rotation*/
      {
      lrsum=0;
      return(-1);
      }
   /* lrsum > 0 if the impossible transition */
   lrsum=0;
   return(0);
}///New ROTMETHOD


void setup()
{
   ///New ROTMETHOD
   pinMode(LEFT, INPUT_PULLUP);
   pinMode(RIGHT, INPUT_PULLUP);
   pinMode(PUSH, INPUT_PULLUP);
   Serial.begin(9600);
   Serial.println(menuCounter, DEC);
   ///New ROTMETHOD
   

  //------------------------------------------------------
  lcd.init();//lcd.begin(); /// not known in library  lcd.init();///                  // initialize the lcd
  lcd.backlight();
  //------------------------------------------------------
  lcd.setCursor(0, 0); //Defining positon to write from first row, first column .
  lcd.print("Menu demo");
  lcd.setCursor(0, 1); //Second row, first column
  lcd.print("Rotary encoder");
  lcd.setCursor(0, 2); //Second row, first column
  lcd.print("Improved version");
  delay(50); //wait 1 sec

  lcd.clear(); //clear the whole LCD

  printLCD(); //print the static parts on the screen
  //------------------------------------------------------

  //attachInterrupt(digitalPinToInterrupt(RotaryCLK), rotate, CHANGE); //CLK pin is an interrupt pin
  //attachInterrupt(digitalPinToInterrupt(PushButton), pushButton,  FALLING); //PushButton pin is an interrupt pin //DOUNCE? USE RISING?

  // HE Sensor code
  // HE Sensor code
  /// Serial.println("Hall Module Test"); ///TESTING///
  pinMode(DETECT, INPUT);//define detect input pin
  pinMode(ACTION, OUTPUT);//define ACTION output pin
  // HE Sensor code
  // HE Sensor code

  pinMode(redRELAY_PIN, OUTPUT);
  pinMode(greyRELAY_PIN, OUTPUT); 

  digitalWrite(greyRELAY_PIN, HIGH);//RepeatNotColourChanger
  digitalWrite(redRELAY_PIN, HIGH);
 

  
}

void loop()
{
  ///New ROTMETHOD
   RotationCheck ();
   ///New ROTMETHOD
   unsigned long currentMillis = millis();
  if (buttonPushed == true)
      {
          pushButton();
          buttonPushed=false;
      }
  if (menu4_selected == true)     ///MINUS COUNT TRIGGER
      {
            //delay(500);
            if (currentMillis - previousMillis >= interval) {/////RUNNING BLINK
                  // save the last time you blinked the LED
                  previousMillis = currentMillis;
                     // if the LED is off turn it on and vice-versa:
                  if (RUNNINGSTATE == true) {
                    lcd.setCursor(9, 3); //4th line, 2nd block
                 lcd.print("Running"); //text
                    RUNNINGSTATE = false;
                  } else {
                    lcd.setCursor(9, 3); //4th line, 2nd block
                 lcd.print("        "); //blank previous
                    RUNNINGSTATE = true;
                  }
            }
       

            if (menu1_Value != 0)
            {
              // HE Sensor code
              // HE Sensor code
              int HEreading = digitalRead(DETECT);// read Hall sensor
              if ( HEreading == HIGH)
              {
                menu1_Value = menu1_Value - 1;

                      if (menu2_Value != 0)               //Menu2 value storage
                      {
                        if (menu2_StoredValue == 0)
                        {
                        menu2_StoredValue = menu2_Value;
                        }
                        menu2_Value = menu2_Value - 1;
                      }
                      if (menu2_Value < 0)
                      {
                        menu2_Value = menu2_StoredValue;
                      }
              //////////////////////////////////////////////////////////
                      if (menu3_Value != 0)               //Menu3 value storage
                      {
                        if (menu3_StoredValue == 0)
                        {
                        menu3_StoredValue = menu3_Value;
                        }
                        menu3_Value = menu3_Value - 1;
                      }
                      if (menu3_Value < 0)
                      {
                        menu3_Value = menu3_StoredValue;                      
                      }
                      
                delay(150); ////DELAY FOR LIMITING -1 COUNT
                HEreading = LOW;
              }
        
              // HE Sensor code
              // HE Sensor code
              
              refreshLCD = true;
              //delay(500);
            }
            
            if (menu1_Value == 0)///RELAY TRIGGER
            {
              digitalWrite(redRELAY_PIN, HIGH);                            //StopNotColourChanger
              digitalWrite(greyRELAY_PIN, LOW);
              menu4_selected = false;
              lcd.setCursor(9, 3); //4th line, 2nd block
              lcd.print("Complete"); //text
              refreshLCD = true;
              
            }
            if (menu2_Value == 0 && menu2_StoredValue > 0 && menu1_Value != 0)///RELAY TRIGGER
            {
              digitalWrite(redRELAY_PIN, HIGH);                           //StopNotColourChanger
              digitalWrite(greyRELAY_PIN, LOW);
              lcd.setCursor(9, 3); //4th line, 2nd block
              lcd.print("Stopped"); //text
              refreshLCD = true;
              
            }
            if (menu3_Value == 0 && menu3_StoredValue > 0 && menu1_Value != 0)///RELAY TRIGGER
            {
              if (ColourRepeat == true)
              {
              Serial.println("REPEAT COLOUR CHANGER");
              digitalWrite(redRELAY_PIN, LOW);                            //RepeatColourChanger
              digitalWrite(greyRELAY_PIN, HIGH); 
              }
              if (ColourRepeat == false)
              {
              Serial.println("STOP COLOUR CHANGER");
              digitalWrite(redRELAY_PIN, LOW);                             //StopColourChanger
              digitalWrite(greyRELAY_PIN, LOW);              
              }
              
              
              refreshLCD = true;
              
            }

       if (menu1_Value != 0 && menu2_Value == 0 && menu3_Value == 0) // All 0
       {
        
       }
       if (menu1_Value == 0 && menu2_Value != 0 && menu3_Value != 0) // All 0
       {
        
       }
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
       if (menu1_Value == 0 && menu2_Value == 0 && menu3_Value == 0) // All 0
       {
        
       }
       if (menu1_Value != 0 && menu2_Value != 0 && menu3_Value != 0) // All 0
       {
        
       }
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////             
       if (menu1_Value != 0 && menu2_Value != 0 && menu3_Value == 0) // All 0
       {
        
       }
       if (menu1_Value == 0 && menu2_Value == 0 && menu3_Value != 0) // All 0
       {
        
       }
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////   
       
       if (menu1_Value == 0 && menu2_Value != 0 && menu3_Value == 0) // All 0
       {
        
       }
       if (menu1_Value != 0 && menu2_Value == 0 && menu3_Value != 0) // All 0
       {
        
       }
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////    
       if (menu1_Value != 0 && menu2_Value != 0 && menu3_Value == 0) // All 0
       {
        
       }
       if (menu1_Value == 0 && menu2_Value == 0 && menu3_Value != 0) // All 0
       {
        
       }
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////          

                 
       }

  
  if (refreshLCD == true) //If we are allowed to update the LCD ...
  {
    updateLCD(); // ... we update the LCD ...

    //... also, if one of the menus are already selected...
    if (menu1_selected == true || menu2_selected == true || menu3_selected == true || menu4_selected == true)
    {
      // do nothing
    }
    else
    {
      updateCursorPosition(); //update the position
    }

    refreshLCD = false; //reset the variable - wait for a new trigger
  }

  if (refreshSelection == true) //if the selection is changed
  {
    updateSelection(); //update the selection on the LCD
    refreshSelection = false; // reset the variable - wait for a new trigger
  }
}

void rotate() ///INTERRUPT FUNCTION
{
  //-----MENU1--------------------------------------------------------------
  if (menu1_selected == true)
  {   
    if (res == 1) //If RotEncDir Moved CW
     { 
        if (menu1_Value < 9999) //we do not go above 9999
        {
          menu1_Value++;
        }
        else
        {
          menu1_Value = 0;
        }
     }
    if (res == -1) //If RotEncDir Moved CCW
     { 
        if (menu1_Value < 1) //we do not go below 0
        {
          menu1_Value = 9999;
        }
        else
        {
          // Encoder is rotating B direction so decrease
          menu1_Value--;
        }
     }
     refreshLCD = true;
}
  //---MENU2---------------------------------------------------------------
  else if (menu2_selected == true)
  {
      if (res == 1) //If RotEncDir Moved CW
      { 
        if (menu2_Value < 9999) //we do not go above 9999
        {
          menu2_Value++;
        }
        else
        {
          menu2_Value = 0;
        }
      }
      if (res == -1) //If RotEncDir Moved CCW
      { 
        if (menu2_Value < 1) //we do not go below 0
        {
          menu2_Value = 9999;
        }
        else
        {
          // Encoder is rotating in B direction, so decrease
          menu2_Value--;
        }
      }
refreshLCD = true;    
}
  //---MENU3--------------------------------------------------------------- X stop at ColourChanger
  else if (menu3_selected == true)
  {   
      if (res == 1) //If RotEncDir Moved CCW
      { 
        if (menu3_Value < 9999) //we do not go above 9999
        {
          menu3_Value++;
        }
        else
        {
          menu3_Value = 0;
        }
      }
      if (res == -1) //If RotEncDir Moved CCW
      { 
        if (menu3_Value < 1) //we do not go below 0
        {
          menu3_Value = 9999;
        }
        else
        {
          // Encoder is rotating B direction so decrease
          menu3_Value--;
        }
      }
      
    refreshLCD = true;
  }
  //---MENU4----------------------------------------------------------------START/PAUSE = HALL EFFECT TRIGGER + DECREMENT
  else if (menu4_selected == true)
  {

    refreshLCD = true;

  }
else //MENU COUNTER----------------------------------------------------------------------------
{ 
  if (res!=0) //If RotEnc Moved
  {  
      if (res == 1) //If RotEnc Moved
      { 
          if (menuCounter < 3) //we do not go above 3
          {
            menuCounter++;
          }
          else
          {
            menuCounter = 3;
          }
      }
      if (res == -1) //If RotEnc Moved
        { 
          if (menuCounter < 1) //we do not go below 0
          {
            menuCounter = 0;
          }
          else
          {
            // Encoder is rotating CW so decrease
            menuCounter--;
          }
        } 
      } 
    refreshLCD = true;
}

}
void pushButton() ///INTERRUPT FUNCTION
{
  if (menu3_selected == true) ///COLOUR REPEATING/STOP Function
      {   
        ColourRepeater();
      }
      
  switch (menuCounter)
  {
    case 0:
      menu1_selected = !menu1_selected;  //we change the status of the variable to the opposite
      break;

    case 1:
      menu2_selected = !menu2_selected;
      break;

    case 2:
      menu3_selected = !menu3_selected;
      break;

    case 3:
      menu4_selected = !menu4_selected;      
      break;
  }
  
  refreshLCD = true; //Refresh LCD after changing the value of the menu
  refreshSelection = true; //refresh the selection ("X")
}

void printLCD()                                                        ///MAINMENU NAMING
{
  //These are the values which are not changing the operation

  lcd.setCursor(1, 0); //1st line, 2nd block
  lcd.print("Rows"); //text
  //----------------------
  lcd.setCursor(1, 1); //2nd line, 2nd block
  lcd.print("Stop"); //text
  //----------------------
  lcd.setCursor(1, 2); //3rd line, 2nd block
  lcd.print("Colour"); //text
  //----------------------
  lcd.setCursor(1, 3); //4th line, 2nd block
  lcd.print("Start"); //text
  //----------------------
  lcd.setCursor(13, 0); //1st line, 14th block
  lcd.print("cnt: "); //counts - text
  //----------------------
  lcd.setCursor(14, 2); //4th line, 2nd block C.C. REPEAT OPTION
  lcd.print("RPT:"); //blank previous
}

void updateLCD()
{
  lcd.setCursor(17, 0); //1st line, 18th block
  lcd.print(menuCounter); //counter (0 to 3)

  lcd.setCursor(9, 0); //1st line, 10th block
        if (menu1_Value  < 1000) { //hundred
          lcd.print ("0");
        }
        if (menu1_Value  < 100) { //ten
          lcd.print ("0");
        }
        if (menu1_Value  < 10) { //one
          lcd.print ("0");
        }
  lcd.print(menu1_Value); //print the value of menu1_Value variable

  lcd.setCursor(9, 1);
        if (menu2_Value  < 1000) { //hundred
          lcd.print ("0");
        }
        if (menu2_Value  < 100) { //ten
          lcd.print ("0");
        }
        if (menu2_Value  < 10) { //one
          lcd.print ("0");
        }
  lcd.print(menu2_Value); //
    
  lcd.setCursor(9, 2);
        if (menu3_Value  < 1000) { //hundred
          lcd.print ("0");
        }
        if (menu3_Value  < 100) { //ten
          lcd.print ("0");
        }
        if (menu3_Value  < 10) { //one
          lcd.print ("0");
        }
  lcd.print(menu3_Value); //
      if (ColourRepeat == false)
      {
        lcd.setCursor(18, 2); //4th line, 2nd block C.C. REPEAT OPTION
        lcd.print(" "); //blank previous 
        lcd.setCursor(18, 2); //4th line, 2nd block C.C. REPEAT OPTION
        lcd.print("N"); //blank previous 
      }
      if (ColourRepeat == true)
      {
        lcd.setCursor(18, 2); //4th line, 2nd block C.C. REPEAT OPTION
        lcd.print(" "); //blank previous
        lcd.setCursor(18, 2); //4th line, 2nd block C.C. REPEAT OPTION
        lcd.print("Y"); //blank previous 
      }
  //lcd.setCursor(9, 3);
 // lcd.print(menu4_Value); //
}

void updateCursorPosition()
{
  //Clear display's ">" parts
  lcd.setCursor(0, 0); //1st line, 1st block
  lcd.print(" "); //erase by printing a space
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(0, 2);
  lcd.print(" ");
  lcd.setCursor(0, 3);
  lcd.print(" ");
  
  //Place cursor to the new position
  switch (menuCounter) //this checks the value of the counter (0, 1, 2 or 3)
  {
    case 0:
      lcd.setCursor(0, 0); //1st line, 1st block
      lcd.print(">");
      break;
    //-------------------------------
    case 1:
      lcd.setCursor(0, 1); //2nd line, 1st block
      lcd.print(">");
      break;
    //-------------------------------
    case 2:
      lcd.setCursor(0, 2); //3rd line, 1st block
      lcd.print(">");
      break;
    //-------------------------------
    case 3:
      lcd.setCursor(0, 3); //4th line, 1st block
      lcd.print(">");
      break;
  }
}

void updateSelection()
{
  //When a menu is selected ">" becomes "X"

  if (menu1_selected == true)
  {
    lcd.setCursor(0, 0); //1st line, 1st block
    lcd.print("X");
  }
  //-------------------
  if (menu2_selected == true)
  {
    lcd.setCursor(0, 1); //2nd line, 1st block
    lcd.print("X");
  }
  //-------------------
  if (menu3_selected == true)
  {
    lcd.setCursor(0, 2); //3rd line, 1st block
    lcd.print("X");
  }
  //-------------------
  if (menu4_selected == true)
  {
    lcd.setCursor(0, 3); //4th line, 1st block
    lcd.print("X");
  }
}

void RotationCheck (){ //Checks if Rot encoder Has moved
     ///New ROTMETHOD

   res = rotary(); // res = -1 CCW / 0 NONE / +1 CW
   if (res!=0)
   {  
      rotate();
      num = num + res;
      //Serial.println(num);
      if (res == 1)
      {
        
      }
      if (res == -1)
      {
        
      }
   }
   if (digitalRead(PUSH) == 0)
   {
      buttonPushed = true;
      delay(250);
   }
   ///New ROTMETHOD
}

void ColourRepeater() ///COLOUR REPEATING/STOP Function
{   
  if (ColourRepeat == false)
  {
    
    Serial.println("ColourRepeat = Y");
    //delay(500);
    //buttonPushed == false;
    ColourRepeat = true;
    updateLCD();
  }
  else if (ColourRepeat == true)
  {
    
    Serial.println("ColourRepeat = N");
    //delay(500);
    //buttonPushed == false;
    ColourRepeat = false;
    updateLCD();
  }

}

Yeh. This used to be a nice and cold country...

Unsure
Which would be easier to setup and keep track of? I've got a statemachine in the code already are they more or less resource intensive than basic nested if statements?
Running on a nanov3 and i believe its getting close to its mem capacity.

So the counters are all incremented using a rot encoder. I found someone that had made a pretty decent non debouncing smoothing method for absolute encoder detection
https://github.com/RalphBacon/226-Better-Rotary-Encoder---no-switch-bounce
(Works amazing by the way. Screw debouncing this method is flawless)

Then once menu4 is detected in the main loop as selected it should listen for a reed switch signal to decrement each counter.
My problem is this.
The output signal to the relays need to be different dependant on which counter reaches 0 and if two reach 0 then it needs a diffent output.

Example:
Currently when Menu1 and Menu3_Y = 0 the relays switch back and forth at lightning speed because the script is sending contesting signals.

My question remains. If i want to setup a statemachine for this or simple nested if statements.

If statemachine is the answer where would i implement it into the script?

if you run out of SRAM, you should read about the F-Makro on the Arduino and put all *) your lcd.print and Serial.print into F-Makros.

lcd.print("Running");

to

lcd.print(F("Running"));

do this with all your fix texts.

*) all means all longer texts. Single characters don't need to use F-Makros, but you can spare one byte if you just print a char, not a null terminated string (which needs an additional byte for the null terminator)

lcd.print("X");

just

lcd.print('X');

talking about your code, ... there are lot of code duplicates. I don't get the point why you use a swich case here for example:

//Place cursor to the new position
  switch (menuCounter) //this checks the value of the counter (0, 1, 2 or 3)
  {
    case 0:
      lcd.setCursor(0, 0); //1st line, 1st block
      lcd.print(">");
      break;
    //-------------------------------
    case 1:
      lcd.setCursor(0, 1); //2nd line, 1st block
      lcd.print(">");
      break;
    //-------------------------------
    case 2:
      lcd.setCursor(0, 2); //3rd line, 1st block
      lcd.print(">");
      break;
    //-------------------------------
    case 3:
      lcd.setCursor(0, 3); //4th line, 1st block
      lcd.print(">");
      break;
  }

why not just a

if (menuCounter <= 3)
{
  lcd.setCursor(0, menuCounter);
  lcd.print('>');
}

Interesting never heard of fmacro before ty for the info!

I was going to leave cleaning up duplication and repetition untill i had it all working. But that was a glaring waste of resources.

So i've put together the relay control script i want but looking at it i feel i've done the same and made a mess of it... Any advice?

void loop()
{
  ///New ROTMETHOD
   RotationCheck ();
   ///New ROTMETHOD
   unsigned long currentMillis = millis();
  if (buttonPushed == true)
      {
          pushButton();
          buttonPushed=false;
      }
  if (menu4_selected == true)     ///MINUS COUNT TRIGGER
      {
            //delay(500);
            if (currentMillis - previousMillis >= interval) {/////RUNNING BLINK
                  // save the last time you blinked the LED
                  previousMillis = currentMillis;
                     // if the LED is off turn it on and vice-versa:
                  if (RUNNINGSTATE == true) {
                    lcd.setCursor(9, 3); //4th line, 2nd block
                 lcd.print("Running"); //text
                    RUNNINGSTATE = false;
                  } else {
                    lcd.setCursor(9, 3); //4th line, 2nd block
                 lcd.print("        "); //blank previous
                    RUNNINGSTATE = true;
                  }
            }
       
            
            if (menu1_Value != 0)
            {
              int HEreading = digitalRead(DETECT);// read Hall sensor
              if ( HEreading == HIGH)
              { 
                menu1_Value = menu1_Value - 1;
                
                if (menu2_Value != 0)               //Menu2 value decrement
                {
                  menu2_Value = menu2_Value - 1;
                }
                if (menu2_Value < 0)
                {
                  menu2_Value = menu2_StoredValue;
                }
              //////////////////////////////////////////////////////////
                if (menu3_Value != 0)               //Menu3 value decrement
                {
                  menu3_Value = menu3_Value - 1;
                }
                if (menu3_Value < 0)
                {
                  menu3_Value = menu3_StoredValue;                      
                }
                      
                delay(150); ////DELAY FOR LIMITING -1 COUNT
                HEreading = LOW;
              }
              
              refreshLCD = true;
              //delay(500);
            }
          //////////////////////////////////////////////TABLESETS//////////////////////////////////////////////
          if (menu1_Value == 0 && menu2_Value == 0 && menu3_Value != 0) ///1B
          {
           RelayState = 1;
           RelayOutputs();
           Serial.println("1B");
          }

          //////////////////////////////////////////////TABLESETS//////////////////////////////////////////////
          if (menu1_Value == 0 && menu2_Value != 0 && menu3_Value == 0 && ColourRepeat == true) ///1C
          {
           RelayState = 4;
           RelayOutputs();
           Serial.println("1C");
          }

          //////////////////////////////////////////////TABLESETS//////////////////////////////////////////////
          if (menu1_Value == 0 && menu2_Value != 0 && menu3_Value == 0 && ColourRepeat == false) ///1D
          {
           RelayState = 4;
           RelayOutputs();
           Serial.println("1D");
          }

          //////////////////////////////////////////////TABLESETS//////////////////////////////////////////////
          if (menu1_Value == 0 && menu2_Value == 0 && menu3_Value == 0 && ColourRepeat == true) ///1E
          {
           RelayState = 4;
           RelayOutputs();
           Serial.println("1E");
          }

          //////////////////////////////////////////////TABLESETS//////////////////////////////////////////////       
          if (menu1_Value == 0 && menu2_Value == 0 && menu3_Value == 0 && ColourRepeat == false) ///1F
          {
           RelayState = 4;
           RelayOutputs();
           Serial.println("1F");
          }

          //////////////////////////////////////////////TABLESETS//////////////////////////////////////////////
          if (menu2_Value == 0 && menu2_Value != 0 && menu3_Value == 0 && ColourRepeat == true) ///2C
          {
           RelayState = 4;
           RelayOutputs();
           Serial.println("2C");
          }

          //////////////////////////////////////////////TABLESETS//////////////////////////////////////////////
          if (menu2_Value == 0 && menu2_Value != 0 && menu3_Value == 0 && ColourRepeat == false) ///2D
          {
           RelayState = 4;
           RelayOutputs();
           Serial.println("2D");
          }

          //////////////////////////////////////////////TABLESETS////////////////////////////////////////////// 
          //////////////////////////////////////////////TABLESETS////////////////////////////////////////////// 
          if (menu1_Value == 0 && menu2_Value != 0 && menu3_Value != 0) ///1.1
          {
           RelayState = 1;
           RelayOutputs();
           Serial.println("1.1");
          }

          //////////////////////////////////////////////TABLESETS////////////////////////////////////////////// 
          if (menu2_Value == 0 && menu2_Value != 0 && menu3_Value != 0) ///2
          {
           RelayState = 1;
           RelayOutputs();
           Serial.println("2");
          }
          
          //////////////////////////////////////////////TABLESETS////////////////////////////////////////////// 
          if (menu1_Value != 0) ///1
          {
           RelayState = 2;
           RelayOutputs();
           Serial.println("1");
          }

          //////////////////////////////////////////////TABLESETS//////////////////////////////////////////////                     
          //////////////////////////////////////////////TABLESETS////////////////////////////////////////////// 
          if (menu3_Value == 0 && ColourRepeat == true && menu2_Value != 0 && menu3_Value != 0) ///3.1
          {
           RelayState = 3;
           RelayOutputs();
           Serial.println("3.2");
          }

          //////////////////////////////////////////////TABLESETS////////////////////////////////////////////// 
          if (menu3_Value == 0 && ColourRepeat == false && menu2_Value != 0 && menu3_Value != 0) ///3.2 
          {
           RelayState = 4;
           RelayOutputs();
           Serial.println("3.2");
          }

          //////////////////////////////////////////////TABLESETS//////////////////////////////////////////////
          refreshLCD == true;           
       }

  
  if (refreshLCD == true) //If we are allowed to update the LCD ...
  {
    updateLCD(); // ... we update the LCD ...

    //... also, if one of the menus are already selected...
    if (menu1_selected == true || menu2_selected == true || menu3_selected == true || menu4_selected == true)
    {
      // do nothing
    }
    else
    {
      updateCursorPosition(); //update the position
    }

    refreshLCD = false; //reset the variable - wait for a new trigger
  }

  if (refreshSelection == true) //if the selection is changed
  {
    updateSelection(); //update the selection on the LCD
    refreshSelection = false; // reset the variable - wait for a new trigger
  }
}

void RelayOutputs()
{
  switch(RelayState)
    {    
    case 1://do something when RelayState equals 1 //StopNoColourChanger
    //Serial.println("STOP NO COLOUR CHANGER");
    digitalWrite(redRELAY_PIN, HIGH);                            
    digitalWrite(greyRELAY_PIN, LOW);
    menu4_selected = false;
    
    lcd.setCursor(9, 3);
    if (menu1_Value == 0)
    {
     lcd.print("Complete"); //text (FINISHED)
    }
    else
    {
     lcd.print("Stopped"); //text (PAUSED)
    }
    refreshLCD = true;
    break;
//-------------------------------    
    case 2://do something when RelayState equals 2 //RepeatNoColourChanger                   
    //Serial.println("REPEAT NO COLOUR CHANGER");
    digitalWrite(redRELAY_PIN, HIGH);                            
    digitalWrite(greyRELAY_PIN, HIGH);
    break;
//-------------------------------
    case 3://do something when RelayState equals 3 //RepeatColourChanger                    if (ColourRepeat == true)
    //Serial.println("REPEAT AT COLOUR CHANGER");
    digitalWrite(redRELAY_PIN, LOW);                            
    digitalWrite(greyRELAY_PIN, HIGH); 
    break;
//------------------------------- 
    case 4://do something when RelayState equals 3 //StopColourChanger                      if (ColourRepeat == false)
    //Serial.println("STOP AT COLOUR CHANGER");
    digitalWrite(redRELAY_PIN, LOW);                             
    digitalWrite(greyRELAY_PIN, LOW);       
    break;
//-------------------------------
    default: // if nothing else matches, do the default
    
    break;
    }
}    

A rewording of my question helped me work out what i actually need

(R==0 , R!=0) (S==0, S!=0) (Y==0, Y!=0) (N==0, N!=0)

I need a way that cover all possible permutations of these. 48 permutations?
Anything that is inside brackets cannot be in the same permutation as its opposite. IE R==0 cannot be with R!=0.

This is my problem. 48 if statements is alot for something so basic

"Note to self: remember i need to have a initialisation of a 0 check before this to prevent it from triggering counters that have no value filled in"

I don't get the point.
Your matrix diagram in your entry post shows one 1 and six 2 ... a total of seven ifs ... not more.

I think i've over cooked my brain.

Im sun baked rn. So i've made a backup and am trying to work this out by fiddling with the script.
Pretty sure i got the right thing here...

if (R == 0 && S != 0 && C != 0) // ROW = 0
{
    menu2_StoredValue = 0;
    menu3_StoredValue = 0:
    Toggle R Relay State; 
}
if (R == 0 && S == 0 && C != 0) // ROW + STOP = 0
{
    menu2_StoredValue = 0;
    menu3_StoredValue = 0:
    Toggle R Relay State; //STOPNOCC
}
if (R == 0 && S != 0 && C == 0) // ROW + CC = 0
{
  If (ColourRepeat == true)
  {
    
  }
  If (ColourRepeat == false)
  {
    
  }
    menu2_StoredValue = 0;
    menu3_StoredValue = 0:
}

if (R == 0 && S == 0 && C == 0) // ROW + STOP + CC = 0
{
  If (ColourRepeat == true)
  {
    
  }
  If (ColourRepeat == false)
  {
    
  }
    menu2_StoredValue = 0;
    menu3_StoredValue = 0:
}


If (R != 0) 
{
    if (S == 0 && C != 0) // STOP = 0
    {
      Toggle S Relay State;
    }     
    if (C == 0 && S != 0) // CC = 0
    {
        If (ColourRepeat == true)
        {
          
        }
        If (ColourRepeat == false)
        {
      
        } 
    }
     
    if (S == 0 && C == 0) STOP + CC = 0
    {
        If (ColourRepeat == true)
        {
          
        }
        If (ColourRepeat == false)
        {
      
        }    
    }
Toggle Repeat Relay State;
}

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