The pulseIn() function is not at all suitable for reading consecutive HIGH and LOW times. When it reads a HIGH pulse it doesn't return until the signal goes LOW. After that it is too late to read a LOW pulse because pulseIn() will wait until the end of the next HIGH pulse to start timing.
CHANGE interrupt. If the pin is HIGH it was a rising edge. If the pin is LOW it was a falling edge.
In this case, it doesn't even matter much if the edge is rising or falling since all of the states must be 500 milliseconds (+/- 25). If you get a rising edge followed by 6 changes at the required intervals, the pattern is present.
Here is an example of how it might be done on an External Interrupt pin (pin 2, in this case). NOTE: This looks for three HIGH pulses with two LOW pulses between. Changing the desired count to 7 would require the third LOW pulse to be followed by a HIGH at the expected time.
volatile bool PatternFound = false;
void ChangeISR2()
{
unsigned long currentMicros = micros();
static unsigned long previousMicros = 0;
static byte changeCount = 0;
int pinState = digitalRead(2);
if (changeCount == 0)
{
if (pinState == HIGH) // First rising edge
{
changeCount = 1;
previousMicros = currentMicros;
}
}
else
{
unsigned long elapsedMicros = currentMicros - previousMicros;
if (elapsedMicros < 475000ul || elapsedMicros > 525000ul)
{
// Pulse or gap too long or too short
changeCount = 0;
if (pinState == HIGH) // A new 'First rising edge'
{
changeCount = 1;
previousMicros = currentMicros;
}
}
else
{
// Valid pulse or gap
changeCount++;
previousMicros = currentMicros;
if (changeCount == 6)
{
changeCount = 0;
PatternFound = true;
}
}
}
}
In this case, I intend to read IC CMX673 output data, the expected data is 500 millisecond HIGH and 500 millisecond LOW. With a slight tolerance (+/-25).
To ensure that the HIGH and LOW statuses are correct, I think there are at least three identical HIGH LOW patterns, so the pattern is considered correct.
I'm still confused with the interrupt function.
Sorry if this is a stupid question: what if the Digital Input used as the Input Signal is not read on PIN2? Can you use the interrupt function like the code you wrote?
I really appreciate your time to take time to help my case.
I will study the lines of code you wrote, and will update you as soon as I try them out.
Thanks
To use the built-in "attachInterrupt()" function you need to use a pin that supports External Interrupts. On the UNO or NANO that is Pin 2 or Pin 3. For most other pins you can use the third-party "PinChangeInterrupts" library to get interrupts or hand-code them.
Currently using ATmega328 (ARDUINO UNO R3), but in the future I plan to use a microcontroller with simpler specs, such as Attiny44. I'm ordering it online today.
I am very excited to read it. So I then thought of using a lower spec microcontroller.
I'm sure you will agree. If you can use components that are more efficient, why should you use expensive components. As long as the desired specs can be met.
The code you wrote, I have just tried, and it works fine.
void PatternFound()
{
// Put the code here to execute when the pattern is detected
Serial.println("HEY! I AM HERE. I'M ON! I'M ON!");
}