Thank you very much for your help!
The rotary encoder I am using is an EC11, leftover from another project I did.
Here is the code, some clarification:
a) You'll see the code for the encoder is structured to manage various encoder, I am using only one for this project.
b) The double IF statement within encoder (to keep counter[0] within 0-25 range, as I need it for this project), could be probably be written better, outside encoder() but I had no time so far, still it works.
c) The whole sketch is divided into 3 tabs, that's the reason for the method declaration before void setup();.
The problem is that displayvisualization(); blocks my encoder reading.
I can't get why the encoder gets stucked and not the button.
Many thanks for your help!
Alessandro
MAIN TAB
// -----------------------------------------------------------------------------
// Libraries
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Display
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(128, 32, &Wire, OLED_RESET);
// -----------------------------------------------------------------------------
// Mode Buttons
const byte modeButton = A3;
// -----------------------------------------------------------------------------
// Clk & Data pins for each encoder
byte pinClk [] = {A2};
byte pinData [] = {A1};
#define N_ENC sizeof(pinData) // determine # of encoders
// -----------------------------------------------------------------------------
// Methods Declarations
int readModeButton();
void displayvisualization ();
int8_t read_rotary();
int encoder();
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void setup() {
pinMode(modeButton, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Test Begin");
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// -----------------------------------------------------------------------------
// Rotary Encoders Pin Set-up
for (int i=0; i < N_ENC; i++){
pinMode (pinData[i], INPUT_PULLUP);
pinMode (pinClk[i], INPUT_PULLUP);
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void loop() {
int mode = readModeButton(3);
//Serial.print(mode);
int a_counter = encoder(0);
//Serial.print(a_counter);
displayvisualization (mode, a_counter); // THIS BLOCK THE ROTARY ENCODER
}
// -----------------------------------------------------------------------------
TAB 1
// -----------------------------------------------------------------------------
// Read the SW Button of specific encoder
int readModeButton(int modeTotNumber){
static byte modeCounter = 1;
static byte modeNow;
static byte modePrevious;
uint32_t now = 0;
int debounce_delay = 150;
modeNow = digitalRead(modeButton);
if ((millis()-now) > debounce_delay){
if (modeNow == LOW && modePrevious == HIGH){
if (modeCounter == modeTotNumber) modeCounter = 0;
modeCounter += 1;
Serial.println(modeCounter);
modePrevious = modeNow;
}
else if (modeNow == HIGH && modePrevious == LOW){
modePrevious = modeNow;
}
now = millis();
}
return modeCounter;
}
// -----------------------------------------------------------------------------
// Display Visualization
void displayvisualization (int mode, int a_counter) {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.print("Display TEST");
display.setCursor(0, 8);
display.print("MODE: "); display.print(mode);
display.setCursor(0,16);
display.print("A Counter "); display.print(a_counter);
display.display();
}
TAB 2
// -----------------------------------------------------------------------------
// A vald CW or CCW move returns 1, invalid returns 0.
int8_t read_rotary (int & store, int & prevNextCode, byte data, byte clk )
{
static int8_t rot_enc_table[] = {
0,1,1,0, 1,0,0,1,
1,0,0,1, 0,1,1,0 };
prevNextCode <<= 2;
prevNextCode |= data << 1;
prevNextCode |= clk;
prevNextCode &= 0x0F;
// If valid then store as 16 bit data.
if (rot_enc_table [prevNextCode] ) {
store <<= 4;
store |= prevNextCode;
store &= 0xFF;
if (store == 0x2b) {
return -1;
}
if (store == 0x17) {
return 1;
}
}
return 0; // invalid input
}
// -----------------------------------------------------------------------------
// Rotary Encoders
int encoder (int idx ) {
// allocate state variables for each encoder (i.e. N_ENC)
static int encState [N_ENC] = {};
static int encInp [N_ENC] = {};
static long encPos [N_ENC] = {};
static long prevencPos [N_ENC] = {};
static int res;
res = read_rotary (encState [idx], encInp [idx],
digitalRead (pinData [idx]),
digitalRead (pinClk [idx]) );
encPos [idx] += res;
static int counter [N_ENC];
if (res == -1) {
if(idx == 0 && counter[0] > 0) {
counter[0]--;
Serial.println(counter[0]);
}
}
if (res == 1) {
if(idx == 0 && counter[0] < 24) {
counter[0]++;
Serial.println(counter[0]);
}
}
if (res) {
char s [80];
sprintf (s, " %d: %02X %2d", idx, encState [idx], encPos [idx]);
//Serial.println (s);
}
return counter[0];
}