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.
- Power up Port A set to 1.6V & Port B set to 0.990V
- Press button1 to select Port A and set volts, So Port B can not bet changed.
- Press button 2 to select Port B and set volts, Disable Port A from been changed.
- 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.
- 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;
}
}