statePin := gpioreg.ByName("GPIO20"),
dataPin := gpioreg.ByName("GPIO21"),
statePin.In(gpio.PullUp, gpio.BothEdges)
// I tried BothEdges on dataPin with no effect.
dataPin.In(gpio.PullUp, gpio.NoEdge)
Counter-Clockwise Turn
On a Counter-Clockwise Turn, things work as expected. statePin unblocks with an edgeEvent and state=low. Reading the dataPin returns High. statePin then unblocks again, and dataPin returns Low. Here's some output on a switch turn.
2021/08/10 16:31:50 rotaryHandler() unblocked. State: Low Last State: High Data: Low Last Data: High time (Nanos):...29 879 957
2021/08/10 16:31:50 rotaryHandler() unblocked. State: High Last State: Low Data: High Last Data: Low time (Nanos):...96 961 395
Clockwise Turn
A clockwise turn starts with the state line transitioning to low, and the Data lines SHOULD be LOW. The second event is the state line transitioning to high, and the data line should be HIGH. However, what I'm seeing is the data pin is high on both edge events.
2021/08/10 16:30:36 rotaryHandler() unblocked. State: Low Last State: High Data: High Last Data: High time (Nanos):...164 553 515
2021/08/10 16:30:36 rotaryHandler() unblocked. State: High Last State: Low Data: High Last Data: High time (Nanos):...248 856 352
Additional Information
The only thing that I can see is that the time between the transitions is "slightly" longer for a CW turn. Here's a time sample for four turns in each direction. I think the time difference could be explained by the geometry of the switch contacts.
CW Turn
84.5ms
94.1ms
90.5ms
100ms
CCW Turn
66.8ms
62ms
73ms
69ms
I suppose one theory is that for CW turns, the latency to read the data pin exceeds the time that the data pin remains low. For CCW turns, slightly different geometry makes the system work. Unfortunately, I don't have a digital signal storage oscilloscope (yet) that I could use to measure the widths.
I measured the time to execute both .Read() commands and it's around 4-5 ms. Perhaps the issue is a mixture of the geometry and the time for .WaitForEdge() to unblock.
Do you have any ideas on how I could address this? If you'd like, I can post the source that I'm working on. For my use, doing only CCW turns is a work-around, but I would like to figure out how to make it work in both directions.
Sorry for the length, but I'm trying to sort this out in my mind...
Description
Hardware: Raspberry Pi 4 OS: Raspbian w/ All Updates Go Version: 1.15.8 linux/arm
I'm running into a problem using the GPIO library. I'm using an Adafruit rotary switch and I can get the CCW turns working, but not the CW turns.
On the same device with the same switch, I can run a Java implementation using Pi4J, and both clockwise and counter-clockwise work as expected.
I'll explain how it works inline, but the best description is in the section labeled Quadrature Phase Shift Encoding here:
https://www.best-microcontroller-projects.com/rotary-encoder.html
I'm provisioning two pins:
Counter-Clockwise Turn
On a Counter-Clockwise Turn, things work as expected. statePin unblocks with an edgeEvent and state=low. Reading the dataPin returns High. statePin then unblocks again, and dataPin returns Low. Here's some output on a switch turn.
Clockwise Turn
A clockwise turn starts with the state line transitioning to low, and the Data lines SHOULD be LOW. The second event is the state line transitioning to high, and the data line should be HIGH. However, what I'm seeing is the data pin is high on both edge events.
Additional Information
The only thing that I can see is that the time between the transitions is "slightly" longer for a CW turn. Here's a time sample for four turns in each direction. I think the time difference could be explained by the geometry of the switch contacts.
CW Turn
84.5ms 94.1ms 90.5ms 100ms
CCW Turn
66.8ms 62ms 73ms 69ms
I suppose one theory is that for CW turns, the latency to read the data pin exceeds the time that the data pin remains low. For CCW turns, slightly different geometry makes the system work. Unfortunately, I don't have a digital signal storage oscilloscope (yet) that I could use to measure the widths.
I measured the time to execute both .Read() commands and it's around 4-5 ms. Perhaps the issue is a mixture of the geometry and the time for .WaitForEdge() to unblock.
Do you have any ideas on how I could address this? If you'd like, I can post the source that I'm working on. For my use, doing only CCW turns is a work-around, but I would like to figure out how to make it work in both directions.
Thanks.
George