Jump to content

Logging 4 Channels to TDMS - am I losing data?


Recommended Posts


I'm using the 9229 and borrowed a community example to log 4 voltage inputs to TDMS. I need to output RMS voltage on channels 1&2 and the wavform on channels 3&4.

Essentially what I've done is averaged channels 3&4 using the same # of samples that the RMS is averaged, that way I'm able to make sure they are time synchronized (see code attached). Another advantage doing averaging the samples is that I am reducing the amount of data to analyze later.

When i compare the TDMS read results to the # of samples in the TDMS file there seems to be a discrepancy in time. I tried to add a time stamp to the logged TDMS file but couldn't get it to work. besides using time stamps, Is there an easy way to confirm that I am saving all of the data I am capturing? Eventually i will be logging data at 30min-40min intervals so I want to make sure that i'm not losing data.



Logging Code.PNG

Link to comment

As far as the code goes I think it is pretty simple, and looks right.  You have continuous sampling which is good, multiple finite reads is something I wouldn't recommend here.  I might suggest a few improvements to have better performance, not that what you are doing is wrong.  But I notice you are reading 28 samples at a time, and your DAQ session is setup to sample at 1612.9 Hz.  This means your loop rate will be no less than 17ms per iteration.  

This seems relatively fast.  Imagine if updating the graphs, and redrawing them, and logging the samples to disk takes 20ms what will happen?  Well samples won't be lost, right away it will just lag behind, and the data you log will be more and more from the past, until your DAQ read buffer fills up and then you'll get an error and stop.  Also even if you don't full the buffer and error out, clicking Stop will stop and the data in the buffer that you haven't read out yet won't be logged either.  

To help with this you can choose to not update the UI with every iteration, but instead just update it a couple of times a second which will probably be enough for most users.  Also instead of logging each sample as they come in, you can build a buffer of samples, and then when you get so many, log them at once.  The overhead of logging single point data to a TDMS can be larger than the payload of data to log.  This may mean a few changes with shift registers to keep track of the data in your own buffer, and changing the charts to graphs.

Of course a more simple solution if you can get away with it is to take more samples at a time, or making a seperate loop where you log, and update the UI.

  • Like 1
Link to comment

Hooovahh, thanks for the insight. I am actually measuring wire that is moving through a laser micrometer at 14 inches per second. The reason i'm reading (and averaging) 28 samples at a time is so I can measure the wire every 0.25 inches.

I like the idea of building a buffer of samples and then logging that buffer at once. Would this mean a for loop within the while loop i already have? I can't quite picture how this would be done.


Link to comment

Sure thing, attached is a somewhat crude approach that isn't easily scaleable but I think it is pretty simple.  You have 4 shift registers for the data to log, and 4 more for the data in the graph instead of chart which has the benefit of having it's own buffer, but you have less control over it, like when it gets updated.

If you have more than 30 samples of data log it, this should be roughly once every 500ms.  This can be increased or decreased as needed.  After getting 30 new sample the data is appended to the end of the graph data, but if more than 1000 samples are in a graph, only the last 1000 are kept and shown.  Also the graphs will only be updated at most every 250ms.

Then after it stops executing the samples in the buffer that haven't been logged yet, are logged.  This will be samples between 0 and 30 that haven't been logged because there wasn't more than 30 at a time yet.

I also added a feedback node to measure the loop rate and put it on an indicator and chart.  Removing this will likely cause better loop rates, but if I were you I'd be curious what rates you get, and maybe remove this code once you are sure it is working well enough.

TDMS_Logging_Simple_4chan hooovahh edit.vi

  • Like 1
Link to comment

@hooovahh so far this is working beautifully with simulated data. I've increased the buffer size to 280 (10x the loop) just to try and reduce system resources... it doesn't seem to be a problem now, but might as well play it safe!

I'm going to test it tomorrow with real data and will let you know how it goes.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Similar Content

    • By Peter Herrmann
      Hello LAVA community,
      I use a USB 6215.
      With two TTL output signals, two different colored lasers are to be triggered.
      TTL 1 activates a blue laser. TTL 2 activates a green laser. 
      This external device also outputs 2 analog signals that I can capture with the USB 6215.
      While the lasers are active, the analog signals output characteristic values.
      The two TTL signals should be output by the USB6215 as follows:
      Both TTLs should be active for 10 ms every 100 ms, one after the other with a 2 ms delay.
      So TTL1 active for 10 ms, then 2 ms delay then TTL 2 active for 10 ms. The times should be adhered to as precisely as possible.
      The two analog signals should be calculated during the time in which both TTL are active (i.e. over the 22ms).
      The analog signals are sampled at 1 kHz.
      The analog data acquisition via DAQmx is clear. 
      I only have problems programming the timing of the digital triggers (TTL) accordingly.
      Does anyone have any idea how to start? 
      Maybe someone has already programmed something similar?
      Thanks in advance
    • By Aniket Gadekar
      Hello Network,
      I am writing array of timestamp in TDMS file. "TDMS Write.vi" generates an error after calling this VI as follows.
      Group Name = "DUT T1"
      Channel Names = "DUT T1_Time"
      Please let me know if anyone has any suggestions.
    • By paulofelora
      I have a requirement that I thought would be SIMPLE, but can't get it to work.  I have a 9205 card in a little 9174 cDAQ USB chassis.
      My *intended* behavior is to wait (block) at the DAQmx Trigger/Start Analog Edge on, say channel ai1, until I get a falling edge thru, say, -0.050V.  So I have a little vi (that contains 2 parallel loops) that I want to sit & wait for the trigger to be satisifed.  I'm doing "routine" voltage measurements in another AI loop on a different channel.  I want this vi to run separately from my "routine" voltage measurements because I want the app to respond "instantly" to input voltage exceeding a limit to prevent expensive damage to load cells.  I was afraid that if I used either Finite or Continuous sampling to "catch" an excessive voltage, I might miss it while I'm doing something else.  Yes, yes, a cRIO real-time setup would be better for this, but this is a very cost-sensitive task... I just want to "Arm & Forget" this process until it gets triggered, whereupon it fires an event at me.  SO... I'm also reading the same voltage on channel ai0 for regular-ole voltage measurements, and just jumpering them together.  I did this because I read somewhere that you can't use the same channel for multiple DAQ tasks - I *thought* I would need to set up the tasks differently.  {but now that think about it, the setups can be the same...}.
      I've set up the DAQmx task the same as shipping examples and lots of posts I've seen.  I'm supplying a nice clean DC voltage to a 9205 card using a high quality HP variable power supply.  Using NI-MAX, I've verified that my 9174 chassis & 9205 are working properly.
      THE PROBLEM - When I run it, the vi just sails right through to the end, with no error, and an empty data array out.  No matter WHAT crazy voltage I give the "DAQmx Trigger.vi" (set up for Start Analog Edge), it never waits for the trigger to be satisfied, just breezes on through as if it weren't there.  If I set the Sample Clock for "Finite Samples", the DAQmx Read fails with timeout - makes sense, since the trigger wasn't satisfied.  What could I possibly be doing wrong with such a simple task???????
      So my fundamental misunderstanding still vexes me - does the DAQmx Trigger vi not block and wait for the trigger condition to be satisfied, like the instructions state - "Configures the task to start acquiring or generating samples when an analog signal crosses the level you specify"?
      I stripped my requirement down to the bare essentials - see the 1st snippet, the 2nd is my actual vi.  Any ideas, anybody?

    • By Lipko
      Hi all!
      I'm new to the forum and I have a strange issue with reading TDMS custom properties with Labview.

      Creating user properties is working fine using TDMS Set Properties.vi, but I can't read them with TDMS Get Properties.vi. I can read the "standard" properties, and also I do see the properties in DiAdem (dataportal and using script) and also in Excel when I use TDM(s) importer. The property names are not listed when calling TDMS Set Properties.vi without the property name and data type terminals connected.   
      There is no simultaneous file reading or writing.
      I solved the problem with loading DiAdem and running a script, but that's very slow and also not all target machines have DiAdem installed (and no licence either, obviously).
      I also tried with property names such as User Properties\Device_ID, User_Properties/Device_ID in whatever combinations (I look for the property "Device_ID") without success.
      Thank you for any hints in advance!
    • By neunited
      Dear All, 
      I'm new to this forum and I'm really glad I became a member.
      I am currently in the phase of designing a simple program which can control all the DAQmx channels using a configuration file (.ini) which is capable of change voltage range during mid-simulation. 
      At the moment my .ini file reads as follows: 
      [AO Channel 1] 
      Name = T2
      Physical Channel = cDAQ1Mod1/ao0
      Max Value = 10 
      Min Value = 0 
      [AO Channel 2] 
      Name = T3
      Physical Channel = cDAQ1Mod1/ao1
      Max Value = 10 
      Min Value = 0 
      [AO Channel 1] 
      Name = T2
      Physical Channel = cDAQ1Mod1/ao0
      Max Value = 5 
      Min Value = 0 
      [AO Channel 2] 
      Name = T3
      Physical Channel = cDAQ1Mod1/ao1
      Max Value = 10 
      Min Value = 0 
      My LabVIEW VI for the .ini script  is attached. I'm relatively new to using configuration file functions and I don't really understand where "Get Key Names" section should be wired to. I have placed a constant on it for now which reads the "AO Channel 1" but how can I get it to read all the channels in the .ini file.
      I am welcome to all suggestions here, I just want to make sure that I don't cause any problems to any of the channels and use best practice methods. All constructive criticism welcome!
      Thank you. 

      Read Configuration (INI) File (1).vi
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.