{"id":19473071,"url":"https://github.com/issus/networkedtestequipment","last_synced_at":"2025-04-15T07:52:15.775Z","repository":{"id":65143127,"uuid":"583393195","full_name":"issus/NetworkedTestEquipment","owner":"issus","description":"Pure .NET library for connecting to and communicating with LXI based test equipment using SCPI commands","archived":false,"fork":false,"pushed_at":"2023-04-15T18:03:22.000Z","size":877,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-15T07:52:05.792Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/issus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-12-29T16:38:32.000Z","updated_at":"2023-05-18T15:55:32.000Z","dependencies_parsed_at":"2023-02-18T21:31:24.537Z","dependency_job_id":null,"html_url":"https://github.com/issus/NetworkedTestEquipment","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/issus%2FNetworkedTestEquipment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/issus%2FNetworkedTestEquipment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/issus%2FNetworkedTestEquipment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/issus%2FNetworkedTestEquipment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/issus","download_url":"https://codeload.github.com/issus/NetworkedTestEquipment/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249031769,"owners_count":21201357,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T19:17:07.385Z","updated_at":"2025-04-15T07:52:15.758Z","avatar_url":"https://github.com/issus.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# .NET Networked Test Equipment Library\n\nThis library allows you to easily connect to and control your electronics test equipment over a network connection. It is implemented entirely in native .NET, so it does not require any additional equipment libraries or vendor specific DLLs. The library can be used on all platforms that support .NET, including Windows, Mac, Linux, and embedded systems.\n\nUsing this library, you can perform a variety of tasks such as sending commands, reading measurements, and configuring settings on your test equipment. It is designed to be easy to use, with a straightforward API and detailed documentation to help you get started.\n\n\n# Supported Equipment\n\nCurrently, the following equipment is supported:\n* Rigol MSO5000 Series Oscilloscopes\n* Rigol DP800 Series Power Supplies\n* Rigol DL3000 Series DC Loads\n* Rohde \u0026 Schwarz LCX Series LCR Meters\n* Siglent SDG series arbitrary function generators\n\nHowever, the code **should** work with most oscilloscopes/supplies/loads with most functions.\n\n# Examples\n\n## Connecting to a DP800 Power Supply and Setting Channel Voltage\nConnecting to a power supply instrument and setting the output to 3.3V:\n\n```csharp\n    var dp800a = new RigolDP800Instrument();\n    await dp800a.Connect(\"10.0.0.132\");\n    \n    Console.WriteLine($\"Connected to {dp800a.Identity.Manufacturer} {dp800a.Identity.Model}\");\n    \n    await dp800a.SelectChannel(Channel.CH1);\n    await dp800a.Output.Disable();\n    await dp800a.Voltage.Set(3.3);\n    await dp800a.WaitForOperationComplete(1);\n    await dp800a.Output.Enable();\n```\n\n# Oscilloscope Usage\n\nThe NetworkedTestEquipmentLibrary provides a class called `RigolMSO5000Instrument` for interacting with a Rigol MSO5000 oscilloscope.\n\nThe following example methods show how you can use the `RigolMSO5000Instrument` class to perform various tasks with an oscilloscope.\n\n## Connect to an MSO5000 Oscilloscope\n\n```csharp\nvar mso5000 = new RigolMSO5000Instrument();\nawait mso5000.Connect(\"10.0.0.74\");\n```\n\n## Enabling/Disabling Oscilloscope Channel Display\nYou can use the SetDisplay method of the Channel object to enable or disable the display of a specific channel on the oscilloscope. The method takes a bool indicating whether to enable (true) or disable (false) the display, and a ScopeChannel representing the channel to enable or disable (e.g. CH1, CH2, etc.).\n\nHere is an example of how to disable the display of all channels and then re-enable the display of channels 1 and 2:\n\n```csharp\nif (mso != null)\n{\n    // Disable display of all channels\n    await mso.Channel.SetDisplay(false, ScopeChannel.CH1);\n    await mso.Channel.SetDisplay(false, ScopeChannel.CH2);\n    await mso.Channel.SetDisplay(false, ScopeChannel.CH3);\n    await mso.Channel.SetDisplay(false, ScopeChannel.CH4);\n\n    // Wait for all operations to complete before continuing\n    await mso.WaitForOperationComplete();\n\n    // Enable display of channels 1 and 2\n    await mso.Channel.SetDisplay(true, ScopeChannel.CH1);\n    await mso.Channel.SetDisplay(true, ScopeChannel.CH2);\n}\n```\n\n## Setting a Scope Channel to Display a Current Waveform\n\nTo set a scope channel to display a current waveform and adjust the channel scaling and offset, you can use the following methods of the `Channel` object:\n\n-   `SetCoupling(Coupling coupling, ScopeChannel channel)`: Sets the coupling type (DC or AC) of the specified channel.\n-   `SetUnits(ChannelUnits units, ScopeChannel channel)`: Sets the units (e.g. voltage, current) of the specified channel.\n-   `SetFineAdjustment(bool enable, ScopeChannel channel)`: Enables or disables fine adjustment of the specified channel.\n-   `SetScale(double scale, ScopeChannel channel)`: Sets the scale (vertical sensitivity) of the specified channel.\n-   `SetOffset(double offset, ScopeChannel channel)`: Sets the offset (vertical position) of the specified channel.\n\nHere is an example of how to use these methods to set a scope channel (e.g. CHAN1) to display a current waveform:\n\n```csharp\nif (mso == null) return;\n\nvar current = 0.1; // 100mA\n\n// Set channel 1 to display a DC current waveform\nawait mso.Channel.SetCoupling(Coupling.DC, ScopeChannel.CHAN1);\n// Set the units of channel 1 to Ampere\nawait mso.Channel.SetUnits(ChannelUnits.Ampere, ScopeChannel.CHAN1);\n// Enable fine adjustment for channel 1\nawait mso.Channel.SetFineAdjustment(true, ScopeChannel.CHAN1);\n// Set the scale of channel 1 to give 1 division of headroom\nawait mso.Channel.SetScale(Math.Round(current / 6, 2), ScopeChannel.CHAN1);\n// Set the offset of channel 1 to give 1 division of footspace\nawait mso.Channel.SetOffset(-(current / 2), ScopeChannel.CHAN1);\n\n// Wait for the operation to be completed\nawait mso.WaitForOperationComplete();\n```\n\nNote that the `WaitForOperationComplete` method can be used to wait for the oscilloscope to complete the current operation before continuing with the next operation. This is useful to ensure that the oscilloscope has finished updating the display and is ready to accept new commands.\n\n## Setting the Trigger\nTo set up the trigger on an oscilloscope channel, you can use the following steps:\n\n1.  Set the coupling of the trigger to DC using the `SetCoupling` method.\n2.  Set the trigger mode to EDGE using the `SetMode` method.\n3.  Set the trigger edge source to CHAN1 using the `SetSource` method of the `Edge` property.\n4.  Set the trigger edge slope to POS (positive) using the `SetSlope` method of the `Edge` property.\n5.  Set the trigger level to a desired value (e.g. 8.2 volts) using the `SetLevel` method.\n6.  Set the trigger sweep mode to NORM (normal) using the `SetSweep` method.\n7.  Use the `WaitToContinue` method to wait for the oscilloscope to complete the current operation before continuing with the next operation.\n8.  Use the `SendKeypress` method to hide the trigger menu by pressing the MOFF (Menu Off) button on the scope.\n9.  Use the `WaitForOperationComplete` method to wait for the oscilloscope to complete the current operation.\n\n```csharp\nif (mso == null) return;\n\ndouble triggerLevel = 8.2; // 8.2volts\n\nawait mso.Trigger.SetCoupling(Coupling.DC);\nawait mso.Trigger.SetMode(TriggerMode.EDGE);\nawait mso.Trigger.Edge.SetSource(TriggerEdgeSource.CHAN1);\nawait mso.Trigger.Edge.SetSlope(TriggerSlope.POS);\nawait mso.Trigger.Edge.SetLevel(triggerLevel);\nawait mso.Trigger.SetSweep(TriggerSweep.NORM);\nawait mso.WaitToContinue();\n\n// press the Menu Off (MOFF) button on the scope to hide the trigger menu\nawait mso.SendKeypress(ScopeKey.MOFF);\n\nawait mso.WaitForOperationComplete();\n```\n\nThis code sets up the trigger on the oscilloscope to be an edge trigger on channel 1 with a positive slope and a trigger level of 8.2 volts. The sweep mode is set to NORM, which means that the scope will trigger based on the configured trigger settings. Finally, the MOFF button is pressed to hide the trigger menu on the scope.\n\n**Note:** The `TriggerSweep` enumeration has three values: AUTO (auto trigger as well as configured trigger), NORM (only trigger based on configuration), or SIGN (single trigger, then stop the scope). You can choose the appropriate trigger sweep mode based on your needs.\n\n\n## Displaying Measurements and Statistics\n\nTo display measurements or measurements with statistics on the oscilloscope, you can use the `EnableMeasurement` and `EnableStatistic` methods of the `Measure` object. These methods take a `MeasureFunction` representing the measurement function to display (e.g. `VPP`, `VMAX`, `VRMS`) and a `MeasureChannel` representing the channel to display the measurement for (e.g. `CHAN1`, `CHAN2`).\n\nHere is an example of how to use these methods to display various measurements and statistics on the oscilloscope:\n\n```csharp\nif (mso != null)\n{\n    // Enable statistical measurements for VPP and VMAX on channel 1\n    await mso.Measure.EnableStatistic(MeasureFunction.VPP, MeasureChannel.CHAN1);\n    await mso.Measure.EnableStatistic(MeasureFunction.VMAX, MeasureChannel.CHAN1);\n\n    // Enable statistical measurement for VMIN on channel 2\n    await mso.Measure.EnableStatistic(MeasureFunction.VMIN, MeasureChannel.CHAN2);\n\n    // Enable measurements for VRMS and VAVG on channel 2\n    await mso.Measure.EnableMeasurement(MeasureFunction.VRMS, MeasureChannel.CHAN2);\n    await mso.Measure.EnableMeasurement(MeasureFunction.VAVG, MeasureChannel.CHAN1);\n\n    // Wait for all operations to complete before continuing\n    await mso.WaitToContinue();\n}\n```\n\n## Removing Measurements from the Display\nTo remove measurements from the display of the oscilloscope, you can use the `Clear` method of the `Measure` object. Passing in the value `MeasureItem.ALL` as the parameter will remove all measurements from the display, regardless of which channel or function they are for.\n\nHere is an example of how to use the Clear method:\n\n```csharp\nif (mso != null)\n{\n\t// Remove the first measurement item\n\tawait scope.Measure.Clear(MeasureItem.ITEM1);\n\t\n    // Remove all measurements from the display\n    await mso.Measure.Clear(MeasureItem.ALL);\n}\n```\n\n\n## Querying Measurements\nYou can use the `Measure.QueryMeasurement` method to retrieve the value of a specific measurement (e.g. VMAX, VPP, PERIOD, etc) on the specific channel (CH1, CH2, MATH1, etc.) from the oscilloscope. If you do not specify the channel, it will use the channel you selecting with the `Measure.SetSource` method. The method below returns a double representing the voltage measurement.\n\n```csharp\ninternal async Task\u003cdouble\u003e QueryScopeMeasurement(MeasureFunction function, MeasureChannel channel)\n{\n    // Check if oscilloscope object is available\n    if (mso == null)\n        return double.NaN;\n\n    // Initialize measurement and attempt counter\n    double meas = double.NaN;\n    int attempts = 0;\n\n    // Make multiple attempts to retrieve measurement\n    while (attempts++ \u003c 20)\n    {\n        meas = await mso.Measure.QueryMeasurement(function, channel);\n\n        // Return measurement if it is valid (not double.NaN)\n        if (!double.IsNaN(meas))\n            return meas;\n    }\n\n    // Return measurement (could be double.NaN if all attempts failed)\n    return meas;\n}\n```\n\n**Note:** A measurement may return `double.NaN` if the oscilloscope is busy updating the measurement when you attempt to read it. In this case, the method will make multiple attempts until a valid measurement is returned or the maximum number of attempts is reached.\n\n## Querying Statistics\nYou can use the `Measure.QueryStatistic` method to retrieve the value of a specific measurement (e.g. VMAX, VPP, PERIOD, etc) on the specific channel (CH1, CH2, MATH1, etc.) from the oscilloscope. This will allow you to read the statistics from the measurement window (e.g. Maximum, Average, Deviation.) If you do not specify the channel, it will use the channel you selecting with the `Measure.SetSource` method. The method below returns a double representing the voltage measurement.\n\n```csharp\ninternal async Task\u003cdouble\u003e QueryScopeStatistic(MeasureFunction function, MeasureType type, MeasureChannel channel)\n{\n    // Check if oscilloscope object is available\n    if (mso == null)\n        return double.NaN;\n\n    // Initialize measurement and attempt counter\n    double meas = double.NaN;\n    int attempts = 0;\n\n    // Make multiple attempts to retrieve measurement\n    while (double.IsNaN(meas) \u0026\u0026 attempts++ \u003c 20)\n    {\n        meas = await mso.Measure.QueryStatistic(function, type, channel);\n    }\n\n    // Return measurement (could be double.NaN if all attempts failed)\n    return meas;\n}\n```\n\n**Note:** A measurement may return `double.NaN` if the oscilloscope is busy updating the measurement when you attempt to read it. In this case, the method will make multiple attempts until a valid measurement is returned or the maximum number of attempts is reached.\n\n## Capturing and Saving the Oscilloscope Display\n\nTo capture the display of the oscilloscope and save it to a file, you can use the `Capture` method of the `Display` object and the `SaveAsPngAsync` method of the `Image` object. The `Capture` method returns an `Image` object representing the current display of the oscilloscope. The `SaveAsPngAsync` method takes a file path as a parameter and saves the image to the specified location in PNG format.\n\nHere is an example of how to use these methods to capture and save the oscilloscope display:\n\n```csharp\nif (mso != null)\n{\n    // Capture the oscilloscope display as an Image object\n    var display = await mso.Display.Capture();\n\n    // Save the image to a file if it was successfully captured\n    if (display != null)\n    {\n        await display.SaveAsPngAsync(\"C:\\\\temp\\\\screenshot.png\");\n    }\n}\n```\n\n**Note:** You will need to have the [SixLabors.ImageSharp](https://www.nuget.org/packages/SixLabors.ImageSharp/) NuGet package installed in order to use this code.\n\n## Capturing Waveform Data from the Oscilloscope\n\nTo capture waveform data from the oscilloscope, you can use the `Data` method of the `Waveform` object. This method takes a `WaveformSource` representing the source of the waveform data (e.g. `CHAN1`, `CHAN2`) and a `WaveformMode` representing the mode of the waveform data (e.g. `NORM`, `MAX`, `RAW`). The `WaveformMode` can be one of the following:\n\n-   `NORM`: Reads the waveform data currently displayed on the screen.\n-   `MAX`: Reads the waveform data displayed on the screen when the oscilloscope is in the Run state; reads the waveform data in the internal memory when the oscilloscope is in the Stop state.\n-   `RAW`: Reads the waveform data in the internal memory. **Note:** *The data in the internal memory can only be read when the oscilloscope is in the Stop state. You are not allowed to operate the instrument when it is reading data.*\n\nThe `Data` method returns a `List\u003cWaveformDataPoint\u003e` object, where each `WaveformDataPoint` object represents a point on the waveform with a `Time` and `Voltage` value.\n\nHere is an example of how to use the `Data` method to capture waveform data from the oscilloscope:\n\n```csharp\nif (mso != null)\n{\n    // Capture waveform data from channel 1 in normal mode\n    var scopeWave = await mso.Waveform.Data(WaveformSource.CHAN1, WaveformMode.NORM);\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fissus%2Fnetworkedtestequipment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fissus%2Fnetworkedtestequipment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fissus%2Fnetworkedtestequipment/lists"}