Counter misfunctioning with OLED I2C display

Hi,

new to Arduino here. Just did most of Paul McWhoter's "most excelent" arduino tutorials and jumped in trying to use an rotary encoder as a way to control a simple menu.

Using it while displaying it on Serial is just fine, but when I, instead, print to an OLED I2C display, the counter miscounts (or skips counts). All problems go away when I comment the display part (keeping all the wiring and setup, just comment the if statements regarding the oled). Any ideas why?

Thanks in advance!

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

int inputCLK=6;
int inputDT=5;
int inputSW=4;

int counter=0;
int currentStateCLK;
int previousStateCLK;

//int SCLPin=A5;
//int SDAPin=A4;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 oled (SCREEN_WIDTH, SCREEN_HEIGHT,&Wire, -1);

void setup() {
  // put your setup code here, to run once:

// Start serial
//Serial.begin(9600);


// Start screen
  if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }
  
//define pinModes
pinMode(inputCLK, INPUT);
pinMode(inputDT, INPUT);
pinMode(inputSW, INPUT);

//current state
previousStateCLK=digitalRead(inputCLK);

//delay setup
delay(2000);

}

void loop() {
  // put your main code here, to run repeatedly:
currentStateCLK=digitalRead(inputCLK);

if (currentStateCLK!=previousStateCLK){
  //se se mexeu CCW
  if (digitalRead(inputDT) != currentStateCLK){
    counter=counter+1;
    if (counter>3){
      counter=3;
    }
    }
  // se se mexeu CW
   if (digitalRead(inputDT) == currentStateCLK){
      counter=counter-1;
      if (counter<0){
        counter=0;
      }
  }
}

//Serial.println(counter);

if (counter==0){
oled.clearDisplay();
oled.setCursor(0,0);
oled.setTextColor(WHITE);
oled.setTextSize(2);
oled.println("Temp");
oled.println("Humidade");
oled.println("Luz");
oled.display();
previousStateCLK = currentStateCLK;
}

if (counter==1){
oled.clearDisplay();
oled.setCursor(0,0);
oled.setTextColor(WHITE);
oled.setTextSize(2);
oled.println(">Temp");
oled.println("Humidade");
oled.println("Luz");
oled.display();
previousStateCLK = currentStateCLK;
}

if (counter==2){
oled.clearDisplay();
oled.setCursor(0,0);
oled.setTextColor(WHITE);
oled.setTextSize(2);
oled.println("Temp");
oled.println(">Humidade");
oled.println("Luz");
oled.display();
previousStateCLK = currentStateCLK;
}

if (counter==3){
oled.clearDisplay();
oled.setCursor(0,0);
oled.setTextColor(WHITE);
oled.setTextSize(2);
oled.println("Temp");
oled.println("Humidade");
oled.println(">Luz");
oled.display();
previousStateCLK = currentStateCLK;
}

previousStateCLK = currentStateCLK;
}

The OLED via I2C is slow, it takes time. That why it is skipping the encoder.
A encoder is often used with a interrupt, at least one, and sometimes two.
Encoder library: https://www.pjrc.com/teensy/td_libs_Encoder.html

I agree with @Koepel .

Also the code to print to the OLED is a bit neiva. Clearing the display every time you want to print to it takes a lot of time. Better to update the OLED only when needed and only the line that needs updating. Clear any existing text on a line by drawing a solid block over the whole line and then updating it.

I note that you are printing almost the same thing for each count.

Naïve?

There is more to it. The sketch does not work.
I can not find a Youtube tutorial of Paul McWhorter about a rotary encoder

Here is the sketch in Wokwi: https://wokwi.com/projects/336288233654583890

Try rotating the encoder, it does not work.
Comment out the section in the loop() with "if (counter == 0)" and "counter == 1" and "counter == 2".
Then try it. It does not work either (maybe a little).

joaopnacabral, your sketch needs some work.
You can try to understand the rotary encoder. Wokwi can add a Logic Analyzer. You can also use the Encoder library. I think it is best to use that library.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.