MCP3208 Single acquisition time
I'm trying to get 100 samples from a single channel of the MCP3208 using the following code:
PRI GetHP | C
C := 0
repeat
hp[C] := ADC.in(0)
C++
while C < 100
The number of samples is less important than the time over which they are acquired. I'm trying to discover how long, in time, the above code will acquire. Is there a known length of time a single "ADC.in(0)" type cycle takes?
Thanks.
PRI GetHP | C
C := 0
repeat
hp[C] := ADC.in(0)
C++
while C < 100
The number of samples is less important than the time over which they are acquired. I'm trying to discover how long, in time, the above code will acquire. Is there a known length of time a single "ADC.in(0)" type cycle takes?
Thanks.
Comments
easy to measure empirically
_start := cnt
hp[C] := ADC.in(0)
_stop := cnt
time := _stop - _start
compare this time with
_start := cnt
_stop := cnt
time := _stop - _start
to extract the execution time of command hp[C] := ADC.in(0)
If the systemcounter cnt has wrapped around from max to zero between _start and _stop the result will be wrong
To avoid this you can use
a calculation like in the method below
PUB elapsed_time_msec(p_TimeVar) | RightNow, ClockTicks 'can measure up to 26843 Milliseconds '(2147483647 CounterTicks / 80.000.000 Hz = 26843 Milliseconds) RightNow := cnt if RightNow < p_TimeVar ClockTicks := ||($FFFFFFFF - RightNow + p_TimeVar) else ClockTicks := ||(RightNow - p_TimeVar) result := ClockTicks / (clkfreq / 1_000) 'calculate milliseconds '##################################################################################### 'explanatio how it works ' SPIN treats longs as SIGNED longs meaning bit 32 represents the sign "+-" ' the systemcounter thinks of the 32bits as UNsigned meaning bit 32 is ' just another bit of the number and NOT a sign "+-" ' if one or both values are negative it could happen ' that the result is negative too ' the command "||" calculates the absolute value of the SIGNED longs 'if the systemcounter has wrapped around since snapshot of 'systemcounter (value of parameter p_TimeVar), 'this method calculates the timedifference in the right way 'wrap-around example with easy numbers: counter maxvalue 1000 'p_TimeVar containing value 980 'time goes on counter wraps around from 1000 to 0 'time goes on 'RightNow containing 300. This means 20 ticks until maximum 1000 and 300 ticks 'since wrapping from 1000 to 0 in summary 320 ticks of time has gone 'this is calculated by MaxCounter - p_TimeVar + RightNow 'in numbers 1000 - 980 + 300 = 320 'the real systemcounter has 32bits max value 2^32 -1 = 4294967295 'hexadecimal $FFFFFFFF '#####################################################################################
best regards
Stefan
' @80MHz to match the ~26sec range before := cnt ... after := cnt{before+clkfreq*26} elapsed := after - before
Can you give me a single example for before/after which would justify the use of your method instead of simply subtracting one from the other (ignoring msec conversion)?TCP71, what rate do you want to sample at? There are objects already for that chip that sample nice and fast. There is a MCP3208_fast_multi somewhere.
t := -cnt analog := 0 repeat 100 analog += adc.read(0, adc#SE) analog /= 100 t += cnt - 544 term.str(string("Time used: ")) term.dec(t / (clkfreq/1000) ) term.str(string("ms"))
The first type runs constantly in the background, cycling thru the requested ports. It always returns the 'current' value of the adc port. If you call this repeatedly, you may end up getting duplicate adc values, because it hasn't had time to complete the next iteration between calls. These values may skew your average calculation.
The second type of driver calculates a new value each time it is called. This is the true time needed to retrieve a value from the chip. So if you call this repeatedly, you will get a new value each time. This will give you a true average over a number of samples. I believe the time to calculate a sample is around 6000 machine cycles.
I can give you examples of each type of driver if you're interested.
Jim
as long as you simply watch for a difference of just a second everything stays alright.
Try the different repeat-loops in the following code and watch the resulting values for at least a minute.
You will see that at some point the values turn negative and that they get smaller and smaller.
I tried different versions (calling the method elapsed-time with and without caclculating milliseconds, using local and global variables
but with all these versions if you wait long enough the values turn negative.
If you or somebody else can explain to me why this happends only after a certain amount of seconds I appreciate it very much.
CON _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 VAR long Start long Stop long Diff OBJ debug : "FullDuplexSerialPlus" PUB Main | RightNow, ClockTicks Debug.Start(31,30,0,115200) 'start(rxpin, txpin, mode, baudrate) : '' '"rx" and "tx" viewed from Propeller-Chip. Propeller-Chip-PIN-Tx ----> PC Start := cnt repeat Stop := cnt ClockTicks := Stop - Start WaitCnt(ClkFreq / 5 + cnt) Debug.Str(string("elapsed_time =")) Debug.Dec(ClockTicks) Debug.Tx(13) Debug.Tx(13) repeat Stop := cnt ClockTicks := (Stop - Start) WaitCnt(ClkFreq / 5 + cnt) Debug.Str(string("elapsed_time =")) Debug.Dec(ClockTicks) Debug.Tx(13) Debug.Tx(13) repeat RightNow := cnt ClockTicks := (RightNow - Start) WaitCnt(ClkFreq / 5 + cnt) Debug.Str(string("elapsed_time =")) Debug.Dec(ClockTicks) Debug.Tx(13) Debug.Tx(13) repeat WaitCnt(ClkFreq / 5 + cnt) Debug.Str(string("elapsed_time =")) Debug.Dec(elapsed_time_msec(Start)) Debug.Tx(13) Debug.Tx(13) repeat Start := cnt WaitCnt (ClkFreq + cnt) Stop := cnt Debug.Str(string("Stop - Start =")) Debug.Dec(Stop) Debug.Str(string(" - ")) Debug.Dec(Start) Debug.Str(string(" = ")) Diff := Stop - Start Debug.Dec(Diff) Debug.Tx(13) Debug.Tx(13) PUB elapsed_time_msec(p_TimeVar) | RightNow, ClockTicks 'can measure up to 26843 Milliseconds '(2147483647 CounterTicks / 80.000.000 Hz = 26843 Milliseconds) RightNow := cnt ClockTicks := (RightNow - p_TimeVar) { if RightNow < p_TimeVar ClockTicks := ||($FFFFFFFF - RightNow + p_TimeVar) else ClockTicks := ||(RightNow - p_TimeVar) } 'result := ClockTicks / (clkfreq / 1_000) 'calculate milliseconds result := ClockTicks '/ (clkfreq / 1_000) 'calculate milliseconds
best regardsStefan
hex(A-B) method dec(A-B) elapsed_time = 7D539440 7D539A81 2102629440 elapsed_time = 7E4C4D20 7E4C5361 2118929696 elapsed_time = 7F4518E0 7F451F21 2135234784 elapsed_time = 803DE260 7FC2175F -2143428000 elapsed_time = 8136AB10 7EC94EAF -2127123696 elapsed_time = 822F8EB0 7DD06B0F -2110812496
After that the difference (left column) still works until we reached double/full range (~53sec) provided you can handle/ignore the sign.