Stopwatch? Timer/Counter?
rtowler
Posts: 29
I have a 4-wire RS-422 device that I'll drive using a TI SN65C1167 driver/receiver. It is a simple device where you send it a start pulse and then wait for the stop pulse. What I need to do is (very accurately) measure the time between the start and stop pulses. Ideally the resolution would be 0.1 usec or better with a minimum resolution of 0.3 usec within a range of ~90 usecs to ~4000 usecs. I think this pretty much excludes doing it entirely on the stamp (BS2p).
So my question is, does anyone know of an "easy to interface" IC that would act as a stopwatch timer working within the above specs? I've been googling for much of the day investigating this and have been looking at timers, counters, PITs... and I'm a bit surprised I haven't been able to find anything simple (by which I mean everything I need on a chip including SPI/I2C interface). I also haven't been able to figure out how to build something like this from separate components but that might just be because I am dense . I've found the LS7366R which might be as good as I will find but was hoping for something a bit simpler. Not that I'm not up for a challenge but...
Anyone have any experience with this? Any ideas?
So my question is, does anyone know of an "easy to interface" IC that would act as a stopwatch timer working within the above specs? I've been googling for much of the day investigating this and have been looking at timers, counters, PITs... and I'm a bit surprised I haven't been able to find anything simple (by which I mean everything I need on a chip including SPI/I2C interface). I also haven't been able to figure out how to build something like this from separate components but that might just be because I am dense . I've found the LS7366R which might be as good as I will find but was hoping for something a bit simpler. Not that I'm not up for a challenge but...
Anyone have any experience with this? Any ideas?
Comments
So given that I have a sensor that when connected to the driver/receiver basically has a start pin and stop pin. When a trigger pulse (~2ms low-high-low) is applied to the start pin and then anywhere from 90-4000 usecs later the stop pin goes low-high-low to indicate a stop. I need to calculate the time from when the start pulse is initiated to when the stop pulse is received.
So, in general, how would this be done with the propeller?
I see the app note on the counters. I guess I would use one for the timing?
And another cog would monitor the start/stop pins?
I guess I have a lot to think about.
When you call the start routine from the main program (that does the other work), it starts this assembly routine in another cog (processor). All this routine does is to wait for the start pin to be low, then waits for the leading edge and records the system clock time of this (to within about 65ns). It then waits for the leading edge of the stop pulse and records the system clock time of this. It calculates the difference and copies that to the address in main memory originally passed when the cog was started. The getNext routine sets the pulseWidth variable to zero which shouldn't normally occur. It then waits for the other cog (processor) to record the next pulse width and returns that as its value. It's in units of the system clock time (12.5ns for an 80MHz clock) and you can do any kind of normalization you want on the value.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
Mike, thank you very much for the code snippet.
I think I am starting to understand this... It's a bit of a jump from the basic stamp. The code you posted simply defines the functions I would need, right? The "PUB" sections define (public) subroutines? "DAT" defines the assembly function. PAR is a reserved word that is what? I see the result of the getNext assembly function is written to it, but what is it? A return register? Is there only one or can functions return multiple values? (pardon my ignorance)
To use your functions, I would add the main program below your code? Something like (in pseduo-code)
So when the pulseout (prop equivalent) is called, the timer running on another cog starts (because it is waiting for the start pin to go high). The call to getNext will wait until a value is returned which might not be a wait at all if the timer function executes faster than the spin code. It shouldn't (since the min value is ~90us), but I am just trying to understand the flow and how this whole parallel execution stuff works.
I'm off to read the manual. Again, thanks for the code and suggestions. The propeller is a very elegant way to tackle this problem (and project). I hope I can work it into the schedule.
-r
There are a couple of reasons for writing the routine the way I did. 1) The start pulse may still be high (given your description) after the stop pulse has come and gone. That's why it always waits for the start pin to be low. 2) The assembly routine just sits there waiting for the next start pulse. There's an initialization penalty for starting up a cog ... it's on the order of 100us. As a result, it's unusual to just start up a cog for a single action. Usually there's a repeated action. Often the cog routine waits for a variable to be set to a particular value that tells it what to do next. 3) The reason for 'getNext' to set the pulseWidth value to zero, then wait for the next value to be stored is that this guarantees that it's a new reading. If you're just tracking the sensor values and it doesn't matter whether you see the same value twice, you don't need any of that code, just use 'pulseWidth' in your calculations and it will reflect the most recent reading. Another thing you can do is to move the 'pulseWidth := 0' to the end of 'getNext'. This allows you to "double buffer" the readings. You're still using each reading only once, but can do something else while the assembly routine is handling the next reading.