I'm trying to understand how I might go about getting a constant sample rate using high resolution (24bit) ADC on the T7Pro.
I understand that I can't use the stream mode in 24bit mode, so I'm just reading command response registers. Is there a correct way to set that up such that I get a constant, known (even if relatively slow, single digit Hz) sample rates. I see that on resolution mode 12, the sample time is 159ms, which is fine. But is there anyway to setup the ADC to continuous conversion mode at that rate, so that I get a continuous stream of data ( I only need one channel).
Thanks
Joe
In command-response mode the timing is controlled by software. What are you using for software?
I'm using a very simple python script, using ljm
I just loop reading
results = ljm.eReadNames(self.handle, numFrames, names) data.append(results[0]) At the moment names is a list of only 1 item (AIN0).As you say the timing is controlled by software. Is there any way for this not to be the case for the 24 bit ADC? I'd like to get a defined sample rate, which seems unlikely in a purely software controlled implementation
As long as you use an interval timing method, rather than a simple series sleep or delay, software is quite capable of consistent timing with low jitter. We actually are now providing an interval timer in the LJM library, as such timers are not obvious in all languages. I'll mark this for someone else to follow up about that.
One the software timing will work great, but I can see a way to do this with hardware timing using Lua script. You could write a script that acquires the readings at the desired interval and puts them in USER_RAM_FIFO. Then your python program periodically (faster than the Lua interval) reads USER_RAM_FIFO#_NUM_BYTES_IN_FIFO to see if new readings are available.
https://labjack.com/support/datasheets/t-series/lua-scripting
Thanks
It sounds like using the timer would solve any jitter type issues I have (at least long term drift of the sample rate). However what I'd really like to do ensure that I get gapless sampling. With the AD7190 (which I think is the underlying hardware) it has a continuous conversion mode. The reason I'd really like to use that, is that it means that the effective sample rate from an anti-alias perspective is 300kHz (fmod/16), the sigma delta modulator frequency. However as soon as there are gaps between samples that is no longer true, and pulse information (which I'm trying to include in my measurement) gets missed, so I would have to design my anti-alias filter for the trigger rate (a few Hz) so losing a lot of the benefit of having a SD convertor.
What I think I'm hearing is that you are running the AD7190 is single conversion mode, with a sample trigger set by the read command. Is that correct?
Yes, that is correct that we use single-shot conversion mode, but not sure that has the adverse anti-alias effect you mention. See details on how we use the AD7190 in post #15 of old forum topic 6707:
https://forums.labjack.com/index.php?showtopic=6707&p=22967
Reposting here to make sure this info is on the current forum.
Here are some details about the high resolution sigma-delta ADC.
Resolution Index, AD7190 Output Data Rate, AD7190 FS value:
Res=9, 800 Hz, FS=2
Res=10, 200 Hz, FS=8
Res=11, 40 Hz, FS=40
Res=12, 16.7 Hz, FS=96
The ADC filter response for resolution=12 looks like Figure 22 of the AD7190 datasheet. That figure is for a 16.7 Hz output data rate (Resolution=12). For other data rates multiply the x-axis values by the ratio DataRate/16.7.
Note that the U6-Pro/T7-Pro times are slower than 1/DataRate. This is because we operate in single-shot conversion mode and in addition sometimes add extra settling.
We operate in single conversion mode because the conversion timing needs to be dictated by the host or U6/T7, not by the ADC.
It is not feasible to use the sigma-delta ADC in stream mode. A couple reasons are that the communication used with the sigma-delta ADC just does not mesh with the stream firmware implemented for the high-speed ADC, and that the maximum speeds of the sigma-delta ADC barely warrant using stream mode anyway.
Post #4 mentions a timer being supported in LJM. I expect that it will be release on Friday or Monday. I will update this thread when it is released.
LJM 1.1700, which is now available, introduces the interval timer functions. See LJM_StartInterval for more information.
I'm pretty sure that if the underlying SD hardware isn't sampling continuously, then you can miss events. It looks like in the AD7190 datasheet if running in single conversion mode then the front end actually powers down between conversions.
In my case what I actually want to know the average value, but it can can have spikes in it, which I want to include in the sampling. Is there any way to submit a feature request?
I'm just looking, and I seem to get an output datarate of 160ms (or 6.25Hz per sample) which corresponds well to the value of Fs=96 being written to the register.
However according to Table 11 in the datasheet, (assuming Sinc4 mode, with chop enabled). In that mode the actual output data rate (not including settling time could be up to 12.5Hz however. presumable you have enabled the configuration bit that forces the AD7190 to wait for the settling time before giving a result, hence the achievable sample rate being 6.25Hz.
I think that means that none of the frequency response curves in the datasheet are really valid, because they all assume that continuous conversion mode is being used.
I'm pretty sure that if the underlying SD hardware isn't sampling continuously, then you can miss events. It looks like in the AD7190 datasheet if running in single conversion mode then the front end actually powers down between conversions.
In my case what I actually want to know the average value, but it can can have spikes in it, which I want to include in the sampling. Is there any way to submit a feature request?
Before we consider putting AD7190 continuous conversion mode on our feature request list, lets consider if it would make much difference.
Yes, in single conversion mode there is a dead time of perhaps 1-2 ms between readings where anything happening in the signal has no impact on the converter reading. I estimate this from the 1 ms power-up & settle time mentioned in the AD7190 datasheet, plus 1 ms of communication time between the T7-Pro and host computer. Note that with the high-speed ADC we sometimes add substantial settling time before starting a conversion, but that is not done or needed with the low-speed sigma-delta ADC.
So if a ResIndex=12 reading takes 160 ms, the ADC is settling its filter and converting for perhaps 158 ms of that time. Perhaps the filter is settling for about 98ms and then the conversion takes about 60ms? Not totally clear on that but we can look closer if needed.
In any case, if the signal is varying during that time, what is the result? First off, I would expect the signal to be filtered as shown in Figure 22, so any spike would be substantially filtered. Second, say the signal slowly changed from 1V to 2V over that time. Would the result be an average of about 1.5V or weighted toward the final value of 2V? I suspect the latter but we could ask Analog Devices about that for more explanation.
However according to Table 11 in the datasheet, (assuming Sinc4 mode, with chop enabled). In that mode the actual output data rate (not including settling time could be up to 12.5Hz however. presumable you have enabled the configuration bit that forces the AD7190 to wait for the settling time before giving a result, hence the achievable sample rate being 6.25Hz.
I think that means that none of the frequency response curves in the datasheet are really valid, because they all assume that continuous conversion mode is being used.
Figure 22 is for the configuration we use with ResolutionIndex=12. For other values of ResolutionIndex use the same figure but adjust the x axis as described in post #6 above.
I believe the Figure does apply to single conversion mode, because the chip provides time for the filter to settle. That is a simple question that we will ask Analog Devices.
Did you ever get any feedback from Analog Devices on your questions about the behaviour. I have some good contacts at Analog that can help if you haven't managed to get any feedback.
As you say the weighting curves for the settling time would be informative.
At the moment I am running my system with an anti-alias filter set to a very low frequency. This is working OK, but requires some trade offs in terms of the tolerances that I can achieve
Yes, sorry we forgot to post here. We asked:
We use the AD7190 in single conversion mode. Does the filter response in Figure 22 apply to single conversion mode? I believe it does since you say that the filter is allowed to settle before the conversion.
... ADI replied (Jan 9, 2018):
You can set the filter profile and conversion mode in the mode registers. So, yes, the filter response would apply to single conversion mode if you set it that way. Figure 22 refers to SINC3 with chop enabled and hence you have to enable the CHOP bit as well in the configuration registers.
Not exactly as clear a response as I would have hoped for. A better response would have been simply "yes, Figure 22 applies whether using continuous conversion mode or single conversion mode". In any case their response does seem to say that Figure 22 applies to single conversion mode.
Also, the 3rd answer here is describing how "settling time" is getting the filter set up to work as expected:
http://www.analog.com/en/analog-dialogue/articles/using-sigma-delta-conv...
I think my understanding of that, is that the settling time is there to make sure that any contribution from previous inputs has been discarded, and that only some of the measurement in that time period will contribute to the final sample.
So I think my previous statement is correct, for accurate results I need to design my anti-alias filter to the output sample rate, not to the internal SD sampling rate (as I hoped). I still think that being able to put the convertor in continuous mode would give me benefits in my application, but for the moment it is working OK.
I hope that you might be able to consider this mode in future work.
I want to add to the wish for self clocked / continuous conversion on the 24-bit ADC.
My use case is that I want to sample long time series of several low SNR sinewaves. I use an FFT to extract their amplitudes over time but any time jitter causes spectal broadening.
I find it unlikley that any software approach on a PC could reduce jitter anywhere close to a what the µC och ADC itself can.
My current solution is to busy wait for as little jitter as possible and timestamp to try and restore the time-axis.
The other reason would be to squeeze maximum performance out of the system where higher sampling rates (with maintained voltage resolution of course) would allow for higher frequencies on the sinewaves. When I run the basic command/response loop without any delays I rarley get the maximum sample rate according to the datasheet and always with extreme jitter problems.
Running the 24-bit ADC in continouus conversion mode would be great for low frequency signals such as seismology or magnetic flux measurements.
Regarding the Aliasing effect my antialiasing filter for 1 kHz solved my aliasing problems completely.
Future devices will likely have higher resolution at faster speeds and support higher resolution with hardware clocking, but with the converter discussed above it simply it not possible to use it with the high-speed stream mode used with the 16-bit ADC. Also, that converter is just not very fast.
For hardware clocking with the T7-Pro's sigma-delta converter, you can use Lua scripting to acquire readings with 1 ms resolution. Put thus readings in USER_RAM_FIFO and your software can pull them out when convenient.:
https://labjack.com/support/datasheets/t-series/lua-scripting
Fast is a relative term. The signals of interest for me is a few Hz and lower.
The low SNR however means that the more precise ADC is required.
I will try with the lua scripting approach but I still consider continuous convertion as the preferable option since that would yield better performance. There will always be dead-time in any command response system and that is wasted time.
I thought you were talking about stream mode, but now I understand that you are just talking about using the AD7190 in continuous conversion mode. I could see where a Lua script has register access to the AD7190 so you can configure it however you want, and then the script is also responsible for reading each sample when ready. Or higher level functions are made to start the AD7190 in continuous conversion mode and automatically move readings to a buffer. Neither of these is trivial and would require a decent amount of firmware work, and this would only work while reading from 1 analog input and all others would not be available during that time, so is fairly limited in application.
Yes, you could get higher samples/second at the same effective resolution using continuous conversion mode rather than single conversion mode. Perhaps 3x.
That is exactly the configuration that I would be interested in (1 input, continous conversion mode). I can see that continous conversion is an orthogonal function to switching between inputs. You would still potentially be able to switch between inputs, but just slowly (i.e multiple samples per input). This could actually still be a valuable mode, as it would greatly increase the resolution, reduce the anti-alias filter requirements, and potentially improve 50/60Hz rejection.
When you say firmware work presumably you mean to the Labjack firmware (i.e has to be done by Labjack) rather than Lua work which I could implement myself (with the right documentation as to how to access the AD7190 registers?
I have looked and I can't find any other off the shelf hardware that would have an equivalent capability to the Labjack if this feature was implemented, at least at anything close to this price.
At least it sounds like it is possible which is good news for me. And since it is nice to have rather than need to have I fully understand that two persons are not sufficient to motivate such a large effort.
If it would still be possible to send out digital control signals to control shutters (https://www.thorlabs.com/newgrouppage9.cfm?objectgroup_id=6619) and the like. Then one ADC channel would be fair for me.
Besides I am happy to do auxiliary measurements first then use a single channel for some "high speed" measurements for a while.
Perhaps if more people see the need it might happen.
I have written som lua that might be of use for others. It samples AIN0 and delta CORE_TIMER to as quickly as possible sample AIN0 and at the same time provide some measure of the jitter generated. This solution is far superior in stability, jitter and speed to any C++ implementation I could achieve.
The code uploads data to the FIFO buffers as fast as possible. It buffers 10 samples and it assumes both AIN and dT values are read at the same time. It also handles overflows in the CORE_TIMER without any timing errors.
The data is read from the FIFO buffers from a simple C++ program. I can upload it if relevant.
I would very much like to hear about any improvements possible to make the code faster, leaner or better in any way.
Is it possible for my C++ program to change the voltage range or resolution factor?
--Requires Firmware 1.0161 or newer.
--This system is considered advanced topic. Simple data transfer to/from Lua is easiest with USER_RAM, not a FIFO.
--These FIFO buffers are good for users who want to send an array of information in sequence to/from a Lua script.
--Usually 2 buffers are used for each endpoint, one buffer dedicated for each communication direction (read and write).
--A host may write new data for the Lua script into FIFO0, then once the script reads the data out of that buffer,
--it responds by writing data into FIFO1, and then the host may read the data out of FIFO1.
--See the datasheet for more on USER RAM FIFOs
--http://labjack.com/support/datasheets/t7/scripting
--To get started, simply run the script.
--Once the script is running, open up the Register Matrix, and search USER_RAM_FIFO1_DATA_F32
--add this USER_RAM_FIFO1_DATA_F32 register to the active watch area, and
--view each element coming out in sequence at the update rate of the software.
local mbRead=MB.R --local functions for faster processing
local mbWrite=MB.W
local mbra = MB.RA
local FIOc = 10
local ValueSizeInBytes = 4
local FIOsz = FIOc*ValueSizeInBytes
mbWrite(47900, 1, FIOsz) --allocate USER_RAM_FIFO0_NUM_BYTES_IN_FIFO to 20 bytes
mbWrite(47902, 1, FIOsz) --allocate USER_RAM_FIFO1_NUM_BYTES_IN_FIFO to 20 bytes
mbWrite(48005, 0, 1) --Ensure analog is on
mbWrite(43903, 0, 9) --set AIN_ALL_RESOLUTION_INDEX
--The throttle setting can correspond roughly with the length of the Lua script.
--A rule of thumb for deciding a throttle setting is Throttle = (3*NumLinesCode) + 20
ThrottleSetting = 36 --Default throttle setting is 10 instructions
LJ.setLuaThrottle(ThrottleSetting)
-- config timestamp (40 MHz)
local arr_old = mbra(61520, 0, 2)
local arr_new = mbra(61520, 0, 2)
arr_old = arr_new
local dt = 0;
LJ.IntervalConfig(0, 2000)
local checkInterval=LJ.CheckInterval
-- clear fifos
mbWrite(47930, 1, 1)
mbWrite(47932, 1, 1)
while true do
-- if checkInterval(0) then
--write out to the host with FIFO0
AIN0 = mbRead(0, 3) --read AIN0
-- get time delta from CORE_TIMER (80/2 MHz)
arr_new = mbra(61520, 0, 2)
if arr_new[1] < arr_old[1] then --overflow!
dt = (65536 - arr_old[1] + arr_new[1])*65536 + (arr_new[2] - arr_old[2])
else
dt = (arr_new[1] - arr_old[1])*65536 + (arr_new[2] - arr_old[2])
end
arr_old = arr_new
FIOszn = mbRead(47910, 1) --get current buffer size
if (FIOszn < FIOsz) then
mbWrite(47030, 3, AIN0) --provide a new AIN value
mbWrite(47032, 3, dt) --provide a new array of size numValuesFIO0 to host
print ("Next Value FIFO0: ", AIN0)
else
print ("FIFO0 buffer is full.")
end
print("AIN0", AIN0)
print("dt", dt)
-- end
end
Thanks for publishing your Lua Script. Hopefully another user will find this to be a useful example of the FIFO buffers exposed by the T-Series devices.
Your lua script looks to be following all of our standard best practices to get the best performance.
Addressing your question regarding another application being able to set the resolution & range of analog inputs while a script is running, yes it can.