Absolute Binary Rotary Encoder (#27804)
jmspaggi
Posts: 629
Hi all,
I'm trying to use the Absolute Binary Rotary Encoder (#27804) as a scroll input. Like the mouse middle-wheel.
The problem with this encoder is that they did not used the right way to do it.
It should have been something like:
0 = 000
1 = 001
2 = 011
3 = 010
4 = 110
5 = 111
6 = 101
7 = 100
(but with 4 digits)
That way, when you change from one position to another one, you just have to wait for one digit to change, then you know where you go.
With the 27804, 9 is 1001. To go to A, it needs to change the 2 last digits to be 1010. But as they said, all the digits are not going to move at the same time... So you can read 1000 before 1010, and think the user is going down instead of up.
I'm trying to translate that in SPIN, and I have some troubles.
Here is what I did.
The idea is to add a timeout. So if there is some changes on the bits, I wait them to stabilize for 100ms before taking any action. It's working prety fine, but even with that, when I scroll on the screen, sometime it's wrong and going back-way If I scroll to fast, then I miss the value because I'm waiting for the timeout, and I don't know anymore which direction the user is trying to go to.
Does anyone have already tried to use this "switch" with the prop? Any idea how I can simulate an infinit-scroll-wheel with it?
Thanks,
JM
I'm trying to use the Absolute Binary Rotary Encoder (#27804) as a scroll input. Like the mouse middle-wheel.
The problem with this encoder is that they did not used the right way to do it.
It should have been something like:
0 = 000
1 = 001
2 = 011
3 = 010
4 = 110
5 = 111
6 = 101
7 = 100
(but with 4 digits)
That way, when you change from one position to another one, you just have to wait for one digit to change, then you know where you go.
With the 27804, 9 is 1001. To go to A, it needs to change the 2 last digits to be 1010. But as they said, all the digits are not going to move at the same time... So you can read 1000 before 1010, and think the user is going down instead of up.
I'm trying to translate that in SPIN, and I have some troubles.
Here is what I did.
PUB getStatus : result | scrollValue, oldScrollValue inputStatus := ina & (PIN_UP | PIN_DOWN | PIN_LEFT | PIN_RIGHT | PIN_SELECT | PIN_SCROLL_1 | PIN_SCROLL_2 | PIN_SCROLL_3 | PIN_SCROLL_4) scrollValue := (inputStatus & (PIN_SCROLL_1 | PIN_SCROLL_2 | PIN_SCROLL_3 | PIN_SCROLL_4)) >> 8 if scrollValue <> lastMoveValue lastMoveTime := cnt lastMoveValue := scrollValue result := 0 else if cnt > lastMoveTime + 100 * ms result := 0 oldScrollValue := (inputPreviousStatus & (PIN_SCROLL_1 | PIN_SCROLL_2 | PIN_SCROLL_3 | PIN_SCROLL_4)) >> 8 if (scrollValue == 15) AND (oldScrollValue == 0) result := 1 inputPreviousStatus := inputStatus elseif (scrollValue == 0) AND (oldScrollValue == 15) result := -1 inputPreviousStatus := inputStatus elseif scrollValue - oldScrollValue == 1 result := -1 inputPreviousStatus := inputStatus elseif oldScrollValue - scrollValue == 1 result := 1 inputPreviousStatus := inputStatus
The idea is to add a timeout. So if there is some changes on the bits, I wait them to stabilize for 100ms before taking any action. It's working prety fine, but even with that, when I scroll on the screen, sometime it's wrong and going back-way If I scroll to fast, then I miss the value because I'm waiting for the timeout, and I don't know anymore which direction the user is trying to go to.
Does anyone have already tried to use this "switch" with the prop? Any idea how I can simulate an infinit-scroll-wheel with it?
Thanks,
JM
Comments
Only one bit position changes for any step the encoder makes as you turn it. No race conditions occur with gray code and confuse your code trying to decode it.
A good article is in the nuts and volts section
Column #6, May 2010: Spinning Up Fun with Encoders
wait until a change happens, read it, wait 100ms read again, repeat until you get 2 readings the same.
That's what I did, but if the user scroll to fast, then you skip all the values
Let's imagine the user scroll from 0 to 9 at 99ms per step...
So you read 0, them you read 9. Was it asking to move forward? Or backward? You can't know.
Same if he move from 0 to 5. Was it going from 0 to 15 to 14... to 5? Or from 0 to 1 to 2 ... to 5?
So far, I removed this switch from my projet since I absolutly don't know how to handle it I have the 5 position switch, and will implement a hold/repeat feature to handle the scrolling.
JM
First - such encoders are typically rated for 120 RPM max - so you should not expect it working properly at higher speeds
Second - such encoders normally are designed to have short bounce time compared to regular switches. All I have seen stop bouncing in under 5 ms (though SMR8016 datasheet does not specify bounce time). So, for debouncing you read the position until you get stable reading for, say, 10 ms. To catch the situation when the bouncing has stoppped, but not all contacts have triggered yet (very unlikely) - you see how much the reading changed related to last known "good" reading. If that is +/-1 - you know the direction, otherwise - discard this new reading and go to debouncing again.
I tried by moving very slowly, and I still have some strange and unexpected behaviours
Here is what I did:
Basicaly, I wait until I'm able to read the same value for more than 50ms, then I handle it. Even with that, I still see sometime my cursor jumping up instead of moving slowing down.
I tried to increase the delay, but result is still the same.
Is there something wrong into my code?
Thanks,
JM
Also, I tried the oposite. Which is updating it only when result is zero. Not very nice result too
JM
This may be a bit harsh, but I have to ask if anyone bothered to ReadTheManual here? The 27804 is an ABSOLUTE POSITION encoder. Its says so in its name, it screams to you when you look at the chart on page 2 of the manual. The silence in the manual is deafening in its failure to mention anything about Grey Code. The code samples just simply read four bits and print the value (0-15).
The 27804 is 'absolutely' the wrong encoder for what you want. The 27805 is what you want ... and it's half the price of the 27804!
cheers ... BBR
Obviously, the correct one for the task is an incremental encoder. But I do not see reasons why absolute encoder cannot do the job with right software
We refered many times to the manual, so we know exactly how it's working.
We are just trying to see if there is a way to use it differently.
JM