I have a project I'm working on that needs to accomplish the following:
a user turns a wheel
depending on the direction of rotation, a linear actuator will be triggered moving up or down.
hardware:
Uno
100 point optical encoder
relays for triggering
linear actuator
I'm working on the following:
-the linear actuator will have limit switches to prevent the shaft from moving outside its design
-I need to prevent a user from rocking the wheel from side to side which would trigger the actuator quickly from up to down (it's being installed in a museum, I don't want to kill the actuator by kids playing with the control wheel)
I'm having problems dealing with the second point - keeping the relays from triggering back and forth if the wheel is rotated quickly from side to side. If I'm using interrupts to detect rotation and direction of rotation, how do I keep it from happening?
or another way to ask: if I turn the wheel clockwise, and the system detects clockwise, how do I keep the system from looking for rotation for 500ms (or however long I decided to run the actuator) while the actuator moves?
I tired poling the encoder using state change, and it was a mess because it takes so little rotation to trigger, I was getting false readings with the encoder inputs moving from High to Low.
I think this could be done using millis() timestamps. One for each direction. Every time you detect an encoder change save the timestamp for that direction. Before moving the actuator, check to see if it has been at least 500 ms since the last encoder change in the other direction.
Jimmus:
I think this could be done using millis() timestamps. One for each direction. Every time you detect an encoder change save the timestamp for that direction. Before moving the actuator, check to see if it has been at least 500 ms since the last encoder change in the other direction.
so something like:
read encoder position
log position
wait X millis()
read position
compare
if move actuator
wait x millis() (or actuator movement)
reset logged position
I think that'll work - thanks for the help! sometime you just gotta get a fresh set of eyes on a project to move forward.
One thing that may complicate matters is making the system work in a way that is intuitive to a "proper" user. Delays that create lags in movement can be very confusing and lead to just the sort of behaviour you want to avoid.
Maybe you could have a red LED that lights up if the user makes an inappropriate movement and then the user waits until the LED turns off before continuing. While the LED is lit all encoder inputs are ignored.
If you are polling the encoder fast enough, or using interrupts that are efficient enough, any change in the encoder state should tell you which direction it is moving. You could probably make the entire thing event driven:
Any time you get an encoder state change
determine the direction
save the timestamp for this direction
if it has been > 500 ms since the timestamp of the opposite direction, and we haven't hit the limit switch
start the actuator moving
Any time it has been > 100 ms since both timestamps
stop the actuator