4.72727

4.7 | 11 ratings Rate this file 44 Downloads (last 30 days) File Size: 12 KB File ID: #28771

ConvertTDMS (v9)

by

 

20 Sep 2010 (Updated )

Import a LabView TDMS file into the MATLAB workspace

| Watch this File

File Information
Description

Import a LabView TDMS file (version 1.1 or 1.2) as a structure in the MATLAB workspace with the option to save the data in a MAT file. It was written in MATLAB 2010b. The original function was based on the work by Brad Humphreys of ZIN Technologies and Grant Lohsen & Jeff Sitterle of GTRI (versions 1 through 4 of this function). The Version 9 function (written by Philip Top), in addition to incorporating the various updates that were added to previous versions, can process files that have been "optimized" by LabView. This function has been tested with a limited number of diverse TDMS files.

Acknowledgements

Convert Tdms (V2) inspired this file.

This file inspired Convert Tdms (V10).

MATLAB release MATLAB 7.11 (R2010b)
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (70)
23 Jun 2014 Tie Xue

Good code,Thanks!

07 Nov 2013 Robert

Brad Humpreys has leveraged off of this function to make a new and improved set of functions: http://www.mathworks.com/matlabcentral/fileexchange/44206-converttdms-v10

31 Oct 2013 Gisselle

Hi,

I am working in Signal Express 2013 v7.0.0.

I've been having difficulties converting TDMS files generated by Signal Express using this version of ConvertTDMS.

I receive an error stating "
In an assignment A(:) = B, the number of elements in A and B must be the same.

Error in convertTDMS/postProcess (line 1109) Value(c) = index.(cname).(cfield).value;

Error in convertTDMS (line 287)
[ConverteData(fnum).Data,CurrGroupNames] = postProcess(ob,channelinfo);

Any help will be great!

Thank You

11 Oct 2013 Harry

@Brad:

Now, all works fine! I use a Workaround (which was already posted on 25 April) to adress the different channel names and the data inside!

11 Oct 2013 Brad Humphreys

Harry,

To get to the data quickly, yu can create a an array of the channels using:

channels=ConvertedData.Data.MeasuredData;

Brad

11 Oct 2013 Brad Humphreys

Harry,

Can you give me the values in the ChanNames and GroupNames? (The 'Object1' are the default values assigned initially in the function.)

I am updating the function and would like to make sure that this is addressed.

Thanks,

Brad

10 Oct 2013 Harry

Short Update:

Now, the convert process works, but the variables dont include the names of the real structure..

this is my answer, after the convert process:

>> [ConvertedData,ConvertVer,ChanNames,GroupNames,ci]=convertTDMS(filename)

Converting 'Messdaten.tdms'...

Conversion complete (saved in 'Messdaten.mat').

ConvertedData =

FileName: 'Messdaten.tdms'
FileFolder: 'C:\Users\Harry\Desktop\v2p5\tdms'
SegTDMSVerNum: 4713
NumOfSegments: 1
Data: [1x1 struct]

ConvertVer =

1.95

ChanNames =

{15x1 cell}

GroupNames =

{4x1 cell}

ci =

Object1: [1x1 struct]
Object2: [1x1 struct]
Object3: [1x1 struct]
Object4: [1x1 struct]
Object5: [1x1 struct]
Object6: [1x1 struct]
Object7: [1x1 struct]
Object8: [1x1 struct]
Object9: [1x1 struct]
Object10: [1x1 struct]
Object11: [1x1 struct]
Object12: [1x1 struct]
Object13: [1x1 struct]
Object14: [1x1 struct]
Object15: [1x1 struct]
Object16: [1x1 struct]
Object17: [1x1 struct]
Object18: [1x1 struct]
Object19: [1x1 struct]
Object20: [1x1 struct]

why are there no names? the chanels of my tdms file are calles temperature, and so on..

thank you for your help

10 Oct 2013 Harry

i receive this error message, if i try to convert a simple tdms file.

>> filename = 'C:\Users\Harry\Desktop\v2p5\tdms\test.tdms';
>> [ConvertedData,ConvertVer,ChanNames,GroupNames,ci]=convertTDMS(filename)
Error using convertTDMS (line 225)
Argument 'SaveConvertedFile' failed validation with error:
Operands to the || and && operators must be convertible to logical scalar values.

can u please explain me, what the problem is?

09 Oct 2013 Brad Humphreys

I sent an update to Robert to submit to fix the error messages. (TDMSFileNameShort is not passed into the function). That's the reason the initial message is being about TDMSFileNameShort.

The message after that though is the root cause of the problem which is either: interleaved data, big-endian format, or TDMS version. These 3 things are not supported by this function. If you get the interleaved message like Navid it is most likely because interleaved data was selected in the TDMS write block in LV (http://zone.ni.com/reference/en-XX/help/371361H-01/glang/tdms_file_write/).

When I get some time, I will see if I can update this function to add interleaved capability. One option you have is to readin the TDMS file in Labview and write it back out as non-interleaved. Fairly simple VI.

Also take a look at the 'Convert Tdms V2' submission in the Acknowledgements above - it may work with interleaved data.

09 Oct 2013 Igal

Hi Robert,
I got the same problem Navid has :(
Please advise.
Thank you.

17 Sep 2013 Navid

Hi Robert,

for some kinds of TDMS files I get this error:

Converting 'ADC_20130808_170115.tdms'...Undefined function or variable 'TDMSFileNameShort'.

Error in convertTDMS>getSegInfo (line 405)
e=errordlg(sprintf(['Seqment %.0f within ''%s'' has interleaved data which is not
supported with this '...

Error in convertTDMS (line 276)
[SegInfo,NumOfSeg]=getSegInfo(fid);

Is there any possibility to solve that?!

Many thanks,
Navid

09 Oct 2012 Kevin

Ooops my bad. Comment on the wrong page. Apologies

09 Oct 2012 Kevin

Many thanks for this work it's great but I have an issue when I try to read a bigger file : few MB works well but with a 80 MB file I get this error :
"
??? Error using ==> TDMS_processLeadIn at 33
Unexpected lead in header

Error in ==> TDMS_preprocessFile at 179
[flags,info,eof_error] = TDMS_processLeadIn(fid,lastLetter);

Error in ==> TDMS_readTDMSFile at 226
metaStruct = TDMS_preprocessFile(fid,tdmsFileName,paramsStruct);

Error in ==> TDMS_getStruct at 57
[temp,metaStruct] = TDMS_readTDMSFile(filePath,readOptions{:});
"
Anyway it's working great for the smaller files.

13 Jul 2012 Hari Patel

Hi Robert,

I tried your code for extracting data from the structure and It return me 533 data set as follows:

Data set 1 is Root and contains 0 samples.

Data set 2 is 07/11/2012 03:01:59 PM - Digital Input - All Data and contains 0 samples.

Data set 3 is 07/11/2012 03:01:59 PM - Digital Input - All Data/Dev1_port0_line0 - line 0 and contains 20159997 samples.

Data set 4 is 07/11/2012 03:01:59 PM - Digital Input - All Data/Dev1_port0_line0 and contains 0 samples.

Data set 5 is 07/11/2012 03:01:59 PM - Digital Input - Decimated Data_Level1 and contains 0 samples.

Data set 6 is 07/11/2012 03:01:59 PM - Digital Input - Decimated Data_Level1/Dev1_port0_line0 and contains 0 samples.

Data set 7 is 07/11/2012 03:01:59 PM - Digital Input - Decimated Data_Level2 and contains 0 samples.

Data set 8 is 07/11/2012 03:01:59 PM - Digital Input - Decimated Data_Level2/Dev1_port0_line0 and contains 0 samples.

Data set 9 is 07/11/2012 03:01:59 PM - Digital Input - Decimated Data_Level3 and contains 0 samples.

Data set 10 is 07/11/2012 03:01:59 PM - Digital Input - Decimated Data_Level3/Dev1_port0_line0 and contain

whos
Name Size Bytes Class Attributes

ChanNameOfInterest 1x1 8 double
ConvertedData 1x1 2147483647 struct
x 1x1 8 double

The number of samples is correct but I still don't know how to read actual measured data. What I want to do is to convert these structure of data into matrix, So I can do post signal processing on the actual data.

Thank you

13 Jul 2012 Robert

Hi Hari,

Please see the comment I posted on 25 APR 2012 on how to extract your data from the structure.

Hope this helps,

Robert

13 Jul 2012 Hari Patel

I am able to read a file in the MATLAB but it only returns me following :

FileName: 'Digital_Input.tdms'
FileFolder: ''
SegTDMSVerNum: [190x1 double]
NumOfSegments: 190
Data: [1x1 struct]

It also generates .mat file corrosponding to the .tdms file. However, none of these values contain the actual measurement data.

Does this code allows to extract actual measurement data.

23 May 2012 Brad Humphreys

On a quick look, it looks like this could happen when there is no root object in the TDMS file. Have does the file look when you open it in Labview using their TDMS viewer? There should be a "file tree". the first level of the tree will be "/" and then there will be objects under it. Is that how your file looks?

By the way, how big is the file in bytes?

23 May 2012 Robert

Hi Dedric,

I’m sorry but I won’t be any help with your problem. It’s been well over a year since I’ve processed any TDMS files so, I no longer work with this function nor track any LabView/NI changes. Perhaps some others that monitor this function may be able to help you. I know there are a few that have helped me in the past to get it to the point where it is now.

Good Luck,

Robert

22 May 2012 Dedric Xu

Hi,Robert
Now I am encounteering a maddening problem, which is that my TDMS file format version is 2.0. And I have tried to use your function to read this file,but failed.

The command window says "Reference to non-existent field 'rawdataindex'.
Error in convertTDMS_one (line 414)
index(end).rawdataindex=index(end-1).rawdataindex;"

Could you help me solve this problem?
Thank you very much.

25 Apr 2012 Robert

Hi Xiao,

Your data should be contained within the structure.

ConvertedData=convertTDMS(SaveFlag,FileName);

To access the data, iterate through the entries within the "ConvertedData.Data.MeasuredData" field. This field contains 4 fields: "Name" (string), "Data" (numeric), "Total_Samples" (numeric) and "Property" (structure). The data are contained within the "ConvertedData.Data.MeasuredData.Data" field. Here's one way to see all the channels and their number of samples in the Command Window and to retrieve the data for a particular channel of interest (you need to specify the "ChanNameOfInterest").

for x = 1:numel(ConvertedData.Data.MeasuredData)

fprintf('\nData set %.0f is %s and contains %.0f samples.\n',x,ConvertedData.Data.MeasuredData(x).Name,ConvertedData.Data.MeasuredData(x).Total_Samples)

if strcmpi(ChanNameOfInterest,ConvertedData.Data.MeasuredData(x).Name)
MyData=ConvertedData.Data.MeasuredData(x).Data
end

end

If this method doesn't work, then NI may have changed their file format (again). If all else fails, you should be able to find a free TDMS reader as an Excel add-in.

HTH,

Robert

23 Apr 2012 Xiao

Hi all, I got same issue as Current got. convetTDMS() works OK, but created mat file can not retrive measured data, only structure. Did I miss something?

23 Mar 2012 Daniel

Many thanks to all who made this possible. It is a huge improvement over the DLLs that NI publishes.

04 Feb 2012 Current

Hi, thank you very much for developing this code. I am having some trouble extracting the data from my TDMS files. After conversion, there will be a 1x1 structure with "FileName", "FileFolder", "SegTDMSVerNum", "NumOfSegments", and "Data". However, none of these values contain the actual measurement data. Under "Data", it only lists the names of the channels measured from my data acquisition board (under "MeasuredData", and the "Root".

Does this code allow you to be able to extract the measured data? Or only the structure of the TDMS file.

Thanks!

04 Nov 2011 Daeniel

You need two input arguments.
e.g.:
a = convertTDMS(0,'filename.tdms');

Zero as the first argument states that you don´t want Matlab to save the converted data automatically. If you give a 1 as the first argument the data will automatically be saved as a .mat- file.

It works for me! Thank you very much. Saves a lot of time.

BR, Daeniel

10 Oct 2011 Daniele

Hello. I can't run this application. When I press the start button the following error appears:

??? Error using ==> convertTDMS at 225
Not enough input arguments.

I'm still a dummy user of Matlab....

Can you help me, please? Thanks.

Regards

Daniele

22 Sep 2011 tony  
27 May 2011 Ivy

Thank you for your contribution. I appreciate it.

In my case, reading 85 MB TDMS file takes 1 hour. And there is an error:
In an assignment A(:) = B, the number of elements in A and B
must be the same.

Error in ==> convertTDMS>postProcess at 1109
Value(c)=index.(cname).(cfield).value;

Error in ==> convertTDMS at 287
[ConvertedData(fnum).Data,CurrGroupNames]=postProcess(ob,channelinfo);

Thank you!

17 May 2011 Robert

Thanks to Philip Top, the updated function dated 17 MAY 11 fixes a couple of bugs that arose with NI-DAQmx 9.2.3. It should post here soon. I don't know if it will help with the "out of memory" issue that Sage has encountered.

06 May 2011 Sage Hahn

With large test files I am getting>

Converting 'testData.tdms' ...??? Error Out of Memory. Type HELP MEMORY for your options.

Error in ==> convertTDMS>getChannelInfo at 584
index.(obname).index = zeros(NumOfSeg,1);

Error in ==> convertTDMS at 292
channelinfo=getChannelInfo(fid,SegInfo,NumOfSeg);

Watching memory usage as file is converted I see huge spike right be for error occurs (obviously).

07 Apr 2011 George Metaxas

A great routine, worked 100% right away. Thanks Robert!

06 Apr 2011 Noah

Works Great. Thanks for the update. Tried to use the NI files alone and it was a mess. This was much cleaner and works very cleanly. Thanks again.

18 Mar 2011 Sage Hahn

This update has resolved my previous problems reading test files. Thank you so much!

18 Mar 2011 Robert

Thanks to Philip Top and Pribislav, the updated function dated 18 MAR 11 fixes several bugs. It should post here soon.

10 Feb 2011 Pribislav

Hi Robert & Michael,
first of all thanks to both of you for helping out all those desperate Matlab users. However I found a "solution" to my problem. The function Michael wrote and published at NI works perfectly fine with Matlab 2010b (but not 2008a). I think the problem is somehow due to the fact that my TDMS file contains strings and integers. It is certainly not due to interleaved data, I checked that one (they are not interleaved).

Cheers,
Pribislav

10 Feb 2011 Robert

Hi Pribislav,

It sounds like to me that your issue may be caused by interleaved data. Regrettably, dealing with that is out of my realm of expertise. I recommend checking your LabView application that's creating the file to see if it is in fact writing the data with an interleaved layout. Unfortunately, LabView may be doing it automatically (i.e. you can't change it) as part of its undocumented "optimization" algorithm. I suspect that the latter is the case, especially since the Excel TDMS add-in reads the file correctly. Perhaps Philip Top has some recommendations on how to fix your issue.

As you found out, using NI's DLL isn't a very robust solution. Initially, I tried using it to read my TDMS files and it didn't take long for me to abandon that approach and develop this function.

Sorry I can't be more help.

Regards,

Robert

07 Feb 2011 Pribislav

Mike,

thanks for your reply. I tried your script already. Unfortunately Matlab crashed completely when running it (Segmentation violation, somehow connected to the m_interpreter.dll). For the ConvertTDMS.m v9 script I could figure out, that some values are just skipped, meaning that all values being read are correct but huge chunks in between are missing. Somehow the datastartindex and/or the multiplier miss some entries.

Thanks, Pribislav

07 Feb 2011 Michael

Pribislav,

I had a similar issue with some of my TDMS files. I don't know if it is a viable option for you or not, but I wrote a MATLAB script that makes use of NI's DLL to process TDMS files. That wasn't my preferred solution, but it works for my files. See the link in my post from 21 JAN 2011 above.

-Mike

05 Feb 2011 Pribislav

Thanks a lot for this great import function and all the work you put into it. However I have a problem reading some data. Most of the TDMS file is read perfectly fine as compared to the Excel-importer result. But in two channels the data are somehow messed up. The TDMS file consists of 42 channels in 4 groups. All but two channels have the same size (approx. 500 values). These two channels have more like 5000 values, but vary in size. The first values in these channels are ok but after approx. 10 values some values are skipped and after approx. 700 values there are only zeros until the end. But the size of the channel is correctly read. These values are usually 4 to 7 digits long and are written as doubles. I run Matlab 2008a on a Windows XP machine. I would be really gratefull for any hint to solve this issue.

Thanks a lot,
Pribislav

21 Jan 2011 Michael

I would have preferred to use a native MATLAB solution like the one provided here for importing TDMS data, but ConvertTDMS still doesn't work correctly with all of TDMS files.

For this reason I resorted to using NI's TDMS reading DLL. The script they provide is pretty useless so I wrote my own. Because it uses NI's DLL, it should work properly with all TDMS files (in theory at least).

Check this NI forum page if using a MATLAB script with NI's DLL is a viable solution for you. You are welcome to steal and adapt the script I wrote. http://forums.ni.com/t5/LabVIEW/TDMS-file-will-not-properly-import-into-Matlab/m-p/1415232#M548709

21 Jan 2011 Joacim

Seems like a lot of people are trying to import tdms in Matlab. I have a solution that works for me, reading 320 MB in less than 4 seconds. However, at the moment it requires that the .tdms file is accompanied by a "_meta.txt" file generated by the NI-software.
My question to you: Is this meta-file generated by all NI-software?

20 Jan 2011 Brad Humphreys

First, It's great to see that this tool carried forward. When I wrote this back with version 1.0 tdms files, I thought that I must be creating something others already had but I could not find (never liked the issues that we had to wait on new compiled versions of the .dll when Labview or MATLAB changed).

I did want to pass along one suggestion to those using it. This is actually a LV programming suggestion (hah). A lot of the time when there is complaints about the speed of reading TDMS files it is often related to how the "TDMSWrite" function was called in LV. Every time the write is called, it inserts all of the descriptive header data between the actual raw data. This means that the header data has to be read and parsed. CALL THE TDMSWrite only when you need to in Labview, concat your waveforms or arrays together over several cycles and then TDMSwrite. It will immensely help the speed (and file size). I believe this is what the LV tdms optimizer cleans up. Not for sure, but it looks like there are people here that would know ;)

20 Jan 2011 Brad Humphreys  
20 Dec 2010 Robert

Since I can't reproduce the error with any of the sample data files that I have, I'm sorry to say that I can't attempt to fix your issue without a file that does.

15 Dec 2010 Sage Hahn

recent change in the file I am processing. Not sure what change is causing it. Cannot supply file. Sorry for being 0 help.

15 Dec 2010 Robert

Hi Sage,

What do you mean by "... recent format change.. "? Is that a change in how LabView is writing the file, did you change TDMS versions, etc.? If possible, can you please send me a sample data file? That'll probably be the easiest way to try to debug this.

Thanks,

Robert

14 Dec 2010 Sage Hahn

This file has been very helpful to me, however a recent format change has generated this error.

Converting 'TestFormat1_345569974.tdms'...??? Subscript indices must either be real positive integers or logicals.

Error in ==> convertTDMS>getChannelInfo at 605
index.(obname).datastartindex(ccnt)=SegInfo.DataStartPosn(segCnt);

Error in ==> convertTDMS at 268
channelinfo=getChannelInfo(fid,SegInfo,NumOfSeg);

14 Dec 2010 Sage Hahn  
06 Dec 2010 Johan

Hurray!! The new version works great. Thank you so much Robert and Philip and possibly others who have contributed! /Johan

17 Nov 2010 Jeremie CLEMENT

Brillant!

Thank you very much to anyone who was involved in writing this code.

Regards,
Jeremie

16 Nov 2010 Robert

Thanks to some outstanding work from Philip Top, the updated file dated 16 NOV 10 fixes the issue of loading data files that have been "optimized" by LabView. Additionally, he restructured the code to decrease the data loading time.

29 Oct 2010 Robert

Hi Jeremie,

At this point, that's probably the most realistic workaround: Launching Excel as a COM object in MATLAB then call the TDMS Add-in function. It will be significantly slower, but at least it will load the data correctly. If I could just get a look at the code within the XLA, I think I could fix the 'convertTDMS.m' function to process optimized files. Unfortunately, that's not possible because it's a compiled application written by NI. Hopefully, I'll be able to eventually get the issue resolved.

Cheers,

Robert

29 Oct 2010 Jeremie CLEMENT

Hi Robert,

Thank you very much for looking into our issue here.
I managed to achieve what I wanted i.e. have our TDMS converted into matfiles, but it is using excel tdms converter from matlab which is much less convenient than your function.

I'll keep an eye on this page to see if any solution comes up as it would be very useful for us.

Thanks again for your time and effort.
Regards,
Jeremie

27 Oct 2010 Robert

Hi Martin,

No, I haven't encountered this error before. If possible, can you please send me a sample data file?

Thanks,

Robert

27 Oct 2010 Martin

Hello Robert,

I'm really pleased to find a tdms program for Matlab, thank you for the effort - it will make my life soo much easier.

At the moment when I try and import this file I get the error below. Is this something you have seen before please?

Thank you,

Martin

Converting '4.tdms'...??? Reference to non-existent field 'cnt'.

Error in ==> convertTDMS>postProcess at 947
if ob.(cname).(cfield).cnt==1

Error in ==> convertTDMS at 796
[ConvertedData(fnum).Data,CurrGroupNames]=postProcess(ob);

27 Oct 2010 Robert

Hi Johan,

I actually attempted the NI "help desk" route before I decided to write this function. I too thought that NI would want to help. But, that turned-out not to be the case. I basically got referred to a clunky DLL. I did attempt to use it, but it's not robust (i.e. it didn't work with many of my TDMS files), it's very memory intensive and it's very slow. I took some time to try to fix the DLL, but I wasn't able to make it much better. After that, I finally decided to use version 4 of the "convertTDMS.m" function and the web site I posted on 25 OCT 10 to write my own function. There's been a long standing conflict between LabView/NI and The MathWorks because as they've both continued to grow, they have encroached into each other's areas of expertise. My experience has been that neither of those companies are anxious to help users with applications that use their competitors products. I even attempted to get NI help by saying I was writing a C-based application (i.e. not mentioning MATLAB), but even that didn't work. I'm quite sure the expertise to fix my MATLAB function exists within NI, but I doubt I'll ever get access to it. Hopefully, there's a MATLAB user out there that's more knowledgeable than me on the NI end of things that can help make this function more robust.

Cheers,

Robert

27 Oct 2010 Johan

Hi Robert,

Thank you very much for looking into this. The internal layout of a TDMS file seems quite complicated so I understand you're having difficulties. Isn't there anyone at NI who can help us out here? Shouldn't it be of their interest too that there is a well functioning TDMS converter?

I really appreciate your efforts. Regards! /Johan

26 Oct 2010 Robert

The updated file dated 25 OCT 10 fixes an error with channels that contain no data. Previously, if a channel contained no data, then it was not passed to the output structure even if it did contain properties. It also fixes an error with capturing the properties of the Root object. "GroupNames" was added as an optional output variable. Unfortunately, this update does not address the multi-segment "optimization" issue.

25 Oct 2010 Robert

Hi Jeremie,

I think you're having the same issue as Johan. Unfortunately, I don't have a solution yet.

Sorry,

Robert

25 Oct 2010 Robert

For some reason, the NI link didn't post correctly... http://zone.ni.com/devzone/cda/tut/p/id/5696

25 Oct 2010 Robert

Hi Johan,

You are not the only one who has encountered this issue. I have received emails from several people with what appears to be the same problem (I believe Johan's problem has the same cause). I believe it has to do with how NI applications "optimize" data files that have multiple segments (see the paragraph titled "Optimization" in this NI document: http://zone.ni.com/devzone/cda/tut/p/id/5696). Unfortunately, my function does not appear to properly parse the binary file when the optimization algorithm is invoked. It seems to happen more with TDMS version 4713 files with multiple segments (>10). At this point in time, I'm not sure how to fix the issue. I'm not hopeful that I can fix it anytime soon, especially after reading the last sentence in the "Conclusion" paragraph of the NI document:

"In brief, the TDMS file format is designed to write and read measured data at very high speed, while maintaining a hierarchical system of descriptive information. While the binary layout by itself is rather simple, the optimizations enabled by writing meta data incrementally can lead to very sophisticated file configurations."

If anyone has managed to fix this issue, please let me know.

As far as your date issue, I'm not sure what's going on with the "wf_start_time". I've never investigated it because none of the files I deal with daily store any of the waveform properties. I suspect it has to do with the fact that LabView and MATLAB use different reference years. Also, MATLAB does not have a string form of the date that includes fractions of seconds. You could modify the function to store the date as a number (instead of converting it to "dd-mmm-yyyy HH:MM:SS") which does keep fractions of seconds.

HTH,

Robert

25 Oct 2010 Jeremie CLEMENT

Hello,

This function is also very usefull for me. Exactly the tool I need.
But when used to convert a TDMS file coming from a brake dyno, it seems to randomly miss out some values.
So, for example, when an excell TDMS converter will read 1815 values in one block, this function will read only 615values. We are logging at 50Hz, and when analysing the result file, we can see that the time is fine from 0 to 0.54 and then suddenly jump to 1.96... It is the same for all the other channels, missing out random values.

I would really appreciate if someone could help me out.

Thank you for your time.
Best regards
Jeremie

21 Oct 2010 Johan

Ooops! The rating posted itself before I had the chance to write something.

I really like this function. It is exactly the tool that I need. However, when I try to convert my set of data, it only includes the first 2.000 samples in the mat-file. My original TDMS file contains 300.000 samples per channel and I cannot figure out why it suddenly stops. I have noticed that it loops through 300 segments, each of which contain 1000 samples per channel. After two such turns, the length of the "index vector" reduces to 1 and thereafter, no more samples are read.

Do I have a problem with my TDMS file that convertTDMS cannot interpret or is this due to some bug in the function? I have tried both (v6) and (v8) .

Further, I noticed that the wf_start_time property is not calculated correctly. It differs 6 hours between LabVIEW's TDMS Viewer and the converted mat-file. It would also be nice if it contained fractional seconds.

I would really appreciate if somebody could look into this. I can send my TDMS-file via e-mail or upload it somewhere if that helps.

Regards // Johan

13 Oct 2010 Robert

Most of the recent errors I have received from users have related in some way to long channel/property names and/or channel/property names that contain special characters (ä, #, ß, é, etc.). These errors happen because the function I used as a basis to write my first version of the current function used those names as the basis for creating structure fieldnames which means they have to adhere to the MATLAB rules for variable names. Accordingly, the main function included a sub-function to create compliant fieldnames. While this technique worked for many data files, it's not very robust and the channel/property names can end-up quite convoluted from their original values. Sometimes it was difficult to correlate fieldnames to channels.

Also, I recently found out that my algorithm to create compliant field names did not work correctly with very long channel names (thanks to Peter Sulcs). It generated the most bothersome kind of error: It didn't trip an actual error, per se; instead, it just concatenated additional data into the wrong channel. So, the user wouldn't necessary know an error had occurred.

In light of all this, I have posted an updated function (posted 12 OCT 10). Now, the sections of the function that create the channel/property names that are used within the body of the function are robust against long channel/property names and names that contain non-UTF8 characters. The original channel/property names are now retained (with no truncation or character replacement) and included in the output structure. I have added the option to return the list of channel names in its own cell array. I have also added a much more detailed 'help' description to the function ('doc convertTDMS'). In the process of modifying the function, I discovered (and corrected) an error in the time stamp calculation (it was off by exactly 1 hour) that appears to have been present since the first version. Unfortunately, I am only able to test the function with a limited number of diverse TDMS files.

30 Sep 2010 Robert

The updated file dated 30 SEP 10 hopefully addresses the issue of special characters by identifying characters that are not "A" through "Z", "a" through "z", 0 through 9 or underscore. The characters are replaced with an underscore and a message is written to the Command Window explaining to the user what has happened and how to fix it. This may not be the best solution, but it should be robust. Unfortunately, I was only able to test it with a very limited number of special characters.

30 Sep 2010 Robert

The special characters that have been identified so far are enumerated in the 'fixcharformatlab' local function (line 767 within version 1.7 updated 29 SEP 10). Add the following line to the bottom of the block of special characters that are already listed within the function: textin=strrep(textin,'é','e'); I intend to determine a more robust method (as opposed to enumeration) to handle the myriad of possible special characters. HTH

30 Sep 2010 callisto genco

Hi,

I have download the converter ver 1.7. It is a great job and I see I will save a lot of time.

Unfortunately I have a filename problem:

I have the software Signal Express version 2.5 in french. It has generated files:
Déformation.tdms_index
Déformation.tdms

with the french "é". It gives me the field error "A valid file name could not be created". I changed the tdms datafile in Deformation and I get the same error. I know I can change the file name in the sgnal express software for the next time. Unfortunately I have already generated the sata and it looks like the file name in inside the tdms file as well.
Is there any solution for these problems ?

Regards

Callisto Genco

29 Sep 2010 Robert

Thanks to André Rüegg for his work in developing the 29 SEP 10 update

22 Sep 2010 Robert

Thanks for the suggestion Michael. For some reason, I hadn't thought to do that; it's done now. That's also a good idea to include your modifications in any future updates. I suspect that it'll make the function more robust.

22 Sep 2010 Michael

Robert,

Please post a comment on the thread for previous versions of this utility if you are going to post a new version of the ConvertTDMS utility as opposed to an update (I was "watching" the v6 page, but had no idea that you had already posted this v7 until you responded to Chris' post).

Thanks for the utility though. I have had success with it in modified form (making many of the modifications you have done in parallel to you as well as a few of my own). Once I finish making the changes that help me in my particular application, I'd like to coordinate with you so that my changes get wrapped into your latest version.

Mike

20 Sep 2010 Mark Shore

My suggestion would be to keep the TDMS converter FEX submissions as a single file, with updates, rather than starting a new file number for each new version.

I have not rated it, since when testing with fairly large TDMS files (240 MB) the previous TDMS converter took far longer to read the file (in fact, I halted the process after five minutes) than writing a MATLAB-readable binary data file in LabVIEW and then importing it into MATLAB directly.

Other people's results may differ, of course.

Updates
22 Sep 2010

Fixes error encountered with some data files containing waveform data

29 Sep 2010

Adds capability to read files independent of the character encoding set in MATLAB. Also fixes error reading files containing objects with the same raw data in successive segments.

30 Sep 2010

Adds "error trapping" for group and channel names that contain characters that are not "A" through "Z", "a" through "z", 0 through 9 or underscore.

12 Oct 2010

Improved robustness against channel/property names. Fixed an error in the time stamp conversion. Added 'Channel List' as an optional output parameter. Added a more detailed 'help' description.

19 Oct 2010

Fixed an error with the 'save' routine.

25 Oct 2010

Fixed an error with channels that contain no data. Fixed an error with capturing the properties of the Root object. Added 'GroupNames' as an optional output variable.

16 Nov 2010

Code restructured to decrease data loading time. Fixed the issue with reading "optimized" files.

18 Mar 2011

Fixed some bugs with string input and file optimization with TDMS version 2 files.

17 May 2011

Fixes a couple of bugs that arose with NI-DAQmx 9.2.3.

Contact us