Record encoder PWM on SD card and Replay at fast speeds

Hi all, i'm trying to record a PWM signal and save it to SD card and when button is pressed replay it on a pin. Any help is greatly appreciated.

The code should:
1)Record rising edge time and falling edge time of the PWM signal every time there is a change.

2)Save this data on a SD card possibly with a circular buffer to avoid lost of data.

  1. when a button is pressed replay on one of the Arduino pin's the same exact PWM signal recorded.
    (code should be very efficient in order to measure fast changes).

I tried using "Input Capture feature of the UNO" on Timer1 that is pin8, to accurately measure the falling edge time and rising edge time and print on serial. But is not giving consistent results. (For the PWM i'm using an encoder to send the varying PWM.)

This are some of the values when turning the encoder: (that don't make much sense: 0us or 38us, 2147483648us).

Rising to Falling: 0 us, Falling to Rising: 0 us
Rising to Falling: 0 us, Falling to Rising: 0 us
Rising to Falling: 38 us, Falling to Rising: 2147483648 us
Rising to Falling: 15970 us, Falling to Rising: 2147467648 us
Rising to Falling: 2147465728 us, Falling to Rising: 17921 us
Rising to Falling: 0 us, Falling to Rising: 0 us
Rising to Falling: 11 us, Falling to Rising: 2147483648 us
Rising to Falling: 2147470976 us, Falling to Rising: 12689 us
Rising to Falling: 0 us, Falling to Rising: 0 us


volatile unsigned long rising_edge_time = 0;
volatile unsigned long falling_edge_time = 0;
volatile bool rising_edge_captured = false;

void setup() {
  Serial.begin(115200);

  // Set up Timer1 for Input Capture
  TCCR1A = 0;                         // Reset Timer1 control registers
  TCCR1B = 0;
  TCCR1B |= (1 << ICES1);             // Enable Input Capture Noise Canceler
  TCCR1B |= (1 << CS11);              // Set prescaler to 8 (for 16MHz Arduino)
  TIMSK1 |= (1 << ICIE1);             // Enable Timer1 Input Capture Interrupt
  sei();                              // Enable global interrupts
}

void loop() {
  // Your main code here
}

ISR(TIMER1_CAPT_vect) {
  unsigned long current_time = ICR1;  // Get the captured timer value

  if (TCCR1B & (1 << ICES1)) {        // Check if the interrupt was triggered on rising edge
    rising_edge_time = current_time;
    rising_edge_captured = true;
    TCCR1B &= ~(1 << ICES1);          // Configure for falling edge capture
  } else {
    falling_edge_time = current_time;
    rising_edge_captured = false;
    TCCR1B |= (1 << ICES1);           // Configure for rising edge capture

    // Calculate and print the time intervals
    unsigned long rising_to_falling = falling_edge_time - rising_edge_time;
    unsigned long falling_to_rising = rising_edge_time - falling_edge_time;

    Serial.print("Rising to Falling: ");
    Serial.print(rising_to_falling);
    Serial.print(", Falling to Rising: ");
    Serial.println(falling_to_rising);
  }
}

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