Nano 33 IOT: Serial Monitor Glitches when using rising and falling ext HW interrupts to interpret PWM waveforms

Hi all,

Basically I am having trouble getting a consistent, clean serial monitor output of data I am getting from 2 external 2khz PWM waves (produced by 2 different sensors) I am analyzing using external HW interrupts.

Some more detail: I am using 4 external HW interrupts (basically 2 pairs) to measure the on time of each PWM wave in microseconds. I display the microsecond values of each along with a microsecond timestamp as CSVs in the serial monitor however there are often glitches in what the serial monitor prints. Sometimes data is skipped when printing and sometimes numbers get attached to previous numbers when they should not and the serial monitor prints a very large number (newline in println() or a comma can get 'skipped' from printing if you know what I mean). But it does not seem consistent as to what is skipped and when. This is a big problem as I am using Tera Term to save the serial monitor output exactly as it is printed an save it to a CSV file on my desktop. My goal is to cleanly analyze this data in CSV format in excel (or Matlab) but I must have 3 columns without missing or agglutinated numeric values that can mess up data analysis down the road.

I have tried using delays in the code to allow the serial monitor to 'have time' to print everything out without skipping values. I have also put flags in my code to force the serial monitor to print only once an entire PWM waveform has been captured from a given sensor. However, none of the above have seemed to fix the issue. Does anyone know of a good fix for this issue or have any ideas? Also does anyone know of an alternative method to save data to a CSV that doesn't rely on Tera Term or other software?

Thank you!!

My code here:

#include <stdio.h>

//Interrupt Specific Parameters
volatile float dpwm1; //duration of pin 1 PWM in microseconds 
volatile float pTime1;
volatile float dpwm2; //duration of pin 2 PWM in microseconds
volatile float pTime2;

//Other Variables
int pin1 = 3; 
int pin2 = 10;
float FS_threshold = 500.0;
bool X1_Val = false;
bool X2_Val = false;

//ISR FUNCTIONS
void RisingISR_1() { //ISR that emulates functionality of pulseIn()
  pTime1 = micros();
  attachInterrupt(digitalPinToInterrupt(pin1),FallingISR_1,FALLING);
  }

void FallingISR_1() { 
  dpwm1 = micros() - pTime1;
  attachInterrupt(digitalPinToInterrupt(pin1),RisingISR_1,RISING);
  }
  
void RisingISR_2() { 
  pTime2 = micros();
  attachInterrupt(digitalPinToInterrupt(pin2),FallingISR_2,FALLING);
  }

void FallingISR_2() { 
  dpwm2 = micros() - pTime2;
  attachInterrupt(digitalPinToInterrupt(pin2),RisingISR_2,RISING);
  }

void setup() {
  pinMode(pin1, INPUT);
  pinMode(pin2, INPUT);
  Serial.begin(9600); 
  attachInterrupt(digitalPinToInterrupt(pin1),RisingISR_1,RISING);
  attachInterrupt(digitalPinToInterrupt(pin2),RisingISR_2,RISING);
}
 
void loop() {
    if (dpwm1 <= FS_threshold) {
          X1_Val = true;
      }
    
    if (dpwm2 <= FS_threshold)  {
          X2_Val = true; 
      }
    
    if (X1_Val && X2_Val) { //flags for both interrupts should both be true..
    Serial.print(micros()); //Timestamp
    //delayMicroseconds(800); //delays here to try to change the serial monitor output
    Serial.print(",");
    //delayMicroseconds(800);
    Serial.print(dpwm1); //HE1 Value 
    //delayMicroseconds(800);
    Serial.print(",");
    //delayMicroseconds(800);
    Serial.println(dpwm2); //HE2 Value 
    }
    delayMicroseconds(800);
    X1_Val = X2_Val = false;
}

You do realize that Serial.print(), which is slow in practice, is using interrupts. So while you are busy printing, interrupts could be disabled causing you to miss pin 1 and pin2 interrupts.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.