please help i am use time intervals to calculate an avg over time
Tony_tsi
Posts: 98
I have a sensor that will be triggered a few times a second. I am trying to calculate the average times per hour this sensor will be triggered. It will be around 2400 times an hour. I know there are many problems with this pub but i do not know there solutions. The two biggest problems I know of are that the values that i am working with are to big to store in a long. also the way i am using cnt to keep up with time interval is bad because it also counts the time it takes the code to execute. I have only included the pub that i am having trouble with.pub for avg.spin
Comments
You can scale the values to milliseconds or centiseconds and store them that way. There are 3,600,000 milliseconds in an hour, certainly small enough to store in a long.
You can monitor the trigger in a variable and accumulate them until an hour passes, when the hour passes, take the count and store it, then clear the trigger count, clear the milliseconds count and start over
This is untested psuedocode to give you an idea.
avg := accumulated_events * seconds_per_hour / accumulated_seconds
This assumes, of course, that you have a simple mechanism of counting inputs (perhaps using a counter) every second and can run this formula every second.
What precision do you need ? - ie what is the desired LSB / how many digits ?
If you want to display a value around 2400, and stick inside 32 bit maths, then the time LSB needs to be slower than appx 1us ( 1MHz count rate ) - as an example, clock at 1MHz and edges/hr is 3.6e9, which just fits inside 32 bits, and 2400pph will be 1.5e6 counts.
If you speed up one LSB, now the closest adjacent possible displayed value is 1e6*3600/(1500000-1) = 2400.00160
So that is the numeric limit.
If you want a rolling average you'll have to take 8 or so samples, average them and then do the math, something like this. (there are quicker ways to do this with a FIFO buffer, but this makes more sense for a visual explanation in my opinion)
Thankyou I will try this. I have no experence with pasm but I think I understand how to use this code.
what is clk? I have not been able to try this code yet. I am at work and thumbed through the propeller manual and did not find clk as a command. I dont have the program on this computer so I cant check it.
timesPerSecond := (clk/l_edgeToEdgeTime)
what is clk? I have not been able to try this code yet. I am at work and thumbed through the propeller manual and did not find clk as a command. I dont have the program on this computer so I cant check it. should it be clkfreq ?
_CLKMODE = XTAL1 + PLL16X
_CLKFREQ = 80_000_000
you can set a variable named clk to 80000000 to represent 80 million clock cycles per second. If you have a 5mhz crystal and a different multiplier (PLL16x) ( 5x16 = 80 million) then you would set your clk variable to something else. You can also used clkfreq as well, which is a predefined variable built into spin.
Basically it represents a constant or a known value that is unchanging. You need this to start your calculations from and build from that.
As an FYI, if you decide to try, I have found John's objects pretty simple to use, even when I didn't know how to read a word of PASM. Usually they are like a .net object where you may not know what is going on in the background but you can still use it to input and receive results, like a dll.
Keep us posted on how it is going.
None of the code I posted is PASM; it's 100% SPIN. As you are monitoring wide pulses that are infrequent, and you want to estimate pulses per hour based on edge-to-edge timing, it's easy to do without resorting to Assembly programming; the ability to access the Propeller's free-running counter (cnt) and determine elapsed time between events is something I find very useful.
BTW, you'll note that t1 is loaded with the negative value of the counter; this makes finding the elapsed time as easy as adding the new ending counter value to the starting counter value, and takes care of negative values in the process. This will work with an event duration up to about 29 seconds at 80MHz. Note that this code will no properly handle a situation where there is an excessive delay between edges; I'll leave that to you (work on it after you get the basics handled).
You wrote it yourself in your post.
Enjoy!
Mike