What if i want to use two rotary encoders on UNO, NANO etc?
I building a frequency generator, with ad9833 the output will also be plugged in pin 5 to use freqcount and measure it.
The generator will have an encoder to increase/decrease frequency, and another to change the scale (x1,x10,x100,x1000...) the first encoder will increase 1*scale.
So i faced the problem that all examples using rotary encoders, uses pins 2 and 3 (on nano) which are the only interrupt pins, if I use any other pins, will it be a problem? (i only have one rotary, but more are on the go, so i cant test yet)
If its a problem, how to solve it? i saw one library that clains to use 4 rotary encoders at same time, but, some parts of the code have conficts with freqcount.
the main question its, why its needed to use interrupt pins? i mean, if the behaviour its like a push button, i can use a push button on any pin, why not rotary encoder "push button"?
So I assume that it is manually operated, at low pulse rate. Then it's not required to use interrupts, in detail if mechanical contacts deserve debouncing.
Yes, it will be manually operated both encoders, the scale encoder will change almost like 1 or 2 Hz, and the other maybe could get .. what to say, 100Hz? on dont know if i could speed it more than that
xD
So if i understood it, interrupts are mandatory if the encoder will click at a very high speed? like measuring an engine?
It is possible to use a single timer interrupt to handle as many rotary encoders as you have. The example here uses the timer interrupt to sample the encoder pins to detect rotation. The interrupts occur every 1.024 ms, and the pins are sampled every 10 interrupts. This will provide debouncing of mechanical contacts. You won't be able to use PWM on pin 6, as that timer channel is used for the interrupt. The code works for UNO/NANO. The example handles one encoder but can be easily expanded or altered.
#define phaseA 2 // Pins for the encoder
#define phaseB 3
volatile int position;
volatile bool lastPhaseA, lastPhaseB;
void setup() {
Serial.begin(9600);
lastPhaseA =digitalRead(phaseA); // initial values
lastPhaseB = digitalRead(phaseB);
// Initialize interrupt
// Configure OC0A for an interrupt
OCR0A = 128; // Interrupt occurs midway between Arduino time interrupts
TIMSK0 |= 1 << OCIE0A; // Enable the interrupt
}
void loop() {
static int oldPosition;
int pos;
cli();
pos = position; // atomic reference
sei();
if (pos != oldPosition) {
oldPosition = pos;
Serial.println(pos);
}
}
ISR(TIMER0_COMPA_vect) {
// Check to see if a pin has changed
static uint8_t cnt; // check every 10 interrupts
if (cnt-- == 0) {
bool a = digitalRead(phaseA);
bool b = digitalRead(phaseB);
cnt = 10;
if (lastPhaseA != a) {
position += (a == b) ? -1 : 1;
lastPhaseA = a;
}
if (lastPhaseB != b) {
position += (a == b) ? 1 : -1;
lastPhaseB = b;
}
}
}