Timing the interval between peak values

WhiteSpace

Well-known member
Can anyone please point me in the direction of the best way to time the interval between ADC values reaching a particular level (eg. the length of time between two points in a series of readings at which ADC reaches 100)? The intervals are likely to be between 1x and 2x per second. I'm currently using a 14M2, but could switch to an X2 if there was no other option. I have looked at "time" on the M2 series, but that seems to increment only once per second. Settimer seems to be able to time shorter periods, but works only on the X2s, and I don't see how it is used in practice. I've searched on the forum and in the manuals but am none the wiser. Thanks very much.
 

inglewoodpete

Senior Member
Can anyone please point me in the direction of the best way to time the interval between ADC values reaching a particular level (eg. the length of time between two points in a series of readings at which ADC reaches 100)? The intervals are likely to be between 1x and 2x per second. I'm currently using a 14M2, but could switch to an X2 if there was no other option. I have looked at "time" on the M2 series, but that seems to increment only once per second. Settimer seems to be able to time shorter periods, but works only on the X2s, and I don't see how it is used in practice. I've searched on the forum and in the manuals but am none the wiser. Thanks very much.
I have done this on a PIC using a 1mS timer interrupt. It could be done using a timer interrupt on an X2 PICAXE but the minimum practical interval would be around 10mS.

If your definition of time is fluid and you can work with arbitrary units, then you could use a loop-counting method of determining the time between peak readings on any M2 running at 32MHz. Time to experiment!
 

AllyCat

Senior Member
Hi,
.. the interval between ADC values reaching a particular level (eg. the length of time between two points in a series of readings at which ADC reaches 100)? The intervals are likely to be between 1x and 2x per second.
Could you clarify what determines those intervals? Is it some other part(s) of your program that only "polls" the ADC occasionally, or something else?

It might be possible to add to those "other parts" of the program so that they keep an approximate "record" of the passing of time. The execution time of some/many subroutines (or their individual instructions) is reasonably "predictable", even with a PICaxe. The problem arises if the program is dependent on some "external" event such as SERIN or PULSIN, etc.. They do have a timeout facility (which you might count and then re-enter) but the timeout period may be too long.

As you say, the "time" variable increments too slowly (and sadly doesn't scale with SETFREQ) for some purposes; It actually uses a 20ms "tick" from Timer 1 (which CAN be read with a PEEKSFR .... command) but the intermediate "Pre-Scaler" (i.e. up to a rollover at 50) is not accessible to the programmer/user. Therefore, the only (M2) solution I can think of is for the program to keep track of T1 rollovers (i.e. currentvalue < lastvalue ). I did this recently to indicate the PICaxe's "loading" (by checking T1 whilst waiting for the next 1-second period to complete) when nothing else needed to be processed, with some success, but haven't formally documented it yet.

A solution may be possible by using interrupts, but it depends how amenable your program is to using an interrupt (and how comfortable you are with their use ;) ).

Cheers, Alan.
 

WhiteSpace

Well-known member
Thanks @inglewoodpete and @AllyCat for these useful pointers. It’s good to hear that I hadn’t overlooked some obvious timer. To respond to AllyCat’s question, another part of the program will be checking the ADC from a photodiode. In fact I had inspiration while asleep (which often seems to happen)! What I will try is for the ADC to be measured in a loop that incs a variable on each turn until it peaks, and then I can count the number of turns. If I know the cycle time (eg. 20 ms/loop). I can convert that into an interval time. I think that’s similar to some of your suggestions. I’ll go away and play with it and report back. I haven’t been brave enough to try interrupts yet, so I might try this first. Thanks again
 

inglewoodpete

Senior Member
I haven’t been brave enough to try interrupts yet, so I might try this first. Thanks again
I'm pretty sure that Timer interrupts are only available on an X2 PICAXE anyway.

When I wrote the code (in 'C') for the PIC, I used an averaging algorithm (actually, I just added the last 3 or 4 values together after each ADC read) and when the value started to reduce, I treated that time point as the start and/or finish of the cycle. At the finish of each cycle, the timer count was read, stored and compared with the previous one to give the duration of the latest cycle.
 

AllyCat

Senior Member
Hi,

READADC{10} doesn't take any longer to execute than the majority of PICaxe instructions (< 1 ms), so even a "peak test" (i.e. a comparison with a previous value), a loop count and closing the loop (with a WHILE or UNTIL) could take around only 5 ms. Of course it depends on how "sharp" is the peak, to know when you have definitely passed it. ;)

IMHO, interrupts are not one of PICaxe's strengths and add another level of complication, delay and potential uncertainty to the program. Indeed the M2s don't have an internal (timer) interrupt; it is possible to use (say) a PWM output linked externally to an input pin, but the maximum PWM period is around 20 ms, so it may be better just to poll Timer 1. Inspired by your question, I have "written up" a Code Snippet to demonstrate how it's possible for a program to measure the passage of a short period of time, reasonably accurately, whilst it is running.

Cheers, Alan.
 

WhiteSpace

Well-known member
Thanks, that's very useful. Currently having a bit of a challenge isolating the peaks! I'll report back when (if) I make some progress. Thanks again.
 

WhiteSpace

Well-known member
Thanks @Buzby - at the moment it’s a stream of ADC readings that I am viewing via SerTXD. I need to do more work setting up ReadADC, experimenting with resistor value and the right reference voltage, as well as working out how often I need to be reading ADC! There’s a bit to do before I can share anything at all without wasting everyone’s time. Thanks for the offer.
 
Top