DIAdem

cancel
Showing results for 
Search instead for 
Did you mean: 

Create tdms files, using C# Visual Studio 2017

Solved!
Go to solution

Hi all,

I have a project, collecting data from an activeX interfache into a C# application. To process the data with diadem, creating reports eg I need to put the data into a tdms file (don't want to make the work around with txt file).

I asked the support for an example, but they only sent this link: 

 

https://www.ni.com/en/support/documentation/supplemental/06/the-ni-tdms-file-format.html

 

I downloaded the TDM C DLL but have no idea how to implement into my C# code. Does someone has experience or an example to get started? 

 

Thamks a lot

 

BR

 

0 Kudos
Message 1 of 5
(3,796 Views)

To go with an C interface you need to play around with .net InteropServices.

 

I have some an example written some time ago of some of the writing methods.
Hope this helps you as a starting point.

 

For help check the documentation of the download.

Make sure the nilibddc.dll can be found beneath or exe or in the PATH environment variable.

 

The code will only work for 64bit processes.

 

 

internal class nilibddc {
public enum DDCDataType {
    DDC_UInt8 = 5,
    DDC_Int16 = 2,
    DDC_Int32 = 3,
    DDC_Float = 9,
    DDC_Double = 10,
    DDC_String = 23,
    DDC_Timestamp = 30
}

public enum DDCError {
    DDC_NoError = 0,
    DDC_ErrorBegin = -6201,
    DDC_OutOfMemory = -6201,
    DDC_InvalidArgument = -6202,
    DDC_InvalidDataType = -6203,
    DDC_UnexpectedError = -6204,
    DDC_UsiCouldNotBeLoaded = -6205,
    DDC_InvalidFileHandle = -6206,
    DDC_InvalidChannelGroupHandle = -6207,
    DDC_InvalidChannelHandle = -6208,
    DDC_FileDoesNotExist = -6209,
    DDC_CannotWriteToReadOnlyFile = -6210,
    DDC_StorageCouldNotBeOpened = -6211,
    DDC_FileAlreadyExists = -6212,
    DDC_PropertyDoesNotExist = -6213,
    DDC_PropertyDoesNotContainData = -6214,
    DDC_PropertyIsNotAScalar = -6215,
    DDC_DataObjectTypeNotFound = -6216,
    DDC_NotImplemented = -6217,
    DDC_CouldNotSaveFile = -6218,
    DDC_MaximumNumberOfDataValuesExceeded = -6219,
    DDC_InvalidChannelName = -6220,
    DDC_DuplicateChannelName = -6221,
    DDC_DataTypeNotSupported = -6222,
    DDC_FileAccessDenied = -6224,
    DDC_InvalidTimeValue = -6225,
    DDC_ReplaceNotSupportedForSavedTDMSData = -6226,
    DDC_PropertyDataTypeMismatch = -6227,
    DDC_ChannelDataTypeMismatch = -6228,
    DDC_ErrorEnd = -6228,
    DDC_ErrorForceSizeTo32Bits = -1
}

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_CreateFile", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_CreateFile([System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string filePath, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string fileType, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string name, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string description, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string title, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string author, ref System.IntPtr file) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_AddChannelGroup", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_AddChannelGroup(System.IntPtr file, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string name, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string description, ref System.IntPtr channelGroup) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_AddChannel", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_AddChannel(System.IntPtr channelGroup, DDCDataType dataType, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string name, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string description, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string unitString, ref System.IntPtr channel) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_SaveFile", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_SaveFile(System.IntPtr file) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_CloseFile", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_CloseFile(System.IntPtr file) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_SetDataValuesUInt8", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_SetDataValuesUInt8(System.IntPtr channel, System.Byte[] values, System.UInt64 numValues) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_SetDataValuesInt16", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_SetDataValuesInt16(System.IntPtr channel, short[] values, System.UInt64 numValues) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_SetDataValuesInt32", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_SetDataValuesInt32(System.IntPtr channel, System.Int32[] values, System.UInt64 numValues) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_SetDataValuesFloat", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_SetDataValuesFloat(System.IntPtr channel, float[] values, System.UInt64 numValues) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_SetDataValuesDouble", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_SetDataValuesDouble(System.IntPtr channel, double[] values, ulong numValues) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_CreateChannelGroupPropertyDouble", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_CreateChannelGroupPropertyDouble(System.IntPtr channelGroup, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string property, double value) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_CreateChannelGroupPropertyString", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  int DDC_CreateChannelGroupPropertyString(System.IntPtr channelGroup, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string property, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string value) ;

[System.Runtime.InteropServices.DllImportAttribute(NILIBDDC_DLL_PATH, EntryPoint="DDC_GetLibraryErrorDescription", CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern  System.IntPtr DDC_GetLibraryErrorDescription(int errorCode) ;

private const string NILIBDDC_DLL_PATH = "nilibddc.dll";
}

 

afterwards you can use it like the C interface.

 

using static nilibddc;

private static void WriteFile(string fileType, string tdmsFilePath)
{
    IntPtr file = new IntPtr();
    ddcChk(DDC_CreateFile(tdmsFilePath, fileType, "", "my_desc", "measured file", "me", ref file));
    try
    {
        IntPtr group1 = new IntPtr();
        ddcChk(DDC_AddChannelGroup(file, "my_first_group", "my_desc", ref group1));
        ddcChk(DDC_CreateChannelGroupPropertyDouble(group1, "my_r64_prop", 1.234));
        ddcChk(DDC_CreateChannelGroupPropertyString(group1, "my_string_prop", "my_string_val"));

        IntPtr channel1_1 = new IntPtr();
        ddcChk(DDC_AddChannel(group1, DDCDataType.DDC_Double, "channel1", "my_channel_desc", "m", ref channel1_1));
        IntPtr channel1_2 = new IntPtr();
        ddcChk(DDC_AddChannel(group1, DDCDataType.DDC_Double, "channel2", "my_channel_desc", "kg", ref channel1_2));

        double[] channel1_1Data = new double[] { 1.1, 2.1, 3.1 };
        double[] channel1_2Data = new double[] { 1.2, 2.2, 3.2 };

        ddcChk(DDC_SetDataValuesDouble(channel1_1, channel1_1Data, (System.UInt64)channel1_1Data.Length));
        ddcChk(DDC_SetDataValuesDouble(channel1_2, channel1_2Data, (System.UInt64)channel1_2Data.Length));

        IntPtr group2 = new IntPtr();
        ddcChk(DDC_AddChannelGroup(file, "my_second_group", "my_desc", ref group2));

        IntPtr channel2_1 = new IntPtr();
        ddcChk(DDC_AddChannel(group2, DDCDataType.DDC_Int32, "channel1", "my_channel_desc", "m", ref channel2_1));

        int[] channel2_1Data = new int[] { 1, 2, 3 };
        ddcChk(DDC_SetDataValuesInt32(channel2_1, channel2_1Data, (System.UInt64)channel2_1Data.Length));

        ddcChk(DDC_SaveFile(file));
    }
    finally
    {
        ddcChk(DDC_CloseFile(file));
    }
}

private static void ddcChk(int status)
{
    if((int)DDCError.DDC_NoError != status)
    {
        IntPtr error_buffer = DDC_GetLibraryErrorDescription(status);
        string error_string = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(error_buffer);
        throw new ApplicationException($"DDCError({status}):{error_string}");
    }
}

 

 

Message 2 of 5
(3,751 Views)

Very thanks for your reply AndreasK

 

I did a step ahead. I was able to implement your code into my project and call your example function.

The dll seems to be load.

global::Writer.WriteFile("DDC_FILE_TYPE_TDMS", "test.TDMS");

But I get an exception when I pass the file type and file name to the WritFile function.

 

2020-12-18_09-56-36.jpg

Is there a chance to find out which parameter is invalid?

 

0 Kudos
Message 3 of 5
(3,735 Views)
Solution
Accepted by topic author Tobias_G

 

lobal::Writer.WriteFile("TDMS", "test.TDMS");

lobal::Writer.WriteFile("TDM", "test.TDM");

 

In the c code DDC_FILE_TYPE_TDMS is a constant reresenting the string "TDMS".
There are only two available Store types: ["TDM", "TDMS"] with the same file extension.

0 Kudos
Message 4 of 5
(3,690 Views)

Very thanks. I got it to run!

 

Thank you very much AndreasK

0 Kudos
Message 5 of 5
(3,670 Views)