Hi ,
I'm working on a project that has a mechanical rotary encoder. The device is also supposed to be low power(<10uA) when in sleep. The encoder is also supposed to wake up the device so it's connected to the interrupt pins.
The problem I'm running into is the pull-up resistors. Unlike a button, the encoder can be left in a closed position meaning there is a current flowing through the pull-up resistor. I'm using 100k ones which is the highest I could go before it started acting funny but it still draws 40uA. that's 80uA if the encoder isn't left in a detent.
Sometimes the encoder falls into a position where neither of the resistors draws any current but it's not all that common. I've also played with the built-in pull-ups but it wasn't very helpful either. They just draw more current.
Is there any way to avoid this problem? Did someone else encounter the same issue? ???
Yes. it's atmega328P on a custom PCB. And yes they can both be grounded although it's unlikely as the encoder has detents and it would have to stay in a position between two detents.
How about this: use external pull-ups connected
to another pin configured as an output HIGH
when you need the encoder and set to input
when you don't. Then you can use another
pin with a push-button to wake up the uC.
Herb
The whole point of detents is to prevent the knob from coming to rest at a bad place. Your encoder should always come to rest at a detent, with both switches open. It seems that would have to be the case if the encoder will be used to wake up the Arduino.
Some encoders can have both switches closed or both switches open at a detent. These have half as many pulses per revolution as detents per revolution. What you should use is one with the same number of pulses and detents per revolution. And it should be almost impossible for it to come to rest between detents.
You need something like 5M pullups and 1nF capacitors on the encoder pins. The capacitors will stop noise pickup and should go to ground. That gives a time-constant of 5ms which ought to be quick enough for a rotary encoder switch. If the ATmega328 hysteresis isn't enough you might also need 74HC14 to provide a solid schmitt-trigger action.
The encoder I'm using is SIQ-02FVS3 and it's probably not the best one since whenever it's resting in a detent there is a 50/50 chance one of the switches will be closed.
I have to use this encoder due to its small size but I'm also putting a knob on it which adds a little extra weight which it was clearly not designed to handle. hence why it can rest in between two detents.
I'll try the 5M pull-ups with the capacitor and if it doesn't work I'll have to disable each pull-up that's grounded before going to sleep.
The first picture below is the functional diagram of your encoder from the datasheet. If taken literally, it appears to be possible that the lower switch could be either way at a detent. That's not a good design, and I'm not sure the drawing should be taken literally.
The more typical encoder will have detents as shown in red in the second picture, which will cause both switches to be open at a detent.
Anyway, for wakeup you probably want to rely only on the switch that's always open at a detent, assuming it's always the same switch. Or, you could just read both switches before sleeping and turn off the one that's low.
SOLVED. Thanks to everyone for the great suggestions. I often forget how wonderful this community is
THE SOLUTION that worked for me was basically what MarkT suggested:
You need something like 5M pullups and 1nF capacitors on the encoder pins. The capacitors will stop noise pickup and should go to ground. That gives a time-constant of 5ms which ought to be quick enough for a rotary encoder switch. If the ATmega328 hysteresis isn't enough you might also need 74HC14 to provide a solid schmitt-trigger action.
I used the same values he suggested and it just worked. 5ms was indeed enough. Even if it wasn't fast enough I could always just activate the internal pull-ups once the Arduino wakes up. The sleep current is about 1uA now which is just great. That's years of battery life. which is exactly what I was aiming for.
If I don't forget I'll also update this thread with the schematic, code and everything else once the project is finished. Hopefully it will help someone else too