Rotary encoder on analog pins (as digital) does not work (Arduino Uno)

Hi,

I’m trying to read the pins of a rotary encoder with analog pin A4 and A5 used as digital pins (18 and 19).

The purpose is to turn the volume of the sound up and down. I’m using the Mozzi audio library.

The sketch works without any problem when using digital pins, but does not work when using analog pins.

I think the problem does not come from the Mozzi audio library because I made a sketch to test the encoder without including any library and I get the same problem.

I can also say that I tried with a simple push button (reading it from A5 as digital 19) for turning on and off a led and it worked fine.

I post here (in GENERAL) and not in AUDIO because I think the problem is not related to the audio library I 'm using.

Hope I was clear enough. If not, just ask.

Here is the sketch :

#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/sin2048_int8.h
#define CONTROL_RATE 128
Oscil <2048, AUDIO_RATE> aSin(SIN2048_DATA);

byte volume = 0;
int a_input = 18; //A4
int b_input = 19; //A5
int aLastState;
int bLastState;
int aState;
int bState;

void setup() {
  pinMode(a_input, INPUT);
  pinMode(b_input, INPUT);
  
  aLastState = digitalRead(a_input);
  bLastState = digitalRead(b_input);
  
  aSin.setFreq(440);
  startMozzi(CONTROL_RATE);
}

void updateControl(){
  // Update volume
  aState = digitalRead(a_input);
  bState = digitalRead(b_input);
  
  if(aState != aLastState){
    if((digitalRead(a_input) == 0) && (digitalRead(b_input) == 1)){
      if(volume <= 240) volume = volume + 10;
    }
  } else if(bState != bLastState){
    if((digitalRead(a_input) == 1) && (digitalRead(b_input) == 0)){
      if(volume >= 10) volume = volume - 10;
    }
  }
  aLastState = aState;
  bLastState = bState;
}

int updateAudio(){
    return ((int)aSin.next() * volume) >> 8; // shift back into range after multiplying by 8 bit value
}

void loop() {
  audioHook();
}

The pins make no difference. It's something else. Tell us your expected behavior and the behavior you are experiencing.

In UpdaeControl you perform a Read and save the value, then compare teh value to a stored value, then perform a read again - Why?

void updateControl(){
  // Update volume
  aState = digitalRead(a_input);
  bState = digitalRead(b_input);
 
  if(aState != aLastState){
    if((digitalRead(a_input) == 0) && (digitalRead(b_input) == 1)){
      if(volume <= 240) volume = volume + 10;
    }
  } else if(bState != bLastState){
    if((digitalRead(a_input) == 1) && (digitalRead(b_input) == 0)){

Surely

void updateControl(){
  // Update volume
  aState = digitalRead(a_input);
  bState = digitalRead(b_input);
 
  if(aState != aLastState){
    if((aState == 0) && (bState == 1)){
      if(volume <= 240) volume = volume + 10;
    }
  } else if(bState != bLastState){
    if((aState) && bState == 0)){

would be simpler and avoid the chance that the readings are different.

Not sure whether this will affect the results or address your problem.

#include <tables/sin2048_int8.h
#define CONTROL_RATE 128
Oscil <2048, AUDIO_RATE> aSin(SIN2048_DATA);

This looks wonky. The include is not properly terminated and I believe you need a ‘’ to continue a statement on the next line.

Thanks for your replies.

I decided to use a rotary encoder library and it works now. Don't know what was the problem but I don't care anymore, the library does the job.

The library is : https://github.com/brianlow/Rotary

jowell88: I decided to use a rotary encoder library

I don't know the one you are using. This Encoder Library is known to be super robust and efficient. (just in case you need high performance)