Issues with interrupt triggered by IR receiver

I am currently working on a project to reverse engineer the Valve Base Stations, with the hope of being able to create my own compatible trackers.

I made a simple program which detects IR pulses and outputs the time taken for each HIGH and LOW pulse, and that worked fine. However, I only need to measure the time between HIGH pulses, so I tried using an interrupt which runs whenever the IR receiver detects a HIGH pulse, and starts counting when the signal becomes LOW again.

I know there are libraries out there to detect signals from remotes and convert them straight to hexadecimal, but this wouldn't work in my case as the Base Stations do not use the same protocols included with these.

int receiverPin = 2;

volatile unsigned long duration;

void setup() {
  Serial.begin(9600);
  pinMode(receiverPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(receiverPin), measureTime, RISING);
}

void loop() {
  
}

void measureTime() {
  duration = pulseIn(receiverPin, LOW, 2000);
  Serial.println(duration);
}

I get the expected times in the serial monitor when testing the code with a TV remote, but the results are all separated by a random number of 0s. For example: (Using code format for output because its quite long)

0
0
0
639
1231
639
641
639
640
1237
641
1238
1235
1237
639
642
0
0
0
638
1237
0
0
0
638
640
0
0
0
640

It seems as though the interrupt is running when it shouldn't. I tried fixing the problem by increasing the timeout of pulseIn(). This got rid of most of the 0s, but caused another problem where a bunch of random data would appear at random times.

Am I using the interrupt completely wrong? I researched other ways to do this but I couldn't find another way to run the code only when the IR receiver detects a signal.

I am using an Arduino Nano with a VS1838B, the board is being powered through the USB cable.

Thoomas,
According to this link, pulsein returns 0 after timeout.
Are you sure your pulses are arriving before timeout?

Thanks

Yes, I am sure. As I said originally, I've tried increasing the timeout as high as it can go but a similar issue occurs.
After receiving the data I expect, the Arduino also outputs a bunch of random data without the interrupt being called.

How is your IR sensors connected to the arduino input?
Is it possible that the input is triggered due to noise?

I checked the input with an oscilloscope and the sensor seems very reliable.

As it turns out my arduino was faulty and ended up completely dying. I replaced it and now everything works fine, no more random interrupts.

Thank you for your help, I should've checked these things from the start.

Try this, to avoid doing pulseIn() and Serial.println() inside an ISR. Switch 'millis()' to 'micros()' if you want more resolution.

const int ReceiverPin = 2;

volatile unsigned long TimeBetweenRisingEdges;

void setup()
{
  Serial.begin(9600);
  pinMode(ReceiverPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(ReceiverPin), measureTime, RISING);
}

void loop()
{
  unsigned long duration;
  noInterrupts();
  duration = TimeBetweenRisingEdges;
  TimeBetweenRisingEdges = 0;
  interrupts();

  if (duration != 0)
    Serial.println(duration);
}

void measureTime()
{
  static unsigned long PreviousRisingEdgeTime = 0;
  unsigned long risingEdgeTime = millis();  // Change to micros() for more resolution

  TimeBetweenRisingEdges = PreviousRisingEdgeTime - risingEdgeTime;
  PreviousRisingEdgeTime = risingEdgeTime;
}

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