1
\$\begingroup\$

I am trying to read two 2 kHz (500 μs period) PWM waves (from two Hall-effect sensors) at two digital pins of an Arduino Nano 33 IoT simultaneously with on-duty ranging from roughly 30 to 70%.

One problem I have run into is noise in the form of PWM jitter when reading the on-duty cycle output of the waveforms.

I have implemented code (using interrupts) as below to decode the waveforms:

void RisingISR_1() { 
  pTime1 = micros(); // Start timer upon detection of Rising edge
  attachInterrupt(digitalPinToInterrupt(pin_r), FallingISR_1, FALLING); 
}

void FallingISR_1() { 
  dpwm_r = micros() - pTime1; 
  attachInterrupt(digitalPinToInterrupt(pin_r), RisingISR_1, RISING);
  Key_r_ISR_f = true; 
}

void RisingISR_2() {
  pTime2 = micros();
  attachInterrupt(digitalPinToInterrupt(pin_l), FallingISR_2, FALLING);
}

void FallingISR_2() { 
  dpwm_l = micros() - pTime2;
  attachInterrupt(digitalPinToInterrupt(pin_l), RisingISR_2, RISING);
  Key_l_ISR_f = true;
}

void setup() {
  pinMode(pin_r, INPUT); 
  pinMode(pin_l, INPUT);
  Serial.begin(9600); 
  attachInterrupt(digitalPinToInterrupt(pin_r), RisingISR_1, RISING); 
  attachInterrupt(digitalPinToInterrupt(pin_l), RisingISR_2, RISING);
}

In the main loop I basically read the dpwm_r and dpwm_l variables which give the on-duty cycle values in μs.

This works as expected, but I get jitter at the output in the form of 1 μs amplitude fluctuations with occasional random 3 μs peaks (up or down). I was wondering if anyone had any suggestions in terms of minimizing the jitter, as well as knowledge of what could be causing it and/or if there is a different method to implement this that would minimize it.

P.S. I know about/have used the PulseIn() function to read the PWM waves, but have avoided using it because it doesn't work well with reading two PWM waves at once and it is harder to control if I'm reading rising or falling.

I have also hypothesized it could be due to the way I have been using interrupts but this is the best I have managed to minimize the noise so far.

\$\endgroup\$
3
  • 4
    \$\begingroup\$ Have you tried using one of the SAMD21G's timers to get period and duty cycle of the sensor output? \$\endgroup\$
    – ocrdu
    Commented Feb 13 at 1:00
  • 2
    \$\begingroup\$ Exactly! These microcontrollers already bring exactly the peripheral you need to count the duration of the on and/or off cycles, and write them to a buffer in memory. I believe using Arduino as a software platform is undesirable in this context, as that makes no provisions for making management of that buffer feasible \$\endgroup\$
    – sina bala
    Commented Feb 13 at 1:02
  • 2
    \$\begingroup\$ All CMSIS interfaces are available, so using peripherals, DMA, the event system, etc. of the SAMD21G from C++ in the Arduino IDE is perfectly doable. Here's an (experimental) example that gets period and duty cycle from a signal using TCC1, the event system, and DMA. \$\endgroup\$
    – ocrdu
    Commented Feb 13 at 1:15

0