File Exchange

image thumbnail

ConvertTDMS (v10)

version 1.5 (38.1 KB) by

Import or convert a LabView TDMS file into the MATLAB workspace or a mat file

4.66667
11 Ratings

165 Downloads

Updated

Import or convert a LabView TDMS file (version 1.0 through 2.0). Interleaved and Non-Interleaved tdms files are supported.
These functions also work with tdms files that contain channels using the DAQmxRaw data typr (raw ADC data written by LV), if the files are translated first using the information found at: https://decibel.ni.com/content/docs/DOC-32817

Adding another submission so that Robert Seltzer who has provided a great deal of support for several years and is no longer actively working with TDMS files can hand back off development.

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. Robert Seltzer of Borg Warner has provided a great deal of support and input. this version is the first using FileEx's new GitHub interface (thanks Mathworks!).

This function has been tested with a limited number of diverse TDMS files.

Comments and Ratings (71)

twreal

twreal (view profile)

Hello I am having an issue with his script:
I am loading a file which is rather large (2h of data logged at 10kHz) ~~2GB what is the maximum limit of import file lenght???

I get :
Error using TDMS_readFileHelper_v1 (line 188)
Catastrophic error detected, code probably has an error somewhere

Error in TDMS_readTDMSFile (line 252)
    data = TDMS_readFileHelper_v1(fid,optionStruct,metaStruct,paramsStruct);

Error in TDMS_getStruct (line 57)
[temp,metaStruct] = TDMS_readTDMSFile(filePath,readOptions{:});

Error in TM_TDMS_IMPORT (line 2)
TM_tdms_struct = TDMS_getStruct(filename,3);

Hi Brad,

Thank you for the script!
I have sometimes a problem, on some measurments and on some channels, the converted data is corrupted, that means a lot of e308 and e-300 infinite values.

the files are rather small.

what do you think the problem is?

Thanks,

Lior

C.-S.

C.-S. (view profile)

Hi Brad,
I do a little study. It turns out Timestamp is in Universal Time. In your code, "propsValue=tsec/86400+695422-4/24;" (line 932), I guess your time zone is UTC-4. Therefore, need to minus 4 hours to get right datetime. In my case, need to add 8 hours because of my timezone is UTC+8. I wonder if any UTC offset property exist in TDMS property?

C.-S.

C.-S. (view profile)

Hi Brad,
Thank you for your contribution. One problem occurred while using your code. The attribute, wf_start_time, got in ConvertdData.Data.MeasuredData.Property shifts 12 hours. For example, actual start time is 08-Feb-2017 12:17:28 but ConvertTDMS gives '09-Feb-2017 00:17:28'. Any idea about this problem?

Thanks a lot.

C.S.

Thanks!

Hello Brad,

thank you for publishing this scripts. We have been using it very successfully to convert data we acquired with our LabView setup.

However we would like to replace the LabView data acquisition program with a .Net solution. The workaround to convert DAQmxRaw data TDMS files to regular files therefore doesn't work anymore. Do you have any ideas how we can solve this problem? Do you know of any way to convert DAQmxRaw files without using LabView?

Thanks a lot,
Johannes

annie Moy

Hi

I am trying to use the convertTDMS file to read in a TDMS file that I have but it looks like it skips my second column of data when it process . Is there a section in the code where it sets the length of the data it reads?

I know that it skips my second column data because when it saves the data position it points to the first column data.

I suspect the issue might be in this code:

Ttag=fread(fid,1,'uint8','l');
    Dtag=fread(fid,1,'uint8','l');
    Stag=fread(fid,1,'uint8','l');
    mtag=fread(fid,1,'uint8','l');

but i don't understand what the position number means in terms of excel colums(i can open it in excel importer add in).

Jacob Hedrick

The following error message occurs when processing "raw" formatted TDMS files from a cDAQ generated by NI CAS.

```
Converting 'Raw000.tdms'...Error using zeros
NaN and Inf not allowed.

Error in convertTDMS>getData (line 1156)
            ob.(cname).data=zeros(nsamples,1);

Error in convertTDMS (line 338)
    ob=getData(fid,channelinfo,SegInfo); %Returns the objects which have data. See postProcess function (appends to all of the objects)
```

See the githib repo and issue #5 for more details.

Every other TDMS parser (excel, python) we've tried seems to not have an issue with these files.

Can't tell if the problem comes from reading off the wrong datatype from various channels, or if there is an error reading TOC which sets the 2nd `datastartindex` to zero.

We tried a hotfix by deleting the index with a zero `datastartindex`, and it does drop out a segment but all other data seems to be have the right shape, although not the correct value as the datatype is wrong.

Any ideas? Any suggested way of debugging this issue?

Ralf

Ralf (view profile)

Hi Brad,

thank you for your reply. I will ask the creator of these large files to convert them for me into smaller ones.

Brad Humphreys

Brad Humphreys (view profile)

Ralf,

I am afraid that I don't have a good answer for you. That is a very large file. I typically set my TDMS writes to start a new files after they reach about 100MB. This is not just for converting to MATLAB, it is pretty easy for a file that size to get corrupted (I know from experience). You might me able to write a VI that reads it and breaks it up.

Ralf

Ralf (view profile)

I need to convert a large tdms file (450 MB) and I am getting out of memory messages:

Error using zeros
Out of memory. Type HELP MEMORY for your options.

Error in convertTDMS>getChannelInfo (line 719)
                index.(obname).byteSize=zeros(NumOfSeg,1);

Error in convertTDMS (line 332)
    [channelinfo SegInfo]=getChannelInfo(fid,SegInfo,NumOfSeg);

Is there anything I can do?
I figured out that my file contains at least 255 objects (obname) with 655201 NumOfSeg each.

Thank you very much!

Good, but the timestamps appear to be 12 hours too early

Brad Humphreys

Brad Humphreys (view profile)

Would someone be able to email me (or drop box) a tdms file with the issue below in it? I have not been able to replicate it and I think it is from a datatype that I don't typically use. My email is on my author page.

Hi Brad,

I am having the same issue with line 991, with some, but not all of my TDMS files. When I add the index.(obname) line, I get the following:

name: 'Object119'
         long_name: 'Synchronous Waveforms - 1'
      rawdatacount: 1
    datastartindex: [4188x1 double]
          arrayDim: [4188x1 double]
           nValues: [4188x1 double]
          byteSize: [4188x1 double]
             index: [4188x1 double]
     rawdataoffset: [4188x1 double]
        multiplier: [4188x1 double]
              skip: [4188x1 double]
      rawdataindex: 0
         Property1: [1x1 struct]
      PropertyInfo: [1x1 struct]

Any solutions out there yet?

Michael

Hello. My LabVIEW TDMS file has 7 columns of data (N x 7 columns), when I convert them to Matlab, I have 7 data variables representing each column of the original LabVIEW data file, I need these 7 columns to be in a single Matlab.mat file (N x 7 Column) array where each column in Matlab is the same as LabVIEW. Right now, after the conversion, I have 7 variables/structure. Please help.

Chuan He

Hello Brad,

I added the code before 991. Here is what I got:

Converting 'TR5277time_20150730_212206_Mod1_ai0.tdms'...
ans =

              name: 'Object1'
         long_name: [1x46 char]
      rawdatacount: 1
    datastartindex: [3x1 double]
          arrayDim: [3x1 double]
           nValues: [3x1 double]
          byteSize: [3x1 double]
             index: [3x1 double]
     rawdataoffset: [3x1 double]
        multiplier: [3x1 double]
              skip: [3x1 double]
          dataType: 9
          datasize: 4

ans =

              name: 'Object1'
         long_name: [1x46 char]
      rawdatacount: 2
    datastartindex: [3x1 double]
          arrayDim: [3x1 double]
           nValues: [3x1 double]
          byteSize: [3x1 double]
             index: [3x1 double]
     rawdataoffset: [3x1 double]
        multiplier: [3x1 double]
              skip: [3x1 double]
          dataType: 9
          datasize: 4

Subscript indices must either be real positive integers or
logicals.

Error in convertTDMS>getChannelInfo (line 782)
                    index.(obname).datastartindex(ccnt)=0;
                    

Michael Kolb

Hi Brad,

thanks for investing time.
I did what you suggested. The object data is:
              name: 'Object2'
         long_name: 'RPS-KBM-II'
      rawdatacount: 1
    datastartindex: [45x1 double]
          arrayDim: [45x1 double]
           nValues: [45x1 double]
          byteSize: [45x1 double]
             index: [45x1 double]
     rawdataoffset: [45x1 double]
        multiplier: [45x1 double]
              skip: [45x1 double]
      rawdataindex: 0
         Property1: [1x1 struct]
         Property2: [1x1 struct]
         Property3: [1x1 struct]
         Property4: [1x1 struct]
      PropertyInfo: [1x4 struct]

Brad Humphreys

Brad Humphreys (view profile)

To troubleshoot this, could one of you remove the code that Michael's code (good idea though) and add a line before 991:

index.(obname)
if index.(obname).dataType..... <line 991

This will output the object to the command line. Then when you get the error, let me know what it says. Thanks!

Chuan He

Hi Micheal,

I got the same error as you.

Error in convertTDMS>getChannelInfo (line 991)
if index.(obname).dataType==32 %Datatype is a string

I added these three lines after line 986.

if isfield(index.(obname),'dataType')==0
index.(obname).dataType=32;
end

But I got other error
Error:
Subscript indices must either be real positive integers or logicals.

Error in convertTDMS>getChannelInfo (line 782)
index.(obname).datastartindex(ccnt)=0;

Do you have any idea to fix it?

Thanks,

Chuan

Michael Kolb

Michael Kolb

Hi all,

I got the same error other got before and wanted to share my dirty fix:
Error:
Error in convertTDMS>getChannelInfo (line 991)
if index.(obname).dataType==32 %Datatype is a string

So somehow there is a path in the code where the Datatype of the object is not set. When the datatype is checked the program crashes.
So my fix is to set the Datatype to 32 if no Datatype is set.

To do so, you have to add these three lines after line 986 in convertTDMS.m of the version 1.991 (its in the package convert v10 you can download today (03.09.2015)):

             if isfield(index.(obname),'dataType')==0
                index.(obname).dataType=32;
             end

I know it is dirty, but works for me and hopefully also for some of you guys.

I would like to appriciate the work of the active developers of this very useful tool!

Brad Humphreys

Brad Humphreys (view profile)

This code is platform independent (Linux or Windows). A TDMS file generated on Linux or a Windows based device will be the same. Same with reading it; should work on MATLAB running in windows and Linux (I do this regularly). MATLAB 2012 and 2013 both also work. This does not use any compiled libraries (.dll, .so, etc). It just uses the code in the m-file so you should not have to worry about OS, LV, or MATLAB versions (with a couple minor exceptions)

Craig Schiro

Hi Brad—
I am working to get my Matlab upgraded to MATLAB 8.2(R2013b) so I can make an attempt to convert a cRIO-9036 Chassis Linux generated TDMS file into a Matlab object. I am having Matlab (2012b) loadlibrary issues with http://www.ni.com/example/30957/en/ . Do you know if your utility will work on 2012b?
I am running on windows 8.1 and wanted to know if all I need is this version of Matlab and my TDMS file and I am set? I see you say “Other Requirements” is None- that’s the beauty of it.
I hope this is the case.
Regards,
Craig

Brad Humphreys

Brad Humphreys (view profile)

Francisco - Would it be possible for you to upload your data file to the github repo (https://github.com/humphreysb/ConvertTDMS/tree/master/exampleFiles) or possibly put them somewhere that I could download them. See my author page for my email address.

Francisco

Dear Brad, I'm experiencing some problems loading data from TDMS file. In my file I have 8 channels with 1261568 samples each. When I try to load them using convertTDMS it loads 1277952 samples, where, in fact, the last 16384 are zero. Is this a bug in the script?
---
Thanks

Frank Peng

Dear Brad,
Thank you for this work. This function works well when reading the example *.tdms file, simple_test.tdms. But I have some problems when read my own *.tdms files. The warning messages are as bellow:
Error using convertTDMS>getSegInfo (line 530)

 Seqment 1 of the above file contains data in the DAQmxRaw NI datatype
 format which is not supported with this function. See help
 documentation in convertTDMS.m for how to fix this.

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

Error in simpleConvertTDMS (line 94)
    [convertedData,dataOb.convertVer,d.chanNames,d.groupNames,dataOb.ci]=convertTDMS(0,tdmsFileName);
    
Error in ReadTdmsFile (line 3)
matFileName = simpleConvertTDMS('Test_001[fs=48000].tdms');

Can you fix it?

SImon Engler

Dear Brad,
thank you for this function. It works pretty well, but i have a problem that i can´t solve on my own. I am using
the function simpleConvertTDMS in an testbench, and I convert data in 2 groups: The first group is named "Messwerte FSZV" with
8 vectors with up to 200.000 entries each vector - this group works fine. The secound group "Skalare" has 10 strings with the names
"Samplerate", "PositionTiefenanschlag","Backenwerkstoff",... .Each of these Variables has exactly one value, e.g.
Samplerate | PositionTiefenanschlag|Backenwerkstoff|...
10 | 367 | S600 | ...
after using simpleConvertTDMS and loading the .mat file, i have all of them in the Workspace. The problem is, the every variable
has the the value of the first entry ("10"), so in MatLab its:
SkalareSamplerate | SkalarePositionTiefenanschlag | SkalareBackenwerkstoff |...
10 | 10| 10| ...
can you tell what i am doing wrong / what the crux of the matter is?
greetings Simon

Matlab Version: R2013a

used code:

simpleConvertTDMS('FSZV.tdms');
load ('FSZV.mat');

Brad Humphreys

Brad Humphreys (view profile)

Brian - getting a copy of the file would be great. My email address is in my profile. Or if you use GitHub, you can add it to the repository.

Brian Kaul

Yes, sorry, they're just different tdms files we generate. The one we call "raw" contains all of the raw data and is very large; the one we call a "summary" file contains a summary of calculated values and is much smaller. But it's the latter, smaller file that we cannot successfully read using convertTDMS, so it doesn't seem to be size-related as Sebastian's was, although the error message is the same. I can e-mail or upload an example file if needed.

Brad Humphreys

Brad Humphreys (view profile)

Brian - I'm not sure what you mean by a "raw" and a "summary" file. are these both .tdms files that you generate? Or is one of them a .tdms_index file?

Brian Kaul

I'm getting the same error as Sebastian, but not with particularly large files. My data system saves both a "raw" file and a "summary" file; the former can be 500 MB and imports fine, while the latter is 3.5 MB and does not:

Reference to non-existent field 'dataType'.

Error in convertTDMS>getChannelInfo (line 991)
                if index.(obname).dataType==32 %Datatype is a string

Error in convertTDMS (line 332)
    [channelinfo SegInfo]=getChannelInfo(fid,SegInfo,NumOfSeg);

Brad Humphreys

Brad Humphreys (view profile)

I have updated this functions after it was pointed out that the contents of convertTDMS had got copied into the simpleConvertTDMS file. If you are using this set of files for the first time, I suggest starting with the simpleConvertTDMS function.

Brad Humphreys

Brad Humphreys (view profile)

Sebastion - I have added a directory on GitHub to upload files that you are having trouble with for troubleshooting. I have also updated the readme file to describe large file handling.

Sebastian

I have Problem with larger files. I have a file with 5.000.000 lines, I can convert it if I cut it to 147.000 lines. If I cut it to e.g. 300.000 lines I get the following error:

Reference to non-existent field 'dataType'.

Error in simpleConvertTDMS>getChannelInfo (line 983)
                if index.(obname).dataType==32 %Datatype is a string

Error in simpleConvertTDMS (line 324)
    [channelinfo SegInfo]=getChannelInfo(fid,SegInfo,NumOfSeg);

Jack Sharer

I need the native type (class) of the LabView data retained to support uint64 in particular. To accomplish this, I added/changed these lines near original line 1123 in convertTDMS.m:
elseif id.dataType==68
ob.(cname).data=zeros(nsamples,1);
else
ob.(cname).data=zeros(nsamples,1,LV2MatlabDataType(id.dataType));
I also changed line 1213 to
[data,cnt]=fread(fid,nvals*id.multiplier(rr),['*',matType],kTocEndian);

Brad Humphreys

Brad Humphreys (view profile)

Alan, can you email me an example file? (see my profile for my email address)

Alan

Alan (view profile)

Fails at

Error in convertTDMS>getChannelInfo (line 754)
                    index.(obname).arrayDim(ccnt)=index.(obname).arrayDim(ccnt-1);

because ccnt = 1

Brad Humphreys

Brad Humphreys (view profile)

I have updated converter (v1.99) to address an issue with properties updating after raw data is written in a file. Use the "Get From GitHub" button above to download latest version.

Tie Xue

How can I download the code?

Brad Humphreys

Brad Humphreys (view profile)

Stephen - If you wrote the channel as a waveform, you can find the start time in the channel's property. For example, after running simpleConvertTdms, channelName.Property.wf_start_time will have the starting time of the waveform.

Been using this file extensively. I can't determine how to bring out the file start time. Maybe I just can't read the structures.

Grant Lohsen

Need to update the ConvertVer variable.

also, need replace line 427 with this

 else
        fclose(fid);
        
        error('Unable to find TDSm tag. This may not be a tdms file, or you forgot to add the .tdms extension to the filename and are reading the wrong file');
        
    end

this way if you typo the name and feed it a large non tdms file it wont sit there forever searching the file 4 bytes at a time for the TDSm tag

Raj

Raj (view profile)

Great little tool! I've successfully used it on two different projects where we were using LabView + NI A/D converters. Just an FYI, it seems that there is now the capability to host your file-exchange files on GitHub, just like you asked. I found this today when I went to download another file exchange submission called "export_fig": http://www.mathworks.com/matlabcentral/fileexchange/23629-export-fig
I get a nice "Get from GitHub" link instead of the usual "Download Submission" there. You may consider updating your submission.

Randy82

Hello again,

probably I know what the problem was: I use Matlab R2011b and it seems that the function strsplit is unknown there.
So I used following command and it seems to work: splitName=regexp(channelNames{cnum}, '/', 'split')

Randy82

Hello Brad,

I have got a similar problem as Geert.
But in my TDMS-File (when I open it in DIAdem) there is following structure:
The groupname is set together of the name of the project, a date and a timestamp. E.g. like "project - 2014-02-18 05:32:22". In my group there are several channels, e. g. called "channel1", "channel2" and so on.
Now when I use simpleConvertTDMS in Matlab each channel is convertet to "project20140218053222channel1" without any separation or underline between the words.

When I use the code you have suggested i get an error message: Undefined function 'strsplit' for input arguments of type 'char'.

Error in simpleConvertTDMS_test (line 69)
        splitName=strsplit(channelNames{cnum},'/');
 
Thanks for your help!

Geert

Geert (view profile)

Hello Brad,

it works perfect. Thanks a lot !!!

I understand your concern but I do not have the problem of multiple channel groups in one data set so it's fine for me like you proposed.

Brad Humphreys

Brad Humphreys (view profile)

Geert - If you want to do this: In simpleConvertTDMS, after the line:

for cnum=1:numel(channelNames)

Add the following lines:

%--------------
if ~isempty(strfind(channelNames{cnum},'/'));
            splitName=strsplit(channelNames{cnum},'/');
            channelNames{cnum}=splitName{end};
        end
%----------------

You need to be cautious about doing this. The variable names are the GroupName_ChannelNames. In your case it looks like the filename is being used as the group name (this may be the default in LV if no group name is specified. Multiple channel groups can be written to the same .tdms file. If different groups have the same channel names, the channel names are no longer unique and can over write each other using the code above. You may just want to go in your LV code and specify a better group name. Info on the structure of groups and channels in tdms files:http://www.ni.com/white-paper/5696/en/

Geert

Geert (view profile)

Hi Brad,
I used the TDMS-convert scripts with success. They almost do what I was looking for. I have one problem: Each data channel is converted to a structure in the workspace with the name of the file+channelname. I only want the original channelname . I tried to find it back in the scripts but honestly they are like chinese to me :)
How can I change this?
Example:
Channel name in Diadem/Labview = 'speed'
After TDMS convertion to .mat the structurename is "filename'speed'".
I want to run a loop and for example plot ovelays of many files. Therefore same data names in all files works better for me. Thanks a lot!

Brad Humphreys

Brad Humphreys (view profile)

Joseph - We have used these functions to translate files up to 3GB. In general it's not a good practice to write TDMS files over a ~1GB. Typically in Labview, we code for a new tdms file to be "auto-started" every ~500MB. This has saved me several times when a file becomes corrupted (by file handling or LV itself) and we don't loose the whole large data set. So I've never had the need to pull out just a segment during translation. It's something I will look at adding though.

Joseph

Joseph (view profile)

Brad-- Thanks for the response. What I am wondering if there is a method to read segments of a TDMS file, i.e. the first half million pts, then the second half million pts, etc. etc.

Brad Humphreys

Brad Humphreys (view profile)

Joseph - I'm not sure exatly which operation your speaking to. What I suggest for large data files is to:
1) Convert the .tdms file to a .mat file using simpleConvertTDMS.
2) If you want to work with just a particular channel, use the load command to only load the channel from the .mat file: load('FileName.mat','NameOfYourChannel');
3) You can then access the data using: yourData=NameOfYourChannel.Data;

If you need a way to see what channels are in the file without loading whole file, use the "whos" function.

Is that what you are looking for?

Joseph

Joseph (view profile)

I am just new to the NI TDMS format. I have rather large files (high data rates). Is there a way to read segments of the data so that my memory doesn't get obliterated?

Brad Humphreys

Brad Humphreys (view profile)

Zhenwei - You are using the command "a=simpleConvertTDMS();" correct? Then a open file dialog box opens and you are selecting a tdms file that was created by Labview, correct?

Zhenwei

Hi Brad, thank you for your job. I am a freshmen with NI's Device,and I don't know how to use your func to turn a TDMS to a mat file. I would highly appreciate with it if you can help me with detials, how to code with your function.
is this right?
"a=simpleconvert();"
I got error code
"Error in ==> convertTDMS at 304
    [SegInfo,NumOfSeg]=getSegInfo(fid);

Error in ==> simpleConvertTDMS at 58
    [convertedData,dataOb.convertVer,d.chanNames,d.groupNames,dataOb.ci]=convertTDMS(0,tdmsFileName);
    
Error in ==> turn at 3
a=simpleConvertTDMS(); "
thank you a lot. My English is also not so good,I hope you can get my idea.

Brad Humphreys

Brad Humphreys (view profile)

Mark - re: Your question about how data is brought into memory. It's not possible to appened to a variable in a .mat file (It is possible to add whole variables though). So this function intially calculates the needed memory size to store all of the data and then preallocates variables to hold the data. It then fills the variables and once done writes them to the file. So there is minimal resizing of memory space (a MATLAB "best practice" for large variables). We have (often) succesfullly converted multi-GB size files with it.

Mark Ward

Thanks for the update. simpleConvert reads the file ok now.

Brad Humphreys

Brad Humphreys (view profile)

Mark - I submitted an update that modifies simpleConvertTDMS to check and see if the group/channelname starts with a numeric character (it prepends a "d" character at the front if found). The submission is still pending Mathworks approval. Also I figured out why you are getting the date/time stamp.... I had forgotten that the MATLAB variable name is the LV Group Name concatenated with the channel name. It looks like your group name is the date/time stamp.

Mark Ward

Thanks for the quick response!
I'm not deliberately trying to have a channel called 13012014140627VoltageAllData ... I think that it may be auto-generated by labview as it's the date and time of the acquisition. Just putting a letter 'D' in front of anything that starts with a number would be fine. But swapping the starting number to the end is fine too.

Brad Humphreys

Brad Humphreys (view profile)

Sorry, my post got cutoff. It looks like you have a channel that starts with numeric text. In the simple convertor, the LV channel names are used for Matlab variable names. MATLAB can not have variables or fields that begin with numeric text. convertTDMS uses a more generic but cumbersome variable format where the channelnames are not used as variables. I can update the function to swap the numeric begining of the channel name to the end as a fix.

Brad Humphreys

Brad Humphreys (view profile)

Mark - Just wondering, do have channel in LV named "13012014140627VoltageAllData"? If not, this could be a symptom of a different issue.

Mark Ward

ps does it have to have all of the data in ram simultaneously before writing it?
For gathering the readings into a 2d array it looks like combining the
ConvertedData.Data.MeasuredData(jj).Data;
for jj = 3: 2+number of logged channels
will hopefully work. I'm hoping this will still work when the logs are long.

Mark Ward

Thanks for this. I've logged 34 channels of voltage data at 1 kHz and I'm trying to read it now.
Using the "simple convert" vi I get the error
Invalid field name: '13012014140627VoltageAllData'.
Error in simpleConvertTDMS (line 60)
        dataOb.(safeChannelName{cnum}).Data=convertedData.Data.MeasuredData(cnum).Data;

whether or not I've converted it in labview first. (PS I found that changing the "browse options" property of the output filename control to "new or existing" allowed me to create a new file for the output, as opposed to overwriting an existing file)

I don't get an error using the full version, though it seems a bit tricky to work out where the data is amongst the structures. Is there a simple way to reconstruct the channels of data into a 2d array? Thanks

Hi Brad
I made the change and the program was able to convert and save as .mat file. However, when I open the .mat file as text, it is in characters that can't be read, neither was I able to preview the data in Matlab work space. I'll look into this further. Anyway, thanks a lot.

Brad Humphreys

Brad Humphreys (view profile)

This is due to a problem with the try/catch as implmented in a couple of the older versions of MATLAB (http://www.mathworks.com/matlabcentral/newsreader/view_thread/258011). Try changing line 334 to be: " catch, exception=lasterror; " I am guessing then you will get an error message that tells you about why the file can not be saved (possibly you do not have permissions to the create a file in the directory?).

Hi Brad, I ran the program , and an error message saying :"Warning: File: convertTDMS.m Line: 334 Column: 15
 This try-catch syntax will continue to work in R2007a,
 but may be illegal or may mean something different in future releases of MATLAB.
 See Release Notes for MATLAB Version 7.4, "Warning Generated by try-catch" for details.

Error in ==> simpleConvertTDMS at 50
    [convertedData,dataOb.convertVer,d.chanNames,d.groupNames,dataOb.ci]=convertTDMS(0,tdmsFileName);"

I use an 2008 version of matlab, so I'm not sure what to do. Please let me know you have any suggestion. Thanks.

Brad Humphreys

Brad Humphreys (view profile)

My comment below about using the VI to convert only applies if you get an error about DAQmxRaw Data type. Otherwise you should be able to use this function directly.

Brad Humphreys

Brad Humphreys (view profile)

I just submitted an updated function with directions on how to work with data files that have the DAQmxRaw datatype in them (Stepehen Tenney's issue below). The work around is to create a LV VI which reads in the tdms file and then writes it out to another TDMS file (this will convert the datatype to something useable by this function). See: https://decibel.ni.com/content/docs/DOC-32817

Brad, Here's the error and yes it appears to be an undefined data type;

Error using convertTDMSv1>getDataSize (line 1476)
LVData type 4294967295 is not defined

What would this have to do with, the data acquisition box? It's coming from an NI example logger VI.

Brad Humphreys

Brad Humphreys (view profile)

Steve - This would be due to your tdms file having an unsupported datatype (possibly DAQmxRawData. To troubleshoot, please put in the following two lines after line 1468 in convertTDMS:

otherwise
error('LVData type %d is not defined',LVType)

(This follows the line "sz=10;")

Let me know the output of the error message.

I'm getting the following error:

Converting 'array1.tdms'...Error in convertTDMS>getDataSize (line 1450)
switch(LVType)

Output argument "sz" (and maybe others) not assigned during call to
"/Data/Numerics/Matlab2010a/work/convertTDMS/convertTDMS.m>getDataSize".

I'm seeing this in both convertTDMS and simpleConvertTDMS.

I'll continue to look for a solution.

Steve Tenney

Updates

1.5

Added error check per G. Lohsen for stopping when non-TDMS file is selected. replaced call to strsplit per Randy82. Added option to simpleConvertTdms to allow for group name not to be included in variable name.

1.4

Added information to the submission description about how to work with tdms files that have the LV DAQmxRaw data type in them.

1.1

Added help information on how to convert a file with DAQmxRaw data to the help documentation of convertTDMS.

MATLAB Release
MATLAB 8.2 (R2013b)
Acknowledgements

Inspired by: ConvertTDMS (v9)

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video