pulsein help with timeout

I have it working well. It counts pulse duration. ok fine

But I want it to detect a pulse that started and never ended.

If my pulses are generally 700 micro seconds, and then a pulse starts but doesn’t end, I blieve it reverts to a default ‘timeout’ and then returns a ‘0’.

I input an argument for timeout in the function such as: pulsein(MCIN, HIGH, 800)

I have looked at the wiring_pulse.c and I don’t understand why it doesn’t time out after 800 microseconds if a pulse doesn’t end by 800 micro seconds.
From wiring_pulse:

    unsigned long startMicros = micros();
    // wait for any previous pulse to end
    while ((*portInputRegister(port) & bit) == stateMask) {
        if (micros() - startMicros > timeout)
            return 800;
    }

    // wait for the pulse to start
    while ((*portInputRegister(port) & bit) != stateMask) {
        if (micros() - startMicros > timeout)
            return 800;
    }

    unsigned long start = micros();
    
    // wait for the pulse to stop
    while ((*portInputRegister(port) & bit) == stateMask) {
       if (micros() - start > timeout)
         return 800;
   }

    return micros() - start;

I expect the above part to return an 800 if the timeout is set to 800. micros() - start > timeout should fire off.
Instead all I get is 0’s repeatedly.

I believe the 0’s come from:

unsigned long maxloops = microsecondsToClockCycles(timeout)/16;

	unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);

	// prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
	if (width)
		return clockCyclesToMicroseconds(width * 16 + 16);
	else
		return 0;

I believe the 0’s come from there because when I change the ‘return 0’ to ‘return 800’, it returns 800’s but does so even when there is no pulse to be detected which is not what I want. If no pulses, I want 0. If a pulse starts but doesn’t end before timeout, I want it to return an 800 or some other number I choose.

Here is my code:
I have been trying several things to detect a pulse that never ended. and it needs to be fast. Like within a few hundred micro seconds. Any help would be greatly appreciated.

Thank you.

#define DIP 5
#define COIL 10
#define LED A5
#define PWR A2
#define MCOUT 11
#define Bled A3


int PD = 2;
int MCIN = 22;
int DIPs = 0;
int LEDstate = 0;
int MCINs = 0;

unsigned long duration;
unsigned long duration2;
unsigned long previousMillis = 0;
const long interval = 1000;
int PWRraw;
float PWRv;
unsigned long startMicros;
unsigned long endMicros;
unsigned long totalMicros;
unsigned long startMicros2;
unsigned long totalMicros2;

void setup() {
  pinMode(DIP, INPUT);
  pinMode(COIL, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(PD, INPUT);
  pinMode(MCIN, INPUT);
  pinMode(MCOUT, OUTPUT);
  pinMode(Bled, OUTPUT);
  //pinMode(PWR, INPUT);
 
  Serial1.begin(115200);
  delay(50);
//    while (!Serial)
//  {
//    ; // wait for serial port to connect. Needed for Leonardo only
//  }
  Serial.println("setup");

}

void loop() {

DIPs = digitalRead(DIP);
if (DIPs == LOW){
 analogWrite(MCOUT, 125);
}

if (DIPs == HIGH){
  analogWrite(MCOUT, 255);
}

//  duration = pulseIn(PD, HIGH);
//  Serial.print("Pulse Width: ");
//  Serial.print(duration);
//  Serial.println(" uS");

startMicros2 = micros();
  duration2 = pulseIn(MCIN, HIGH, 800);
  Serial.print("Pulse Width: ");
  Serial.print(duration2);
  Serial.println(" uS");

//  startMicros = micros();
//MCINs = digitalRead(MCIN);
//if (MCINs == HIGH){
//  digitalWrite (COIL, LOW);
//  endMicros = micros();
//  //totalMicros = endMicros - startMicros;
//  totalMicros2 = endMicros - startMicros2;
//  //Serial.print("total micros:");
//  //Serial.println(totalMicros);
//  Serial.print("total micros 2:  ");
//  Serial.println(totalMicros2);
//  Serial.println("LASER KILL");
//  delay(1000);
//}
//  digitalWrite(Bled, HIGH);
//  delay(1000);
//  digitalWrite(Bled, LOW);

 
//  PWRraw = analogRead(PWR);
//  delay(50);
//  PWRraw = analogRead(PWR);
//  delay(50);
//  PWRv = PWRraw*(5.0/1023.0);
//   Serial.print("PWR voltage: ");
//  Serial.print(PWRv);
//  Serial.println(" V");
 
  unsigned long currentMillis = millis();

 if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (LEDstate == LOW) {
      LEDstate = HIGH;
    } else {
      LEDstate = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(LED, LEDstate);
    //digitalWrite(Bled, LEDstate);
      }
 
// DIPs = digitalRead(DIP);
//if (DIPs == HIGH){
//  digitalWrite (COIL, HIGH);
//  Serial.println("high");
// 
//}
//if (duration >= 490 && duration <= 510){
//  digitalWrite (COIL, HIGH);
//    Serial.println("HIGH");
//}
//if (duration <= 489){
//  digitalWrite (COIL, LOW);
//  Serial.println("LOW");
//}
//if (duration >= 512){
//   digitalWrite (COIL, LOW);
//  Serial.println("LOW");
//}
}

it is not clear to me if you really just want to just detect a statechange (= “pulse” of a very looong duration)

or

statechange of very short pulses and statechange

and it needs to be fast. Like within a few hundred micro seconds. Any help would be greatly appreciated.

just detecting a statechange regardless if it is from LOW to HIGH or HIGH to LOW
would be a simple loop that just compares the actual reading of an IO-pin to the previously stored value and thats all.

But I guess this detecting is not a self-purpose. I’m pretty sure you want to do more things than just detecting it.
With the detecting - something else shall happen. What is it that shall happen?

What do you have in mind what your code shall do if every detail is programmned? It really depends on that if a polling loop is enough or if you need to use interrupts

best regards Stefan

The default timeout for pulseIn() is 1,000,000 microseconds (1 second). If the pulse does not begin and end within the timeout period, it returns zero. If you want a function that behaves differently, you can write one for yourself.

Does the one you quoted do what you want? Here it is written as a regular Arduino function. It returns the timeout value if anything goes wrong, otherwise, it returns the pulse duration.

unsigned long measurePulse(int pin, int state, unsigned long timeout)
{
  unsigned long startMicros = micros();    
  
  // wait for any previous pulse to end
  while (digitalRead(pin) == state)
  {
    if (micros() - startMicros > timeout)
      return timeout;  // previous pulse never ended
  }


  // wait for the pulse to start
  while (digitalRead(pin) != state)
  {
    if (micros() - startMicros > timeout)
      return timeout;  // New pulse never started
  }


  unsigned long start = micros();  // Pulse has started


  // wait for the pulse to end
  while (digitalRead(pin) == state)
  {
    if (micros() - start > timeout)
      return timeout;  // Pulse started but did not end before the timeout
  }


  return micros() - start;  // Pulse finished
}