Hi,
I'm trying to migrate a project from a pro-mini to a mega.
I have a rotary encoder Rotary Encoder - Illuminated (RGB) - COM-15141 - SparkFun Electronics that works when connected to analogue pins 0 and 1 on the pro-mini.
When I wire it up to the Mega (sticking with analogue pins 0 and 1) it doesn't work (i.e. no output on serial monitor). Here's the code....
/* Rotary encoder read example */
#define ENC_A 14 // Analogue pin 0
#define ENC_B 15 // Analogue pin 1
#define ENC_PORT PINC // The Port C Input Pins register - read only. (Port C is the analogue input pins)
// this code from https://www.circuitsathome.com/mcu/programming/reading-rotary-encoder-on-arduino
// The encoder is this one.https://www.sparkfun.com/products/10982
// And the datasheet http://cdn.sparkfun.com/datasheets/Components/Switches/EC12PLRGBSDVBF-D-25K-24-24C-6108-6HSPEC.pdf
void setup()
{
/* Setup encoder pins as inputs */
pinMode(ENC_A, INPUT);
digitalWrite(ENC_A, HIGH); // turns on pull-up resistor on the pin so it won’t dangle in the air when switch is open
pinMode(ENC_B, INPUT);
digitalWrite(ENC_B, HIGH); // turns on pull-up resistor on the pin so it won’t dangle in the air when switch is open
Serial.begin (115200);
Serial.println("Start");
}
void loop()
{
static uint8_t counter = 0; //this variable will be changed by encoder input
int8_t tmpdata;
/**/
tmpdata = read_encoder();
if( tmpdata ) {
// If non-zero, the encoder is either rotating clockwise or counter clockwise
Serial.print("Counter value: ");
Serial.println(counter, DEC);
counter += tmpdata;
}
// Simulate the microprocessor doing something
delay(10);
}
/* returns change in encoder state (-1,0,1) */
/*
* -1 means clockwise, zero means 'invalid' and +1 means anti-clockwise.
* PREVIOUS CURRENT RESULT
* A B A B
* 0 0 0 0 -1 clockwise
*
*/
int8_t read_encoder()
{
static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; // This is a static array, the contents should
// remain unchanged.
static uint8_t old_AB = 0; // This is an 8 bit byte.
/**/
old_AB <<= 2; // remember previous state - shift each bit two places leftwards.
// Rightmost bits (bits 0 & 1) will now be set to 0,0.
// Example, if old_AB was 00000011, it will now be 00001100
old_AB |= ( ENC_PORT & 0x03 ); // add current state. (Remember, 0x03 = 00000011)
// The first bit "ENC_PORT & 0x03" reads the port to which encoder is connected and sets all but two lower bits to zero
// The 2nd bit, "old_AB |=" ORs the previous state with the new state. The previous state will now be in bits 2 &3, and the
// current state in bits 0 & 1.
// Test if anything has changed.
if ( (bitRead(old_AB,3) != bitRead(old_AB,1)) || (bitRead(old_AB,2) != bitRead(old_AB,0)))
{
//Serial.print(bitRead(old_AB,3));Serial.print(bitRead(old_AB,2));Serial.print(bitRead(old_AB,1));Serial.print(bitRead(old_AB,0));
int8_t result=enc_states[( old_AB & 0x0f )];
if (result == -1)
{
Serial.println(" clockwise.");
}
else if (result == 1)
{
Serial.println(" anti-clockwise.");
}
else
{
Serial.println(" invalid.");
}
}
// Remember, 0x0f = 00001111. Th first bit here "old_AB & 0x0f" simply resets the
// first 4 bits to zero, because we're only interested in the current and previous values.
// The 4 remaining bits, give us a number from 0 to 15, which is used as an index number to return a value from
// the enc_states[] array.
return ( enc_states[( old_AB & 0x0f )]);
}
The code is cribbed off the web somewhere, and despite the fact I'm using, i must admit there are a couple of bits I don't understand.
- The code works (on the pro mini) but ENC_A is defined as pin 14 and ENC_B as pin 15 - but the encoder is physically connected to analogue pins 0 & 1.
- What is PINC? the comments say it's the input pins register, but what does this mean?
- most importantly, why doesn't this work on the Mega?
Thanks