As part of an ongoing project, I recently designed an expander card for my ESP-12E I2C Base. I am referring to this device( Atmega 328P Base PWM Controller Card). At the time of writing that article, I have not released any of the code for the project. This is a very short post, showing one possible way to implement a rotary encoder onto that particular device. (It can also be adapted for other devices, of course)
Arduino Style Code for using a rotary encoder
// Constants and Variables
const int encFWD = 8;
const int encREV = 7;
int aState;
int aLastState;
int encDir;
int encTurned = LOW;
int encLastState;
int encValue = 0;
int lastEncValue;
const int encInc = 10;
unsigned long lastEncDebounce = 0;
unsigned encDebounceDelay = 50;
const int encBtn = 9;
int encButtonState;
int lastEncBtnState = LOW;
int EncBtnValue = LOW;
int encBtnState;
void setup() {
//Rotary Encoder
pinMode(encFWD,INPUT_PULLUP);
pinMode(encREV,INPUT_PULLUP);
pinMode(encBtn,INPUT_PULLUP);
// Init the pins in UNPUT Pullup Mode
encTurned = LOW; // Flag for encoder
encLastState = digitalRead(encFWD);
//Serial
Serial.begin(115200);
//Status LED on D13
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
}
void loop() {
lastEncValue = encValue;
//Handle the Encoder Push Button
encBtnState = digitalRead(encBtn);
if (encBtnState != lastEncBtnState) {
lastEncDebounce = millis();
}
if ((millis() - lastEncDebounce) > encDebounceDelay) {
if (encBtnState != encButtonState) {
encButtonState = encBtnState;
if (lastEncBtnState == LOW) {
EncBtnValue = !EncBtnValue; // Toggle the button Value
}
}
}
lastEncBtnState = encBtnState;
// Handle the Rotary Encoder Dial
aState = digitalRead(encFWD);
if (aState != aLastState) {
if (digitalRead(encREV) != aState) {
if (encTurned == LOW) {
encLastState = encTurned;
encTurned = HIGH; // Set Flag
// Setting this flag will get rid of double value entries caused by contact
// bounce inside the encoder. I found it easier to implement this way
// as opposed to using software debouncing as with the button
} else {
encTurned = LOW; // Set Flag low
// This will ensure that the value is increased only once per "click"
}
if ((encValue < 300) && (encDir == 0)){
if ((encLastState == LOW) && (encTurned == HIGH)){
encValue = encValue + encInc;
encDir = 1;
}
}
} else {
if (encTurned == LOW) {
encLastState = encTurned;
encTurned = HIGH;
} else {
encTurned = LOW;
}
if ((encValue > 0) && (encDir == 0)){
if ((encLastState == LOW) && (encTurned == HIGH)){
encValue = encValue - encInc;
encDir = 2;
}
}
}
encLastState = encTurned;
}
aLastState = aState;
encDir = 0;
// Print Some Status
if (encValue != lastEncValue) {
Serial.print("Encoder Value Changed from ");
Serial.print(lastEncValue);
Serial.print(" to ");
Serial.println(encValue);
}
digitalWrite(13,EncBtnValue);
}
I hope that this will be useful to somebody.