/*
AuCP_RotaryWithOperator.ino
Created: 18-Dec-2022
Author: MicroBeaut
*/
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd1602(0x27, 16, 2);
#define Limit constrain
const int clkPins[] = {2, 4, 6};
const int dtPins[] = {3, 5, 7};
const int pbPins[] = {8, 9, 10};
const int numberOfRotary = 3;
const int loLimits[] = {0, 0, 0}; // Low Limit Value
const int hiLimits[] = {20, 3, 20}; // High Limit Value
bool currClocks[numberOfRotary]; // Current Rotary Clock Variable
bool prevClocks[numberOfRotary]; // Previous Rotary Clock Variable
bool currResets[numberOfRotary]; // Current Reset Variable
bool prevResets[numberOfRotary]; // Previous Reset Variable
int values[numberOfRotary]; // Value and Operator Variable
bool risingEdge; // Rising Edge Detector Variable
bool fallingEdge; // Falling Edge Detector Variable
bool currData; // Current Rotary Data Variable
void RotaryDetection(int const index, bool const rotation);
void setup() {
lcd1602.init();
lcd1602.backlight();
lcd1602.clear();
for (int index = 0 ; index < numberOfRotary ; index++) {
pinMode(clkPins[index], INPUT_PULLUP);
pinMode(dtPins[index], INPUT_PULLUP);
pinMode(pbPins[index], INPUT_PULLUP);
currClocks[index] = true;
currResets[index] = true;
values[index] = loLimits[index];
}
RotaryDetection(1, true);
}
void loop() {
for (int index = 0 ; index < numberOfRotary ; index++) {
// Rotary Push Button Detection
prevResets[index] = currResets[index]; // Store Previous PB Value
currResets[index] = digitalRead(pbPins[index]); // Read Current PB Value
fallingEdge = !currResets[index] && prevResets[index]; // fallingEdge Edge Detector
if (fallingEdge) {
values[index] = loLimits[index]; // Reset Value
RotaryDetection(index, true); // Call Roraty Detection and Comparison Function
}
// Rotary Clock Detection
prevClocks[index] = currClocks[index]; // Store Previous Rotary Clock Value
currClocks[index] = digitalRead(clkPins[index]); // Read Current Rotary Clock Value
risingEdge = currClocks[index] && !prevClocks[index]; // Rising Edge Detector
if (risingEdge) {
currData = digitalRead(dtPins[index]); // Read Current Rotary Data
RotaryDetection(index, currData); // Call Roraty Detection and Comparison Function
}
}
}
void RotaryDetection(int const index, bool const rotation) {
int tempValue;
char charOperator;
float result;
// Rotation = "False" => CW
// Rotation = "True" => CCW
if (rotation) {
tempValue = values[index] - 1;
} else {
tempValue = values[index] + 1;
}
// Limit Value
values[index] = Limit(tempValue, loLimits[index], hiLimits[index]);
switch (values[1]) {
case 0:
charOperator = '+';
result = values[0] + values[2];
break;
case 1:
charOperator = '-';
result = values[0] - values[2];
break;
case 2:
charOperator = 'x';
result = values[0] * values[2];
break;
case 3:
charOperator = '/';
result = (float)values[0] / values[2];
break;
}
// Line No. 1
lcd1602.setCursor(0, 0);
lcd1602.print(" ");
lcd1602.setCursor(0, 0);
lcd1602.print(values[0]);
lcd1602.print(charOperator);
lcd1602.print(values[2]);
// Line No. 2
lcd1602.setCursor(0, 1);
lcd1602.print(" ");
lcd1602.setCursor(0, 1);
lcd1602.print(result);
}