Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4829

Beginners • Specific number of nanosecond pulses generation

$
0
0
I am new to Raspberry Pi. I am using a RPi 4 and I want to be able to generate a specific number of pulses with a time duration between 100 ns and 1 µs. The number of pulses I want to generate, `n_pulses`, varies between 1 and 1000. For my application I need the number of pulses to be very accurate, meaning that if I write `n_pulses=1` then one and only one pulse comes out. After doing some research and some tests, I came up with this code:

Code:

# Starting point: https://raspberrypi.stackexchange.com/a/113709/131225import pigpio # https://github.com/joan2937/pigpiofrom time import sleepfrom time import perf_counter_nsfrom timeit import default_timer as timerimport ctypeslibc = ctypes.CDLL('libc.so.6')def usleep(seconds):libc.usleep(int(seconds*1e6))def spinwait_us(seconds):target = perf_counter_ns() + seconds*1e6 * 1000while perf_counter_ns() < target:passdef brute_force_sleep(seconds):start = timer()while timer()-start < seconds:passclass PulseGenerator:PWM_FREQ = int(1000) # PWMfreq 1-125e6, http://abyz.me.uk/rpi/pigpio/python.html#PWMfreq, don't make the PWM frequency too high because it could fail in generating only one pulse, as we rely on the software to turn off the PWM in the middle of one cycle in order to get a single pulse.MAGIC_FACTOR = 1e6 # The factor `1e6` comes from http://abyz.me.uk/rpi/pigpio/python.html#PWMdutydef __init__(self, output_pin:int):self._output_pin = output_pinself._max_pulse_duration = PulseGenerator.PWM_FREQ**-1/2self._min_pulse_duration = 1/PulseGenerator.MAGIC_FACTOR/PulseGenerator.PWM_FREQ # This will happen when the "duty cycle" parameter is 1.self.PI = pigpio.pi()self.PI.hardware_PWM(self._output_pin, PulseGenerator.PWM_FREQ, 0) # Start the PWM hardware but outputing nothing (duty cycle = 0).def generate_pulses(self, pulse_duration:float, n_pulses:int):if pulse_duration > self._max_pulse_duration:raise ValueError(f'Pulse duration cannot be higher than {self._max_pulse_duration:.2e}, received {pulse_duration:.2e}. ')if pulse_duration < self._min_pulse_duration:raise ValueError(f'Pulse duration cannot be lower than {self._min_pulse_duration:.2e}, received {pulse_duration:.2e}. ')duty_cycle = int(PulseGenerator.MAGIC_FACTOR*pulse_duration*PulseGenerator.PWM_FREQ)sleep_time = 1/PulseGenerator.PWM_FREQ*(n_pulses-.1)self.PI.hardware_PWM(self._output_pin, PulseGenerator.PWM_FREQ, duty_cycle)brute_force_sleep(sleep_time) # We have faith that the program will make it, but this could fail if the processor is too busy.self.PI.hardware_PWM(self._output_pin, PulseGenerator.PWM_FREQ, 0) # The only way I found so far of stopping the PWM, setting a duty cycle of 0.if __name__ == '__main__':pulse_generator = PulseGenerator(12)while True:pulse_generator.generate_pulses(pulse_duration=100e-9, n_pulses=5)
This works, though the number of pulses fluctuates a bit. The reason is that I rely on the CPU to turn off the PWM generator after `n_pulses`, which is not accurate. As you can see, I have tried several sleep methods I found googling, and `brute_force_sleep` is the one that seems to be more accurate.

I also found the
- [original `nanopulse.c`](http://abyz.me.uk/rpi/pigpio/examples.h ... ted%20code)
- [modified `nanopulse.c`(https://gist.github.com/Hermann-SW/fd06 ... 8af5c87d4f)
but the modified `nanopulse.c` does not compile for me and the original `nanopulse.c` does not have the right timing, even after including all the modifications mentioned [here](viewtopic.php?t=191738).

Statistics: Posted by binary_pie — Wed Aug 21, 2024 5:00 pm



Viewing all articles
Browse latest Browse all 4829

Trending Articles