Go Down

Topic: Help: How do I bail out of pulseIn? (Read 4 times) previous topic - next topic

glt

I'm stuck in a pulseIn waiting for the pulse to end. The time out parameter waits for the pulse to start. There is no other time out parameter for the pulse to end.
Thanks...

alfonso.nishikawa

For now, try this.
I didn't checked the assembler code nor have time, so only hope to work acceptable.

Modified from arduino code:

Code: [Select]
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout, unsigned long timeoutstop)
{
     uint8_t bit = digitalPinToBitMask(pin);
     uint8_t port = digitalPinToPort(pin);
     uint8_t stateMask = (state ? bit : 0);
     unsigned long width = 0;
     
     unsigned long numloops = 0;
     unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
     unsigned long maxloopsstop = microsecondsToClockCycles(timeoutstop) / 16 ;

     // wait for any previous pulse to end
     while ((*portInputRegister(port) & bit) == stateMask)
           if (numloops++ == maxloops)
                 return 0;
     
     // wait for the pulse to start
     while ((*portInputRegister(port) & bit) != stateMask)
           if (numloops++ == maxloops)
                 return 0;

     // wait for the pulse to stop
     while ((*portInputRegister(port) & bit) == stateMask)
               if (width++ == maxloopsstop)
                       break ;

     return clockCyclesToMicroseconds(width * 16 + 16);
}

glt

Thanks!. I suppose I need to recompile the Arduino code (which I don't know how to do). Is there a function I could use in my own code?

alfonso.nishikawa

Quote
Thanks!. I suppose I need to recompile the Arduino code (which I don't know how to do). Is there a function I could use in my own code?


Sorry, my fault.

Add this to the beginning of your sketch:
Quote
#include <pins_arduino.h>

and add the function I wrote in the other message to your sketch too.

Hope that works :)
Tell if works or not.

glt

#4
Nov 23, 2010, 02:19 am Last Edit: Nov 23, 2010, 03:29 am by glt Reason: 1
alfonso.nishikawa,

thanks!. With further info from this post: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1289639566
the code works. I needed to recalibrate width to be 20X

For the application I'm using (NEC remote protocol) the granularity is good enough.

I guess I understand why this is not in the standard release; it will increase the granularity of the pulse measurement. I wonder if there is a better way to bail out of the function.

Thanks again.

Edit: Further reading indicate that the multiplier is 19: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282768194

alfonso.nishikawa

Sure. Recalibrated with 19.
The comments on the original code, where says 16 cycles per iteration, are wrong too. I recalibrated to 16 as told in the comments, but good job finding the last post :) good to know.

glt

#6
Nov 23, 2010, 07:40 pm Last Edit: Nov 23, 2010, 07:44 pm by glt Reason: 1
I did some measurements on the NEC remote pulses
I used *20+16 for width

These are the results on average of 50-100 measurements:

Theoretical (usec):  560  1690  2250  4500
Measured  (usec):   532  1674  2227  4549
Difference (usec):   -28    -16     -23   +49


So *20+16 seems to work (Arduino 0021 and  Duemilanove 168)


One additional comment: The reason I needed a bailout is because I am measuring HIGH pulses from the IR receiver. The normal off state of the receiver (no IR received) is HIGH, so if you get a spurious signal of one pulse the receiver out signal will go low, then high and stay there until the next event. In the meantime, pulseIn will wait for the end of the HIGH pulse forever...

alfonso.nishikawa


Go Up