-
Notifications
You must be signed in to change notification settings - Fork 23
Analog threshold improvements #141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
Thanks Andy. I think supporting seperate thresholds for rising and falling edge generation is desirable but I think there may be annother way of implementing it which is more general and possibly simpler. Rather than modifying the rising_threshold = hw.Analog_threshold(threshold=2000, rising_event='rising_edge')
falling_threshold = hw.Analog_threshold(threshold=1000, falling_event='falling_edge')
analog_input = hw.Analog_input(
pin='X5', name='Analog 1', sampling_rate=1000, thresholds=[rising_threshold, falling_threshold]
) or alternatively: analog_input = hw.Analog_input(
pin='X5', name='Analog 1', sampling_rate=1000, thresholds=[
{'threshold':2000, 'rising_event': 'rising_edge'},
{'threshold':1000, 'falling_event': 'falling_edge'}
]
) Supporting multiple thresholds on a single analog input was part of the rationale for seperating out the threshold into a seperate class. An advantage of this approach is that it would support implementing as many different threshold values as required, each capable of generating rising and/or falling edges, giving the user very rich control of event generation. A dissadvantage is it would incur somewhat higher overheads than your current implementation for a basic Schmitt trigger. What do you think? |
Yes, I like your suggestion and the first syntax. I took a swing at implementing it. An analog input can now have triggers added to it. A trigger can have a rising and/or falling event. I made a here is an example task: from pyControl.utility import *
from devices import Rotary_encoder
from pyControl.hardware import ValueTrigger, SchmittTrigger
high_trigger = ValueTrigger(threshold=9000, rising_event="crossed_high")
mid_trigger = ValueTrigger(threshold=8000, rising_event="crossed_mid", falling_event="crossed_mid")
low_trigger = ValueTrigger(threshold=7000, falling_event="crossed_low")
schmitt_trigger = SchmittTrigger(bounds=(1000, 5000), rising_event="run_start", falling_event="run_stop")
running_wheel = Rotary_encoder(
name="running_wheel",
sampling_rate=40,
output="velocity",
triggers=[high_trigger, low_trigger, mid_trigger, schmitt_trigger],
)
states = [
"idle",
]
events = [
"run_stop",
"run_start",
"crossed_low",
"crossed_mid",
"crossed_high",
"change_during_session", # trigger this event from the controls dialog
]
initial_state = "idle"
def idle(event):
if event == "change_during_session":
high_trigger.set_threshold(-1000)
schmitt_trigger.set_bounds((50, 200)) Previously, from what I could tell, threshold values could not be reconstructed from the data? I think you'd have to look at the task file or hardware definition. Now, especially since it is easier to adjust thresholds during a task, I think there should automatic logging of the thresholds. I did this crudely by adding a “trigger” subtype to the print MsgType, but hopefully you'll have a more elegant solution. Ideally the log should track the thresholds just like variables are tracked, i.e. it should show run_start values, all changes in the session, and run_end values. |
Thanks Andy, this looks good. A couple of thoughts:
Also, I have updated the dev branch to include the latest commits on master, could you update the pull request so it is based ont the current dev branch to make it easier to see which files have changed. |
- can now provide a upper and lower threshold - raise an error if a rising or falling event is provided without a threshold - raise errors if threshold(s) not provided correctly - add ability to change threshold(s) after task has started
fbe1609
to
1d57995
Compare
…backwards compatible
- uses new syntax for adding trigger - demonstrates ability to have multiple triggers
The following task code can be used for you to testing: from pyControl.utility import *
from devices import Rotary_encoder, SchmittTrigger
from pyControl.hardware import Analog_threshold
high_trigger = Analog_threshold(threshold=9000, rising_event="crossed_high")
mid_trigger = Analog_threshold(threshold=8000, rising_event="crossed_mid", falling_event="crossed_mid")
low_trigger = Analog_threshold(threshold=7000, falling_event="crossed_low")
schmitt_trigger = SchmittTrigger(bounds=(1000, 5000), rising_event="run_start")
running_wheel = Rotary_encoder(
name="running_wheel",
sampling_rate=40,
output="velocity",
triggers=[high_trigger, low_trigger, mid_trigger, schmitt_trigger],
)
states = ["idle"]
events = [
"run_stop",
"run_start",
"crossed_low",
"crossed_mid",
"crossed_high",
"change_during_session", # trigger this event from the controls dialog
]
initial_state = "idle"
def idle(event):
if event == "change_during_session":
high_trigger.set_threshold(-1000)
schmitt_trigger.set_bounds((50, 200)) |
Added an option to provide upper and lower thresholds for triggering the rising and falling events. This is particularly useful if you have a noisy signal and want to implement a software Schmitt trigger.
Also added a helper function
change_threshold()
for more easily adjusting the threshold after a task has started.