How do I use rotary encoder as dial with positions

Hi,

I want to use a 20 position rotary encoder as a sort of menu by having each position select something and then pressing the button built into the encoder to select it. I am new to this concept and would appreciate advice on how to have each position do something and make sure that there are only 20 options, not more. If I have overlooked something, I apologize. I am a noob at this.

Thanks in advance.

rainy_day

Look at a rotary encoder as a pair of buttons that, when pushed, increment or decrement a variable whose value varies between 0 and 19 (or 1 and 20).

Ok, I was hoping for code, but thanks for the concept. How would I do this in code?

From list of "useful links":
http://forum.arduino.cc/index.php?topic=261411.0
Includes code as well.

Thanks for that, but is there something simpler that is more suited to my project

rainy_day:
Thanks for that, but is there something simpler that is more suited to my project

Looks like that is eminently suited for your project. You need to know which way the encoder is turning and when each step is encountered and when you stop turning, you need to know that it at the current position for some period of time before recognizing this step is where you want to wait for a switch pressing.

This is NOT a rotary switch, as you well know.

Paul

#include <Bounce2.h>

/* 
 DESCRIPTION
 ====================
 Reads the 2 switches in an encoder, 
 determines direction,
 updates counter.
 No interrupts.
 Switches debounced, didn't test first, just did it anyway.
 */


const byte ENCODER_PINA= 2;
const byte LED_PINA= 12;
const byte ENCODER_PINB= 3;
const byte LED_PINB= 11;

int valueA; //debounced encoder switch reads
int valueB;

bool motionDetected = false;
int grossCounter = 0; // total steps
int nettCounter = 0;  // cw-ccw
int fullRevolutions = 0;
int surplusSteps = 0; //part revs
bool CW;

byte cyclesPerRev =20;  //check encoder datasheet

// Instantiate 2 Bounce object
Bounce debouncerA = Bounce(); 
Bounce debouncerB = Bounce(); 

// setup ********************************************
void setup() {
  Serial.begin(9600);
  Serial.println("Setup");
  // Setup the buttons
  pinMode(ENCODER_PINA,INPUT_PULLUP);
  pinMode(ENCODER_PINB,INPUT_PULLUP);


  // After setting up the button, setup debouncer
  debouncerA.attach(ENCODER_PINA);
  debouncerA.interval(5);
  debouncerB.attach(ENCODER_PINB);
  debouncerB.interval(5);

  //Setup the LED
  pinMode(LED_PINA,OUTPUT);
  pinMode(LED_PINB,OUTPUT);
  Serial.println("Setup done");
}

// loop *****************************************
void loop() {

  // Update the debouncers
  doDebounce();

  // Read the encoder switches
  doEncoderRead();

  // Update LEDs and serial print A, a, B, b
  updateLEDs();

  //determine direction and update counter

  updateCounter();

} //loop

// my functions **************************************************
void doDebounce()
{
  debouncerA.update();
  debouncerB.update();
} //doDebounce

void doEncoderRead()
{
  valueA = debouncerA.read();
  valueB = debouncerB.read();
} //doEncoderRead

void updateLEDs()
{

  if ( valueA == HIGH) {
    digitalWrite(LED_PINA, HIGH );
    //Serial.print("A");

  } 
  else {
    digitalWrite(LED_PINA, LOW );
    //Serial.print("a");
  }

  if ( valueB == HIGH) {
    digitalWrite(LED_PINB, HIGH );
    //Serial.println("B");
  } 
  else {
    digitalWrite(LED_PINB, LOW );
    //Serial.println("b");  
  }

} //updateLEDs

void updateCounter()
{

  /*
  the possibilites are:
   
   AB: in a detent
   if just arrived, update counter, clear motiondetected
   otherwise do nothing
   Ab: start of CW or end of CCW
   if start, set CW bool and set motionDetected
   if at end (know becasue motionDetected already set), do nothing
   aB: start of CCW or end of CW
   if start, clear CW bool and set motionDetected
   if at end (know becasue motionDetected already set), do nothing
   ab: in middle of either CW or CCW, do nothing
   */

  if (valueA && valueB && motionDetected ) //in a detent and just arrived
  {
    if (CW)
    {
      grossCounter= grossCounter + 1;
      nettCounter= nettCounter + 1;
  if (nettCounter > 19)
  nettCounter = 19;
    }
    else //CCW
    {
      grossCounter= grossCounter + 1;
      nettCounter= nettCounter - 1;
  if (nettCounter < 0)
  nettCounter = 0;
    }
    motionDetected = false;
    Serial.print("grossCounter: ");
    Serial.println(grossCounter);
    Serial.print("nettCounter: ");
    Serial.println(nettCounter);
    
    fullRevolutions = nettCounter / cyclesPerRev; 
    surplusSteps = nettCounter % cyclesPerRev;
    
    Serial.print("Nett position: ");
    Serial.print(fullRevolutions);
    Serial.print(" + ");
    Serial.println(surplusSteps);
    Serial.println(" ");
    
    


  }

  if (valueA && !valueB && !motionDetected ) // just started CW
  {
    CW= true;
    motionDetected=true;
    Serial.println("CW");

  }

  if (!valueA && valueB && !motionDetected )  //just started CCW
  {
    CW= false;
    motionDetected=true;
    Serial.println("CCW");

  }
} //updateCounter

It really does not get much simpler than this.
I copied the code from the link.
I changed it for your case (nettCounter stays between 0 and 19).

This is an advanced project for a self described "noob".

First, follow the tutorials that come with Arduino and learn how to read buttons, time events, blink an LED without using delay, etc.