Skip to content

machine: Add nchanges param to time_pulse_us func. - #16160

Open
IhorNehrutsa wants to merge 6 commits into
micropython:masterfrom
IhorNehrutsa:time_hardware_pulse_us
Open

IhorNehrutsa wants to merge 6 commits into
micropython:masterfrom
IhorNehrutsa:time_hardware_pulse_us

Conversation

@IhorNehrutsa

@IhorNehrutsa IhorNehrutsa commented Nov 5, 2024 •

Copy link
Copy Markdown
Contributor

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

github-actions Bot commented Nov 5, 2024 •

Copy link
Copy Markdown

Code size report:

Reference:  esp32/machine_sdcard: Expose SDMMC host bus slot width in board config. [1a4df82]
Comparison: Update machine_pwm.py [merge of 9b147ab]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:   +40 +0.005% standard
      stm32:    +8 +0.002% PYBV10
      esp32:   +68 +0.004% ESP32_GENERIC
     mimxrt:    +8 +0.002% TEENSY40
        rp2:   +24 +0.002% RPI_PICO_W
       samd:   +40 +0.014% 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

codecov Bot commented Nov 5, 2024 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.55%. Comparing base (49fe174) to head (9b147ab).
⚠️ Report is 5 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #16160   +/-   ##
=======================================
  Coverage   98.55%   98.55%           
=======================================
  Files         179      179           
  Lines       23244    23246    +2     
=======================================
+ Hits        22908    22910    +2     
  Misses        336      336           
Flag Coverage Δ
unix-coverage-32bit 98.55% <100.00%> (-0.01%) ⬇️
unix-coverage-64bit 98.48% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 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 2 times, most recently 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 Outdated
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).

Comment thread tests/extmod_hardware/machine_pwm.py Outdated
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.

@IhorNehrutsa IhorNehrutsa Jul 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

nchanges=4 works, nchanges=2 don't works

@dpgeorge

Copy link
Copy Markdown
Member

@IhorNehrutsa there are some review comments above that need to be addressed before this PR can move forward.

@IhorNehrutsa
IhorNehrutsa force-pushed the time_hardware_pulse_us branch 2 times, most recently from 0682017 to d887a4f Compare July 13, 2026 10:39
@IhorNehrutsa
IhorNehrutsa force-pushed the time_hardware_pulse_us branch 3 times, most recently from 3b28814 to eefa846 Compare July 15, 2026 13:36
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, 4)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

On esp32 generic board if nchanges=4 works, if nchanges=2 or 3 don't works.
@robert-hh
If you have time, could you test tests/extmod_hardware/machine_pwm.py on the mimxrt port?
Thanks.

@IhorNehrutsa
IhorNehrutsa force-pushed the time_hardware_pulse_us branch from eefa846 to da6c42a Compare July 22, 2026 09:20
@IhorNehrutsa
IhorNehrutsa force-pushed the time_hardware_pulse_us branch from da6c42a to 9b147ab Compare July 22, 2026 09:36
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