I was using an Uno with an rotary encoder and now want to add a second rotary encoder so I moved over to the Mega256 as this has 3 set's of interrupts pins (2,3,17,18,19,20,21), Pins 20,21 I'm using for the I2C part.
The code below worked on an Uno but only with rotary encoder implemented at the time using pins 2,3.
I think it may be something to do with this part, But I don't really understand if I need to change or alter this part for the mega256, trying to get my head around it.
// Configure interrupt and enable for rotary encoder.
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
This is my full code with 2 rotary encoders implemented but the values do not change when I rotate the knobs.
Rotary encoder 1 on pins 2,3 (same as the uno)and rotary encoder 2 on pins 18,19.
#include <Rotary.h> // Rotary encoder: https://github.com/brianlow/Rotary
#include <Wire.h>
#include <TimedAction.h>
#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 <Adafruit_MCP4725.h>
Adafruit_MCP4725 dac;
Adafruit_MCP4725 dacB; // constructor
#include <Adafruit_ADS1015.h> //Include the libarary for 16Bit A/D converencoderValuester
#define VOLTS_CHAN0 0 //channel 1 value
#define VOLTS_CHAN1 1 //chanel2 value
#define stepPin1 18 // Set 'Step' rotary encoder pins
#define stepPin2 19
int Amp_multiplier = 17;
Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
uint16_t err1; //ADC0 variable
uint16_t err2; //ADC1 variable
float Vmultiplier = 0.0001875F; // used to convet readings this is calculated
float Vmultiplier1 = 0.0001875F; // used to convet readings this is calculated
float Vresults0; // Holds raw battery voltage value
float Vresults1; // Holds raw battery current value
float Voltage1 = 0.0;
float Voltage2 = 0.0;
int DAC8574_Ch2_Val = 0;
float r1 = 47000.0;
float r2 = 6200.0;
float Actual_volt = 0;
float Set_volt = 0;
Rotary Volts_Rotary = Rotary(2, 3); // Rotary encoder for frequency connects to interrupt pins
Rotary Amps_Rotary = Rotary(stepPin1, stepPin2); // Rotary encoder for frequency connects to interrupt pins
int selector = 0;
float Voltage3 = 0;
bool buttonPress = false;
bool inMenu = false;
long unsigned int Dac_volt_Chanel1 = 1157; // Set initial Dac_volt_Chanel1uency.
long unsigned int Dac_Amp_Chanel1 = 0;
int stepPointer = 1;
unsigned long Dac_multiplier = 0;
//String units = stepText[stepPointer];
//#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
const int numOfInputs = 2;
const int inputPins[numOfInputs] = {4, 17};
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW, LOW};
bool inputFlags[numOfInputs] = {LOW, LOW};
int inputCounters[numOfInputs];
long lastDebounceTime[numOfInputs] = {0, 0};
long debounceDelay = 50;
int output = 0;
void TimerService01();
TimedAction Timedact01 = TimedAction(80, TimerService01); // mS
void TimerService02();
TimedAction Timedact02 = TimedAction(250, TimerService02); // mS
void setup() {
dacB.begin(0x62); // The I2C Address: Run the I2C Scanner if you're not sure
ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
ads.begin(); //start the 16bit A/D converter
for (int i = 0; i < numOfInputs; i++) {
pinMode(inputPins[i], INPUT);
digitalWrite(inputPins[i], HIGH); // pull-up 20k
}
//pinMode(stepPin1, INPUT_PULLUP); // Pins for step rotary encoder on analogue pins A2, A3
// pinMode(stepPin2, INPUT_PULLUP);
// Configure interrupt and enable for rotary encoder.
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
//Set PCIE0 to enable PCMSK2 scan.
sei();
lcd.begin(20, 4);
lcd.setBacklightPin(3, POSITIVE); // BL, BL_POL
lcd.setBacklight(HIGH); //set LCD backlight on
lcd.clear();
}
void getStep() {
switch (stepPointer) {
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();
Timedact01.check();
Timedact02.check();
DAC8574_Ch2_Val = Dac_volt_Chanel1;
dacB.setVoltage(DAC8574_Ch2_Val, false);
}
ISR(PCINT2_vect) {
unsigned int result = Volts_Rotary.process();
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) >= 1157) Dac_volt_Chanel1 -= Dac_multiplier;
}
if (Dac_volt_Chanel1 <= 729) Dac_volt_Chanel1 = 1157;
if (Dac_volt_Chanel1 >= 4095) Dac_volt_Chanel1 = 4095;
}
unsigned int result1 = Amps_Rotary.process();
if (result1) {
if (result1 == DIR_CW) {
if ((Dac_Amp_Chanel1 + Dac_multiplier) <= 4095) Dac_Amp_Chanel1 += Dac_multiplier;
} else {
if ((Dac_Amp_Chanel1 - Dac_multiplier) >= 1157) Dac_Amp_Chanel1 -= Dac_multiplier;
}
if (Dac_Amp_Chanel1 <= 729) Dac_Amp_Chanel1 = 1157;
if (Dac_Amp_Chanel1 >= 4095) Dac_Amp_Chanel1 = 4095;
}
}
void TimerService01() {
//#################################################################
//# Read both ADC channels #
//#################################################################
//Read BAttery volatage
err1 = ads.readADC_SingleEnded(VOLTS_CHAN0) ; // Ch.0 (3) 16bit
Voltage1 = err1 * Vmultiplier ; //conert to float
Actual_volt = Voltage1 / (r2 / (r1 + r2)); //convert to real time reading
/*
err2 = ads.readADC_SingleEnded(VOLTS_CHAN1) ; // Ch.1 (3) 16bit
Voltage2 = err2 * Vmultiplier1 ;// Convert to actual input v
Voltage3 = Voltage2 - 1.293; //set the reading to zero but show a minius
Voltage2 = Voltage3 * 4.096; ///this is wherer I've tried differtn methods to set voltage to read saem as actual voltage
*/
Voltage2 = map(Dac_volt_Chanel1, 1157, 4057, 0, 4057);
Set_volt = Voltage2 * 4.993 / 1023 ;
}
void TimerService02() {
//
// units = stepText[stepPointer];
lcd.setCursor(0, 0);
lcd.print("V Set = ");
lcd.print(Set_volt, 2);
lcd.print(" V");
lcd.setCursor(0, 1);
lcd.print("V ACT = ");
if ( Actual_volt >= 6.5) {
lcd.print(Actual_volt, 2);//DAC8574_Ch2_Val
} else {
lcd.print(Actual_volt, 3);//DAC8574_Ch2_Val
}
lcd.setCursor(0, 2);
lcd.print("D ");
lcd.print(DAC8574_Ch2_Val);//DAC8574_Ch2_Val
lcd.print(" : ");
lcd.print(stepPointer);
lcd.print(" ;");
lcd.print(Dac_multiplier);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(Voltage2);//DAC8574_Ch2_Val DACSetSteps[i]
lcd.print(" : ");
lcd.print(Dac_Amp_Chanel1); //result stepPointer
lcd.print(" ");
// 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) {
// Input Toggle Logic
inputCounters[i]++;
stepPointer = inputCounters[i];
inputFlags[i] = LOW;
getStep();
}
if (inputCounters[i] > 3) {
inputCounters[i] = 0;
stepPointer = 1;
}
}
}