Search code examples
c++arduino

Arduino read pulse-width frequency and duty cycle from a single digital input


I'm new to Arduino and coding, but have done all the tutorials and think I'm getting a grasp on how it all works.

I have a real-world problem that I'd love to solve with the arduino.

I have a PWM signal from a fuel injector on a gasoline engine that I need to derive two separate logical functions from inside the arduino.

Determine the delay between each rising edge (to derive engine RPM) range between 6ms - 120ms between rising edges and read pulse-width Duty Cycle (to determine the fuel injector's duty cycle) Pulsewidth range from 0.02ms to over 10ms for the pulse lengths.

these need to be represented independently in the logic as "RPM" and "Pulse Width"

I have read this blog about "secrets of Arduino PWM" and find it informative on how to WRITE pulse-width outputs of varying frequency and duty cycle, but I am trying to READ pulse-widths of varying frequency and duty cycle to create a variable byte or int to use for each.


Solution

  • Correct there is not a lot on timing pulse inputs or alike. Where the Arduino's ATmega can capture the timing of each side of the duty cycle by the below methods. And it will be up to the code to put them together and consider them a PWM for your needs.

    There are several methods with examples.

    1. Tight loop polling of the timed events. Such as with PulseIn

    2. A better method is to create a timer1 overflow interrupt and during that ISR pull the pin. This is the original method that Ken Shirriff's Infrared Library works - 50ms pull shirriff IR Library where its resolution is only as good as the overflow.

    3. Use Pin Change Interrupts ISR to get the time. Where it will be slightly latent. Where microtherion's fork of Ken's IR library converted the overflow to PinChangeInt. Where MicroTherion's code did this discretely in the library. Where the PinChangeInt library makes it simpler.

    4. Use the Timer Input capture. In short when the corresponding input pin changes the system clock is captured and an interrupt is issued. So the ISR can latently get the exact time it occurred. InputCapture.ino