Arduino pulsein() help

Thread Starter

robotDR

Joined Mar 17, 2020
90
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:

Code:
    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 bolded red part to return an 800 if the timeout is set to 800. micros() - start > timeout should fire off.

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.

Code:
#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");
//}
}
 

AlbertHall

Joined Jun 4, 2014
12,343
From the arduino reference:
" timeout (optional): the number of microseconds to wait for the pulse to start; default is one second. Allowed data types: unsigned long. "
So that timeout is in case the pulse doesn't start, not for the case where it doesn't end.
 

Thread Starter

robotDR

Joined Mar 17, 2020
90
From the arduino reference:
" timeout (optional): the number of microseconds to wait for the pulse to start; default is one second. Allowed data types: unsigned long. "
So that timeout is in case the pulse doesn't start, not for the case where it doesn't end.
However in this arduino.cc guide it says it timed out an incomplete pulse:
https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/?setlang=it

thank you for taking a look and time to reply
 

Thread Starter

robotDR

Joined Mar 17, 2020
90
Write your own code.

Timer capture code is not that complex, you can make it do whatever you want.
Yeah but it looks complicating. Why do they have this entire code if it’s just Simple timer capture.

thank you for the reply.
Yeah but it looks complicating. Why do they have this entire code if it’s just Simple timer capture.
 

Sensacell

Joined Jun 19, 2012
3,432
Yeah but it looks complicating. Why do they have this entire code if it’s just Simple timer capture.

thank you for the reply.
Yeah but it looks complicating. Why do they have this entire code if it’s just Simple timer capture.
Library coding can be quick and easy, but I often see people running into problems that become very time-consuming to fix, and often require awkward and inefficient solutions.

Some libraries use the same resources or have incompatible timing schemes that cause haywire behaviors when used together, and the programmer is usually sitting in the dark, with no idea how to resolve the problem. All of which can be avoided by understanding what's going on with the core resources of the chip.

Investing the time to learn the intricacies of the peripheral itself will pay off 100X over struggling with a poorly documented library function.
 
Top