national-instruments-helper
This commit is contained in:
@ -118,7 +118,7 @@ dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template
|
|||||||
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name
|
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name
|
||||||
dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2");
|
dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2");
|
||||||
dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant.
|
dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant.
|
||||||
dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary
|
dotnet_diagnostic.IDE0005.severity = none # Using directive is unnecessary
|
||||||
dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
|
dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
|
||||||
dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified
|
dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified
|
||||||
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
|
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
|
||||||
|
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -8,7 +8,7 @@
|
|||||||
"name": ".NET Core Launch (console)",
|
"name": ".NET Core Launch (console)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "build",
|
"preLaunchTask": "Build",
|
||||||
"program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Watcher.dll",
|
"program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Watcher.dll",
|
||||||
"args": [
|
"args": [
|
||||||
"s"
|
"s"
|
||||||
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -42,6 +42,7 @@
|
|||||||
"PDSF",
|
"PDSF",
|
||||||
"pged",
|
"pged",
|
||||||
"Phares",
|
"Phares",
|
||||||
|
"Pinnable",
|
||||||
"Rijndael",
|
"Rijndael",
|
||||||
"Serilog",
|
"Serilog",
|
||||||
"SUBM",
|
"SUBM",
|
||||||
|
18
.vscode/tasks.json
vendored
18
.vscode/tasks.json
vendored
@ -7,8 +7,6 @@
|
|||||||
"type": "process",
|
"type": "process",
|
||||||
"args": [
|
"args": [
|
||||||
"user-secrets",
|
"user-secrets",
|
||||||
"-p",
|
|
||||||
"${workspaceFolder}/File-Watcher.csproj",
|
|
||||||
"init"
|
"init"
|
||||||
],
|
],
|
||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
@ -19,8 +17,6 @@
|
|||||||
"type": "process",
|
"type": "process",
|
||||||
"args": [
|
"args": [
|
||||||
"user-secrets",
|
"user-secrets",
|
||||||
"-p",
|
|
||||||
"${workspaceFolder}/File-Watcher.csproj",
|
|
||||||
"set",
|
"set",
|
||||||
"_UserSecretsId",
|
"_UserSecretsId",
|
||||||
"6516d19d6569"
|
"6516d19d6569"
|
||||||
@ -43,19 +39,16 @@
|
|||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "build",
|
"label": "Build",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build"
|
||||||
"${workspaceFolder}/File-Watcher.csproj",
|
|
||||||
"/property:GenerateFullPaths=true",
|
|
||||||
"/consoleloggerparameters:NoSummary"
|
|
||||||
],
|
],
|
||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Format-Whitespaces",
|
"label": "Format Whitespaces",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"args": [
|
"args": [
|
||||||
@ -74,10 +67,7 @@
|
|||||||
"win-x64",
|
"win-x64",
|
||||||
"-c",
|
"-c",
|
||||||
"Release",
|
"Release",
|
||||||
"-p:PublishAot=true",
|
"-p:PublishAot=true"
|
||||||
"${workspaceFolder}/File-Watcher.csproj",
|
|
||||||
"/property:GenerateFullPaths=true",
|
|
||||||
"/consoleloggerparameters:NoSummary"
|
|
||||||
],
|
],
|
||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
|
@ -12,11 +12,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CliWrap" Version="3.8.2" />
|
<PackageReference Include="CliWrap" Version="3.8.2" />
|
||||||
<PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" />
|
<PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" />
|
||||||
<PackageReference Include="Nancy.Owin" Version="2.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.Owin" Version="4.2.2" />
|
|
||||||
<PackageReference Include="Microsoft.Owin.Cors" Version="4.2.2" />
|
|
||||||
<PackageReference Include="Microsoft.Owin.Hosting" Version="4.2.2" />
|
|
||||||
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="4.2.2" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.16" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.16" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||||
@ -34,4 +29,12 @@
|
|||||||
<PackageReference Include="Phares.Shared" Version="8.0.118.14751" />
|
<PackageReference Include="Phares.Shared" Version="8.0.118.14751" />
|
||||||
<PackageReference Include="Phares.Metadata" Version="8.0.118.14751" />
|
<PackageReference Include="Phares.Metadata" Version="8.0.118.14751" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Nancy.Owin" Version="2.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Owin" Version="4.2.2" />
|
||||||
|
<PackageReference Include="Microsoft.Owin.Cors" Version="4.2.2" />
|
||||||
|
<PackageReference Include="Microsoft.Owin.Hosting" Version="4.2.2" />
|
||||||
|
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="4.2.2" />
|
||||||
|
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
12
Helpers/DAQmx/CSVTime.cs
Normal file
12
Helpers/DAQmx/CSVTime.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
#pragma warning disable IDE1006 // Naming Styles
|
||||||
|
#pragma warning disable IDE0044 // Add readonly modifier
|
||||||
|
#pragma warning disable IDE0051 // Remove unused private members
|
||||||
|
#pragma warning disable CS0169 // Field is never assigned to, and will always have its default value
|
||||||
|
|
||||||
|
public struct CSVTime
|
||||||
|
{
|
||||||
|
private ulong lsb;
|
||||||
|
private long msb;
|
||||||
|
}
|
17
Helpers/DAQmx/CVIAbsoluteTime.cs
Normal file
17
Helpers/DAQmx/CVIAbsoluteTime.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
#pragma warning disable IDE0044 // Add readonly modifier
|
||||||
|
#pragma warning disable IDE0051 // Remove unused private members
|
||||||
|
#pragma warning disable IDE1006 // Naming Styles
|
||||||
|
#pragma warning disable CS0169 // Field is never assigned to, and will always have its default value
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public struct CVIAbsoluteTime
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private CSVTime cviTime;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private uint[] u32Data;
|
||||||
|
}
|
13
Helpers/DAQmx/DAQmx.cs
Normal file
13
Helpers/DAQmx/DAQmx.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public static class DAQmx
|
||||||
|
{
|
||||||
|
public static string GetErrorString(int errorCode)
|
||||||
|
{
|
||||||
|
StringBuilder errorString = new(256);
|
||||||
|
_ = Interop.DAQmxGetErrorString(errorCode, errorString, (uint)(errorString.Capacity + 1));
|
||||||
|
return errorString.ToString();
|
||||||
|
}
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxActiveEdge.cs
Normal file
7
Helpers/DAQmx/DAQmxActiveEdge.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxActiveEdge
|
||||||
|
{
|
||||||
|
Falling = 10171, // 0x000027BB
|
||||||
|
Rising = 10280, // 0x00002828
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxDataLayout.cs
Normal file
7
Helpers/DAQmx/DAQmxDataLayout.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxDataLayout
|
||||||
|
{
|
||||||
|
GroupByChannel,
|
||||||
|
GroupByScanNumber,
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxDigitalPatternTriggerWhen.cs
Normal file
7
Helpers/DAQmx/DAQmxDigitalPatternTriggerWhen.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxDigitalPatternTriggerWhen
|
||||||
|
{
|
||||||
|
PatternDoesNotMatch = 10253, // 0x0000280D
|
||||||
|
PatternMatches = 10254, // 0x0000280E
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxEdge.cs
Normal file
7
Helpers/DAQmx/DAQmxEdge.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxEdge
|
||||||
|
{
|
||||||
|
Falling = 10171, // 0x000027BB
|
||||||
|
Rising = 10280, // 0x00002828
|
||||||
|
}
|
14
Helpers/DAQmx/DAQmxException.cs
Normal file
14
Helpers/DAQmx/DAQmxException.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public class DAQmxException : Exception
|
||||||
|
{
|
||||||
|
public DAQmxException(string message)
|
||||||
|
: base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DAQmxException(int errorCode, string message)
|
||||||
|
: base(errorCode.ToString() + " - " + message + " (" + DAQmx.GetErrorString(errorCode) + ")")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxFillMode.cs
Normal file
7
Helpers/DAQmx/DAQmxFillMode.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxFillMode
|
||||||
|
{
|
||||||
|
GroupByChannel,
|
||||||
|
GroupByScanNumber,
|
||||||
|
}
|
10
Helpers/DAQmx/DAQmxInputTerminalConfiguration.cs
Normal file
10
Helpers/DAQmx/DAQmxInputTerminalConfiguration.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxInputTerminalConfiguration
|
||||||
|
{
|
||||||
|
Default = -1, // 0xFFFFFFFF
|
||||||
|
NonReferencedSingleEnded = 10078, // 0x0000275E
|
||||||
|
ReferencedSingleEnded = 10083, // 0x00002763
|
||||||
|
Differential = 10106, // 0x0000277A
|
||||||
|
Pseudodifferential = 12529, // 0x000030F1
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxLevel.cs
Normal file
7
Helpers/DAQmx/DAQmxLevel.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxLevel
|
||||||
|
{
|
||||||
|
High = 10192, // 0x000027D0
|
||||||
|
Low = 10214, // 0x000027E6
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxLineGrouping.cs
Normal file
7
Helpers/DAQmx/DAQmxLineGrouping.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxLineGrouping
|
||||||
|
{
|
||||||
|
OneChannelForEachLine,
|
||||||
|
OneChannelForAllLines,
|
||||||
|
}
|
8
Helpers/DAQmx/DAQmxLoggingMode.cs
Normal file
8
Helpers/DAQmx/DAQmxLoggingMode.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxLoggingMode
|
||||||
|
{
|
||||||
|
Off = 10231, // 0x000027F7
|
||||||
|
LogAndRead = 15842, // 0x00003DE2
|
||||||
|
Log = 15844, // 0x00003DE4
|
||||||
|
}
|
9
Helpers/DAQmx/DAQmxLoggingTDMSOperation.cs
Normal file
9
Helpers/DAQmx/DAQmxLoggingTDMSOperation.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxLoggingTDMSOperation
|
||||||
|
{
|
||||||
|
Open = 10437, // 0x000028C5
|
||||||
|
OpenOrCreate = 15846, // 0x00003DE6
|
||||||
|
CreateOrReplace = 15847, // 0x00003DE7
|
||||||
|
Create = 15848, // 0x00003DE8
|
||||||
|
}
|
5
Helpers/DAQmx/DAQmxMemoryException.cs
Normal file
5
Helpers/DAQmx/DAQmxMemoryException.cs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public class DAQmxMemoryException(string message) : Exception(message)
|
||||||
|
{
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxPolarity.cs
Normal file
7
Helpers/DAQmx/DAQmxPolarity.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxPolarity
|
||||||
|
{
|
||||||
|
ActiveHigh = 10095, // 0x0000276F
|
||||||
|
ActiveLow = 10096, // 0x00002770
|
||||||
|
}
|
8
Helpers/DAQmx/DAQmxSampleMode.cs
Normal file
8
Helpers/DAQmx/DAQmxSampleMode.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxSampleMode
|
||||||
|
{
|
||||||
|
ContinuousSamples = 10123, // 0x0000278B
|
||||||
|
FiniteSamples = 10178, // 0x000027C2
|
||||||
|
HardwareTimedSinglePoint = 12522, // 0x000030EA
|
||||||
|
}
|
347
Helpers/DAQmx/DAQmxTask.cs
Normal file
347
Helpers/DAQmx/DAQmxTask.cs
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
#pragma warning disable IDE1006 // Naming Styles
|
||||||
|
#pragma warning disable IDE0044 // Add readonly modifier
|
||||||
|
#pragma warning disable IDE0051 // Remove unused private members
|
||||||
|
#pragma warning disable CS0169 // Field is never assigned to, and will always have its default value
|
||||||
|
|
||||||
|
public class DAQmxTask
|
||||||
|
{
|
||||||
|
|
||||||
|
private IntPtr taskHandle;
|
||||||
|
|
||||||
|
private DAQmxTask()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public double DT { get; private set; }
|
||||||
|
public int Channels { get; private set; }
|
||||||
|
public ulong TotalSamplesRead { get; private set; }
|
||||||
|
public DateTime TaskStartedUtc { get; private set; }
|
||||||
|
public ulong TotalSamplesWrite { get; private set; }
|
||||||
|
public ulong TotalSamplesPerChanRead { get; private set; }
|
||||||
|
public ulong TotalSamplesPerChanWrite { get; private set; }
|
||||||
|
|
||||||
|
public static DAQmxTask Create(string taskName)
|
||||||
|
{
|
||||||
|
DAQmxTask result;
|
||||||
|
IntPtr taskHandle;
|
||||||
|
int task = Interop.DAQmxCreateTask(taskName, out taskHandle);
|
||||||
|
if (task < 0)
|
||||||
|
throw new DAQmxException(task, "Could not create Task");
|
||||||
|
result = new() { taskHandle = taskHandle, Channels = 0 };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConfigureLoggingTechnicalDataManagementStreaming(string filePath, DAQmxLoggingMode loggingMode, string groupName, DAQmxLoggingTDMSOperation operation)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxConfigureLogging(taskHandle, filePath, (int)loggingMode, groupName, (int)operation);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not configure technical data management streaming logging");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateAnalogInputVoltageChannel(string physicalChannel, string nameToAssignToChannel, DAQmxInputTerminalConfiguration terminalConfig, double minVal, double maxVal, DAQmxUnits units, string customScaleName)
|
||||||
|
{
|
||||||
|
int analogInputVoltageChan = Interop.DAQmxCreateAIVoltageChan(taskHandle, physicalChannel, nameToAssignToChannel, (int)terminalConfig, minVal, maxVal, (int)units, customScaleName);
|
||||||
|
if (analogInputVoltageChan < 0)
|
||||||
|
throw new DAQmxException(analogInputVoltageChan, "Could not create analog input voltage channel");
|
||||||
|
++Channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateAnalogOutputVoltageChan(string physicalChannel, string nameToAssignToChannel, double minVal, double maxVal, DAQmxUnits units, string customScaleName)
|
||||||
|
{
|
||||||
|
int analogOutputVoltageChan = Interop.DAQmxCreateAOVoltageChan(taskHandle, physicalChannel, nameToAssignToChannel, minVal, maxVal, (int)units, customScaleName);
|
||||||
|
if (analogOutputVoltageChan < 0)
|
||||||
|
throw new DAQmxException(analogOutputVoltageChan, "Could not create analog output voltage channel");
|
||||||
|
++Channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateDigitalOutputChanel(string lines, string nameToAssignToLines, DAQmxLineGrouping lineGrouping)
|
||||||
|
{
|
||||||
|
int doChan = Interop.DAQmxCreateDOChan(taskHandle, lines, nameToAssignToLines, (int)lineGrouping);
|
||||||
|
if (doChan < 0)
|
||||||
|
throw new DAQmxException(doChan, "Could not create digital output channel");
|
||||||
|
++Channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if unsafe
|
||||||
|
public unsafe void ReadAnalogF64(int numSamplesPerChan, double timeout, DAQmxFillMode fillMode, Span<double> data)
|
||||||
|
{
|
||||||
|
int arraySizeInSamples = numSamplesPerChan * Channels;
|
||||||
|
if (data.Length < arraySizeInSamples)
|
||||||
|
throw new DAQmxMemoryException("Span length too short. (Span length: " + data.Length.ToString() + ", required length: " + arraySizeInSamples.ToString() + ")");
|
||||||
|
fixed (double* readArray = &data.GetPinnableReference())
|
||||||
|
{
|
||||||
|
IntPtr samplesPerChanRead;
|
||||||
|
int errorCode = Interop.DAQmxReadAnalogF64(taskHandle, numSamplesPerChan, timeout, (int)fillMode, readArray, (uint)arraySizeInSamples, out samplesPerChanRead, IntPtr.Zero);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not read samples");
|
||||||
|
int int32 = samplesPerChanRead.ToInt32();
|
||||||
|
if (int32 != numSamplesPerChan)
|
||||||
|
throw new DAQmxException("Could not read requested number of samples");
|
||||||
|
TotalSamplesPerChanRead += (ulong)int32;
|
||||||
|
TotalSamplesRead += (ulong)arraySizeInSamples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public double ReadAnalogScalarF64(double timeout)
|
||||||
|
{
|
||||||
|
double result;
|
||||||
|
int errorCode = Interop.DAQmxReadAnalogScalarF64(taskHandle, timeout, out result, IntPtr.Zero);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not read samples");
|
||||||
|
++TotalSamplesRead;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if unsafe
|
||||||
|
public double ReadAnalogF64(double timeout)
|
||||||
|
{
|
||||||
|
double result = DAQmxReadAnalogF64(timeout);
|
||||||
|
++TotalSamplesRead;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if unsafe
|
||||||
|
private unsafe double DAQmxReadAnalogF64(double timeout)
|
||||||
|
{
|
||||||
|
double results;
|
||||||
|
int numSamplesPerChan = 1;
|
||||||
|
uint arraySizeInSamples = 1;
|
||||||
|
IntPtr samplesPerChanRead = IntPtr.Zero;
|
||||||
|
double* readArray = stackalloc double[1];
|
||||||
|
int fillMode = (int)DAQmxFillMode.GroupByChannel;
|
||||||
|
int errorCode = Interop.DAQmxReadAnalogF64(taskHandle,
|
||||||
|
numSamplesPerChan,
|
||||||
|
timeout,
|
||||||
|
fillMode,
|
||||||
|
readArray,
|
||||||
|
arraySizeInSamples,
|
||||||
|
out samplesPerChanRead,
|
||||||
|
IntPtr.Zero);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not read samples");
|
||||||
|
results = *readArray;
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxStartTask(taskHandle);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not start Task");
|
||||||
|
TaskStartedUtc = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxStopTask(taskHandle);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not stop Task");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxClearTask(taskHandle);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not clear Task");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgSampleClkTiming(string source, double rate, DAQmxActiveEdge activeEdge, DAQmxSampleMode sampleMode, ulong samplesPerChan)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgSampClkTiming(taskHandle, source, rate, (int)activeEdge, (int)sampleMode, samplesPerChan);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgSampleClkTiming failed.");
|
||||||
|
DT = 1.0 / SampleClockRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DAQmxCfgHandshakingTiming(DAQmxSampleMode sampleMode, ulong samplesPerChan)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgHandshakingTiming(taskHandle, (int)sampleMode, samplesPerChan);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "DAQmxCfgHandshakingTiming failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DAQmxCfgBurstHandshakingTimingImportClock(DAQmxSampleMode sampleMode, ulong samplesPerChan, double sampleClkRate, string sampleClkSrc, DAQmxPolarity sampleClkActiveEdge, DAQmxLevel pauseWhen, DAQmxPolarity readyEventActiveLevel)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgBurstHandshakingTimingImportClock(taskHandle, (int)sampleMode, samplesPerChan, sampleClkRate, sampleClkSrc, (int)sampleClkActiveEdge, (int)pauseWhen, (int)readyEventActiveLevel);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "DAQmxCfgBurstHandshakingTimingImportClock failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DAQmxCfgBurstHandshakingTimingExportClock(DAQmxSampleMode sampleMode, ulong samplesPerChan, double sampleClkRate, string sampleClkOutputTerm, DAQmxPolarity sampleClkPulsePolarity, DAQmxLevel pauseWhen, DAQmxPolarity readyEventActiveLevel)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgBurstHandshakingTimingExportClock(taskHandle, (int)sampleMode, samplesPerChan, sampleClkRate, sampleClkOutputTerm, (int)sampleClkPulsePolarity, (int)pauseWhen, (int)readyEventActiveLevel);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "DAQmxCfgBurstHandshakingTimingExportClock failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DAQmxCfgChangeDetectionTiming(string risingEdgeChan, string fallingEdgeChan, DAQmxSampleMode sampleMode, ulong samplesPerChan)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgChangeDetectionTiming(taskHandle, risingEdgeChan, fallingEdgeChan, (int)sampleMode, samplesPerChan);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "DAQmxCfgChangeDetectionTiming failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DAQmxCfgImplicitTiming(DAQmxSampleMode sampleMode, ulong samplesPerChan)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgImplicitTiming(taskHandle, (int)sampleMode, samplesPerChan);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "DAQmxCfgImplicitTiming failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DAQmxCfgPipelinedSampleClkTiming(string source, double rate, DAQmxActiveEdge activeEdge, DAQmxSampleMode sampleMode, ulong samplesPerChan)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgPipelinedSampClkTiming(taskHandle, source, rate, (int)activeEdge, (int)sampleMode, samplesPerChan);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "DAQmxCfgPipelinedSampleClkTiming failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public double SampleClockRate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
double result = 0.0;
|
||||||
|
int sampleClkRate = Interop.DAQmxGetSampClkRate(taskHandle, ref result);
|
||||||
|
if (sampleClkRate < 0)
|
||||||
|
throw new DAQmxException(sampleClkRate, "Could not get SampleClockRate");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxSetSampClkRate(taskHandle, value);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not set SampleClockRate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double SampleClockMaxRate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
double result = 0.0;
|
||||||
|
int sampleClkMaxRate = Interop.DAQmxGetSampClkMaxRate(taskHandle, ref result);
|
||||||
|
if (sampleClkMaxRate < 0)
|
||||||
|
throw new DAQmxException(sampleClkMaxRate, "Could not get SampleClockMaxRate");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisableStartTrig()
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxDisableStartTrig(taskHandle);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "DisableStartTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgDigEdgeStartTrig(string triggerSource, DAQmxEdge triggerEdge)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgDigEdgeStartTrig(taskHandle, triggerSource, (int)triggerEdge);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgDigEdgeStartTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgAnalogEdgeStartTrig(string triggerSource, DAQmxEdge triggerSlope, double triggerLevel)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgAnlgEdgeStartTrig(taskHandle, triggerSource, (int)triggerSlope, triggerLevel);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgAnalogEdgeStartTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgAnalogMultiEdgeStartTrig(string triggerSources, DAQmxEdge[] triggerSlopes, double[] triggerLevels) =>
|
||||||
|
throw new NotImplementedException("CfgAnalogMultiEdgeStartTrig is not implemented in this version.");
|
||||||
|
|
||||||
|
public void CfgAnalogWindowStartTrig(string triggerSource, DAQmxWindowTriggerWhen triggerWhen, double windowTop, double windowBottom)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgAnlgWindowStartTrig(taskHandle, triggerSource, (int)triggerWhen, windowTop, windowBottom);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgAnalogWindowStartTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgTimeStartTrig(CVIAbsoluteTime when, DAQmxTimescale timescale)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgTimeStartTrig(taskHandle, when, (int)timescale);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgTimeStartTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgDigPatternStartTrig(string triggerSource, string triggerPattern, DAQmxDigitalPatternTriggerWhen triggerWhen)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgDigPatternStartTrig(taskHandle, triggerSource, triggerPattern, (int)triggerWhen);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgDigPatternStartTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisableRefTrig()
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxDisableRefTrig(taskHandle);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "DisableRefTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgDigEdgeRefTrig(string triggerSource, DAQmxEdge triggerEdge, uint pretriggerSamples)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgDigEdgeRefTrig(taskHandle, triggerSource, (int)triggerEdge, pretriggerSamples);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgDigEdgeRefTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgAnalogEdgeRefTrig(string triggerSource, DAQmxEdge triggerSlope, double triggerLevel, uint pretriggerSamples)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgAnlgEdgeRefTrig(taskHandle, triggerSource, (int)triggerSlope, triggerLevel, pretriggerSamples);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgAnalogEdgeRefTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgAnalogMultiEdgeRefTrig(string triggerSources, DAQmxEdge[] triggerSlopes, double[] triggerLevels, uint pretriggerSamples) =>
|
||||||
|
throw new NotImplementedException("CfgAnalogMultiEdgeRefTrig is not implemented in this version.");
|
||||||
|
|
||||||
|
public void CfgAnalogWindowRefTrig(string triggerSource, DAQmxWindowTriggerWhen triggerWhen, double windowTop, double windowBottom, uint pretriggerSamples)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgAnlgWindowRefTrig(taskHandle, triggerSource, (int)triggerWhen, windowTop, windowBottom, pretriggerSamples);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgAnalogWindowRefTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CfgDigPatternRefTrig(string triggerSource, string triggerPattern, DAQmxDigitalPatternTriggerWhen triggerWhen, uint pretriggerSamples)
|
||||||
|
{
|
||||||
|
int errorCode = Interop.DAQmxCfgDigPatternRefTrig(taskHandle, triggerSource, triggerPattern, (int)triggerWhen, pretriggerSamples);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "CfgDigPatternRefTrig failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteAnalogF64(int numSamplesPerChan, bool autoStart, double timeout, DAQmxDataLayout dataLayout, Span<double> data)
|
||||||
|
{
|
||||||
|
int num = numSamplesPerChan * Channels;
|
||||||
|
if (data.Length < num)
|
||||||
|
throw new DAQmxMemoryException("Span length too short. (Span length: " + data.Length.ToString() + ", required length: " + num.ToString() + ")");
|
||||||
|
IntPtr samplesPerChanWritten;
|
||||||
|
int errorCode = Interop.DAQmxWriteAnalogF64(taskHandle, numSamplesPerChan, autoStart, timeout, dataLayout > DAQmxDataLayout.GroupByChannel, data.ToArray(), out samplesPerChanWritten, IntPtr.Zero);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not write samples");
|
||||||
|
int int32 = samplesPerChanWritten.ToInt32();
|
||||||
|
if (int32 != numSamplesPerChan)
|
||||||
|
throw new DAQmxException("Could not write requested number of samples");
|
||||||
|
TotalSamplesPerChanWrite += (ulong)int32;
|
||||||
|
TotalSamplesWrite += (ulong)num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteDigitalLines(int numSamplesPerChan, bool autoStart, double timeout, DAQmxDataLayout dataLayout, Span<byte> data)
|
||||||
|
{
|
||||||
|
int num = numSamplesPerChan * Channels;
|
||||||
|
if (data.Length < num)
|
||||||
|
throw new DAQmxMemoryException("Span length too short. (Span length: " + data.Length.ToString() + ", required length: " + num.ToString() + ")");
|
||||||
|
IntPtr samplesPerChanWritten;
|
||||||
|
int errorCode = Interop.DAQmxWriteDigitalLines(taskHandle, numSamplesPerChan, autoStart, timeout, dataLayout > DAQmxDataLayout.GroupByChannel, data.ToArray(), out samplesPerChanWritten, IntPtr.Zero);
|
||||||
|
if (errorCode < 0)
|
||||||
|
throw new DAQmxException(errorCode, "Could not write samples");
|
||||||
|
int int32 = samplesPerChanWritten.ToInt32();
|
||||||
|
if (int32 != numSamplesPerChan)
|
||||||
|
throw new DAQmxException("Could not write requested number of samples");
|
||||||
|
TotalSamplesPerChanWrite += (ulong)int32;
|
||||||
|
TotalSamplesWrite += (ulong)num;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxTimescale.cs
Normal file
7
Helpers/DAQmx/DAQmxTimescale.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxTimescale
|
||||||
|
{
|
||||||
|
HostTime = 16126, // 0x00003EFE
|
||||||
|
IODeviceTime = 16127, // 0x00003EFF
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxUnits.cs
Normal file
7
Helpers/DAQmx/DAQmxUnits.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxUnits
|
||||||
|
{
|
||||||
|
FromCustomScale = 10065, // 0x00002751
|
||||||
|
Volts = 10348, // 0x0000286C
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxWindowTriggerWhen.cs
Normal file
7
Helpers/DAQmx/DAQmxWindowTriggerWhen.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxWindowTriggerWhen
|
||||||
|
{
|
||||||
|
EnteringWindow = 10163, // 0x000027B3
|
||||||
|
LeavingWindow = 10208, // 0x000027E0
|
||||||
|
}
|
7
Helpers/DAQmx/DAQmxWriteRegenMode.cs
Normal file
7
Helpers/DAQmx/DAQmxWriteRegenMode.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
public enum DAQmxWriteRegenMode
|
||||||
|
{
|
||||||
|
AllowRegen = 10097, // 0x00002771
|
||||||
|
DoNotAllowRegen = 10158, // 0x000027AE
|
||||||
|
}
|
431
Helpers/DAQmx/Interop.cs
Normal file
431
Helpers/DAQmx/Interop.cs
Normal file
@ -0,0 +1,431 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
#pragma warning disable IDE1006 // Naming Styles
|
||||||
|
#pragma warning disable SYSLIB1054 // Type or member is obsolete
|
||||||
|
|
||||||
|
namespace Helpers.DAQmx;
|
||||||
|
|
||||||
|
internal class Interop
|
||||||
|
{ // cSpell:disable
|
||||||
|
|
||||||
|
private const string lib = "DAQmx";
|
||||||
|
private static IntPtr libHandle = IntPtr.Zero;
|
||||||
|
|
||||||
|
static Interop() =>
|
||||||
|
NativeLibrary.SetDllImportResolver(typeof(Interop).Assembly, ImportResolver);
|
||||||
|
|
||||||
|
private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
|
||||||
|
{
|
||||||
|
if (libraryName == "DAQmx" && !(libHandle != IntPtr.Zero))
|
||||||
|
{
|
||||||
|
bool loaded;
|
||||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
loaded = NativeLibrary.TryLoad("C:/Windows/System32/nicaiu.dll", assembly, searchPath, out libHandle);
|
||||||
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||||
|
{
|
||||||
|
loaded = NativeLibrary.TryLoad("/usr/local/lib64/libnidaqmxbase.so", assembly, searchPath, out libHandle);
|
||||||
|
if (!loaded)
|
||||||
|
loaded = NativeLibrary.TryLoad("/usr/local/lib/libnidaqmxbase.so", assembly, searchPath, out libHandle);
|
||||||
|
if (!loaded)
|
||||||
|
loaded = NativeLibrary.TryLoad("/usr/local/natinst/lib/libnidaqmx.so", assembly, searchPath, out libHandle);
|
||||||
|
if (!loaded)
|
||||||
|
loaded = NativeLibrary.TryLoad("/usr/lib/x86_64-linux-gnu/libnidaqmx.so", assembly, searchPath, out libHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new PlatformNotSupportedException("Unsupported platform for DAQmx library.");
|
||||||
|
if (!loaded)
|
||||||
|
throw new DllNotFoundException($"Failed to load {lib} library.");
|
||||||
|
}
|
||||||
|
return libHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxGetSampClkRate(IntPtr taskHandle, ref double data);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxSetSampClkRate(IntPtr taskHandle, double data);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxGetSampClkMaxRate(IntPtr taskHandle, ref double data);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxSetWriteRegenMode(IntPtr taskHandle, int data);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCreateAIVoltageChan(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string physicalChannel,
|
||||||
|
string nameToAssignToChannel,
|
||||||
|
int terminalConfig,
|
||||||
|
double minVal,
|
||||||
|
double maxVal,
|
||||||
|
int units,
|
||||||
|
string customScaleName);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCreateAOVoltageChan(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string physicalChannel,
|
||||||
|
string nameToAssignToChannel,
|
||||||
|
double minVal,
|
||||||
|
double maxVal,
|
||||||
|
int units,
|
||||||
|
string customScaleName);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCreateDOChan(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string lines,
|
||||||
|
string nameToAssignToLines,
|
||||||
|
int lineGrouping);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxGetErrorString(
|
||||||
|
int errorCode,
|
||||||
|
StringBuilder errorString,
|
||||||
|
uint buffersize);
|
||||||
|
|
||||||
|
#if unsafe
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern unsafe int DAQmxReadAnalogF64(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int numSampsPerChan,
|
||||||
|
double timeout,
|
||||||
|
int fillMode,
|
||||||
|
double* readArray,
|
||||||
|
uint arraySizeInSamps,
|
||||||
|
out IntPtr sampsPerChanRead,
|
||||||
|
IntPtr reserved);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxReadAnalogScalarF64(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
double timeout,
|
||||||
|
out double value,
|
||||||
|
IntPtr reserved);
|
||||||
|
|
||||||
|
#if unsafe
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern unsafe int DAQmxReadBinaryI16(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int numSampsPerChan,
|
||||||
|
double timeout,
|
||||||
|
int fillMode,
|
||||||
|
bool* readArray,
|
||||||
|
uint arraySizeInSamps,
|
||||||
|
out IntPtr sampsPerChanRead,
|
||||||
|
IntPtr reserved);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if unsafe
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern unsafe int DAQmxReadBinaryU16(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int numSampsPerChan,
|
||||||
|
double timeout,
|
||||||
|
int fillMode,
|
||||||
|
ushort* readArray,
|
||||||
|
uint arraySizeInSamps,
|
||||||
|
out IntPtr sampsPerChanRead,
|
||||||
|
IntPtr reserved);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if unsafe
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern unsafe int DAQmxReadBinaryI32(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int numSampsPerChan,
|
||||||
|
double timeout,
|
||||||
|
int fillMode,
|
||||||
|
int* readArray,
|
||||||
|
uint arraySizeInSamps,
|
||||||
|
out IntPtr sampsPerChanRead,
|
||||||
|
IntPtr reserved);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if unsafe
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern unsafe int DAQmxReadBinaryU32(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int numSampsPerChan,
|
||||||
|
double timeout,
|
||||||
|
int fillMode,
|
||||||
|
uint* readArray,
|
||||||
|
uint arraySizeInSamps,
|
||||||
|
out IntPtr sampsPerChanRead,
|
||||||
|
IntPtr reserved);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxConfigureLogging(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string filePath,
|
||||||
|
int loggingMode,
|
||||||
|
string groupName,
|
||||||
|
int operation);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxLoadTask(string taskName, out IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCreateTask(string taskName, out IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxAddGlobalChansToTask(IntPtr taskHandle, string[] channelNames);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxStartTask(IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxStopTask(IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxClearTask(IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxWaitUntilTaskDone(IntPtr taskHandle, double timeToWait);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxWaitForValidTimestamp(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int timestampEvent,
|
||||||
|
double timeout,
|
||||||
|
CVIAbsoluteTime timestamp);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxIsTaskDone(IntPtr taskHandle, out uint isTaskDone);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxTaskControl(IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxGetNthTaskChannel(IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxGetNthTaskDevice(IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxGetTaskAttribute(IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCfgSampClkTiming(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string source,
|
||||||
|
double rate,
|
||||||
|
int activeEdge,
|
||||||
|
int sampleMode,
|
||||||
|
ulong sampsPerChan);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCfgHandshakingTiming(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int sampleMode,
|
||||||
|
ulong sampsPerChan);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCfgBurstHandshakingTimingImportClock(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int sampleMode,
|
||||||
|
ulong sampsPerChan,
|
||||||
|
double sampleClkRate,
|
||||||
|
string sampleClkSrc,
|
||||||
|
int sampleClkActiveEdge,
|
||||||
|
int pauseWhen,
|
||||||
|
int readyEventActiveLevel);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCfgBurstHandshakingTimingExportClock(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int sampleMode,
|
||||||
|
ulong sampsPerChan,
|
||||||
|
double sampleClkRate,
|
||||||
|
string sampleClkOutpTerm,
|
||||||
|
int sampleClkPulsePolarity,
|
||||||
|
int pauseWhen,
|
||||||
|
int readyEventActiveLevel);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCfgChangeDetectionTiming(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string risingEdgeChan,
|
||||||
|
string fallingEdgeChan,
|
||||||
|
int sampleMode,
|
||||||
|
ulong sampsPerChan);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCfgImplicitTiming(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int sampleMode,
|
||||||
|
ulong sampsPerChan);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxCfgPipelinedSampClkTiming(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string source,
|
||||||
|
double rate,
|
||||||
|
int activeEdge,
|
||||||
|
int sampleMode,
|
||||||
|
ulong sampsPerChan);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxGetTimingAttribute(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int attribute,
|
||||||
|
out object value);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxSetTimingAttribute(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int attribute,
|
||||||
|
object value);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxResetTimingAttribute(IntPtr taskHandle, int attribute);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxGetTimingAttributeEx(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string deviceNames,
|
||||||
|
int attribute,
|
||||||
|
out object value);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxSetTimingAttributeEx(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string deviceNames,
|
||||||
|
int attribute,
|
||||||
|
object value);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int DAQmxResetTimingAttributeEx(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string deviceNames,
|
||||||
|
int attribute);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxDisableStartTrig(IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgDigEdgeStartTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSource,
|
||||||
|
int triggerEdge);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgAnlgEdgeStartTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSource,
|
||||||
|
int triggerSlope,
|
||||||
|
double triggerLevel);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgAnlgMultiEdgeStartTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSources,
|
||||||
|
int[] triggerSlopeArray,
|
||||||
|
double[] triggerLevelArray,
|
||||||
|
uint arraySize);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgAnlgWindowStartTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSource,
|
||||||
|
int triggerWhen,
|
||||||
|
double windowTop,
|
||||||
|
double windowBottom);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgTimeStartTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
CVIAbsoluteTime when,
|
||||||
|
int timescale);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgDigPatternStartTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSource,
|
||||||
|
string triggerPattern,
|
||||||
|
int triggerWhen);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxDisableRefTrig(IntPtr taskHandle);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgDigEdgeRefTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSource,
|
||||||
|
int triggerEdge,
|
||||||
|
uint pretriggerSamples);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgAnlgEdgeRefTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSource,
|
||||||
|
int triggerSlope,
|
||||||
|
double triggerLevel,
|
||||||
|
uint pretriggerSamples);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgAnlgMultiEdgeRefTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSources,
|
||||||
|
int[] triggerSlopeArray,
|
||||||
|
double[] triggerLevelArray,
|
||||||
|
uint pretriggerSamples,
|
||||||
|
uint arraySize);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgAnlgWindowRefTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSource,
|
||||||
|
int triggerWhen,
|
||||||
|
double windowTop,
|
||||||
|
double windowBottom,
|
||||||
|
uint pretriggerSamples);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxCfgDigPatternRefTrig(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
string triggerSource,
|
||||||
|
string triggerPattern,
|
||||||
|
int triggerWhen,
|
||||||
|
uint pretriggerSamples);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxGetTrigAttribute(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int attribute,
|
||||||
|
out object value);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxSetTrigAttribute(IntPtr taskHandle, int attribute, object value);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxResetTrigAttribute(IntPtr taskHandle, int attribute);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxWriteAnalogF64(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int numSampsPerChan,
|
||||||
|
bool autoStart,
|
||||||
|
double timeout,
|
||||||
|
bool dataLayout,
|
||||||
|
double[] writeArray,
|
||||||
|
out IntPtr sampsPerChanWritten,
|
||||||
|
IntPtr reserved);
|
||||||
|
|
||||||
|
[DllImport("DAQmx", CallingConvention = CallingConvention.StdCall)]
|
||||||
|
public static extern int DAQmxWriteDigitalLines(
|
||||||
|
IntPtr taskHandle,
|
||||||
|
int numSampsPerChan,
|
||||||
|
bool autoStart,
|
||||||
|
double timeout,
|
||||||
|
bool dataLayout,
|
||||||
|
byte[] writeArray,
|
||||||
|
out IntPtr sampsPerChanWritten,
|
||||||
|
IntPtr reserved);
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,12 @@
|
|||||||
using CliWrap;
|
using CliWrap;
|
||||||
using File_Watcher.Models;
|
using File_Watcher.Models;
|
||||||
|
|
||||||
|
#if ShellProgressBar
|
||||||
|
|
||||||
using ShellProgressBar;
|
using ShellProgressBar;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
@ -21,13 +27,24 @@ internal static partial class DeterministicHashCodeHelper
|
|||||||
{
|
{
|
||||||
|
|
||||||
public long Ticks { get; init; }
|
public long Ticks { get; init; }
|
||||||
public int? CurrentTick => _ProgressBar?.CurrentTick;
|
public int? CurrentTick =>
|
||||||
|
#if ShellProgressBar
|
||||||
|
_ProgressBar?.CurrentTick;
|
||||||
|
#else
|
||||||
|
throw new NotSupportedException("ShellProgressBar is not supported in this context.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ShellProgressBar
|
||||||
private ProgressBar? _ProgressBar;
|
private ProgressBar? _ProgressBar;
|
||||||
private readonly ProgressBarOptions _ProgressBarOptions;
|
private readonly ProgressBarOptions _ProgressBarOptions;
|
||||||
|
#endif
|
||||||
|
|
||||||
public Windows() =>
|
public Windows() =>
|
||||||
|
#if ShellProgressBar
|
||||||
_ProgressBarOptions = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
_ProgressBarOptions = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||||
|
#else
|
||||||
|
throw new NotSupportedException("ShellProgressBar is not supported in this context.");
|
||||||
|
#endif
|
||||||
|
|
||||||
DeterministicHashCode IWindows.GetDeterministicHashCode(HttpClient httpClient, Uri uri) =>
|
DeterministicHashCode IWindows.GetDeterministicHashCode(HttpClient httpClient, Uri uri) =>
|
||||||
GetDeterministicHashCode(httpClient, uri);
|
GetDeterministicHashCode(httpClient, uri);
|
||||||
@ -98,18 +115,26 @@ internal static partial class DeterministicHashCodeHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IWindows.Tick() =>
|
void IWindows.Tick() =>
|
||||||
|
#if ShellProgressBar
|
||||||
_ProgressBar?.Tick();
|
_ProgressBar?.Tick();
|
||||||
|
#else
|
||||||
|
throw new NotSupportedException("ShellProgressBar is not supported in this context.");
|
||||||
|
#endif
|
||||||
|
|
||||||
void IDisposable.Dispose()
|
void IDisposable.Dispose()
|
||||||
{
|
{
|
||||||
|
#if ShellProgressBar
|
||||||
_ProgressBar?.Dispose();
|
_ProgressBar?.Dispose();
|
||||||
|
#endif
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IWindows.ConstructProgressBar(int maxTicks, string message)
|
void IWindows.ConstructProgressBar(int maxTicks, string message)
|
||||||
{
|
{
|
||||||
|
#if ShellProgressBar
|
||||||
_ProgressBar?.Dispose();
|
_ProgressBar?.Dispose();
|
||||||
_ProgressBar = new(maxTicks, message, _ProgressBarOptions);
|
_ProgressBar = new(maxTicks, message, _ProgressBarOptions);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlyCollection<string> IWindows.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(ResultSettings resultSettings, HttpClient? httpClient, FilePath filePath)
|
ReadOnlyCollection<string> IWindows.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(ResultSettings resultSettings, HttpClient? httpClient, FilePath filePath)
|
||||||
|
75
Helpers/NationalInstrumentsHelper.cs
Normal file
75
Helpers/NationalInstrumentsHelper.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
using File_Watcher.Models;
|
||||||
|
using Helpers.DAQmx;
|
||||||
|
|
||||||
|
namespace File_Watcher.Helpers;
|
||||||
|
|
||||||
|
internal static partial class NationalInstrumentsHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
private static Dictionary<string, DAQmxTask>? _DataAcquisitionTasks = null;
|
||||||
|
|
||||||
|
internal static bool WriteData(AppSettings appSettings, ILogger<Worker> logger)
|
||||||
|
{
|
||||||
|
double value;
|
||||||
|
LogNetToHoursSince(logger);
|
||||||
|
if (_DataAcquisitionTasks is null)
|
||||||
|
{
|
||||||
|
string name;
|
||||||
|
_DataAcquisitionTasks = [];
|
||||||
|
DAQmxTask dataAcquisitionTask;
|
||||||
|
const DAQmxUnits volts = DAQmxUnits.Volts;
|
||||||
|
NationalInstrumentsConfiguration ni = appSettings.NationalInstrumentsConfiguration;
|
||||||
|
const DAQmxInputTerminalConfiguration differential = DAQmxInputTerminalConfiguration.Differential;
|
||||||
|
const DAQmxInputTerminalConfiguration referencedSingleEnded = DAQmxInputTerminalConfiguration.ReferencedSingleEnded;
|
||||||
|
foreach (string physicalChannel in appSettings.NationalInstrumentsConfiguration.DifferentialPhysicalChannels.Distinct())
|
||||||
|
{
|
||||||
|
name = !physicalChannel.Contains('/') ? physicalChannel : physicalChannel.Split('/')[1];
|
||||||
|
dataAcquisitionTask = DAQmxTask.Create(name);
|
||||||
|
dataAcquisitionTask.CreateAnalogInputVoltageChannel(physicalChannel, name, differential, ni.MiniumValue, ni.MaximumValue, volts, ni.CustomScaleName);
|
||||||
|
_DataAcquisitionTasks.Add(name, dataAcquisitionTask);
|
||||||
|
}
|
||||||
|
foreach (string physicalChannel in appSettings.NationalInstrumentsConfiguration.ReferencedSingleEndedPhysicalChannels.Distinct())
|
||||||
|
{
|
||||||
|
name = !physicalChannel.Contains('/') ? physicalChannel : physicalChannel.Split('/')[1];
|
||||||
|
dataAcquisitionTask = DAQmxTask.Create(name);
|
||||||
|
dataAcquisitionTask.CreateAnalogInputVoltageChannel(physicalChannel, name, referencedSingleEnded, ni.MiniumValue, ni.MaximumValue, volts, ni.CustomScaleName);
|
||||||
|
_DataAcquisitionTasks.Add(name, dataAcquisitionTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (KeyValuePair<string, DAQmxTask> keyValuePair in _DataAcquisitionTasks)
|
||||||
|
{
|
||||||
|
if (appSettings.NationalInstrumentsConfiguration.UsePointerMethod)
|
||||||
|
throw new NotSupportedException("Pointer method is not supported in this implementation.");
|
||||||
|
value = keyValuePair.Value.ReadAnalogScalarF64(appSettings.NationalInstrumentsConfiguration.ReadTimeout);
|
||||||
|
logger.LogInformation("{key}-{read}: {value}", keyValuePair.Key, keyValuePair.Value.TotalSamplesRead, value);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LogNetToHoursSince(ILogger<Worker>? logger)
|
||||||
|
{
|
||||||
|
double secondsInAHour = 3600f;
|
||||||
|
long epoch = new DateTime(1970, 1, 1).Ticks;
|
||||||
|
long net8ReleaseDate = new DateTime(2023, 11, 14).Ticks;
|
||||||
|
long net9ReleaseDate = new DateTime(2024, 11, 12).Ticks;
|
||||||
|
long net10ReleaseDate = new DateTime(2026, 01, 01).Ticks;
|
||||||
|
long framework48ReleaseDate = new DateTime(2019, 04, 18).Ticks;
|
||||||
|
double net8TotalSeconds = new TimeSpan(net8ReleaseDate - epoch).TotalSeconds;
|
||||||
|
double net9TotalSeconds = new TimeSpan(net9ReleaseDate - epoch).TotalSeconds;
|
||||||
|
double net10TotalSeconds = new TimeSpan(net10ReleaseDate - epoch).TotalSeconds;
|
||||||
|
double framework48TotalSeconds = new TimeSpan(framework48ReleaseDate - epoch).TotalSeconds;
|
||||||
|
logger?.LogInformation("It has been {net8TotalSeconds} seconds since net8 was released", net8TotalSeconds);
|
||||||
|
logger?.LogInformation("It has been {net9TotalSeconds} seconds since net9 was released", net9TotalSeconds);
|
||||||
|
logger?.LogInformation("It has been {net10TotalSeconds} seconds since net10 was released", net10TotalSeconds);
|
||||||
|
logger?.LogInformation("It has been {framework48TotalSeconds} seconds since framework48 was released", framework48TotalSeconds);
|
||||||
|
double net8TotalHours = Math.Floor((DateTimeOffset.UtcNow.ToUnixTimeSeconds() - net8TotalSeconds) / secondsInAHour);
|
||||||
|
double net9TotalHours = Math.Floor((DateTimeOffset.UtcNow.ToUnixTimeSeconds() - net9TotalSeconds) / secondsInAHour);
|
||||||
|
double net10TotalHours = Math.Floor((DateTimeOffset.UtcNow.ToUnixTimeSeconds() - net10TotalSeconds) / secondsInAHour);
|
||||||
|
double framework48TotalHours = Math.Floor((DateTimeOffset.UtcNow.ToUnixTimeSeconds() - framework48TotalSeconds) / secondsInAHour);
|
||||||
|
logger?.LogInformation("It has been {net8TotalHours} hours since net8 was released", net8TotalHours);
|
||||||
|
logger?.LogInformation("It has been {net9TotalHours} hours since net9 was released", net9TotalHours);
|
||||||
|
logger?.LogInformation("It has been {net10TotalHours} hours since net10 was released", net10TotalHours);
|
||||||
|
logger?.LogInformation("It has been {framework48TotalHours} hours since framework48 was released", framework48TotalHours);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,6 +16,7 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
|
|||||||
IsoConfiguration IsoConfiguration,
|
IsoConfiguration IsoConfiguration,
|
||||||
MetadataSettings MetadataSettings,
|
MetadataSettings MetadataSettings,
|
||||||
MetrologyConfiguration MetrologyConfiguration,
|
MetrologyConfiguration MetrologyConfiguration,
|
||||||
|
NationalInstrumentsConfiguration NationalInstrumentsConfiguration,
|
||||||
NugetConfiguration NugetConfiguration,
|
NugetConfiguration NugetConfiguration,
|
||||||
ResultSettings ResultSettings,
|
ResultSettings ResultSettings,
|
||||||
SeleniumConfiguration SeleniumConfiguration,
|
SeleniumConfiguration SeleniumConfiguration,
|
||||||
@ -42,6 +43,7 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
|
|||||||
IsoConfiguration? isoConfiguration = configurationRoot.GetSection(nameof(IsoConfiguration)).Get<IsoConfiguration>();
|
IsoConfiguration? isoConfiguration = configurationRoot.GetSection(nameof(IsoConfiguration)).Get<IsoConfiguration>();
|
||||||
MetadataSettings? metadataSettings = configurationRoot.GetSection(nameof(MetadataSettings)).Get<MetadataSettings>();
|
MetadataSettings? metadataSettings = configurationRoot.GetSection(nameof(MetadataSettings)).Get<MetadataSettings>();
|
||||||
MetrologyConfiguration? metrologyConfiguration = configurationRoot.GetSection(nameof(MetrologyConfiguration)).Get<MetrologyConfiguration>();
|
MetrologyConfiguration? metrologyConfiguration = configurationRoot.GetSection(nameof(MetrologyConfiguration)).Get<MetrologyConfiguration>();
|
||||||
|
NationalInstrumentsConfiguration? nationalInstrumentsConfiguration = configurationRoot.GetSection(nameof(NationalInstrumentsConfiguration)).Get<NationalInstrumentsConfiguration>();
|
||||||
NugetConfiguration? nugetConfiguration = configurationRoot.GetSection(nameof(NugetConfiguration)).Get<NugetConfiguration>();
|
NugetConfiguration? nugetConfiguration = configurationRoot.GetSection(nameof(NugetConfiguration)).Get<NugetConfiguration>();
|
||||||
ResultSettings? resultSettings = configurationRoot.GetSection(nameof(ResultSettings)).Get<ResultSettings>();
|
ResultSettings? resultSettings = configurationRoot.GetSection(nameof(ResultSettings)).Get<ResultSettings>();
|
||||||
SeleniumConfiguration? seleniumConfiguration = configurationRoot.GetSection(nameof(SeleniumConfiguration)).Get<SeleniumConfiguration>();
|
SeleniumConfiguration? seleniumConfiguration = configurationRoot.GetSection(nameof(SeleniumConfiguration)).Get<SeleniumConfiguration>();
|
||||||
@ -63,6 +65,7 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
|
|||||||
|| isoConfiguration is null
|
|| isoConfiguration is null
|
||||||
|| metadataSettings is null
|
|| metadataSettings is null
|
||||||
|| metrologyConfiguration is null
|
|| metrologyConfiguration is null
|
||||||
|
|| nationalInstrumentsConfiguration is null
|
||||||
|| nugetConfiguration is null
|
|| nugetConfiguration is null
|
||||||
|| resultSettings is null
|
|| resultSettings is null
|
||||||
|| seleniumConfiguration is null
|
|| seleniumConfiguration is null
|
||||||
@ -96,6 +99,7 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
|
|||||||
isoConfiguration,
|
isoConfiguration,
|
||||||
metadataSettings,
|
metadataSettings,
|
||||||
metrologyConfiguration,
|
metrologyConfiguration,
|
||||||
|
nationalInstrumentsConfiguration,
|
||||||
nugetConfiguration,
|
nugetConfiguration,
|
||||||
resultSettings,
|
resultSettings,
|
||||||
seleniumConfiguration,
|
seleniumConfiguration,
|
||||||
|
27
Models/NationalInstrumentsConfiguration.cs
Normal file
27
Models/NationalInstrumentsConfiguration.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Watcher.Models;
|
||||||
|
|
||||||
|
public record NationalInstrumentsConfiguration(string CustomScaleName,
|
||||||
|
string[] DifferentialPhysicalChannels,
|
||||||
|
int MaximumValue,
|
||||||
|
int MiniumValue,
|
||||||
|
string[] ReferencedSingleEndedPhysicalChannels,
|
||||||
|
int ReadTimeout,
|
||||||
|
bool UsePointerMethod)
|
||||||
|
{
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, NationalInstrumentsConfigurationSourceGenerationContext.Default.NationalInstrumentsConfiguration);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(NationalInstrumentsConfiguration))]
|
||||||
|
internal partial class NationalInstrumentsConfigurationSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
#if Nancy
|
||||||
|
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.Extensions;
|
using Nancy.Extensions;
|
||||||
|
|
||||||
@ -48,4 +50,6 @@ public class SyncModule : NancyModule
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,5 @@
|
|||||||
|
#if Nancy
|
||||||
|
|
||||||
using Microsoft.Owin.Cors;
|
using Microsoft.Owin.Cors;
|
||||||
using Nancy.Owin;
|
using Nancy.Owin;
|
||||||
using Owin;
|
using Owin;
|
||||||
@ -16,4 +18,6 @@ public class Startup
|
|||||||
_ = app.UseNancy();
|
_ = app.UseNancy();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -24,7 +24,9 @@ public partial class Worker : BackgroundService
|
|||||||
_IsWindowsService = collection.Contains(nameof(WindowsServiceLifetime));
|
_IsWindowsService = collection.Contains(nameof(WindowsServiceLifetime));
|
||||||
if (appSettings.FileWatcherConfiguration.Helper == nameof(Helpers.SyncHelper))
|
if (appSettings.FileWatcherConfiguration.Helper == nameof(Helpers.SyncHelper))
|
||||||
{
|
{
|
||||||
|
#if Nancy
|
||||||
_ = Microsoft.Owin.Hosting.WebApp.Start<Startup>(appSettings.SyncConfiguration.UniformResourceLocator);
|
_ = Microsoft.Owin.Hosting.WebApp.Start<Startup>(appSettings.SyncConfiguration.UniformResourceLocator);
|
||||||
|
#endif
|
||||||
logger.LogInformation("Server running on {url}", appSettings.SyncConfiguration.UniformResourceLocator);
|
logger.LogInformation("Server running on {url}", appSettings.SyncConfiguration.UniformResourceLocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,6 +89,7 @@ public partial class Worker : BackgroundService
|
|||||||
nameof(Helpers.HelperWaferCounter) => Helpers.HelperWaferCounter.MoveFile(_AppSettings, _Logger),
|
nameof(Helpers.HelperWaferCounter) => Helpers.HelperWaferCounter.MoveFile(_AppSettings, _Logger),
|
||||||
nameof(Helpers.HelperSerial) => Helpers.HelperSerial.ReadWrite(_AppSettings, _Logger, cancellationToken),
|
nameof(Helpers.HelperSerial) => Helpers.HelperSerial.ReadWrite(_AppSettings, _Logger, cancellationToken),
|
||||||
nameof(Helpers.HelperMetrologyFiles) => Helpers.HelperMetrologyFiles.SortAndDelete(_AppSettings, _Logger),
|
nameof(Helpers.HelperMetrologyFiles) => Helpers.HelperMetrologyFiles.SortAndDelete(_AppSettings, _Logger),
|
||||||
|
nameof(Helpers.NationalInstrumentsHelper) => Helpers.NationalInstrumentsHelper.WriteData(_AppSettings, _Logger),
|
||||||
nameof(Helpers.DeterministicHashCodeHelper) => Helpers.DeterministicHashCodeHelper.WindowsWork(_AppSettings, _Logger),
|
nameof(Helpers.DeterministicHashCodeHelper) => Helpers.DeterministicHashCodeHelper.WindowsWork(_AppSettings, _Logger),
|
||||||
#if Selenium
|
#if Selenium
|
||||||
nameof(Helpers.SeleniumHelper) => Helpers.SeleniumHelper.HyperTextMarkupLanguageToPortableNetworkGraphics(_AppSettings, _Logger),
|
nameof(Helpers.SeleniumHelper) => Helpers.SeleniumHelper.HyperTextMarkupLanguageToPortableNetworkGraphics(_AppSettings, _Logger),
|
||||||
|
Reference in New Issue
Block a user