Input Capture Unit¶
This module loads the Input Capture (icu) driver of the embedded device.
An Input Capture unit is a mcu peripheral that is able to read a digital signal on a pin and measure times between HIGH
and LOW
transition.
Imagine to have this signal on a digital pin:
HIGH _______ ________________ _________
| | | | | |
| | | | | |
_____| |__________| |___| |____ LOW
<------><----------><---------------><-><--------->
T0 T1 T2 T3 T4
Often it is very useful to know T0,T1, etc.. with a very good precision (such as in IR decoder). Writing a program that listens for transitions from HIGH
to LOW
or viceversa and saves the time passed in between can surely be done, but a modern mcu is usually equipped with a piece of hardware (being it a timer or a dedicated input capture unit) that can obtain the same result with almost no code and a staggering precision (in the order of sub-microseconds).
The icu module is a general interface with such mcu hardware.
init(drvname)
Loads the icu driver identified by drvname
Returns the previous driver without disabling it.
capture(pin, trigger, max_samples, time_window=1000, time_unit=MILLIS, pull=LOW, bits=-1)
Activates the Input Capture Unit on pin
and starts capturing the signal with the following constraints:
-
waits until the signal on
pin
is equal totrigger
. If trigger isLOW
the capture starts when a transitionHIGH
toLOW
is detected. Otherwise the capture starts when a transitionLOW
toHIGH
is detected. Synonyms forLOW
transition areHIGH_TO_LOW
orFALLING_EDGE
. Synonyms forHIGH
areLOW_TO_HIGH
orRISING_EDGE
. It is possible to select a trigger on any edge withBOTH_EDGES
. -
once the capture is started, the input capture units starts saving times at each transition.
-
the capture ends if
max_samples
are captured or iftime_window
expires, whichever condition verifies first. -
pin
is set to INPUT_PULLDOWN ifpull
is LOW else is set to INPUT_PULLUP
This function is blocking and returns a tuple of times expressed in microseconds as soon as the capture ends. The type of the returned value can be changed by setting bits
to a non negative value. If bits
is 0, a tuple is returned, the first item being the times, the second item being the digital value of pin
during the first captured time. If bits
is 1, the result is a tuple, the first item being the times, the second item being a tuple of zeros and ones representing the digital value of pin
during each captured time. Non negative values for bits
other than 0 and 1 are reserved and will be used in future enhancements of the function.
Imagine to have this signal on pin
:
HIGH _______ ________________ _________
| | | | | |
| | | | | |
_______| |__________| |___| |____ LOW (forever)
^ ^ ^ ^ ^ ^
edges 0 1 2 3 4 5
<------><----------><---------------><-><--------->
ms 7 10 16 3 9
Here are some examples:
import icu
# Case 1:
x = icu.capture(D3.ICU,HIGH,10,50)
# trigger is set to HIGH, so capture starts at edge 0
# x is (7000,10000,16000,3000,9000) --> result in microseconds
# Case 2:
x = icu.capture(D3.ICU,HIGH_TO_LOW,10,50)
# trigger is set to HIGH_TO_LOW, so capture starts at edge 1
# x is (10000,16000,3000,9000) --> result in microseconds
# Case 3:
x = icu.capture(D3.ICU,RISING_EDGE,10,18)
# trigger is set to RISING_EDGE, so capture starts at edge 0
# x is (7000,10000) --> time_window is 18 so after the first 18 ms,
# the capture ends
# Case 4:
x,y = icu.capture(D3.ICU,BOTH_EDGES,10,18,bits=1)
# trigger is set to BOTH_EDGES, so capture starts at first available edge, edge 0
# x is (7000,10000) --> time_window is 18 so after the first 18 ms,
# the capture ends
# y is (1,0) --> first captured time (7000) was HIGH, second captured time (10000) was LOW
Some boards have restrictions on how icu pins can be used, refer to the single board documentation for details.