Hello! I'm new here (but not to programming btw).
It seems like pulseIn(pin,LOW) if it is ALREADY low will wait until it gets high and THEN low again before it measures the time it takes for it to get high after that. Okay, maybe it is hard to explain in a understandable way, but I had to rewrite the function to get the behavior I expected.
I was sitting for hours going insane at this weird behavior (at least weird to me).
If I must then I can show you my code...
It's a IR receiver I'm working on, my readings from the sensor is good and I would suspect the same behavior from these two code snippets I post below. But only the one where I wrote my own timing stuff instead of using pulseIn works as expected. And with "expected" I mean collecting timing data of the "on and off" pulses until the remote signals stopped.
This is where I tried using pulseIn to simplify things:
#define ir_pin 7
void setup() {
pinMode(ir_pin,INPUT);
Serial.begin(9600);
Serial.println("Ready...");
}
unsigned long onDuration=0;
unsigned long offDuration=0;
unsigned int count=0;
unsigned int data[300];
unsigned long microseconds=0;
boolean timeout=false;
//LOW = IR light, HIGH = no IR light (that's how my IR receiver reads)
void loop() {
onDuration = pulseIn(ir_pin,LOW);
if (onDuration > 0) { //did it blink?
data[count] = onDuration;
count ++;
microseconds = micros();
while (digitalRead(ir_pin)==HIGH && timeout==false) { //messure delay between blinks
if (micros()-microseconds > 10000) { //been off for a second or more
timeout = true; //rather use break?
}
}
if (timeout == false) {
offDuration = micros()-microseconds;
data[count] = offDuration;
count ++;
} else { //end of blinks, output data
Serial.println("########################################");
for (int i=0; i<count; i++) {
Serial.println(data[i]);
}
count = 0;
timeout = false;
}
}
if (count > 298) {
count = 0;
Serial.println("too much data");
}
}
This is the working code (when I decided to not use pulseIn for timing):
#define ir_pin 7
void setup() {
pinMode(ir_pin,INPUT);
Serial.begin(9600);
Serial.println("Ready...");
}
unsigned long onDuration=0;
unsigned long offDuration=0;
unsigned int count=0;
unsigned int data[300];
unsigned long microseconds=0;
boolean timeout=false;
boolean wasLow=false;
//LOW = IR light, HIGH = no IR light (that's how my IR receiver reads)
void loop() {
microseconds = micros();
while (digitalRead(ir_pin)==LOW) { //messure delay between blinks
wasLow=true;
}
if (wasLow==true) { //did it blink?
onDuration = micros()-microseconds;
wasLow=false;
} else {
onDuration = 0;
}
if (onDuration > 0) {
data[count] = onDuration;
count ++;
microseconds = micros();
while (digitalRead(ir_pin)==HIGH && timeout==false) { //messure delay between blinks
if (micros()-microseconds > 100000) { //been off for a second or more
timeout = true; //rather use break?
}
}
if (timeout == false) {
offDuration = micros()-microseconds;
data[count] = offDuration;
count ++;
} else { //end of blinks, output data
Serial.println("########################################");
for (int i=0; i<count; i++) {
Serial.println(data[i]);
}
count = 0;
timeout = false;
}
}
if (count > 298) {
count = 0;
Serial.println("too much data");
}
}
As you see the only changes is a few lines over "if (onDuration > 0)". I may be crazy but shouldn't the snippets behave the same way? At least that would make sense to me.