Scroll through states using rotary encoder

Hello, this is my first Arduino project and I'm trying to have my LCD screen and rotary encoder scroll through a list of options on a screen. There are 14 options. My research showed that people used the remainder function and/or the state function, but I haven't had any luck figuring it out. Does anyone have sample code for a similar project?

The code I'm using so far has info about button presses and turns in the serial print, so I know my wiring is correct.

// Rotary Encoder Inputs
#define CLK 2
#define DT 3
#define SW 4

int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir ="";
unsigned long lastButtonPress = 0;

// Set up LCD screen
#include <Wire.h>

#include <SerLCD.h> //Click here to get the library: http://librarymanager/All#SparkFun_SerLCD
SerLCD lcd; // Initialize the library with default I2C address 0x72

// Set up Remainder operation
int values[14];
int i = 0;

void setup() {
  Wire.begin();

  lcd.begin(Wire); //Set up the LCD for I2C communication

  lcd.setBacklight(255, 255, 255); //Set backlight to bright white
  lcd.setContrast(5); //Set contrast. Lower to 0 for higher contrast.

  lcd.clear(); //Clear the display - this moves the cursor to home position as well
  lcd.print("Welcome, Pls Scroll");
  
  // Set encoder pins as inputs
  pinMode(CLK,INPUT);
  pinMode(DT,INPUT);
  pinMode(SW, INPUT_PULLUP);

  // Setup Serial Monitor
  Serial.begin(9600);

  // Read the initial state of CLK
  lastStateCLK = digitalRead(CLK);
}

void loop() {
  
  // Read the current state of CLK
  currentStateCLK = digitalRead(CLK);

  // If last and current state of CLK are different, then pulse occurred
  // React to only 1 state change to avoid double count
  if (currentStateCLK != lastStateCLK  && currentStateCLK == 1){

    // If the DT state is different than the CLK state then
    // the encoder is rotating CCW so decrement
    if (digitalRead(DT) != currentStateCLK) {
      counter --;
      currentDir ="CCW";
    } else {
      // Encoder is rotating CW so increment
      counter ++;
      currentDir ="CW";
    }

    Serial.print("Direction: ");
    Serial.print(currentDir);
    Serial.print(" | Counter: ");
    Serial.println(counter);
    lcd.clear();
    lcd.setCursor(0,0); // Defining positon to write from second row, first column
    lcd.print("Adios");
    lcd.setCursor(0,1); // Defining positon to write from second row, first column .
    lcd.print("Classic Daiquiri");
  }

  // Remember last CLK state
  lastStateCLK = currentStateCLK;

  // Read the button state
  int btnState = digitalRead(SW);

  //If we detect LOW signal, button is pressed
  if (btnState == LOW) {
    //if 50ms have passed since last LOW pulse, it means that the
    //button has been pressed, released and pressed again
    if (millis() - lastButtonPress > 50) {
      Serial.println("Button pressed!");
    }

    // Remember last button press event
    lastButtonPress = millis();
  }

  // Put in a slight delay to help debounce the reading
  delay(1);
}

Please post your attempts. The code you posted seems to not even try.

The logic is pretty simple - after an increment, check to see if it exceeds the bound, if so, reset.

What is so complicated about that?

Like I said, I'm a beginner, so everything is complicated. Here's one attempt I made.

 if (currentStateCLK != lastStateCLK  && currentStateCLK == 1){

    // If the DT state is different than the CLK state then
    // the encoder is rotating CCW so decrement
    if (digitalRead(DT) != currentStateCLK) {
      counter --;
      currentDir ="CCW";
      mixAdios();
    } else {
      // Encoder is rotating CW so increment
      counter ++;
      currentDir ="CW";
      mixClassicDaiquiri();
    }

This is the called function

void mixAdios() {
  lcd.clear();
  lcd.setCursor(0,0); // Defining positon on screen
  lcd.print("Adios");
}

void mixClassicDaiquiri() {
  lcd.clear();
  lcd.setCursor(0,0); // Defining positon on screen
  lcd.print("Classic Daiquiri");
}

That code also does not attempt to constrain the counter. Is that your actual problem or have I misunderstood?

In other words, there is nothing to prevent 'counter' from reaching astronomical values...

If you could explain how to use the remainder or state function to accomplish my goal, that's what I'm looking to solve on the forum

Why is that so important to you? It's not a magic bullet that will fix your flawed logic. What "state function" are you talking about? I've never heard of it.

Open to other suggestions

First you have to explain exactly what you are trying to do. Fishing for other ideas with what you have so far, won't help you here. Trust me. But if you don't like my advice, I'm out.

What is the remainder function? Is it the number of scrolls divided by .. ?

What is the state function? Is it for determining absolute encoder position?

If you want to know absolute encoder position you need a absolute encoder. Otherwise you can only know the relative position (since startup)

Briefly describe what you wanted to accomplish.

Do you have the counter incrementing/decrementing once for each encoder detent crossed?

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