Skip to content

machine: Add nchanges param to time_pulse_us func.#16160

Open
IhorNehrutsa wants to merge 1 commit into
micropython:masterfrom
IhorNehrutsa:time_hardware_pulse_us
Open

machine: Add nchanges param to time_pulse_us func.#16160
IhorNehrutsa wants to merge 1 commit into
micropython:masterfrom
IhorNehrutsa:time_hardware_pulse_us

Conversation

@IhorNehrutsa
Copy link
Copy Markdown
Contributor

@IhorNehrutsa IhorNehrutsa commented Nov 5, 2024

time_pulse_us(pin, pulse_level, timeout_us=1000000, nchanges=2, /)

If nchanges is 3, if the pin is initially equal to pulse_level then first
waits until the pin input becomes different from pulse_level.
Then if the current input value of the pin is different to pulse_level,
the function first waits until the pin input becomes equal to pulse_level,
then times the duration that the pin is equal to pulse_level.

The advantage is that there is no need for additional synchronization before measuring the pulse duration.
A little bit longer, but with higher accuracy.

The jitter of the pulse measurement process is about 5-15 μs on the ESP32 board.

Idia from @robert-hh #16147 (comment)

This function is used in DRAFT PR for tests
PWM from 10845 and time_hardware_pulse_us() and test from 16147. #16161
The tests results show the functionality of the function over the entire ESP32 PWM frequency range from 1Hz to 40MHz.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Nov 5, 2024

Code size report:

Reference:  docs/develop/porting: Update session log for example port. [9f396bb]
Comparison: machine: Add num_levels to time_pulse_us func. [merge of c3b0cfc]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:   +56 +0.007% standard
      stm32:   +12 +0.003% PYBV10
      esp32:   +16 +0.001% ESP32_GENERIC
     mimxrt:   +16 +0.004% TEENSY40
        rp2:   +24 +0.003% RPI_PICO_W
       samd:   +40 +0.015% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@robert-hh
Copy link
Copy Markdown
Contributor

Thanks for mentioning me. I considered creating that feature, but as optional argument to time_pulse_us() instead of a new method. That looks like a smaller change, even if the additional code size might be the same..

@IhorNehrutsa IhorNehrutsa force-pushed the time_hardware_pulse_us branch from f59833b to e29b760 Compare November 5, 2024 22:01
@codecov
Copy link
Copy Markdown

codecov Bot commented Nov 5, 2024

Codecov Report

❌ Patch coverage is 80.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 98.45%. Comparing base (9f396bb) to head (c3b0cfc).

Files with missing lines Patch % Lines
extmod/machine_pulse.c 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #16160      +/-   ##
==========================================
- Coverage   98.46%   98.45%   -0.01%     
==========================================
  Files         176      176              
  Lines       22811    22813       +2     
==========================================
+ Hits        22460    22461       +1     
- Misses        351      352       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@IhorNehrutsa IhorNehrutsa force-pushed the time_hardware_pulse_us branch from f25ae18 to b9d6cf0 Compare November 7, 2024 06:22
@IhorNehrutsa IhorNehrutsa force-pushed the time_hardware_pulse_us branch from b9d6cf0 to aa1cba8 Compare December 5, 2024 22:55
@IhorNehrutsa IhorNehrutsa changed the title machine: Add time_hardware_pulse_us function. machine: Add wait_opposite param to time_pulse_us func. Dec 5, 2024
@IhorNehrutsa IhorNehrutsa force-pushed the time_hardware_pulse_us branch 3 times, most recently from 90f267b to 28906bc Compare December 5, 2024 23:24
@IhorNehrutsa IhorNehrutsa force-pushed the time_hardware_pulse_us branch 2 times, most recently from dd7b953 to b6bcf72 Compare December 19, 2024 12:50
@IhorNehrutsa
Copy link
Copy Markdown
Contributor Author

Remove additionnal synchronization time_pulse_us() from tests/extmod_hardware/machine_pwm.py

@dpgeorge
Copy link
Copy Markdown
Member

After discussing with @projectgus , we feel that this is a useful enhancement but maybe not worth the cost in code size.

I think it would be possible to make this PR a lot simpler and less code size. I opened #17346 as a basis for that.

If #17346 is merged, then the additional argument added here could be generalised to a counter, eg:

machine.time_pulse_us(pin, pulse_level, timeout_us=1000000, num_levels=2)

With num_levels=2 it's the same behaviour as before. With num_levels=3 it waits for 3 level changes and that implements the behaviour in this PR. Higher values are possible, which allow more synchronisation.

@robert-hh
Copy link
Copy Markdown
Contributor

then the additional argument added here

It's not (yet) visible in PR 17346.

@dpgeorge
Copy link
Copy Markdown
Member

Now that #17346 is merged, this PR can be updated on that.

@IhorNehrutsa IhorNehrutsa force-pushed the time_hardware_pulse_us branch from 27486f2 to 694ddcd Compare May 4, 2026 14:54
Signed-off-by: IhorNehrutsa <Ihor.Nehrutsa@gmail.com>
Co-Authored-By: Robert Hammelrath <12476868+robert-hh@users.noreply.github.com>
@IhorNehrutsa IhorNehrutsa force-pushed the time_hardware_pulse_us branch from 1cdca1b to c3b0cfc Compare May 4, 2026 18:44
@IhorNehrutsa IhorNehrutsa changed the title machine: Add wait_opposite param to time_pulse_us func. machine: Add nchanges param to time_pulse_us func. May 4, 2026
Comment thread docs/library/machine.rst
The function returns -3 if there was timeout waiting for condition marked (***) above.
The function will return -2 if there was timeout waiting for condition marked
(*) above, and -1 if there was timeout during the main measurement, marked (**)
(**) above, and -1 if there was timeout during the main measurement, marked (*)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's quite tricky to document the nchanges parameter.

I think the original description should remain unchanged. And then add a paragraph at the end stating something like "The above behaviour is for when nchanges=2. That behaviour can be generalised by passing in a larger value for nchanges which is the number of times the function waits for the pin to change. On error the return value can be down to -nchanges and indicates how many edges were missed." Or something like that.

Comment thread extmod/machine_pulse.c
nchanges = mp_obj_get_int(args[3]);
}
mp_uint_t us = machine_time_pulse_us(pin, level, timeout_us, nchanges);
// May return -1 or -2 or -3 in case of timeout
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment needs adjusting because the return value can be between -nchanges and -1 (on timeout).

time_pulse_us(pulse_in, level, timeout)
for _ in range(n_averaging):
t += time_pulse_us(pulse_in, level, timeout)
t += time_pulse_us(pulse_in, level, timeout, 3)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this code should stay as it was, because inside this loop you don't need to wait for an extra change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extmod Relates to extmod/ directory in source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants