MCP4822 and a Rotary encoder

I’ve been playing around with this chip and got it working in a fashion. My end goal is to have one Rotary encoder and a 4 buttons, the other 4 buttons will be controlling other functions but at the moment I just want get this part working first.

This is where I can not think of a way to really implement as I really need to start of Port A at 1.60 volts and Port B of at 0.990 volts,(I know this can be set on start up) But the trouble I found is that I don’t want the Dac_volt_Chanel1 variable to go below zero and above 4095 counts by just using one encoder and when I did this tried to change the port to B but this just gets set straight away to what poer A was set.
This how I would like to work it.

  1. Power up Port A set to 1.6V & Port B set to 0.990V
  2. Press button1 to select Port A and set volts, So Port B can not bet changed.
  3. Press button 2 to select Port B and set volts, Disable Port A from been changed.
  4. Press button 3 to set the multiplier in 1,10,50,100 steps for Port A only while Port A is selected( this is working but only on port A at the moment.
  5. Press button 4 to set the multiplier in 1,10,50,100 steps for Port B only while Port B is selected

At the Moment Port A is giving an output voltage by setting the rotary encoder and Port B is just times by 2 (for testing of both ports).

I know it is possible to d, but 'm not sure which is the best way/method how to approach it and after some ideas as I don’t know how to implement and after advice from more experienced than me .

This is the code that I’ve got working so far but only the first button is working for the multiplier.

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7); //0x27 is the default address of the LCD with I2C bus module
#include <MCP48xx.h>
#include <Rotary.h>
#include <SPI.h>
#include <Wire.h>
MCP4822 dac(10); //DAc selct pint
#define stepPin1 3 // Set 'Step' rotary encoder pins
#define stepPin2 2 // Set 'Step' rotary encoder pins
// We define an int variable to store the voltage in mV so 100mV = 0.1V
Rotary Volts_Rotary = Rotary(stepPin1, stepPin2);              // Rotary encoder for frequency connects to interrupt pins
//########## SET UP TO 8 INPUTS ######################
const int numOfInputs = 8;
const int inputPins[numOfInputs] = {4, 5, 6, 7, 8, 9, A0, A3};
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
bool inputFlags[numOfInputs] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
int inputCounters[numOfInputs];
long lastDebounceTime[numOfInputs] = {0, 0, 0, 0, 0, 0, 0, 0};
long debounceDelay = 50; //set a debounce
long unsigned int Dac_volt_Chanel1 = 0; //Set initial Dac_volt_Chanel1.
long unsigned int Dac_Amp_Chanel1 = 0; // Set initial Dac_AMP_Chanel1.
unsigned long  Dac_multiplier = 0; // Set the mulitplier to 1 click
unsigned long  Dac_multiplier1 = 0; // Set the mulitplier to 1 click
void setup() {
  lcd.begin(20, 4);                                        //set up the LCD's number of columns and rows
  lcd.setBacklightPin(3, POSITIVE);                        // BL, BL_POL
  lcd.setBacklight(HIGH);                                  //set LCD backlight on
  lcd.clear();
  Volts_Rotary.begin(); //Start Rotary encoder off
  pinMode(stepPin1, INPUT_PULLUP); // Pins for step rotary encoder on analogue pins 2,3
  pinMode(stepPin2, INPUT_PULLUP); // Pins for step rotary encoder on analogue pins 2,3
  attachInterrupt(digitalPinToInterrupt(stepPin1), Volts_encoder, CHANGE); //detect change
  attachInterrupt(digitalPinToInterrupt(stepPin2), Volts_encoder, CHANGE); //detect change
  dac.init(); //Start the Dac off
  for (int i = 0; i < numOfInputs; i++) { // Set up all input pins
    pinMode(inputPins[i], INPUT_PULLUP);
    // digitalWrite(inputPins[i], HIGH); // pull-up 20k
  }
  // The channels are turned off at startup so we need to turn the channel we need on
  dac.turnOnChannelA();
  dac.turnOnChannelB();
  // We configure the channels in High gain
  dac.setGainA(MCP4822::High);
  dac.setGainB(MCP4822::High);
  lcd.setCursor(0, 0);
  lcd.print("POWERING");
  lcd.clear();
  delay(2000);
}
void getStep() { //Multiply the dac values
  switch (inputCounters[0]) {
    case 1:  Dac_multiplier = 1; break;
    case 2:  Dac_multiplier = 10; break;
    case 3:  Dac_multiplier = 50; break;
    case 4:  Dac_multiplier = 100; break;

  }
}

void loop() {
  setInputFlags();
  resolveInputFlags();
  dac.updateDAC();
  lcd.setCursor(0, 0);
  lcd.print(Dac_volt_Chanel1);//Display Dac Value
  lcd.print("  ");
  lcd.setCursor(0, 1);
  lcd.print(Dac_multiplier);// Just show multiplier value,Will be removed
  lcd.print("   ");
  dac.setVoltageA(Dac_volt_Chanel1); // Send the Dac Value out on Port A
  dac.setVoltageB(Dac_volt_Chanel1 * 2); // Send the Dac Value out on Port B just timesit by 2 for testing
  dac.updateDAC();

}
void setInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    int reading = digitalRead(inputPins[i]);
    if (reading != lastInputState[i]) {
      lastDebounceTime[i] = millis();
    }
    if ((millis() - lastDebounceTime[i]) > debounceDelay) {
      if (reading != inputState[i]) {
        inputState[i] = reading;
        if (inputState[i] == HIGH) {
          inputFlags[i] = HIGH;
        }
      }
    }
    lastInputState[i] = reading;
  }
}
void resolveInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    if (inputFlags[i] == HIGH) {
      inputAction(i);
      inputFlags[i] = LOW;
    }
  }
}
void Volts_encoder()   {
  unsigned int result = Volts_Rotary.process();
  ///Rotary encoder 1 for setting the volts
  if (result) {
    if (result == DIR_CW) {
      if ((Dac_volt_Chanel1 + Dac_multiplier) <= 4095) Dac_volt_Chanel1 += Dac_multiplier;
    } else {
      if ((Dac_volt_Chanel1 - Dac_multiplier) >= 0) Dac_volt_Chanel1 -= Dac_multiplier;
    }
    if (Dac_volt_Chanel1 <= 0)  Dac_volt_Chanel1 = 0;
    if (Dac_volt_Chanel1 >= 4095) Dac_volt_Chanel1 = 4095;
  }
}
void inputAction(int input) {
  //Button one
  if (input == 0) {
    inputCounters[0]++;
    if (inputCounters[0] > 4) {
      inputCounters[0] = 1;
    }
    getStep();
    //Button 2
  } else if (input == 1) {
    if (inputCounters[1] > 4) {
      inputCounters[1] = 1;
    }
    getStep();
    //Button 3
  } else if (input == 2) {
    // Output_channel1_control =1;

  } else if (input == 3) {
    // Output_channel2_control =1;
  }

}

I don't know the Rotary.h-library. Where did you download this library?

variables that are modified inside interrupt-service-routines must have the attribut volatile
So your variable Dac_volt_Chanel1
should be defined as

volatile unsigned int Dac_volt_Chanel1 = 0; //Set initial Dac_volt_Chanel1.

about the rest I'm sorry I don#T understand your description

you are defining

#define stepPin1 3 // Set 'Step' rotary encoder pins
#define stepPin2 2 // Set 'Step' rotary encoder pins

which are the digital pins

then you use

LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7); //0x27 is the default address of the LCD with I2C bus module

and seem to use these pins as inputs

const int inputPins[numOfInputs] = {4, 5, 6, 7, 8, 9, A0, A3};

which are partially the same pins as for the LCD

What seems really strange to me is you are assiging the function Volts_encoder()
to both interrupts

  attachInterrupt(digitalPinToInterrupt(stepPin1), Volts_encoder, CHANGE); //detect change
  attachInterrupt(digitalPinToInterrupt(stepPin2), Volts_encoder, CHANGE); //detect change

and configure for invoking the interrupt on CHANGE which means each statechange LOW-HIGH and HIGH-LOW
invoke an interrupt.

inside the isr you call

Volts_Rotary.process();

It might be that this is nescessary to make this rotary-lib work but I estimate no. I could be wrong but this looks like a real strange construction or just fals use of it.

me personally I use the NewEncoder-library which works very reliable even with rotary-encoders that have very bouncy mechanical switches

This library has two functions upclick and downclick which deliver a true at the first call and then false for each additional call as long as no new turning of the encoder has happened.

you can download this library here

by clicking on the green code-button and choose download zip

Then you can install this zipfile from the ArduinoIDE skecth - include library - add-zip-library

then do some testing with the single-encoder-example

did you test each part of your code thoroughly before adding a new part?

I tried to understand your code. I did not understand it. Especcially how you handle the buttons is a mystery to me
and I estimate trying to analyse it will me take twice the time than writing a much simpler new version on my own.

You have just four buttons. I would code it pretty simple for each single button

if button1 is pressed mode = adjust voltage_ch1
each change of the rotary-encoder counts up/down a variable dedicated to voltage_ch1

if button2 is pressed mode = adjust voltage_ch2
each change of the rotary-encoder counts up/down a variable dedicated to voltage_ch2

if button3 is pressed mode = choose multiplier for CH1
each change of the rotary-encoder counts up/down a variable dedicated to mutliplier for CH1

if button4 is pressed mode = choose multiplier for CH2
each change of the rotary-encoder counts up/down a variable dedicated to mutliplier for CH2

best regards Stefan

You probably want to take the approach that there is a ‘current’ port, either A or B and those multipliers and encoder apply to those. Then, you don’t need button 4… Something like this

#include <LiquidCrystal_I2C.h>
#include <MCP48xx.h>
#include <Rotary.h>
#include <SPI.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7); //0x27 is the default address of the LCD with I2C bus module
MCP4822 dac(10); //DAc selct pint

#define stepPin1 3 // Set 'Step' rotary encoder pins
#define stepPin2 2 // Set 'Step' rotary encoder pins

Rotary Volts_Rotary = Rotary(stepPin1, stepPin2);              // Rotary encoder for frequency connects to interrupt pins

//########## SET UP TO 8 INPUTS ######################
const int numOfInputs = 8;
const int inputPins[numOfInputs] = {4, 5, 6, 7, 8, 9, A0, A3};
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
bool inputFlags[numOfInputs] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
int inputCounters[numOfInputs];

const byte Dac_multipliers[] = { 1, 10, 50, 100 };
const byte stepCount = sizeof(Dac_multipliers) / sizeof(Dac_multipliers[0]);
volatile byte currentStep = 0;

unsigned long lastDebounceTime[numOfInputs] = {0, 0, 0, 0, 0, 0, 0, 0};
const unsigned long debounceDelay = 50; //set a debounce

enum { CHAN_A, CHAN_B };  // constants for current channel
volatile byte currentChannel = CHAN_A;

int Dac_volts[2] = {1600, 990}; //Set initial Dac_volt.

void setup() {
  lcd.begin(20, 4);                                        //set up the LCD's number of columns and rows
  lcd.setBacklightPin(3, POSITIVE);                        // BL, BL_POL
  lcd.setBacklight(HIGH);                                  //set LCD backlight on
  lcd.clear();
  Volts_Rotary.begin(); //Start Rotary encoder off
  pinMode(stepPin1, INPUT_PULLUP); // Pins for step rotary encoder on analogue pins 2,3
  pinMode(stepPin2, INPUT_PULLUP); // Pins for step rotary encoder on analogue pins 2,3
  dac.init(); //Start the Dac off
  for (int i = 0; i < numOfInputs; i++) { // Set up all input pins
    pinMode(inputPins[i], INPUT_PULLUP);
    // digitalWrite(inputPins[i], HIGH); // pull-up 20k
  }
  // The channels are turned off at startup so we need to turn the channel we need on
  dac.turnOnChannelA();
  dac.turnOnChannelB();
  // We configure the channels in High gain
  dac.setGainA(MCP4822::High);
  dac.setGainB(MCP4822::High);
  dac.setVoltageA(Dac_volts[CHAN_A]); // Send the Dac Value out on Port A
  dac.setVoltageB(Dac_volts[CHAN_B]); // Send the Dac Value out on Port B
  lcd.setCursor(0, 0);
  lcd.print("POWERING");
  lcd.clear();
  delay(2000);
  attachInterrupt(digitalPinToInterrupt(stepPin1), Volts_encoder, CHANGE); //detect change
  attachInterrupt(digitalPinToInterrupt(stepPin2), Volts_encoder, CHANGE); //detect change
}

void loop() {
  setInputFlags();
  resolveInputFlags();
  dac.updateDAC();
  lcd.setCursor(0, 0);
  if ( currentChannel == CHAN_A ) {
    lcd.print("A: ");
    dac.setVoltageA(Dac_volts[CHAN_A]); // Send the Dac Value out on Port A
  } else {
    lcd.print("B: ");
    dac.setVoltageB(Dac_volts[CHAN_B]); // Send the Dac Value out on Port B
  }
  lcd.print(Dac_volts[currentChannel]);//Display Dac Value
  lcd.print("  ");
  lcd.setCursor(0, 1);
  lcd.print(Dac_multipliers[currentStep]);// Just show multiplier value,Will be removed
  lcd.print("   ");
}

void setInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    int reading = digitalRead(inputPins[i]);
    if (reading != lastInputState[i]) {
      lastDebounceTime[i] = millis();
    }
    if ((millis() - lastDebounceTime[i]) >= debounceDelay) {
      if (reading != inputState[i]) {
        inputState[i] = reading;
        if (inputState[i] == HIGH) {
          inputFlags[i] = HIGH;
        }
      }
    }
    lastInputState[i] = reading;
  }
}
void resolveInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    if (inputFlags[i] == HIGH) {
      inputAction(i);
      inputFlags[i] = LOW;
    }
  }
}

void Volts_encoder()   {
  unsigned int result = Volts_Rotary.process();
  ///Rotary encoder 1 for setting the volts
  if (result) {
    int currentDacVolts = Dac_volts[currentChannel];
    if (result == DIR_CW) {
      currentDacVolts += Dac_multipliers[currentStep];
    } else {
      currentDacVolts -= Dac_multipliers[currentStep];
    }
    if (currentDacVolts < 0) currentDacVolts = 0;
    if (currentDacVolts >= 4096) currentDacVolts = 4095;
    Dac_volts[currentChannel] = currentDacVolts;
  }
}

void inputAction(int input) {
  switch (input) {
    case 0: //Button one
      // Select port A and start with first multiplier
      currentChannel = CHAN_A;
      currentStep = 0;
      break;

    case 1:  //Button 2
      // Select port A and start with first multiplier
      currentChannel = CHAN_B;
      currentStep = 0;
      break;

    case 2:     //Button 3
      // set multiplier
      currentStep++;
      if ( currentStep >= stepCount ) currentStep = 0;
      break;
  }
}

Thanks Stefan,

The LCD is an I2C back pack so I think this part

LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7); //0x27 is the default address of the LCD with I2C bus module

Is to do with the PCF8574 as this is what I've always used and it works and does not have an effect on it

As for the button's I watched this here to learn the best or better way of reading button's As I can just change a couple lines of code and add from 1 to 15 buttons say without adding loads of extra code at the beginning to add new buttons
https://www.youtube.com/watch?v=C_w79mtOAzg

What I'm trying to do is use one encoder, Then to select either Port A or Port B of the DAC to adjust the DAC value on the selected port. But What I've found is on start up I can set Port A to 1.60V and Port B to 0.990V but then when I try to change either Port the other port gets set to that value.

So If I set port A to 1.75V then Port B say to 1.23V but then go back to Port A, Port A starts back at 1.23V and not 1.75V.
I've tried a few way to implement but don't seem to get any where, To start with I just got the one Port working fully which was Port B. But now need to add switches to select between setting the Ports without effecting the other Port.
I'm still trying some other ways will post if I get anywhere, Hopefully this will give you a better understanding as I'm not the best at explaining

blh64:
You probably want to take the approach that there is a ‘current’ port, either A or B and those multipliers and encoder apply to those. Then, you don’t need button 4… Something like this

#include <LiquidCrystal_I2C.h>

#include <MCP48xx.h>
#include <Rotary.h>
#include <SPI.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7); //0x27 is the default address of the LCD with I2C bus module
MCP4822 dac(10); //DAc selct pint

#define stepPin1 3 // Set ‘Step’ rotary encoder pins
#define stepPin2 2 // Set ‘Step’ rotary encoder pins

Rotary Volts_Rotary = Rotary(stepPin1, stepPin2);              // Rotary encoder for frequency connects to interrupt pins

//########## SET UP TO 8 INPUTS ######################
const int numOfInputs = 8;
const int inputPins[numOfInputs] = {4, 5, 6, 7, 8, 9, A0, A3};
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
bool inputFlags[numOfInputs] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
int inputCounters[numOfInputs];

const byte Dac_multipliers = { 1, 10, 50, 100 };
const byte stepCount = sizeof(Dac_multipliers) / sizeof(Dac_multipliers[0]);
volatile byte currentStep = 0;

unsigned long lastDebounceTime[numOfInputs] = {0, 0, 0, 0, 0, 0, 0, 0};
const unsigned long debounceDelay = 50; //set a debounce

enum { CHAN_A, CHAN_B };  // constants for current channel
volatile byte currentChannel = CHAN_A;

int Dac_volts[2] = {1600, 990}; //Set initial Dac_volt.

void setup() {
 lcd.begin(20, 4);                                        //set up the LCD’s number of columns and rows
 lcd.setBacklightPin(3, POSITIVE);                        // BL, BL_POL
 lcd.setBacklight(HIGH);                                  //set LCD backlight on
 lcd.clear();
 Volts_Rotary.begin(); //Start Rotary encoder off
 pinMode(stepPin1, INPUT_PULLUP); // Pins for step rotary encoder on analogue pins 2,3
 pinMode(stepPin2, INPUT_PULLUP); // Pins for step rotary encoder on analogue pins 2,3
 dac.init(); //Start the Dac off
 for (int i = 0; i < numOfInputs; i++) { // Set up all input pins
   pinMode(inputPins[i], INPUT_PULLUP);
   // digitalWrite(inputPins[i], HIGH); // pull-up 20k
 }
 // The channels are turned off at startup so we need to turn the channel we need on
 dac.turnOnChannelA();
 dac.turnOnChannelB();
 // We configure the channels in High gain
 dac.setGainA(MCP4822::High);
 dac.setGainB(MCP4822::High);
 dac.setVoltageA(Dac_volts[CHAN_A]); // Send the Dac Value out on Port A
 dac.setVoltageB(Dac_volts[CHAN_B]); // Send the Dac Value out on Port B
 lcd.setCursor(0, 0);
 lcd.print(“POWERING”);
 lcd.clear();
 delay(2000);
 attachInterrupt(digitalPinToInterrupt(stepPin1), Volts_encoder, CHANGE); //detect change
 attachInterrupt(digitalPinToInterrupt(stepPin2), Volts_encoder, CHANGE); //detect change
}

void loop() {
 setInputFlags();
 resolveInputFlags();
 dac.updateDAC();
 lcd.setCursor(0, 0);
 if ( currentChannel == CHAN_A ) {
   lcd.print("A: ");
   dac.setVoltageA(Dac_volts[CHAN_A]); // Send the Dac Value out on Port A
 } else {
   lcd.print("B: “);
   dac.setVoltageB(Dac_volts[CHAN_B]); // Send the Dac Value out on Port B
 }
 lcd.print(Dac_volts[currentChannel]);//Display Dac Value
 lcd.print(”  “);
 lcd.setCursor(0, 1);
 lcd.print(Dac_multipliers[currentStep]);// Just show multiplier value,Will be removed
 lcd.print(”   ");
}

void setInputFlags() {
 for (int i = 0; i < numOfInputs; i++) {
   int reading = digitalRead(inputPins[i]);
   if (reading != lastInputState[i]) {
     lastDebounceTime[i] = millis();
   }
   if ((millis() - lastDebounceTime[i]) >= debounceDelay) {
     if (reading != inputState[i]) {
       inputState[i] = reading;
       if (inputState[i] == HIGH) {
         inputFlags[i] = HIGH;
       }
     }
   }
   lastInputState[i] = reading;
 }
}
void resolveInputFlags() {
 for (int i = 0; i < numOfInputs; i++) {
   if (inputFlags[i] == HIGH) {
     inputAction(i);
     inputFlags[i] = LOW;
   }
 }
}

void Volts_encoder()   {
 unsigned int result = Volts_Rotary.process();
 ///Rotary encoder 1 for setting the volts
 if (result) {
   int currentDacVolts = Dac_volts[currentChannel];
   if (result == DIR_CW) {
     currentDacVolts += Dac_multipliers[currentStep];
   } else {
     currentDacVolts -= Dac_multipliers[currentStep];
   }
   if (currentDacVolts < 0) currentDacVolts = 0;
   if (currentDacVolts >= 4096) currentDacVolts = 4095;
   Dac_volts[currentChannel] = currentDacVolts;
 }
}

void inputAction(int input) {
 switch (input) {
   case 0: //Button one
     // Select port A and start with first multiplier
     currentChannel = CHAN_A;
     currentStep = 0;
     break;

case 1:  //Button 2
     // Select port A and start with first multiplier
     currentChannel = CHAN_B;
     currentStep = 0;
     break;

case 2:     //Button 3
     // set multiplier
     currentStep++;
     if ( currentStep >= stepCount ) currentStep = 0;
     break;
 }
}

Thanks,
I will have a look through the code and have a play with, May be I’m over complicating things.

you may use some different LiquidCrystal_I2C -library but I guess not.

an I2C-bus has only two wires and the standard-call looks like this:

LiquidCrystal_I2C lcd(0x20,16,2);

where

  • parameter 1 is I2C-adress
  • parameter two number of characters in one line
  • parameter three is number of rows

this means so many parameters seem to make no sense to me

What are the IO-pins the I2C-LCD is connected to?

why should a parameter-list like

LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7); //0x27 is the default address of the LCD with I2C bus module

have something to do with your PCF8574 ? They are both I2C but the parameter-list has nothing to do with your
I2C-DAC PCF8574

you may find it unpollite that I ask this but I do ask it: did you thoroughly examine the libraries you are using
and did you compare your use of the functions with the example-codes that most libraries come with?

I might be wrong with my assumptions. I'm asking this because I got the impression you quickly throw code together and if it works go on to the next thing.

best regards Stefan

P.S:: The downside of using a for-loop to run through all inputs it is hard to understand which input does what?

Hi Stefan,
Since I started learning Arduino I've always done it this way and never knew any difference,

I've now updated and changed it, So now it works with

LiquidCrystal_I2C lcd(0x3F, 20, 4); // Change to (0x27,20,4) for 20x4 LCD.

you may find it unpollite that I ask this but I do ask it: did you thoroughly examine the libraries you are using
and did you compare your use of the functions with the example-codes that most libraries come with?
As to you saying I got the impression you quickly throw code together and if it works go on to the next thing

I did look through the library many years ago, There is a saying I use if it isn't broke don't fix it :), But I'm always open to suggestions and improvements, I've looked into the libraries now and strange there was no examples but it was created by Created by Francisco Malpartida on 20/08/11 :astonished:.

Sometimes but not all the times, This is depending on what I'm doing and the approach I do, I always enjoying reading other peoples code and I find I pick up some great tips and ideas but at the same time you can get some bad ideas along the way, I'm no means perfect at coding but have lots of fun in getting things to work,
No offence taken and just like to say thanks for taking the time to help me.

blh64,
I uploaded your code, Pressing the button would not change between the Port's, But after playing around with it I've got it working and you've showed me some great tips so I'd just like to say thank you for taking the time to help,
I'll post my updated code after a few tweaks and that
Kind Regards,
Steve

Stefan,
Your correct about using for loops for reading buttons, I re-tried the original code from that you tube video and on power up it reads all the button and say’s that they have been pressed, This is why my multiplier started of at 10 and not zero.

Like now when I power it up the first channel should be this one

volatile byte currentChannel = CHAN1_CHAN_A;

But because it reads that the button has been pressed it always starts off on CHAN1_CHAB_B.

So I need to look at a better method or way to carry this out.
I’ve changed the code now as I would like to add another MCP4822 to control another 4 motors speeds, On power up both MCP4822’s are set with the min and max, Dac 2 is set slightly lower than the other so I can see the difference.
It’s the button arrangements that I need to think about as I only want to use 5 buttons.
Button 0= is on the encoder, This set’s the multiplier
Button 1 needs to select between motors 1& 2 which are connected to DAC1
Button 2 needs to select between motors 3& 4 which are connected to DAC2
button 3 Needs to select DAC1
button 4 Need to select DAC 2

This is my latest code but need to think how to change the button code so I can select between DAC 1 & DAC2

#include <Wire.h> // Library for I2C communication
#include <LiquidCrystal_I2C.h> // Library for LCD
#include <MCP48xx.h>
#include <Rotary.h>
#include <SPI.h>
LiquidCrystal_I2C lcd(0x3F, 20, 4); // Change to (0x27,20,4) for 20x4 LCD.
MCP4822 dac_Channel1(10); //DAc selct pint
MCP4822 dac_Channel2(9); //DAc selct pint

#define stepPin1 3 // Set 'Step' rotary encoder pins
#define stepPin2 2 // Set 'Step' rotary encoder pins
// We define an int variable to store the voltage in mV so 100mV = 0.1V
Rotary Volts_Rotary = Rotary(stepPin1, stepPin2);              // Rotary encoder for frequency connects to interrupt pins
//########## SET UP TO 4 INPUTS ######################
const int numOfInputs = 5;
//########## BUTTON LAYOUT ##########
// Button 0 = Encoder buttom,Button 1 = Select Port A, Button 2 = Select Port B,
// Button 3 = Set both Motors 1 & 2 (PORT A&B Of DAC 1), channels,Button 4 = Set both Motors 3 & 4 (PORT A&B Of DAC 4)
const int inputPins[numOfInputs] = {4, 8, 7, 6, 5};
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW, LOW, LOW, LOW, LOW};
bool inputFlags[numOfInputs] = {LOW, LOW, LOW, LOW, LOW};
int inputCounters[numOfInputs];
long lastDebounceTime[numOfInputs] = {0, 0, 0, 0, 0};
long debounceDelay = 50; //set a debounce
const byte Dac_multipliers[] = { 1, 10, 50, 100 };
const byte stepCount = sizeof(Dac_multipliers) / sizeof(Dac_multipliers[0]);
volatile byte currentStep = 0;
enum { CHAN1_CHAN_A, CHAN1_CHAN_B, CHAN2_CHAN_A, CHAN2_CHAN_B };  // constants for current channel
volatile byte Set_currentChannel = CHAN1_CHAN_A;

volatile byte currentChannel = CHAN1_CHAN_A;
int Dac_min_volts;
int Dac_volts[4] = {1600, 990, 1598, 988}; //Set initial Dac_volt.
void setup() {
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();                                 //set LCD backlight on
  lcd.clear();
  Volts_Rotary.begin(); //Start Rotary encoder off
  pinMode(stepPin1, INPUT_PULLUP); // Pins for step rotary encoder on analogue pins 2,3
  pinMode(stepPin2, INPUT_PULLUP); // Pins for step rotary encoder on analogue pins 2,3
  attachInterrupt(digitalPinToInterrupt(stepPin1), Volts_encoder, CHANGE); //detect change
  attachInterrupt(digitalPinToInterrupt(stepPin2), Volts_encoder, CHANGE); //detect change
  dac_Channel1.init(); //Start the Dac off
  for (int i = 0; i < numOfInputs; i++) { // Set up all input pins
    pinMode(inputPins[i], INPUT_PULLUP);
    // digitalWrite(inputPins[i], HIGH); // pull-up 20k
  }
  // The channels are turned off at startup so we need to turn the channel we need on
  dac_Channel1.turnOnChannelA();
  dac_Channel1.turnOnChannelB();
  dac_Channel2.turnOnChannelA();
  dac_Channel2.turnOnChannelB();
  // We configure the channels in High gain
  dac_Channel1.setGainA(MCP4822::High);
  dac_Channel1.setGainB(MCP4822::High);
  dac_Channel2.setGainA(MCP4822::High);
  dac_Channel2.setGainB(MCP4822::High);
  lcd.setCursor(0, 0);
  lcd.print("POWERING");
  lcd.clear();
  dac_Channel1.setVoltageA(Dac_volts[CHAN1_CHAN_A]); // Send the Dac Value out on Port A
  dac_Channel1.setVoltageB(Dac_volts[CHAN1_CHAN_B]); // Send the Dac Value out on Port B
  dac_Channel2.setVoltageA(Dac_volts[CHAN2_CHAN_A]); // Send the Dac Value out on Port A
  dac_Channel2.setVoltageB(Dac_volts[CHAN2_CHAN_B]); // Send the Dac Value out on Port B
}

void loop() {
  setInputFlags();
  resolveInputFlags();
  dac_Channel1.updateDAC();
  lcd.setCursor(0, 0);
  lcd.print(Dac_volts[CHAN1_CHAN_A]);//Display Dac Value
  lcd.print(" V1 ");
  lcd.print(Dac_volts[CHAN2_CHAN_A]);//Display Dac Value
  lcd.print(" V2 ");
  lcd.setCursor(0, 1);
  lcd.print(Dac_volts[CHAN1_CHAN_B]);// Just show multiplier value,Will be removed
  lcd.print(" A1 ");
  lcd.print(Dac_volts[CHAN2_CHAN_B]);// Just show multiplier value,Will be removed
  lcd.print(" A2 ");
  lcd.setCursor(0, 2);
  lcd.print(currentStep);// Just show multiplier value,Will be removed
  lcd.print(" : ");
  lcd.print(currentChannel);

  if ( currentChannel == CHAN1_CHAN_A ) {
    lcd.setCursor(0, 3);
    lcd.print("A: ");
    dac_Channel1.setVoltageA(Dac_volts[CHAN1_CHAN_A]); // Send the Dac Value out on Port A
  }
  if ( currentChannel == CHAN1_CHAN_B ) {
    dac_Channel1.setVoltageB(Dac_volts[CHAN1_CHAN_B]); // Send the Dac Value out on Port B
    lcd.setCursor(0, 3);
    lcd.print("B: ");
  }
}
void setInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    int reading = digitalRead(inputPins[i]);
    if (reading != lastInputState[i]) {
      lastDebounceTime[i] = millis();
    }
    if ((millis() - lastDebounceTime[i]) > debounceDelay) {
      if (reading != inputState[i]) {
        inputState[i] = reading;
        if (inputState[i] == HIGH) {
          inputFlags[i] = HIGH;
        }
      }
    }
    lastInputState[i] = reading;
  }
}
void resolveInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    if (inputFlags[i] == HIGH) {
      inputAction(i);
      inputFlags[i] = LOW;
    }
  }
}
void Volts_encoder()   {
  unsigned int result = Volts_Rotary.process();
  ///Rotary encoder 1 for setting the volts
  if (result) {
    int currentDacVolts = Dac_volts[currentChannel];
    if (result == DIR_CW) {
      currentDacVolts += Dac_multipliers[currentStep];
    } else {
      currentDacVolts -= Dac_multipliers[currentStep];
    }
    if (currentDacVolts < Dac_min_volts) currentDacVolts = Dac_min_volts;
    if (currentDacVolts >= 4096) currentDacVolts = 4095;
    Dac_volts[currentChannel] = currentDacVolts;
  }
}
void inputAction(int input) {

  //Button one
  if (input == 0) {
    currentStep++;
    if ( currentStep >= stepCount ) currentStep = 0;

    //Button 2
  } else if (input == 1) {
    currentChannel = CHAN1_CHAN_A;
    Dac_min_volts = 1600;
    currentStep = 0;
    Serial.println("button 1");
    //Button 3
  } else if (input == 2) {
    currentChannel = CHAN1_CHAN_B;
    currentStep = 0;
    Dac_min_volts = 990;
    Serial.println("button 2");

  }

}

if you want further help you should provide download-links to the libraries you are using.
This rotary-lib is working in such a different way than any other encoder-lib I have seen so far
that I'm still in doubt that you are using it the right way.

As a general hint:
Your button-control does not work in all details and you already start addding a second DAC to the code.
making the code bigger and increase the possible sources of bugs.
You like to deal with arrays. If you use an array-index that is out of the defined boundaries this can have absolutely unpredictable effects. Which are very hard to find. So in a code that uses arrays this is another reason to thporoughly test one pasrt of a code including all kinds of "strange" values before adding a new part to the code.

If you divide the code into functional parts and test each functional part thoroughly you can be sure if a bug occurs it is in the new part you are working on and in 99% of all cases not in a part you have tested.

This sounds like additional work. Yes it is. But it pays back time as soon as problem occurs.

best regards Stefan

I got to the bottom of the button issue on first power up and no longer outputs any Serial Data on the input pins like it did to start with.
The Rotary encoder side of things worked very well through all the range, I’ve taken on board what you have said and gone back to basic, Just so I can get the button side of things working I’ve removed all the rotary encoder and MACP4822 code So that I can concentrate on the buttons first. This is the layout of buttons
Button 0 = Multiplier
Button 1 = Select DAC 1
Button 2 = Select DAC 2
Button 3 = Select PORT A (and change depending on DAC Selected)
Button 4 = Select PORT B (and change depending on DAC Selected)

This is what I want/think that should happen and try my best to explain.

  1. On power up DAC 1 & PORT A selected(adjust value if required), Also by pressing button 1 nothing happens
  2. While in DAC 1 mode Press button 3 and still should only adjust PORT A, then While in DAC 1 Mode press button 4 and this just Moves to PORT B of DAC 1
  3. Press Button 2 then this moves to DAC 2 PORT A Press button 3 and still should only adjust PORT A, then While in DAC 2 Mode press button 4 and this just Moves to PORT B of DAC 2

But this is what’s not happening.

  1. On power up I can see DAC 1 PORT A selected, Press button 1 and nothing changes (Good so far)
  2. I can press buttons 3&4 and this changes DAC 1 to PORT A & PORT B. (Good so far)
  3. Press Button 2 it moves over to DAC 2(good so far)
  4. Press button 3 nothing happens(Good so far)
  5. Press Button 4 and this changed to show PORT B selected but then teh Set_currentChannel jumps to value of 3 unlike the others that just changes between 0 & 1 then the display stays on DAC 2 PORT B.
    This is the stripped down code (Latest has I’ve tried lots of ting to get to the bottom of it )
#include <LiquidCrystal_I2C.h> // Libaray from here https://github.com/johnrickman/LiquidCrystal_I2C
LiquidCrystal_I2C lcd(0x3F, 20, 4); // Change to (0x27,20,4) for 20x4 LCD.
#include <Wire.h>
//########## SET UP TO 8 INPUTS ######################
const int numOfInputs = 5;
const int inputPins[numOfInputs] = {4, 8, 7, 6, 5};
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW, LOW, LOW, LOW, LOW};
bool inputFlags[numOfInputs] = {LOW, LOW, LOW, LOW, LOW};
int inputCounters[numOfInputs];
long lastDebounceTime[numOfInputs] = {0, 0, 0, 0, 0};
long debounceDelay = 50; //set a debounce
const byte Dac_multipliers[] = { 1, 10, 50, 100 };
const byte stepCount = sizeof(Dac_multipliers) / sizeof(Dac_multipliers[0]);
volatile byte currentStep = 0;
enum {DAC_1, DAC_2}; // Select DAC 1 or DAC 2
volatile byte Select_Channel = DAC_1; //Set Channel to DAC 1 on power up
enum { CHAN1_CHAN_A, CHAN1_CHAN_B, CHAN2_CHAN_A, CHAN2_CHAN_B };  // constants for current channel
volatile byte Set_currentChannel = CHAN1_CHAN_A; //Set DAC 1, PORT A on power up
int Dac_volts[] = {1600, 990, 1598, 998}; //Set initial Dac_volt.
int Dac1_min_volts;//Sore Min motor 1&2
int Dac2_min_volts;//Store min Motor 3&4

void setup() {
  Serial.begin(9600);
  lcd.begin();                                        //set up the LCD's number of columns and rows
  lcd.backlight();                               //set LCD backlight on
  lcd.clear();
  for (int i = 0; i < numOfInputs; i++) { // Set up all input pins
    pinMode(inputPins[i], INPUT_PULLUP);
    // digitalWrite(inputPins[i], HIGH); // pull-up 20k
  }
  // The channels are turned off at startup so we need to turn the channel we need on
  lcd.clear();
}

void loop() {
  setInputFlags();
  resolveInputFlags();
  lcd.setCursor(0, 0);
  lcd.print(Dac_volts[CHAN1_CHAN_A]);//Display Dac Value
  lcd.print(" V1 ");
  lcd.print(Dac_volts[CHAN2_CHAN_A]);//Display Dac Value
  lcd.print(" V2 ");
  lcd.setCursor(0, 1);
  lcd.print(Dac_volts[CHAN1_CHAN_B]);// Just show multiplier value,Will be removed
  lcd.print(" A1 ");
  lcd.print(Dac_volts[CHAN2_CHAN_B]);// Just show multiplier value,Will be removed
  lcd.print(" A2 ");
  lcd.setCursor(0, 2);
  lcd.print("PORT:");
  lcd.print(Set_currentChannel);
  lcd.print(" DAC CH:");
  lcd.print(Select_Channel);
  //##### SET DAC 1 PORT A&B ############
  if (Select_Channel == DAC_1 && Set_currentChannel == CHAN1_CHAN_A) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 1 PORT A ");
  }
  if (Select_Channel == DAC_1 && Set_currentChannel == CHAN1_CHAN_B) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 1 PORT B ");
  }
  //##### SET DAC 2 PORT A&B ############
  if (Select_Channel == DAC_2 && Set_currentChannel == CHAN2_CHAN_A) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 2 PORT A ");
  }
  if (Select_Channel == DAC_2 && Set_currentChannel == CHAN2_CHAN_B) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 2 PORT B ");
  }
}
void setInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    int reading = digitalRead(inputPins[i]);
    if (reading != lastInputState[i]) {
      lastDebounceTime[i] = millis();
    }
    if ((millis() - lastDebounceTime[i]) > debounceDelay) {
      if (reading != inputState[i]) {
        inputState[i] = reading;
        if (inputState[i] == LOW) {// When this was high this what was sending all the serial data out when should not be
          inputFlags[i] = HIGH;
        }
      }
    }
    lastInputState[i] = reading;
  }
}
void resolveInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    if (inputFlags[i] == HIGH) {
      inputAction(i);
      inputFlags[i] = LOW;
    }
  }
}

void inputAction(int input) {
  //Button 0 sets the Multippler
  if (input == 0) {
    currentStep++;
    if ( currentStep >= stepCount ) currentStep = 0;
    Serial.println("1 OUTPUT SHOULD NOT BE "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 1 Select DAC 1(default on power up and not changed is button 1 is pressed while in DAC 1 Mode).
  } else if (input == 1) {
    Select_Channel = DAC_1;
    Serial.println("2 OUTPUT SHOULD NOT BE "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 2 Select DAC 2 once button pressed and disable DAC 1
  } else if (input == 2 ) {
    Select_Channel = DAC_2;
    Serial.println("3 OUTPUT SHOULD NOT BE "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 3 ADJUST PORT A OF DAC 1 WHILE DAC 1 SELECTED.
  } else if (input == 3 && Select_Channel == DAC_1) {
    Set_currentChannel = CHAN1_CHAN_A;
    Dac1_min_volts = 1600;
    currentStep = 0;
    Serial.println("4 OUTPUT SHOULD NOT BE "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 3 ADJUST PORT A OF DAC 2 WHILE DAC 2 SELECTED.
  } else if (input == 3 && Select_Channel == DAC_2) {
    Set_currentChannel = CHAN1_CHAN_A;
    currentStep = 0;
    Dac1_min_volts = 990;
    Serial.println("5 OUTPUT SHOULD NOT BE "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 4 ADJUST PORT B OF DAC 1 WHILE DAC 1 SELECTED.
  } else if (input == 4 && Select_Channel == DAC_1) {
    Set_currentChannel = CHAN1_CHAN_B;
    Dac2_min_volts = 1598;
    currentStep = 0;
    Serial.println("6 OUTPUT SHOULD NOT BE "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 4 ADJUST PORT A OF DAC 2 WHILE DAC 1 SELECTED.
  } else if (input == 4 && Select_Channel == DAC_2) {
    Set_currentChannel = CHAN2_CHAN_B;
    currentStep = 0;
    Dac2_min_volts = 988;
    Serial.println("7 OUTPUT SHOULD NOT BE "); // Just added to see if there is any output on power up(DEBUGING ONLY)

  }
}

For reference the libraries I’m using are from here
LCD: https://github.com/johnrickman/LiquidCrystal_I2C
Rotary encoder: GitHub - brianlow/Rotary: Rotary encoder library for Arduino

But removed Rotary to help make it easier to understand

OK I would appreciate it very much if you give a brif desciption how the functions

  setInputFlags();
  resolveInputFlags();
  inputAction();

work together.

just explain it on one example
I press button 2 and .... (what does setInputFlags what does resolveInputFlags what does inputAction do)

I don't understand this

  1. Press Button 4 and this changed to show PORT B selected but then teh Set_currentChannel jumps to value of 3 unlike the others that just changes between 0 & 1 then the display stays on DAC 2 PORT B.

please describe it with more words not so compact
first a description how it should work

you press button 4 and then this shall show port B selected and value (which one?) should be (which number?)
and then display should stay on (what?)

then a description what you really see and how it differs from what you want
unlike the others (what do you mean by "the others"?

best regards Stefan

I watched the tutorial in the video several times in the link above I posted to understand how they work, The guy goes into great detail and I don’t expect anyone to sit and watch it for me…
This is basically how it works
setInputFlags();= Just sets a flag and just records and stores that variable and monitors any other buttons pressed and still stores them while another button has been pressed
resolveInputFlags();= get’s the values from setinput flags for the button been pressed, If the any of the flags are low
it does noting If the flag is high it then passes the value to the input flags
inputAction(i); = depending on which button has been pressed as to what the function does.

I’ve done a bit more playing and changed a couple of things and changed the serial print to show button presses, According to the serial Monitor it’s working but the LCD is saying different, I’ve not added the encoder code to check as I would like to get to the bottom of this first.

This is the latest code with minor changes

#include <LiquidCrystal_I2C.h> // Libaray from here https://github.com/johnrickman/LiquidCrystal_I2C
LiquidCrystal_I2C lcd(0x3F, 20, 4); // Change to (0x27,20,4) for 20x4 LCD.
#include <Wire.h>
//########## SET UP TO 8 INPUTS ######################
const int numOfInputs = 5;
const int inputPins[numOfInputs] = {4, 8, 7, 6, 5};
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW, LOW, LOW, LOW, LOW};
bool inputFlags[numOfInputs] = {LOW, LOW, LOW, LOW, LOW};
int inputCounters[numOfInputs];
long lastDebounceTime[numOfInputs] = {0, 0, 0, 0, 0};
long debounceDelay = 50; //set a debounce
const byte Dac_multipliers[] = { 1, 10, 50, 100 };
const byte stepCount = sizeof(Dac_multipliers) / sizeof(Dac_multipliers[0]);
volatile byte currentStep = 0;
enum {DAC_1, DAC_2}; // Select DAC 1 or DAC 2
volatile boolean Select_Channel = DAC_1; //Set Channel to DAC 1 on power up
enum { CHAN1_CHAN_A, CHAN1_CHAN_B, CHAN2_CHAN_A, CHAN2_CHAN_B };  // constants for current channel
volatile boolean Set_currentChannel = CHAN1_CHAN_A; //Set DAC 1, PORT A on power up
int Dac_volts[] = {1600, 990, 1598, 998}; //Set initial Dac_volt.
int Dac1_min_volts;//Sore Min motor 1&2
int Dac2_min_volts;//Store min Motor 3&4

void setup() {
  Serial.begin(9600);
  lcd.begin();                                        //set up the LCD's number of columns and rows
  lcd.backlight();                               //set LCD backlight on
  lcd.clear();
  for (int i = 0; i < numOfInputs; i++) { // Set up all input pins
    pinMode(inputPins[i], INPUT_PULLUP);
    // digitalWrite(inputPins[i], HIGH); // pull-up 20k
  }
  // The channels are turned off at startup so we need to turn the channel we need on
  lcd.clear();
}

void loop() {
  setInputFlags();
  resolveInputFlags();
  lcd.setCursor(0, 0);
  lcd.print(Dac_volts[CHAN1_CHAN_A]);//Display Dac Value
  lcd.print(" V1 ");
  lcd.print(Dac_volts[CHAN2_CHAN_A]);//Display Dac Value
  lcd.print(" V2 ");
  lcd.setCursor(0, 1);
  lcd.print(Dac_volts[CHAN1_CHAN_B]);// Just show multiplier value,Will be removed
  lcd.print(" A1 ");
  lcd.print(Dac_volts[CHAN2_CHAN_B]);// Just show multiplier value,Will be removed
  lcd.print(" A2 ");
  lcd.setCursor(0, 2);
  lcd.print("PORT:");
  lcd.print(Set_currentChannel);
  lcd.print(" DAC CH:");
  lcd.print(Select_Channel);
  //##### SET DAC 1 PORT A&B ############
  if (Select_Channel == DAC_1 && Set_currentChannel == CHAN1_CHAN_A) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 1 PORT A ");
  }
  else if (Select_Channel == DAC_1 && Set_currentChannel == CHAN1_CHAN_B) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 1 PORT B ");
  }
  //##### SET DAC 2 PORT A&B ############
  else if (Select_Channel == DAC_2 && Set_currentChannel == CHAN2_CHAN_A) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 2 PORT A ");
  }
  else if (Select_Channel == DAC_2 && Set_currentChannel == CHAN2_CHAN_B) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 2 PORT B ");
  }
}
void setInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    int reading = digitalRead(inputPins[i]);
    if (reading != lastInputState[i]) {
      lastDebounceTime[i] = millis();
    }
    if ((millis() - lastDebounceTime[i]) > debounceDelay) {
      if (reading != inputState[i]) {
        inputState[i] = reading;
        if (inputState[i] == LOW) {// When this was high this what was sending all the serial data out when should not be
          inputFlags[i] = HIGH;
        }
      }
    }
    lastInputState[i] = reading;
  }
}
void resolveInputFlags() {
  for (int i = 0; i < numOfInputs; i++) {
    if (inputFlags[i] == HIGH) {
      inputAction(i);
      inputFlags[i] = LOW;
    }
  }
}

void inputAction(int input) {
  //Button 0 sets the Multippler
  if (input == 0) {
    currentStep++;
    if ( currentStep >= stepCount ) currentStep = 0;
    Serial.println("1 OUTPUT SHOULD NOT BE "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 1 Select DAC 1(default on power up and not changed is button 1 is pressed while in DAC 1 Mode).
  } else if (input == 1) {
    Select_Channel = DAC_1;
    Serial.println("DAC 1 SELECTED "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 2 Select DAC 2 once button pressed and disable DAC 1
  } else if (input == 2 ) {
    Select_Channel = DAC_2;
    Serial.println("DAC 2 SELECTED "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 3 ADJUST PORT A OF DAC 1 WHILE DAC 1 SELECTED.
  } else if (input == 3 && Select_Channel == DAC_1) {
    Set_currentChannel = CHAN1_CHAN_A;
    Dac1_min_volts = 1600;
    currentStep = 0;
    Serial.println("DAC 1 & PORT A SELECTED "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 3 ADJUST PORT A OF DAC 2 WHILE DAC 2 SELECTED.
  } else if (input == 3 && Select_Channel == DAC_2) {
    Set_currentChannel = CHAN2_CHAN_A;
    currentStep = 0;
    Dac1_min_volts = 990;
    Serial.println("DAC 2 & PORT A SELECTED "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 4 ADJUST PORT B OF DAC 1 WHILE DAC 1 SELECTED.
  } else if (input == 4 && Select_Channel == DAC_1) {
    Set_currentChannel = CHAN1_CHAN_A;
    Dac2_min_volts = 1598;
    currentStep = 0;
    Serial.println("DAC 1 & PORT B SELECTED "); // Just added to see if there is any output on power up(DEBUGING ONLY)
    //Button 4 ADJUST PORT A OF DAC 2 WHILE DAC 1 SELECTED.
  } else if (input == 4 && Select_Channel == DAC_2) {
    Set_currentChannel = CHAN2_CHAN_B;
    currentStep = 0;
    Dac2_min_volts = 988;
    Serial.println("DAC 2 & PORT B SELECTED "); // Just added to see if there is any output on power up(DEBUGING ONLY)

  }
}

And this is now what the Serial monitor is saying when I cycle through the buttons.

DAC 1 SELECTED 
DAC 1 & PORT A SELECTED 
DAC 1 & PORT B SELECTED 
DAC 2 SELECTED 
DAC 2 & PORT A SELECTED 
DAC 2 & PORT B SELECTED 
DAC 1 SELECTED 
DAC 1 & PORT A SELECTED 
DAC 1 & PORT B SELECTED 
DAC 2 SELECTED 
DAC 2 & PORT A SELECTED 
DAC 2 & PORT B SELECTED

Has you can see the button function seems to be working great but the LCD display’s different.
The DAC CH changes from 0 to 1 when I press the buttons, But the SET DAC 1 PORT A,SET DAC 1 PORT B,SET DAC 2 PORT A,SET DAC 2 PORT B does not,
The code below is where I would need to set the DAC value with in for the DAC/PORT selected

 //##### SET DAC 1 PORT A&B ############
  if (Select_Channel == DAC_1 && Set_currentChannel == CHAN1_CHAN_A) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 1 PORT A ");
  }
  else if (Select_Channel == DAC_1 && Set_currentChannel == CHAN1_CHAN_B) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 1 PORT B ");
  }
  //##### SET DAC 2 PORT A&B ############
  else if (Select_Channel == DAC_2 && Set_currentChannel == CHAN2_CHAN_A) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 2 PORT A ");
  }
  else if (Select_Channel == DAC_2 && Set_currentChannel == CHAN2_CHAN_B) {
    lcd.setCursor(0, 3);
    lcd.print("SET DAC 2 PORT B ");
  }

So as you can see in serial monitor it’s working

you can point to the code where you think the error might be as an extra code-section
but you should additionally post the new complete code-version
If I would like to compile it with the complete code there is no hassle where to change something
and in most cases the error is somehwere else

the buttons work yes. And how about adding serial output
printing out the values of
Select_Channel and Set_currentChannel

a) if you leave the function inputAction()
b) right before your if-conditions in the loop

  //##### SET DAC 1 PORT A&B ############
  if (Select_Channel == DAC_1 && Set_currentChannel == CHAN1_CHAN_A) {

For analysing the problem I would do just the same.
I find it much easier to type some additional lines of code than trying to remember

add to your enum another symbol most left

enum {No_DAC, DAC_1, DAC_2}; // Select DAC 1 or DAC 2

this means printing the variable matches the numbers DAC1 DAC2

"variable x has value y this means variable a is set to value b etc. etc. etc."

and printing the values that the program uses excludes all thinking-errors which might be inside the analysis

best regards Stefan