TDMS格式是NI主推的高速测试测量采集系统中的一种二进制数据存储类型,适合存储海量才几级数据,兼有高速。方便和易存取等多种优点。做过实际测量项目的筒子们在NI的相关平台例如:CompactRIO/Labview上应该是能够非常明显的感受到上述特点的。TDMS与常见的csv,txt等通用格式相比,具有非常多的优点,但缺点也非常明显:格式较为封闭,无法方便地分享或者被MATLAB、Python等常见的数据分析软件读取和处理。因此在一般的采样率不是很高或者采集通道不是很多的时候,个人还是比较倾向直接将数据保存为txt等通用数据格式。对于高采样率和多通道采集的情况,一般将采集后的数据转换为通用数据之后进行保存。
目前个人比较熟悉的转换方式有两种:一种是直接在Labview中编写脚本进行转换,第二种是在MATLAB中通过第三方的“CovertTDMS”函数直接读取tdms文件后进行处理或保存。下面对这两大类方法分别进行介绍和说明,本文的重点是介绍第二部分“ConvertTDMS”函数的使用方法。
Labview 中直接进行转换
(1)手动写入
Labview中转换最直接也是最灵活的方法就是直接逐行读取现有的tdms文件,并将其写入新建的txt,或csv等格式文件。好处非常明显,操作灵活,在写入的过程中还可以对数据进行简单的处理:如剔除异常值,无效值等。但缺点也比较明显:编程过程略显繁琐,同时程序运行时间较长,如果有较多文件需要转换的话,耗费时间太久。
(2)调用VI控件
这种方法操作较为简单,直接在Labview中读取TDMS文件,并重新利用官方的“写入测量文件”VI重新写入指定格式文件即可。从设置中可以看到,能选择的格式不多,如果转换为xlsx格式的话,可以在MATLAB中使用xlsread()函数进行读取。
MATLAB中直接读取TDMS文件
MATLAB无法直接读取tdms格式的文件,读取tdms格式文件需要在MATLAB的官网或者GitHub上下载一个第三方提交的ConvertTDMS函数文件,函数的具体说明也都可以在源文件中找到。该函数在读取tdms文件的过程中,不仅能够简单的提取出测试数据,还能同时提取出TDMS中保存的相关通道性质信息,非常强大与方便。先对该函数的主要使用方法做一个简单介绍。
下载得到的ConvertTDMS压缩包中主要有ConvertTDMS和simpleConvertTDMS:官方对这两个函数的说明如下:
ConvertTDMS - Function to load LabView TDMS data file(s) into variables in the MATLAB workspace. An *.MAT file can also be created.
simpleConvertTDMS - Function to convert .tdms files to .mat files. the .mat files can then be easily loaded into MATLAB when needed.
可以看出来最主要的区别就是ConvertTDMS可以在将tdms文件转换为.MAT的文件的同时,将相关数据导入到MATLAB的工作空间中,两者并没有明显的区别。下面就来简单介绍如何ConvertTDMS函数转换单个tdms文件(也可以批量输入地址,具体请查看源函数说明)的用法吧:
函数原型[ConvertedData,ConvertVer,ChanNames,GroupNames,ci]=convertTDMS(SaveConvertedFile,filename)
输入量
SaveConvertedFile(必填):true/false,确定.mat文件是否生成,生成的.mat文件和原始的tdms文件同名,仅文件后缀发生更改。
filename(选填):完整的文件地址名称,如果为空的话会跳出一个文件选择框,也可以输入一个cell来进行批量转换。
输出量
在上面中,最为重要的是‘ConvertedData’,该structure中有'FileName', 'FileFolder', 'SegTDMSVerNum','NumOfSegments' 和'Data'的域其中'Data'域指向的也是一个structure,该structure中有'Root' 和'MeasuredData'两个域'Root'域指向的是一个包含‘Name’和‘Property’域的结构体而'MeasuredData'是一个包含所有通道/组信息的结构体,可以通过数字索引来访问每一个通道的structure,每一个通道的structure中又包含'Name', 'Data'和'Property'三个fields。通过选择合适的通道索引来选择相应的数据ConvertedData (required) - Structure of all of the data objects(数据对象的结构)
ConvertVer (optional) - 函数版本
ChanNames (optional) - Cell array of channel names(通道名的cell)
GroupNames (optional) - Cell array of group names(组名的cell)
ci (optional) - Structure of the channel index (an index towhere all of the information for a channel resides in afile.
下面举一个获取有一个tdms文件中某一通道数据的例子,该文件只有‘TimeData’一个组,共有17个通道,我们取第1个通道的数据的第3个值。
>>result=convertTDMS(true,'D:\电机故障转换后数据\rotor_unb30HZ40Load1012141105.tdms')>>result.('Data').('MeasuredData')(3).('Data')(3)
这里有一点需要注意,我输入的原始文件中只有1个名为“TimeData”的group,而该group下共有17个通道,但当我们运行下列代码时,可以放回如下结果:
>> result.('Data').('MeasuredData')ans = 包含以下字段的 1×19 struct 数组:NameDataTotal_SamplesProperty
通过测试得到,该structure数组中第一和第二个值的‘Name’项的值为‘Root’和‘TimeData’,一个为根文件名,一个是group名,相应的通道数也想向后移。
本文只介绍了ConvertTDMS函数最主要的功能,想要体验更多功能还是建议直接参考函数本身的说明文档。
最后需要注意的是,函数编写者最高测试过3GB大小的数据文件转换,但他同时也建议测量过程中单个tdms文件的大小不要超过1GB。这样当采集过程中labview的文件管理系统奔溃的时候,不至于丢失太大的数据量。