├── .gitattributes
├── .github
└── FUNDING.yml
├── .gitignore
├── Binaries
├── Oscilloscope_1_0.zip
└── Oscilloscope_1_1.zip
├── Docs
├── gnuplot.png
├── gui.png
├── oscilloscope.png
└── speed_graph.png
├── Oscilloscope.sln
├── Oscilloscope
├── App.config
├── Channel.cs
├── GetterSetterAttribute.cs
├── GnuPlot.cs
├── Oscilloscope.cs
├── OscilloscopeCommands.cs
├── OscilloscopeEnum.cs
├── OscilloscopeLib.csproj
├── Properties
│ └── AssemblyInfo.cs
└── WaveForm.cs
├── OscilloscopeCLI
├── OscilloscopeCLI.csproj
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── app.config
├── OscilloscopeGUI
├── FrmMain.Designer.cs
├── FrmMain.cs
├── FrmMain.resx
├── OscilloscopeGUI.csproj
├── Program.cs
├── Properties
│ ├── AssemblyInfo.cs
│ └── app.manifest
├── app.config
└── oscilloscope.ico
├── OscilloscopeTest
├── OscilloscopeTest.cs
├── OscilloscopeTest.csproj
└── Properties
│ └── AssemblyInfo.cs
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: electro-logic
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/Binaries/Oscilloscope_1_0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electro-logic/Oscilloscope/0e2c02bed0aebfc0c84ac1a4b7d9095409adec9f/Binaries/Oscilloscope_1_0.zip
--------------------------------------------------------------------------------
/Binaries/Oscilloscope_1_1.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electro-logic/Oscilloscope/0e2c02bed0aebfc0c84ac1a4b7d9095409adec9f/Binaries/Oscilloscope_1_1.zip
--------------------------------------------------------------------------------
/Docs/gnuplot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electro-logic/Oscilloscope/0e2c02bed0aebfc0c84ac1a4b7d9095409adec9f/Docs/gnuplot.png
--------------------------------------------------------------------------------
/Docs/gui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electro-logic/Oscilloscope/0e2c02bed0aebfc0c84ac1a4b7d9095409adec9f/Docs/gui.png
--------------------------------------------------------------------------------
/Docs/oscilloscope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electro-logic/Oscilloscope/0e2c02bed0aebfc0c84ac1a4b7d9095409adec9f/Docs/oscilloscope.png
--------------------------------------------------------------------------------
/Docs/speed_graph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electro-logic/Oscilloscope/0e2c02bed0aebfc0c84ac1a4b7d9095409adec9f/Docs/speed_graph.png
--------------------------------------------------------------------------------
/Oscilloscope.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.5.33530.505
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OscilloscopeTest", "OscilloscopeTest\OscilloscopeTest.csproj", "{38B8E55F-06FF-435F-8D4A-0967A9B94F4F}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OscilloscopeGUI", "OscilloscopeGUI\OscilloscopeGUI.csproj", "{ADFC469D-78BB-415D-AE23-B6F5D5A5BDFC}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OscilloscopeLib", "Oscilloscope\OscilloscopeLib.csproj", "{6BEA399D-CD60-4AF9-8499-3F720A5EDE80}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OscilloscopeCLI", "OscilloscopeCLI\OscilloscopeCLI.csproj", "{ECE2AD33-6CA7-43CA-9066-E9049D5D6FB0}"
13 | EndProject
14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{55F7DD8E-BDDD-428C-8F7C-F214262EDAB8}"
15 | ProjectSection(SolutionItems) = preProject
16 | README.md = README.md
17 | EndProjectSection
18 | EndProject
19 | Global
20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 | Debug|Any CPU = Debug|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {38B8E55F-06FF-435F-8D4A-0967A9B94F4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {38B8E55F-06FF-435F-8D4A-0967A9B94F4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {38B8E55F-06FF-435F-8D4A-0967A9B94F4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {38B8E55F-06FF-435F-8D4A-0967A9B94F4F}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {ADFC469D-78BB-415D-AE23-B6F5D5A5BDFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {ADFC469D-78BB-415D-AE23-B6F5D5A5BDFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {ADFC469D-78BB-415D-AE23-B6F5D5A5BDFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {ADFC469D-78BB-415D-AE23-B6F5D5A5BDFC}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {6BEA399D-CD60-4AF9-8499-3F720A5EDE80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {6BEA399D-CD60-4AF9-8499-3F720A5EDE80}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {6BEA399D-CD60-4AF9-8499-3F720A5EDE80}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {6BEA399D-CD60-4AF9-8499-3F720A5EDE80}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {ECE2AD33-6CA7-43CA-9066-E9049D5D6FB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {ECE2AD33-6CA7-43CA-9066-E9049D5D6FB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {ECE2AD33-6CA7-43CA-9066-E9049D5D6FB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
40 | {ECE2AD33-6CA7-43CA-9066-E9049D5D6FB0}.Release|Any CPU.Build.0 = Release|Any CPU
41 | EndGlobalSection
42 | GlobalSection(SolutionProperties) = preSolution
43 | HideSolutionNode = FALSE
44 | EndGlobalSection
45 | GlobalSection(ExtensibilityGlobals) = postSolution
46 | SolutionGuid = {B7FD0580-0A90-440D-B243-287A11CC9982}
47 | EndGlobalSection
48 | EndGlobal
49 |
--------------------------------------------------------------------------------
/Oscilloscope/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Oscilloscope/Channel.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | ///
4 | /// Represent an Oscilloscope Channel
5 | ///
6 | public class Channel
7 | {
8 | uint _channelID;
9 | Oscilloscope _oscilloscope;
10 |
11 | public Channel(uint channelID, Oscilloscope oscilloscope)
12 | {
13 | _channelID = channelID;
14 | _oscilloscope = oscilloscope;
15 | }
16 | // --------- Channel commands
17 | public OnOff GetBwLimit()
18 | {
19 | _oscilloscope.Write(":CHAN" + _channelID + ":BWLimit?");
20 | return (OnOff)GetterSetterExtension.FromDescription(_oscilloscope.ReadString());
21 | }
22 | public void SetBwLimit(OnOff value)
23 | {
24 | _oscilloscope.Write(":CHAN" + _channelID + ":BWLimit " + value.SetterDescription());
25 | }
26 | // TODO: Coupling
27 | // TODO: Display
28 | // TODO: Invert
29 | public double GetOffset()
30 | {
31 | _oscilloscope.Write(":CHAN" + _channelID + ":OFFS?");
32 | return double.Parse(_oscilloscope.ReadString());
33 | }
34 | public void SetOffset(double value)
35 | {
36 | _oscilloscope.Write(":CHAN" + _channelID + ":OFFS " + value);
37 | }
38 | // TODO: Probe
39 | public double GetScale()
40 | {
41 | _oscilloscope.Write(":CHAN" + _channelID + ":SCAL?");
42 | return double.Parse(_oscilloscope.ReadString());
43 | }
44 | public void SetScale(double value)
45 | {
46 | _oscilloscope.Write(":CHAN" + _channelID + ":SCAL " + value);
47 | }
48 | public WaveForm GetWaveform()
49 | {
50 | _oscilloscope.Write(":WAVEFORM:DATA? CHAN" + _channelID);
51 | byte[] respose = _oscilloscope.Read();
52 |
53 | long pointsCount = respose.Length - 10;
54 |
55 | double[] data = new double[pointsCount];
56 | double[] times = new double[pointsCount];
57 |
58 | double scale = GetScale();
59 | double offset = GetOffset();
60 | double oscTimeScale = _oscilloscope.GetTimebaseScale();
61 | double oscTimeOffset = _oscilloscope.GetTimebaseOffset();
62 | double sampleRate = _oscilloscope.GetAcquireSamplingRate(_channelID);
63 |
64 | double initial, interval;
65 |
66 | // 600 points
67 | //T(s) = ( - 1) * ( / 50) - [( * 6) - ]
68 | // > 600 points
69 | //T(s) = -[ ( - 10) / (1 / (2*)]
70 |
71 | if (pointsCount > 600)
72 | {
73 | initial = -((1.0 / sampleRate) * (pointsCount / 2)) + oscTimeOffset;
74 | interval = 1.0 / sampleRate;
75 | }
76 | else
77 | {
78 | initial = -(oscTimeScale * 6) - oscTimeOffset;
79 | interval = oscTimeScale / 50;
80 | }
81 |
82 | for (int i = 0; i < pointsCount; i++)
83 | {
84 | // Strip off 10 byte header and loop through data and termination characters
85 | int rawData = (int)respose[i + 10];
86 |
87 | // Scale the vertical data from bytes to volts
88 | // A(V) = [(240 - ) * ( / 25) - [( + * 4.6)]]
89 | data[i] = ((240 - rawData) * scale / 25) - (offset + (scale * 4.6));
90 | times[i] = initial + interval * i;
91 | }
92 |
93 | return new WaveForm(times, data);
94 | }
95 |
96 | // TODO: Filter
97 | // TODO: Vernier
98 | /// From DS1000E/D Waveform Data Formatting Guide
99 | ///
100 | public WaveForm GetWaveformString()
101 | {
102 | _oscilloscope.Write(":WAVEFORM:DATA? CHAN" + _channelID);
103 | string respose = _oscilloscope.ReadString();
104 |
105 | long pointsCount = respose.Length - 10;
106 |
107 | //MessageBox.Show(pointsCount.ToString());
108 | double[] data = new double[pointsCount];
109 | double[] times = new double[pointsCount];
110 |
111 | double scale = GetScale();
112 | double offset = GetOffset();
113 | double oscTimeScale = _oscilloscope.GetTimebaseScale();
114 | double oscTimeOffset = _oscilloscope.GetTimebaseOffset();
115 | double sampleRate = _oscilloscope.GetAcquireSamplingRate(_channelID);
116 |
117 | double initial, interval;
118 |
119 | // 600 points
120 | //T(s) = ( - 1) * ( / 50) - [( * 6) - ]
121 | // > 600 points
122 | //T(s) = -[ ( - 10) / (1 / (2*)]
123 |
124 | if (pointsCount > 600)
125 | {
126 | initial = -((1.0 / sampleRate) * (pointsCount / 2)) + oscTimeOffset;
127 | interval = 1.0 / sampleRate;
128 | }
129 | else
130 | {
131 | initial = -(oscTimeScale * 6) - oscTimeOffset;
132 | interval = oscTimeScale / 50;
133 | }
134 |
135 | for (int i = 0; i < pointsCount; i++)
136 | {
137 | // Strip off 10 byte header and loop through data and termination characters
138 | int rawData = (int)respose[i + 10];
139 |
140 | // Scale the vertical data from bytes to volts
141 | // A(V) = [(240 - ) * ( / 25) - [( + * 4.6)]]
142 | data[i] = ((240 - rawData) * scale / 25) - (offset + (scale * 4.6));
143 | //data[i] = rawData;
144 |
145 | times[i] = initial + interval * i;
146 | }
147 |
148 | return new WaveForm(times, data);
149 | }
150 | }
--------------------------------------------------------------------------------
/Oscilloscope/GetterSetterAttribute.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | using System;
4 |
5 | [AttributeUsage(AttributeTargets.Field)]
6 | ///
7 | /// An attribute that can be applied to fields (like enum fields) and add two string descriptions called getter and setter
8 | ///
9 | public class GetterSetterAttribute : Attribute
10 | {
11 | public string Getter { get; set; }
12 | public string Setter { get; set; }
13 |
14 | public GetterSetterAttribute(string getter_setter)
15 | {
16 | Getter = Setter = getter_setter;
17 | }
18 | public GetterSetterAttribute(string getter, string setter)
19 | {
20 | Getter = getter;
21 | Setter = setter;
22 | }
23 | }
24 |
25 | public static class GetterSetterExtension
26 | {
27 | ///
28 | /// Return Getter description from an enum marked with GetterSetterAttribute, otherwise the enum value
29 | ///
30 | public static string GetterDescription(this Enum value)
31 | {
32 | var getterSetterAttributes = (GetterSetterAttribute[])(value.GetType().GetField(value.ToString())).GetCustomAttributes(typeof(GetterSetterAttribute), false);
33 | return getterSetterAttributes.Length > 0 ? getterSetterAttributes[0].Getter : value.ToString();
34 | }
35 |
36 | ///
37 | /// Return Setter description from an enum marked with GetterSetterAttribute, otherwise the enum value
38 | ///
39 | public static string SetterDescription(this Enum value)
40 | {
41 | var getterSetterAttributes = (GetterSetterAttribute[])(value.GetType().GetField(value.ToString())).GetCustomAttributes(typeof(GetterSetterAttribute), false);
42 | return getterSetterAttributes.Length > 0 ? getterSetterAttributes[0].Setter : value.ToString();
43 | }
44 |
45 | ///
46 | /// Return Enum with description that correspond to GetterSetterAttribute
47 | ///
48 | public static Enum FromDescription(string description)
49 | {
50 | foreach (Enum item in Enum.GetValues(typeof(T)))
51 | {
52 | if (item.GetterDescription() == description)
53 | {
54 | return item;
55 | }
56 | }
57 | throw new Exception("Enum not found: [" + description + "]");
58 | }
59 | }
--------------------------------------------------------------------------------
/Oscilloscope/GnuPlot.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | using System;
4 | using System.Diagnostics;
5 | using System.Drawing;
6 | using System.IO;
7 | using System.Windows.Forms;
8 |
9 | ///
10 | /// Tested with Gnuplot 5.2
11 | ///
12 | public class GnuPlot
13 | {
14 | public GnuPlot()
15 | {
16 | // Default path for gnuplot
17 | this.Path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "gnuplot\\bin\\gnuplot.exe");
18 | // TODO: Check if path is valid
19 | }
20 |
21 | public GnuPlot(string path)
22 | {
23 | this.Path = path;
24 | }
25 |
26 | ///
27 | /// Path of gnuplot.exe
28 | ///
29 | public string Path { get; set; }
30 |
31 | ///
32 | /// Graph input CSV with GnuPlot. NumWaves is the number of channels to draw. If imageOut a PNG image is saved into out.png and displayed.
33 | ///
34 | public void DrawGraph(string csvFileName, int numWaves, bool generatePngImage = true)
35 | {
36 | // gnuplot.exe not found
37 | if(!File.Exists(Path))
38 | {
39 | MessageBox.Show("gnuplot.exe not found. Please check the path.");
40 | return;
41 | }
42 |
43 | var gnuPlot = new Process();
44 | gnuPlot.StartInfo.FileName = Path;
45 | gnuPlot.StartInfo.CreateNoWindow = true;
46 | gnuPlot.StartInfo.UseShellExecute = false;
47 | gnuPlot.StartInfo.RedirectStandardInput = true;
48 | gnuPlot.Start();
49 |
50 | StreamWriter gnuPlotSw = gnuPlot.StandardInput;
51 | if (generatePngImage)
52 | {
53 | // TODO: Remove dependency from Windows Forms
54 | Rectangle bounds = Screen.PrimaryScreen.WorkingArea;
55 | gnuPlotSw.WriteLine("set terminal png size " + (bounds.Width * 0.9) + "," + (bounds.Height * 0.8));
56 | gnuPlotSw.WriteLine("set out 'out.png'");
57 | }
58 | gnuPlotSw.WriteLine("set style data lines"); //linespoints
59 | gnuPlotSw.WriteLine("set datafile separator ';'");
60 | //gnuPlotSw.WriteLine("set decimalsign locale; set decimalsign ','");
61 | gnuPlotSw.WriteLine("set xlabel 'time (s)'");
62 | gnuPlotSw.WriteLine("set ylabel 'value (v)'");
63 | gnuPlotSw.WriteLine("set grid");
64 | //gnuPlotSw.WriteLine("set xtics 0,0.5");
65 | //gnuPlotSw.WriteLine("set ytics 0,5");
66 |
67 | // TODO: evaluate add "every .." to gnuplot cmd line
68 | gnuPlotSw.Write("plot '" + System.IO.Path.GetFullPath(csvFileName) + "' using 1:2 title 'CH1'");
69 | if (numWaves == 2)
70 | gnuPlotSw.WriteLine(", '' using 1:3 title 'CH2'");
71 | else
72 | gnuPlotSw.Write("\n");
73 | gnuPlotSw.Flush();
74 | if (generatePngImage)
75 | {
76 | gnuPlotSw.WriteLine("exit");
77 | gnuPlotSw.Flush();
78 | gnuPlot.WaitForExit();
79 | Process.Start("out.png");
80 | }
81 | gnuPlot.Close();
82 | }
83 | }
--------------------------------------------------------------------------------
/Oscilloscope/Oscilloscope.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | using NationalInstruments.Visa;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.Linq;
8 | using System.Threading;
9 |
10 | ///
11 | /// Handle Rigol's Oscilloscopes like model DS1102E
12 | ///
13 | public partial class Oscilloscope : IDisposable
14 | {
15 | string _model;
16 | string _serialNumber;
17 | string _swVersion;
18 | Channel[] _channels;
19 | uint _numChannels; // 2 Channel models like DS1102E
20 |
21 | MessageBasedSession _mbSession;
22 | static ResourceManager _resManager = new ResourceManager();
23 | bool _isDisposed;
24 |
25 | // TODO: Move in VisaHelper file
26 | public static string[] GetResources()
27 | {
28 | string[] results = new string[] { };
29 | try
30 | {
31 | results = _resManager.Find("?*").ToArray();
32 | }
33 | catch (Exception ex)
34 | {
35 | Debug.WriteLine(ex);
36 | }
37 | return results;
38 | }
39 | public Oscilloscope(string resource = "USB?*DS1E?*INSTR", uint channels = 2)
40 | {
41 | // TODO: check if channels is valid
42 | _numChannels = channels;
43 | _channels = new Channel[_numChannels];
44 |
45 | // Create Message based session, open first resource found
46 | _mbSession = (MessageBasedSession)_resManager.Open(_resManager.Find(resource).First());
47 | _mbSession.TimeoutMilliseconds = 1000 * 60 * 5;
48 |
49 | // Create channel object for every physical channel of oscilloscope
50 | for (uint i = 0; i < _numChannels; i++)
51 | {
52 | _channels[i] = new Channel(i + 1, this);
53 | }
54 |
55 | Write("*IDN?");
56 | // Example response: Rigol Technologies,DS1102E,DS1EB1XXXXXXXX,00.02.06.00.01
57 | string[] fields = ReadString().Split(',');
58 | _model = fields[1];
59 | _serialNumber = fields[2];
60 | _swVersion = fields[3];
61 | }
62 | public Channel[] Channels
63 | {
64 | get => _channels;
65 | set => _channels = value;
66 | }
67 | public Channel Channel1 => _channels[0];
68 | public Channel Channel2 => _channels[1];
69 | ///
70 | /// Return Waveforms of Channel1 and Channel2
71 | ///
72 | public WaveForm GetWaveforms()
73 | {
74 | // TODO: Improve for 4 channel model
75 | WaveForm wave1 = Channel1.GetWaveform();
76 | WaveForm wave2 = Channel2.GetWaveform();
77 | return new WaveForm(wave1.Times, new List() { wave1.Values[0], wave2.Values[0] });
78 | }
79 | public string Model => _model;
80 | public string SerialNumber => _serialNumber;
81 | public string SwVersion=>_swVersion;
82 | public void Write(string str)
83 | {
84 | _mbSession.RawIO.Write(str);
85 | // Give time to process command
86 | Thread.Sleep(50);
87 | // TODO: Improve and validate
88 | }
89 | public string ReadString()
90 | {
91 | // Read the response; omit end-of-line characters.
92 | return _mbSession.RawIO.ReadString().TrimEnd( '\r', '\n');
93 | }
94 | public byte[] Read()
95 | {
96 | // Rigol DS1102E Long Memory can acquire 1M points (1048576 bytes + 10 bytes header)
97 | var readBytes = _mbSession.RawIO.Read(1048586, out var status);
98 | Debug.WriteLine(string.Format("Readed {0} bytes from device with Status {1}", readBytes.Length, status));
99 | return readBytes;
100 | }
101 | ///
102 | /// Wait until Trigger Status is Stop
103 | ///
104 | ///
105 | /// Poll every 50ms
106 | ///
107 | public void WaitTriggerStop()
108 | {
109 | while (GetTriggerStatus() != TriggerStatus.Stop)
110 | {
111 | Thread.Sleep(50);
112 | }
113 | }
114 | protected virtual void Dispose(bool disposing)
115 | {
116 | if (!_isDisposed)
117 | {
118 | if (disposing)
119 | {
120 | _mbSession.Dispose();
121 | }
122 | _isDisposed = true;
123 | }
124 | }
125 | public void Dispose()
126 | {
127 | // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
128 | Dispose(disposing: true);
129 | GC.SuppressFinalize(this);
130 | }
131 | // See OscilloscopeCommands for commands like Run, Stop, Get/Set Property, etc..
132 | }
--------------------------------------------------------------------------------
/Oscilloscope/OscilloscopeCommands.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | using System;
4 |
5 | public partial class Oscilloscope
6 | {
7 | // --------- System Commands
8 |
9 | ///
10 | /// The command initiates the oscilloscope to acquire waveform data according to its current settings.
11 | /// Acquisition runs continuously until the oscilloscope receives a STOP command.
12 | ///
13 | public void Run()
14 | {
15 | Write(":RUN");
16 | }
17 |
18 | ///
19 | /// The command resets the system parameters.
20 | ///
21 | public void Reset()
22 | {
23 | Write("*RST");
24 | }
25 |
26 | ///
27 | /// The command controls the oscilloscope to stop acquiring data. To restart the acquisition, use the RUN command.
28 | ///
29 | public void Stop()
30 | {
31 | Write(":STOP");
32 | }
33 |
34 | ///
35 | /// The command controls the oscilloscope to evaluate all input waveforms characteristics and set the optimum conditions to display the waveforms.
36 | ///
37 | public void Auto()
38 | {
39 | Write(":AUTO");
40 | }
41 |
42 | ///
43 | /// The command is to extract the current information on the screen and save the bitmap into the U disc in the form of “HardCopyxxx.bmp”.
44 | ///
45 | ///
46 | /// This command is unavailable in file system
47 | ///
48 | public void HardCopy()
49 | {
50 | Write(":HARDcopy");
51 | }
52 |
53 | // --------- Acquire commands
54 |
55 | ///
56 | /// Query current acquire type of the oscilloscope.
57 | ///
58 | public AcquireType GetAcquireType()
59 | {
60 | Write(":ACQ:TYPE?");
61 | return (AcquireType)GetterSetterExtension.FromDescription(ReadString());
62 | }
63 |
64 | ///
65 | /// Set current acquire type of the oscilloscope.
66 | ///
67 | public void SetAcquireType(AcquireType memoryDepth)
68 | {
69 |
70 | Write(":ACQ:TYPE " + memoryDepth.SetterDescription());
71 | }
72 |
73 | ///
74 | /// Query current acquire mode of the oscilloscope.
75 | ///
76 | public AcquireMode GetAcquireMode()
77 | {
78 | Write(":ACQuire:MODE?");
79 | return (AcquireMode)GetterSetterExtension.FromDescription(ReadString());
80 | }
81 |
82 | ///
83 | /// Set current acquire mode of the oscilloscope.
84 | ///
85 | public void SetAcquireMode(AcquireMode memoryDepth)
86 | {
87 | Write(":ACQuire:MODE " + memoryDepth.SetterDescription());
88 | }
89 |
90 | ///
91 | /// Query average numbers in Average mode.
92 | ///
93 | public AcquireAverages GetAcquireAverages()
94 | {
95 | Write(":ACQuire:AVERages?");
96 | return (AcquireAverages)GetterSetterExtension.FromDescription(ReadString());
97 | }
98 |
99 | ///
100 | /// Set average numbers in Average mode.
101 | ///
102 | public void SetAcquireAverages(AcquireAverages acquireAverage)
103 | {
104 | Write(":ACQuire:AVERages " + acquireAverage.SetterDescription());
105 | }
106 |
107 | ///
108 | /// Queries the current sampling rate of the analog channel or digital channel (only for DS1000D series). is 1 or 2 means channel 1 or channel 2.
109 | ///
110 | public double GetAcquireSamplingRate(uint channel)
111 | {
112 | if (channel > _numChannels)
113 | {
114 | throw new ArgumentException("Wrong channel");
115 | }
116 | // TODO: Digital channel of DS1000D not supported
117 | Write(":ACQuire:SAMPlingrate? CHANnel" + channel);
118 | return double.Parse(ReadString());
119 | }
120 |
121 | ///
122 | /// Query the memory depth of the oscilloscope.
123 | ///
124 | public AcquireMemoryDepth GetAcquireMemoryDepth()
125 | {
126 | Write(":ACQuire:MEMDepth?");
127 | return (AcquireMemoryDepth)GetterSetterExtension.FromDescription(ReadString());
128 | }
129 |
130 | ///
131 | /// Set the memory depth of the oscilloscope.
132 | ///
133 | public void SetAcquireMemoryDepth(AcquireMemoryDepth memoryDepth)
134 | {
135 | Write(":ACQuire:MEMDepth " + memoryDepth.SetterDescription());
136 | }
137 |
138 | // --------- Display commands
139 | // TODO
140 |
141 | // --------- Timebase commands
142 |
143 | ///
144 | /// Query scan mode of horizontal timebase
145 | ///
146 | public TimebaseMode GetTimebaseMode()
147 | {
148 | Write(":TIMebase:MODE?");
149 | return (TimebaseMode)GetterSetterExtension.FromDescription(ReadString());
150 | }
151 |
152 | ///
153 | /// Set scan mode of horizontal timebase
154 | ///
155 | public void SetTimebaseMode(TimebaseMode value)
156 | {
157 | Write(":TIMebase:MODE " + value.SetterDescription());
158 | }
159 |
160 | ///
161 | /// Query the offset of the MAIN or DELayed timebase
162 | /// (that is offset of the waveform position relative to the trigger midpoint.).
163 | /// In NORMAL mode, the range of is 1s ~ end of the memory;
164 | /// In STOP mode, the range of is -500s ~ +500s;
165 | /// In SCAN mode, the range of is -6*Scale ~ +6*Scale; (Note: Scale indicates the current horizontal scale, the unit is s/div.)
166 | /// In MAIN state, the item [:DELayed] should be omitted.
167 | ///
168 | public double GetTimebaseOffset()
169 | {
170 | // TODO: Delayed option
171 | Write(":TIMebase:OFFS?");
172 | return double.Parse(ReadString());
173 | }
174 |
175 | ///
176 | /// Set the offset of the MAIN or DELayed timebase
177 | ///
178 | public void SetTimebaseOffset(double value)
179 | {
180 | // TODO: Delayed option
181 | Write(":TIMebase:OFFSet " + value);
182 | }
183 |
184 | ///
185 | /// Query the horizontal scale for MAIN or DELayed timebase, the unit is s/div (seconds/grid), thereinto:
186 | /// In YT mode, the range of is 2ns - 50s;
187 | /// In ROLL mode, the range of is 500ms - 50s;
188 | /// In MAIN state, the item [:DELayed] should be omitted.
189 | ///
190 | public double GetTimebaseScale()
191 | {
192 | // TODO: Delayed option
193 | Write(":TIMebase:SCALe?");
194 | return double.Parse(ReadString());
195 | }
196 |
197 | ///
198 | /// Set the horizontal scale for MAIN or DELayed timebase, the unit is s/div (seconds/grid)
199 | ///
200 | public void SetTimebaseScale(double value)
201 | {
202 | // TODO: Delayed option
203 | Write(":TIMebase:SCALe " + value);
204 | }
205 |
206 |
207 | ///
208 | /// Query the horizontal timebase
209 | ///
210 | public TimebaseFormat GetTimebaseFormat()
211 | {
212 | // TODO: Delayed option
213 | Write(":TIMebase:FORMat?");
214 | return (TimebaseFormat)GetterSetterExtension.FromDescription(ReadString());
215 | }
216 |
217 | ///
218 | /// Set the horizontal timebase
219 | ///
220 | public void SetTimebaseFormat(TimebaseFormat value)
221 | {
222 | // TODO: Delayed option
223 | Write(":TIMebase:FORMat " + value.SetterDescription());
224 | }
225 |
226 | // --------- Trigger commands
227 |
228 | // TODO: Complete
229 |
230 | ///
231 | /// Queries the operating status of the oscilloscope. The status could be RUN, STOP, T`D, WAIT or AUTO
232 | ///
233 | public TriggerStatus GetTriggerStatus()
234 | {
235 | Write(":TRIGger:STATus?");
236 | return (TriggerStatus)GetterSetterExtension.FromDescription(ReadString());
237 | }
238 |
239 | public TriggerSweep GetTriggerSweep()
240 | {
241 | Write(":TRIGger:EDGE:SWEep?");
242 | return (TriggerSweep)GetterSetterExtension.FromDescription(ReadString());
243 | }
244 |
245 | public void SetTriggerSweep(TriggerSweep memoryDepth)
246 | {
247 | Write(":TRIGger:EDGE:SWEep " + memoryDepth.SetterDescription());
248 | }
249 |
250 | ///
251 | /// Sets the trigger level to the vertical midpoint of amplitude.
252 | ///
253 | public void TriggerHalf()
254 | {
255 | Write(":Trig%50");
256 | }
257 |
258 | ///
259 | /// Forces the oscilloscope to trigger signal, which is usually used in “Normal” and “Single” mode.
260 | ///
261 | public void TriggerForce()
262 | {
263 | Write(":FORCetrig");
264 | }
265 |
266 | // --------- Storage commands (uncomment to enable it)
267 |
268 | ///
269 | /// Recalls the system settings before leaving factory.
270 | ///
271 | //public void StorageFactoryLoad()
272 | //{
273 | // Write(":STORage:FACTory:LOAD");
274 | //}
275 |
276 | // --------- Math commands
277 |
278 | ///
279 | /// Query the On/Off state of the math operation
280 | ///
281 | public OnOff GetMathDisplay()
282 | {
283 | Write(":MATH:DISPlay?");
284 | return (OnOff)GetterSetterExtension.FromDescription(ReadString());
285 | }
286 |
287 | ///
288 | /// Set the On/Off state of the math operation
289 | ///
290 | public void SetMathDisplay(OnOff display)
291 | {
292 | Write(":MATH:DISPlay " + display.SetterDescription());
293 | }
294 |
295 | // --------- Measure commands
296 |
297 | // --------- Waveform commands
298 |
299 | // :WAVeform:DATA? is in GetWaveform() in Channel class
300 |
301 | ///
302 | /// Query mode of waveform points
303 | ///
304 | public PointsMode GetWaveformPointsMode()
305 | {
306 | Write(":WAVeform:POINts:MODE?");
307 | return (PointsMode)GetterSetterExtension.FromDescription(ReadString());
308 | }
309 |
310 | ///
311 | /// Set mode of waveform points
312 | ///
313 | public void SetWaveformPointsMode(PointsMode value)
314 | {
315 | Write(":WAVeform:POINts:MODE " + value.SetterDescription());
316 | }
317 |
318 | // --------- LA commands
319 | // --------- Key commands
320 |
321 | ///
322 | /// The command unlocks the remote control.
323 | ///
324 | public void Close()
325 | {
326 | Write(":KEY:FORCE");
327 | }
328 |
329 | }
--------------------------------------------------------------------------------
/Oscilloscope/OscilloscopeEnum.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | // Enumerations used by Oscilloscope annotated with GetterSetterAttribute
4 |
5 | public enum OnOff
6 | {
7 | [GetterSetterAttribute("ON")]
8 | On,
9 | [GetterSetterAttribute("OFF")]
10 | Off
11 | }
12 |
13 | // --------- Acquire enums
14 |
15 | public enum AcquireType
16 | {
17 | [GetterSetterAttribute("NORMAL")]
18 | Normal,
19 | [GetterSetterAttribute("AVERAGE")]
20 | Average,
21 | [GetterSetterAttribute("Peak Detect", "PEAKDETECT")]
22 | PeakDetect
23 | }
24 |
25 | public enum AcquireMode
26 | {
27 | [GetterSetterAttribute("REAL_TIME", "RTIM")]
28 | RealTime,
29 | [GetterSetterAttribute("EQUAL_TIME", "ETIM")]
30 | EquiTime
31 | }
32 |
33 | public enum AcquireAverages
34 | {
35 | [GetterSetterAttribute("2")]
36 | Average2,
37 | [GetterSetterAttribute("4")]
38 | Average4,
39 | [GetterSetterAttribute("8")]
40 | Average8,
41 | [GetterSetterAttribute("16")]
42 | Average16,
43 | [GetterSetterAttribute("32")]
44 | Average32,
45 | [GetterSetterAttribute("64")]
46 | Average64,
47 | [GetterSetterAttribute("128")]
48 | Average128,
49 | [GetterSetterAttribute("256")]
50 | Average256
51 | }
52 |
53 | public enum AcquireMemoryDepth
54 | {
55 | [GetterSetterAttribute("NORMAL")]
56 | Normal,
57 | [GetterSetterAttribute("LONG")]
58 | Long
59 | }
60 |
61 | // --------- Display enums
62 |
63 | public enum DisplayType
64 | {
65 | [GetterSetterAttribute("VECTORS")]
66 | Vectors,
67 | [GetterSetterAttribute("DOTS")]
68 | Dots
69 | }
70 |
71 | public enum DisplayGrid
72 | {
73 | [GetterSetterAttribute("FULL")]
74 | Full,
75 | [GetterSetterAttribute("HALF")]
76 | Half,
77 | [GetterSetterAttribute("NONE")]
78 | None
79 | }
80 |
81 | public enum DisplayMenu
82 | {
83 | [GetterSetterAttribute("1s", "1")]
84 | One,
85 | [GetterSetterAttribute("2s", "2")]
86 | Two,
87 | [GetterSetterAttribute("5s", "5")]
88 | Five,
89 | [GetterSetterAttribute("10s", "10")]
90 | Ten,
91 | [GetterSetterAttribute("20s", "20")]
92 | Twelve,
93 | [GetterSetterAttribute("Infinite", "Infinite")]
94 | Infinite
95 | }
96 |
97 | // --------- Timebase enums
98 |
99 | public enum TimebaseMode
100 | {
101 | [GetterSetterAttribute("MAIN")]
102 | Main,
103 | [GetterSetterAttribute("DELAYED")]
104 | Delayed
105 | }
106 |
107 | public enum TimebaseFormat
108 | {
109 | [GetterSetterAttribute("X-Y", "XY")]
110 | XY,
111 | [GetterSetterAttribute("Y-T", "YT")]
112 | YT,
113 | [GetterSetterAttribute("SCANNING")]
114 | Scanning
115 | }
116 |
117 | // --------- Trigger enums
118 |
119 | public enum TriggerMode
120 | {
121 | [GetterSetterAttribute("EDGE")]
122 | Edge,
123 | [GetterSetterAttribute("PULS")]
124 | Pulse,
125 | [GetterSetterAttribute("VIDEO")]
126 | Video,
127 | [GetterSetterAttribute("SLOP")]
128 | Slope,
129 | [GetterSetterAttribute("PATT")]
130 | Pattern,
131 | [GetterSetterAttribute("DUR")]
132 | Duration,
133 | [GetterSetterAttribute("ALT")]
134 | Alternation
135 | }
136 |
137 | public enum TriggerSource
138 | {
139 | [GetterSetterAttribute("CHAN1")]
140 | Channel1,
141 | [GetterSetterAttribute("CHAN2")]
142 | Channel2,
143 | [GetterSetterAttribute("EXT")]
144 | External,
145 | [GetterSetterAttribute("ACL")]
146 | ACLine,
147 | [GetterSetterAttribute("DIG")]
148 | Digital
149 | }
150 |
151 | public enum TriggerSweep
152 | {
153 | [GetterSetterAttribute("AUTO")]
154 | Auto,
155 | [GetterSetterAttribute("NORMAL")]
156 | Normal,
157 | [GetterSetterAttribute("SINGLE")]
158 | Single
159 | }
160 |
161 | public enum TriggerCoupling
162 | {
163 | ///
164 | /// Allow all signals pass.
165 | ///
166 | [GetterSetterAttribute("DC")]
167 | DC,
168 | ///
169 | /// Block DC signals and attenuate the signals lower than 10Hz.
170 | ///
171 | [GetterSetterAttribute("AC")]
172 | AC,
173 | ///
174 | /// Reject high frequency signals (Higher than 150KHz).
175 | ///
176 | [GetterSetterAttribute("HF")]
177 | HF,
178 | ///
179 | /// Reject DC signals and attenuate low frequency signals (Lower than 8KHz).
180 | ///
181 | [GetterSetterAttribute("LF")]
182 | LF
183 | }
184 |
185 | public enum TriggerStatus
186 | {
187 | [GetterSetterAttribute("RUN")]
188 | Run,
189 | [GetterSetterAttribute("STOP")]
190 | Stop,
191 | [GetterSetterAttribute("T'D")]
192 | TD,
193 | [GetterSetterAttribute("WAIT")]
194 | Wait,
195 | [GetterSetterAttribute("AUTO")]
196 | Auto
197 | }
198 |
199 | // --------- Math enums
200 |
201 | public enum MathOperate
202 | {
203 | [GetterSetterAttribute("A+B")]
204 | AplusB,
205 | [GetterSetterAttribute("A-B")]
206 | AminusB,
207 | [GetterSetterAttribute("AB")]
208 | AB,
209 | [GetterSetterAttribute("FFT")]
210 | FFT
211 | }
212 |
213 | // --------- Wavewform enums
214 |
215 | public enum PointsMode
216 | {
217 | [GetterSetterAttribute("NORMAL")]
218 | Normal,
219 | [GetterSetterAttribute("MAXIMUM")]
220 | Maximum,
221 | [GetterSetterAttribute("RAW")]
222 | Raw
223 | }
--------------------------------------------------------------------------------
/Oscilloscope/OscilloscopeLib.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {6BEA399D-CD60-4AF9-8499-3F720A5EDE80}
8 | Library
9 | Properties
10 | OscilloscopeLib
11 | OscilloscopeLib
12 | v4.8
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | false
25 | latest
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 | false
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
70 |
--------------------------------------------------------------------------------
/Oscilloscope/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Oscilloscope")]
9 | [assembly: AssemblyProduct("Oscilloscope")]
10 | [assembly: AssemblyCopyright("Copyright © Leonardo Tazzini 2014")]
11 |
12 | // Setting ComVisible to false makes the types in this assembly not visible
13 | // to COM components. If you need to access a type in this assembly from
14 | // COM, set the ComVisible attribute to true on that type.
15 | [assembly: ComVisible(false)]
16 |
17 | // The following GUID is for the ID of the typelib if this project is exposed to COM
18 | [assembly: Guid("cf7bc634-6bac-4f72-a351-0e514899eacc")]
19 |
20 | // Version information for an assembly consists of the following four values:
21 | //
22 | // Major Version
23 | // Minor Version
24 | // Build Number
25 | // Revision
26 | //
27 | // You can specify all the values or you can default the Build and Revision Numbers
28 | // by using the '*' as shown below:
29 | // [assembly: AssemblyVersion("1.0.*")]
30 | [assembly: AssemblyVersion("1.1.0.0")]
31 | [assembly: AssemblyFileVersion("1.1.0.0")]
32 |
--------------------------------------------------------------------------------
/Oscilloscope/WaveForm.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 |
8 | ///
9 | /// Represent an Oscilloscope WaveForm composed by a list of Times and a list of one or more Values (if waveform contains multiple channels)
10 | ///
11 | public class WaveForm
12 | {
13 | double[] _times;
14 | List _values;
15 |
16 | public WaveForm(double[] times, List values)
17 | {
18 | _times = times;
19 | _values = values;
20 | }
21 |
22 | public WaveForm(double[] times, double[] values)
23 | {
24 | _times = times;
25 | _values = new List();
26 | _values.Add(values);
27 | }
28 |
29 | public double[] Times
30 | {
31 | get { return _times; }
32 | set { _times = value; }
33 | }
34 |
35 | public List Values
36 | {
37 | get { return _values; }
38 | set { _values = value; }
39 | }
40 |
41 | ///
42 | /// Save Waveform in a CSV (Comma Separated Values) file separated by semicolon
43 | ///
44 | public void SaveCSV(string fileName)
45 | {
46 | StringBuilder sb = new StringBuilder(_times.Length * 10);
47 |
48 | int valuesCount = _values.Count;
49 | int timesCount = _times.Count();
50 |
51 | // Header
52 | sb.Append("TIME(s);");
53 | for (int j = 1; j < valuesCount + 1; j++)
54 | {
55 | sb.Append("CH");
56 | sb.Append(j);
57 | sb.Append("(v);");
58 | }
59 | sb.Append("\n");
60 |
61 | // Data
62 | for (int i = 0; i < timesCount; i++)
63 | {
64 | sb.Append(_times[i]);
65 | sb.Append(";");
66 | for (int j = 0; j < valuesCount; j++)
67 | {
68 | sb.Append(_values[j][i]);
69 | sb.Append(";");
70 | }
71 | sb.Append("\n");
72 | }
73 |
74 | //sb = sb.Replace('.', ','); // Excel ITA compatibility
75 | File.Delete(fileName);
76 | File.WriteAllText(fileName, sb.ToString());
77 | }
78 |
79 | //public string Build(int from, int to)
80 | //{
81 | // StringBuilder sb = new StringBuilder((to - from) * 7);
82 | // for (int i = from; i < to; i++)
83 | // {
84 | // sb.Append(_times[i]);
85 | // sb.Append(";");
86 | // for (int j = 0; j < _values.Count; j++)
87 | // {
88 | // sb.Append(_values[j][i] + ";");
89 | // }
90 | // sb.Append("\n");
91 | // }
92 | // return sb.ToString();
93 | //}
94 |
95 | //public void SaveBinary(string fileName)
96 | //{
97 | // byte[] bytes = new byte[_times.Count()];
98 | // for (int i = 0; i < _times.Count(); i++)
99 | // {
100 | // bytes[i] = (byte)_values[i];
101 | // }
102 | // File.WriteAllBytes(fileName, bytes);
103 | //}
104 |
105 | /*
106 | public void SaveOLS(string fileName, double samplingRate)
107 | {
108 | StringBuilder sb = new StringBuilder(_times.Length * 10);
109 | sb.AppendLine(";Rate: " + (int)samplingRate);
110 | sb.AppendLine(";Channels: 1");
111 | for (int i = 0; i < _times.Count(); i++)
112 | {
113 | sb.AppendLine(((Int32)_values[i]).ToString("X") + "@" + i.ToString("X"));
114 | }
115 | File.Delete(fileName);
116 | File.WriteAllText(fileName, sb.ToString());
117 | }
118 | */
119 |
120 | ///
121 | /// Binarize Waveform Values given a threshold
122 | ///
123 | ///
124 | public WaveForm Threshold(double threshold)
125 | {
126 | // Apply threshold to all channels
127 | for (int channelIndex = 0; channelIndex < _values.Count; channelIndex++)
128 | {
129 | for (int index = 0; index < _values[channelIndex].Length; index++)
130 | {
131 | if (_values[channelIndex][index] >= threshold)
132 | {
133 | _values[channelIndex][index] = 1;
134 | }
135 | else
136 | {
137 | _values[channelIndex][index] = 0;
138 | }
139 | }
140 | }
141 | return this;
142 | }
143 | }
--------------------------------------------------------------------------------
/OscilloscopeCLI/OscilloscopeCLI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {ECE2AD33-6CA7-43CA-9066-E9049D5D6FB0}
8 | Exe
9 | Properties
10 | OscilloscopeCLI
11 | OscilloscopeCLI
12 | v4.8
13 | 512
14 |
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | false
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | {6bea399d-cd60-4af9-8499-3f720a5ede80}
53 | Oscilloscope
54 |
55 |
56 |
57 |
58 |
59 |
60 |
67 |
--------------------------------------------------------------------------------
/OscilloscopeCLI/Program.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | using System;
4 | using System.Diagnostics;
5 | using System.Globalization;
6 | using System.Threading;
7 |
8 | namespace OscilloscopeCLI
9 | {
10 | class Program
11 | {
12 | static string csvFileName = "data.csv";
13 |
14 | // Sample usage of Oscilloscope library
15 | static void Main(string[] args)
16 | {
17 | // Decimal separator is '.'
18 | Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
19 |
20 | LongMemoryAcquisitionExample();
21 |
22 | // Display acquired data
23 | Process.Start(csvFileName);
24 |
25 | // Draw CSV file with GNU Plot
26 | GnuPlot gnuPlot = new GnuPlot(); // NB: change path of gnuplot.exe with alternative constructor
27 | gnuPlot.DrawGraph(csvFileName, 1);
28 |
29 | // OscilloscopePromptExample();
30 | }
31 |
32 | // 1M data point acquisition
33 | static void LongMemoryAcquisitionExample()
34 | {
35 | Oscilloscope rigol = new Oscilloscope();
36 | rigol.Run();
37 | rigol.SetWaveformPointsMode(PointsMode.Maximum);
38 | rigol.SetAcquireMemoryDepth(AcquireMemoryDepth.Long);
39 | rigol.SetTriggerSweep(TriggerSweep.Single);
40 | rigol.WaitTriggerStop();
41 | rigol.Stop();
42 | WaveForm wave = rigol.Channel1.GetWaveform();
43 | wave.SaveCSV(csvFileName);
44 | rigol.Close();
45 | }
46 |
47 | ///
48 | /// Simple Command Line Prompt for Rigol oscilloscope
49 | ///
50 | static void OscilloscopePromptExample()
51 | {
52 | Console.WriteLine("Oscilloscope Command Prompt");
53 | Console.WriteLine("Instruments:");
54 | string[] resources = Oscilloscope.GetResources();
55 | for (int i = 0; i < resources.Length; i++)
56 | {
57 | Console.WriteLine("[" + i.ToString() + "]: " + resources[i]);
58 | }
59 |
60 | int resIndex;
61 |
62 | menu:
63 | if (!int.TryParse(Console.ReadLine().Trim(), out resIndex))
64 | {
65 | Console.WriteLine("Please choose instrument ");
66 | goto menu;
67 | }
68 |
69 | Console.WriteLine("Example commands:");
70 | Console.WriteLine("*IDN?");
71 | Console.WriteLine(":WAVEFORM:DATA? CHAN1");
72 | Console.WriteLine("quit");
73 |
74 | // Create instance of Oscilloscope class and stop any acquisition
75 | Oscilloscope rigol = new Oscilloscope(resources[resIndex]);
76 | while (true)
77 | {
78 | Console.Write(">");
79 | string cmd = Console.ReadLine();
80 | if (cmd == "quit")
81 | break;
82 | rigol.Write(cmd);
83 | if (cmd.Contains("?"))
84 | {
85 | Console.WriteLine(rigol.ReadString());
86 | }
87 | }
88 | rigol.Close();
89 | }
90 |
91 | }
92 | }
--------------------------------------------------------------------------------
/OscilloscopeCLI/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("OscilloscopeCLI")]
9 | [assembly: AssemblyProduct("OscilloscopeCLI")]
10 | [assembly: AssemblyCopyright("Copyright © Leonardo Tazzini 2014")]
11 |
12 | // Setting ComVisible to false makes the types in this assembly not visible
13 | // to COM components. If you need to access a type in this assembly from
14 | // COM, set the ComVisible attribute to true on that type.
15 | [assembly: ComVisible(false)]
16 |
17 | // The following GUID is for the ID of the typelib if this project is exposed to COM
18 | [assembly: Guid("1091dc2a-4e99-4bca-9f0f-23d8c28f1312")]
19 |
20 | // Version information for an assembly consists of the following four values:
21 | //
22 | // Major Version
23 | // Minor Version
24 | // Build Number
25 | // Revision
26 | //
27 | // You can specify all the values or you can default the Build and Revision Numbers
28 | // by using the '*' as shown below:
29 | // [assembly: AssemblyVersion("1.0.*")]
30 | [assembly: AssemblyVersion("1.1.0.0")]
31 | [assembly: AssemblyFileVersion("1.1.0.0")]
32 |
--------------------------------------------------------------------------------
/OscilloscopeCLI/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/OscilloscopeGUI/FrmMain.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace OscilloscopeGUI
2 | {
3 | partial class FrmMain
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain));
32 | this.cbResources = new System.Windows.Forms.ComboBox();
33 | this.btnConnect = new System.Windows.Forms.Button();
34 | this.groupBox1 = new System.Windows.Forms.GroupBox();
35 | this.lblPoints = new System.Windows.Forms.Label();
36 | this.label5 = new System.Windows.Forms.Label();
37 | this.panel1 = new System.Windows.Forms.Panel();
38 | this.rbLong = new System.Windows.Forms.RadioButton();
39 | this.rbNormal = new System.Windows.Forms.RadioButton();
40 | this.rbMaxPoints = new System.Windows.Forms.RadioButton();
41 | this.rbNormalPoints = new System.Windows.Forms.RadioButton();
42 | this.label4 = new System.Windows.Forms.Label();
43 | this.label2 = new System.Windows.Forms.Label();
44 | this.label1 = new System.Windows.Forms.Label();
45 | this.cbCh2 = new System.Windows.Forms.CheckBox();
46 | this.cbCh1 = new System.Windows.Forms.CheckBox();
47 | this.btnSaveCSV = new System.Windows.Forms.Button();
48 | this.rbOutGnuPlot = new System.Windows.Forms.RadioButton();
49 | this.rbOutPNG = new System.Windows.Forms.RadioButton();
50 | this.label6 = new System.Windows.Forms.Label();
51 | this.btnRefreshDevices = new System.Windows.Forms.Button();
52 | this.label3 = new System.Windows.Forms.Label();
53 | this.txtGnuPlotPath = new System.Windows.Forms.TextBox();
54 | this.groupBox1.SuspendLayout();
55 | this.panel1.SuspendLayout();
56 | this.SuspendLayout();
57 | //
58 | // cbResources
59 | //
60 | this.cbResources.FormattingEnabled = true;
61 | this.cbResources.Location = new System.Drawing.Point(18, 18);
62 | this.cbResources.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
63 | this.cbResources.Name = "cbResources";
64 | this.cbResources.Size = new System.Drawing.Size(298, 28);
65 | this.cbResources.TabIndex = 99;
66 | //
67 | // btnConnect
68 | //
69 | this.btnConnect.Location = new System.Drawing.Point(18, 63);
70 | this.btnConnect.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
71 | this.btnConnect.Name = "btnConnect";
72 | this.btnConnect.Size = new System.Drawing.Size(420, 35);
73 | this.btnConnect.TabIndex = 1;
74 | this.btnConnect.Text = "&Connect to selected device";
75 | this.btnConnect.UseVisualStyleBackColor = true;
76 | this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
77 | //
78 | // groupBox1
79 | //
80 | this.groupBox1.Controls.Add(this.lblPoints);
81 | this.groupBox1.Controls.Add(this.label5);
82 | this.groupBox1.Controls.Add(this.panel1);
83 | this.groupBox1.Controls.Add(this.rbMaxPoints);
84 | this.groupBox1.Controls.Add(this.rbNormalPoints);
85 | this.groupBox1.Controls.Add(this.label4);
86 | this.groupBox1.Controls.Add(this.label2);
87 | this.groupBox1.Controls.Add(this.label1);
88 | this.groupBox1.Controls.Add(this.cbCh2);
89 | this.groupBox1.Controls.Add(this.cbCh1);
90 | this.groupBox1.Location = new System.Drawing.Point(18, 109);
91 | this.groupBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
92 | this.groupBox1.Name = "groupBox1";
93 | this.groupBox1.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
94 | this.groupBox1.Size = new System.Drawing.Size(420, 209);
95 | this.groupBox1.TabIndex = 9;
96 | this.groupBox1.TabStop = false;
97 | this.groupBox1.Text = "Acquisition";
98 | //
99 | // lblPoints
100 | //
101 | this.lblPoints.AutoSize = true;
102 | this.lblPoints.Location = new System.Drawing.Point(138, 171);
103 | this.lblPoints.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
104 | this.lblPoints.Name = "lblPoints";
105 | this.lblPoints.Size = new System.Drawing.Size(36, 20);
106 | this.lblPoints.TabIndex = 23;
107 | this.lblPoints.Text = "600";
108 | //
109 | // label5
110 | //
111 | this.label5.AutoSize = true;
112 | this.label5.Location = new System.Drawing.Point(75, 171);
113 | this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
114 | this.label5.Name = "label5";
115 | this.label5.Size = new System.Drawing.Size(53, 20);
116 | this.label5.TabIndex = 22;
117 | this.label5.Text = "Points";
118 | //
119 | // panel1
120 | //
121 | this.panel1.Controls.Add(this.rbLong);
122 | this.panel1.Controls.Add(this.rbNormal);
123 | this.panel1.Location = new System.Drawing.Point(142, 71);
124 | this.panel1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
125 | this.panel1.Name = "panel1";
126 | this.panel1.Size = new System.Drawing.Size(232, 37);
127 | this.panel1.TabIndex = 21;
128 | //
129 | // rbLong
130 | //
131 | this.rbLong.AutoSize = true;
132 | this.rbLong.Location = new System.Drawing.Point(120, 2);
133 | this.rbLong.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
134 | this.rbLong.Name = "rbLong";
135 | this.rbLong.Size = new System.Drawing.Size(63, 24);
136 | this.rbLong.TabIndex = 15;
137 | this.rbLong.Text = "Long";
138 | this.rbLong.UseVisualStyleBackColor = true;
139 | this.rbLong.CheckedChanged += new System.EventHandler(this.UpdatePoints);
140 | //
141 | // rbNormal
142 | //
143 | this.rbNormal.AutoSize = true;
144 | this.rbNormal.Checked = true;
145 | this.rbNormal.Location = new System.Drawing.Point(0, 2);
146 | this.rbNormal.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
147 | this.rbNormal.Name = "rbNormal";
148 | this.rbNormal.Size = new System.Drawing.Size(77, 24);
149 | this.rbNormal.TabIndex = 12;
150 | this.rbNormal.TabStop = true;
151 | this.rbNormal.Text = "Normal";
152 | this.rbNormal.UseVisualStyleBackColor = true;
153 | this.rbNormal.CheckedChanged += new System.EventHandler(this.UpdatePoints);
154 | //
155 | // rbMaxPoints
156 | //
157 | this.rbMaxPoints.AutoSize = true;
158 | this.rbMaxPoints.Location = new System.Drawing.Point(262, 108);
159 | this.rbMaxPoints.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
160 | this.rbMaxPoints.Name = "rbMaxPoints";
161 | this.rbMaxPoints.Size = new System.Drawing.Size(94, 24);
162 | this.rbMaxPoints.TabIndex = 20;
163 | this.rbMaxPoints.Text = "Maximum";
164 | this.rbMaxPoints.UseVisualStyleBackColor = true;
165 | this.rbMaxPoints.CheckedChanged += new System.EventHandler(this.UpdatePoints);
166 | //
167 | // rbNormalPoints
168 | //
169 | this.rbNormalPoints.AutoSize = true;
170 | this.rbNormalPoints.Checked = true;
171 | this.rbNormalPoints.Location = new System.Drawing.Point(142, 108);
172 | this.rbNormalPoints.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
173 | this.rbNormalPoints.Name = "rbNormalPoints";
174 | this.rbNormalPoints.Size = new System.Drawing.Size(77, 24);
175 | this.rbNormalPoints.TabIndex = 19;
176 | this.rbNormalPoints.TabStop = true;
177 | this.rbNormalPoints.Text = "Normal";
178 | this.rbNormalPoints.UseVisualStyleBackColor = true;
179 | this.rbNormalPoints.CheckedChanged += new System.EventHandler(this.UpdatePoints);
180 | //
181 | // label4
182 | //
183 | this.label4.AutoSize = true;
184 | this.label4.Location = new System.Drawing.Point(30, 111);
185 | this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
186 | this.label4.Name = "label4";
187 | this.label4.Size = new System.Drawing.Size(97, 20);
188 | this.label4.TabIndex = 18;
189 | this.label4.Text = "Points Mode";
190 | //
191 | // label2
192 | //
193 | this.label2.AutoSize = true;
194 | this.label2.Location = new System.Drawing.Point(18, 75);
195 | this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
196 | this.label2.Name = "label2";
197 | this.label2.Size = new System.Drawing.Size(110, 20);
198 | this.label2.TabIndex = 17;
199 | this.label2.Text = "Memory depth";
200 | //
201 | // label1
202 | //
203 | this.label1.AutoSize = true;
204 | this.label1.Location = new System.Drawing.Point(52, 38);
205 | this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
206 | this.label1.Name = "label1";
207 | this.label1.Size = new System.Drawing.Size(76, 20);
208 | this.label1.TabIndex = 16;
209 | this.label1.Text = "Channels";
210 | //
211 | // cbCh2
212 | //
213 | this.cbCh2.AutoSize = true;
214 | this.cbCh2.Location = new System.Drawing.Point(262, 37);
215 | this.cbCh2.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
216 | this.cbCh2.Name = "cbCh2";
217 | this.cbCh2.Size = new System.Drawing.Size(100, 24);
218 | this.cbCh2.TabIndex = 14;
219 | this.cbCh2.Text = "Channel 2";
220 | this.cbCh2.UseVisualStyleBackColor = true;
221 | this.cbCh2.CheckedChanged += new System.EventHandler(this.UpdatePoints);
222 | //
223 | // cbCh1
224 | //
225 | this.cbCh1.AutoSize = true;
226 | this.cbCh1.Checked = true;
227 | this.cbCh1.CheckState = System.Windows.Forms.CheckState.Checked;
228 | this.cbCh1.Location = new System.Drawing.Point(142, 37);
229 | this.cbCh1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
230 | this.cbCh1.Name = "cbCh1";
231 | this.cbCh1.Size = new System.Drawing.Size(100, 24);
232 | this.cbCh1.TabIndex = 13;
233 | this.cbCh1.Text = "Channel 1";
234 | this.cbCh1.UseVisualStyleBackColor = true;
235 | this.cbCh1.CheckedChanged += new System.EventHandler(this.UpdatePoints);
236 | //
237 | // btnSaveCSV
238 | //
239 | this.btnSaveCSV.Location = new System.Drawing.Point(18, 422);
240 | this.btnSaveCSV.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
241 | this.btnSaveCSV.Name = "btnSaveCSV";
242 | this.btnSaveCSV.Size = new System.Drawing.Size(420, 35);
243 | this.btnSaveCSV.TabIndex = 100;
244 | this.btnSaveCSV.Text = "&Save CSV and output";
245 | this.btnSaveCSV.UseVisualStyleBackColor = true;
246 | this.btnSaveCSV.Click += new System.EventHandler(this.btnSaveCSV_Click);
247 | //
248 | // rbOutGnuPlot
249 | //
250 | this.rbOutGnuPlot.AutoSize = true;
251 | this.rbOutGnuPlot.Location = new System.Drawing.Point(160, 386);
252 | this.rbOutGnuPlot.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
253 | this.rbOutGnuPlot.Name = "rbOutGnuPlot";
254 | this.rbOutGnuPlot.Size = new System.Drawing.Size(85, 24);
255 | this.rbOutGnuPlot.TabIndex = 101;
256 | this.rbOutGnuPlot.Text = "GnuPlot";
257 | this.rbOutGnuPlot.UseVisualStyleBackColor = true;
258 | //
259 | // rbOutPNG
260 | //
261 | this.rbOutPNG.AutoSize = true;
262 | this.rbOutPNG.Checked = true;
263 | this.rbOutPNG.Location = new System.Drawing.Point(280, 386);
264 | this.rbOutPNG.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
265 | this.rbOutPNG.Name = "rbOutPNG";
266 | this.rbOutPNG.Size = new System.Drawing.Size(110, 24);
267 | this.rbOutPNG.TabIndex = 102;
268 | this.rbOutPNG.TabStop = true;
269 | this.rbOutPNG.Text = "PNG Image";
270 | this.rbOutPNG.UseVisualStyleBackColor = true;
271 | //
272 | // label6
273 | //
274 | this.label6.AutoSize = true;
275 | this.label6.Location = new System.Drawing.Point(88, 386);
276 | this.label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
277 | this.label6.Name = "label6";
278 | this.label6.Size = new System.Drawing.Size(58, 20);
279 | this.label6.TabIndex = 103;
280 | this.label6.Text = "Output";
281 | //
282 | // btnRefreshDevices
283 | //
284 | this.btnRefreshDevices.Location = new System.Drawing.Point(326, 14);
285 | this.btnRefreshDevices.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
286 | this.btnRefreshDevices.Name = "btnRefreshDevices";
287 | this.btnRefreshDevices.Size = new System.Drawing.Size(112, 35);
288 | this.btnRefreshDevices.TabIndex = 104;
289 | this.btnRefreshDevices.Text = "&Refresh";
290 | this.btnRefreshDevices.UseVisualStyleBackColor = true;
291 | this.btnRefreshDevices.Click += new System.EventHandler(this.btnRefreshDevices_Click);
292 | //
293 | // label3
294 | //
295 | this.label3.AutoSize = true;
296 | this.label3.Location = new System.Drawing.Point(18, 338);
297 | this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
298 | this.label3.Name = "label3";
299 | this.label3.Size = new System.Drawing.Size(104, 20);
300 | this.label3.TabIndex = 105;
301 | this.label3.Text = "GnuPlot Path";
302 | //
303 | // txtGnuPlotPath
304 | //
305 | this.txtGnuPlotPath.Location = new System.Drawing.Point(135, 334);
306 | this.txtGnuPlotPath.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
307 | this.txtGnuPlotPath.Name = "txtGnuPlotPath";
308 | this.txtGnuPlotPath.Size = new System.Drawing.Size(303, 26);
309 | this.txtGnuPlotPath.TabIndex = 106;
310 | //
311 | // FrmMain
312 | //
313 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
314 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
315 | this.ClientSize = new System.Drawing.Size(458, 474);
316 | this.Controls.Add(this.txtGnuPlotPath);
317 | this.Controls.Add(this.label3);
318 | this.Controls.Add(this.btnRefreshDevices);
319 | this.Controls.Add(this.label6);
320 | this.Controls.Add(this.rbOutPNG);
321 | this.Controls.Add(this.rbOutGnuPlot);
322 | this.Controls.Add(this.btnSaveCSV);
323 | this.Controls.Add(this.groupBox1);
324 | this.Controls.Add(this.btnConnect);
325 | this.Controls.Add(this.cbResources);
326 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
327 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
328 | this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
329 | this.MaximizeBox = false;
330 | this.Name = "FrmMain";
331 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
332 | this.Text = "Oscilloscope GUI v1.1";
333 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmMain_FormClosing);
334 | this.Load += new System.EventHandler(this.FrmMain_Load);
335 | this.groupBox1.ResumeLayout(false);
336 | this.groupBox1.PerformLayout();
337 | this.panel1.ResumeLayout(false);
338 | this.panel1.PerformLayout();
339 | this.ResumeLayout(false);
340 | this.PerformLayout();
341 |
342 | }
343 |
344 | #endregion
345 |
346 | private System.Windows.Forms.ComboBox cbResources;
347 | private System.Windows.Forms.Button btnConnect;
348 | private System.Windows.Forms.GroupBox groupBox1;
349 | private System.Windows.Forms.Label label2;
350 | private System.Windows.Forms.Label label1;
351 | private System.Windows.Forms.CheckBox cbCh2;
352 | private System.Windows.Forms.CheckBox cbCh1;
353 | private System.Windows.Forms.RadioButton rbMaxPoints;
354 | private System.Windows.Forms.RadioButton rbNormalPoints;
355 | private System.Windows.Forms.Label label4;
356 | private System.Windows.Forms.Panel panel1;
357 | private System.Windows.Forms.RadioButton rbLong;
358 | private System.Windows.Forms.RadioButton rbNormal;
359 | private System.Windows.Forms.Label label5;
360 | private System.Windows.Forms.Label lblPoints;
361 | private System.Windows.Forms.Button btnSaveCSV;
362 | private System.Windows.Forms.RadioButton rbOutGnuPlot;
363 | private System.Windows.Forms.RadioButton rbOutPNG;
364 | private System.Windows.Forms.Label label6;
365 | private System.Windows.Forms.Button btnRefreshDevices;
366 | private System.Windows.Forms.Label label3;
367 | private System.Windows.Forms.TextBox txtGnuPlotPath;
368 | }
369 | }
370 |
371 |
--------------------------------------------------------------------------------
/OscilloscopeGUI/FrmMain.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | using System;
4 | using System.Windows.Forms;
5 |
6 | namespace OscilloscopeGUI
7 | {
8 | ///
9 | /// Sample GUI for acquiring Normal / Long memory mode and Normal / Maximum Points mode
10 | ///
11 | public partial class FrmMain : Form
12 | {
13 | Oscilloscope _osc;
14 | GnuPlot _gnuplot = new GnuPlot();
15 |
16 | public FrmMain()
17 | {
18 | InitializeComponent();
19 | }
20 | void FrmMain_Load(object sender, EventArgs e)
21 | {
22 | // Update GnuPlot path
23 | txtGnuPlotPath.Text = _gnuplot.Path;
24 | RefreshDevices();
25 | // Are there connected devices?
26 | if (cbResources.Items.Count == 0)
27 | {
28 | MessageBox.Show("Please connect an oscilloscope, then click Refresh");
29 | }
30 | }
31 | void btnConnect_Click(object sender, EventArgs e)
32 | {
33 | if (cbResources.Items.Count == 0)
34 | {
35 | MessageBox.Show("Please connect an oscilloscope, then click Refresh");
36 | return;
37 | }
38 | if(string.IsNullOrWhiteSpace(cbResources.Text))
39 | {
40 | MessageBox.Show("Please select a device");
41 | return;
42 | }
43 | _osc = new Oscilloscope(cbResources.Text);
44 |
45 | }
46 | void btnSaveCSV_Click(object sender, EventArgs e)
47 | {
48 | SaveCSV();
49 | }
50 | void btnRefreshDevices_Click(object sender, EventArgs e)
51 | {
52 | RefreshDevices();
53 | }
54 | public void RefreshDevices()
55 | {
56 | cbResources.Items.Clear();
57 | cbResources.Items.AddRange(Oscilloscope.GetResources());
58 | cbResources.SelectedIndex = cbResources.Items.Count - 1;
59 | }
60 | public void SaveCSV()
61 | {
62 | if (_osc == null)
63 | {
64 | MessageBox.Show("Please connect a device first");
65 | return;
66 | }
67 |
68 | Cursor = Cursors.WaitCursor;
69 | _gnuplot.Path = txtGnuPlotPath.Text;
70 |
71 | _osc.Run();
72 |
73 | // Set up some settings on oscilloscope
74 | if (rbNormalPoints.Checked)
75 | {
76 | _osc.SetWaveformPointsMode(PointsMode.Normal);
77 | }
78 | else
79 | {
80 | _osc.SetWaveformPointsMode(PointsMode.Maximum);
81 | }
82 |
83 | // Memory depth
84 | if (rbNormal.Checked)
85 | {
86 | _osc.SetAcquireMemoryDepth(AcquireMemoryDepth.Normal);
87 | }
88 | else
89 | {
90 | _osc.SetAcquireMemoryDepth(AcquireMemoryDepth.Long);
91 | }
92 |
93 | _osc.SetTriggerSweep(TriggerSweep.Single);
94 | //_osc.Stop();
95 | // Run and wait trigger
96 | _osc.Run();
97 | _osc.WaitTriggerStop();
98 |
99 | // Get Waveform and save it as CSV file
100 | string csvFileName = "data.csv";
101 |
102 | if (cbCh1.Checked && cbCh2.Checked)
103 | {
104 | _osc.GetWaveforms().SaveCSV(csvFileName);
105 | _gnuplot.DrawGraph(csvFileName, 2, rbOutPNG.Checked);
106 | }
107 | else
108 | {
109 | if (cbCh1.Checked)
110 | {
111 | _osc.Channel1.GetWaveform().SaveCSV(csvFileName);
112 | // Draw CSV file with GNU Plot
113 | _gnuplot.DrawGraph(csvFileName, 1, rbOutPNG.Checked);
114 | }
115 | else if (cbCh2.Checked)
116 | {
117 | _osc.Channel2.GetWaveform().SaveCSV(csvFileName);
118 | _gnuplot.DrawGraph(csvFileName, 1, rbOutPNG.Checked);
119 | }
120 | else
121 | {
122 | // Nothing
123 | }
124 | }
125 |
126 | // Release oscilloscope remote control
127 | _osc.Close();
128 |
129 | Cursor = Cursors.Default;
130 | }
131 |
132 | void UpdatePoints(object sender, EventArgs e)
133 | {
134 | int points = 0;
135 | if (!cbCh1.Checked && !cbCh2.Checked)
136 | {
137 | points = 0;
138 | }
139 | else
140 | {
141 | if (rbNormalPoints.Checked)
142 | {
143 | points = 600;
144 | }
145 | else // Max Points
146 | {
147 | if (rbNormal.Checked)
148 | {
149 | if (cbCh1.Checked && cbCh2.Checked)
150 | {
151 | points = 8192;
152 | }
153 | else
154 | {
155 | points = 16384;
156 | }
157 | }
158 | else
159 | {
160 | if (cbCh1.Checked && cbCh2.Checked)
161 | {
162 | points = 524288;
163 | }
164 | else
165 | {
166 | points = 1048576;
167 | }
168 | }
169 | }
170 | }
171 | lblPoints.Text = points.ToString();
172 | }
173 |
174 | void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
175 | {
176 | // SaveCSV already close device but here we close it again for double check
177 | _osc?.Close();
178 | }
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/OscilloscopeGUI/FrmMain.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 |
123 | AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAABMLAAATCwAAAAAAAAAA
124 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
125 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
126 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
127 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
128 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
129 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
130 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
131 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
132 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
133 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
134 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
135 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
136 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
137 | 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
165 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8bwcBvG8HBvxvBwb8bwcG/G8
166 | HBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
167 | AAAAAAAAAAAAAAAAAAAAAAAA8b0fB/G9Hx/xvR8f8b0fH/G9Hx/yvh8IAAAAAAAAAAAAAAAAAAAAAAAA
168 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
169 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPG9
170 | HwnxvR8f8b0fH/G9Hx/xvR8fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
171 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPK+IQjyviEj8r4hI/K+ISPyviEj8r4hHfK/
172 | IQvyvyIJ8r8iCfK/IgnyvyIJ8r8iCfK/IgnyvyIJ8r8iCfK/IgnyvyIJ8r8iCfK/IgnyvyIJ8r8iCfK/
173 | IgnyvyIJ8r8iCfK/IgnyvyIJ8r8iCfK/IgnyvyIJ8r8iCfK/IgnyvyIJ8r8iCfK/IgnyvyIJ8r8iCfK/
174 | IgnyvyIJ8r8iCfK/IQvyviEd8r4hI/K+ISPyviEj8r4hIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
175 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADywCME8sAjJ/LA
176 | IyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LA
177 | IyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LA
178 | IyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LAIyfywCMn8sAjJ/LAIycAAAAAAAAAAAAA
179 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
180 | AAAAAAAAAAAAAPLBJSXywSUr8sElK/LBJSvywSUr8sElK/LBJSvywSUr8sElK/LBJSvywSUr8sElK/LB
181 | JSvywSUr8sElK/LBJSvywSUr8sElK/LBJSvywSUr8sElK/LBJSvywSUr8sElK/LBJSvywSUr8sElK/LB
182 | JSvywSUr8sElK/LBJSvywSUr8sElK/LBJSvywSUr8sElK/LBJSvywSUr8sElK/LBJSvywSUr8sElK/LB
183 | JSvywSUlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
184 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzwicO88IoL/PCKC/zwigv88IoL/PCKC/zwigv88IoL/PC
185 | KC/zwigv88IoL/PCKC/zwigv88IoL/PCKC/zwigv88IoL/PCKC/zwigv88IoL/PCKC/zwigv88IoL/PC
186 | KC/zwigv88IoL/PCKC/zwigv88IoL/PCKC/zwigv88IoL/PCKC/zwigv88IoL/PCKC/zwigv88IoL/PC
187 | KC/zwigv88IoL/PCKC/zwigv88InDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
188 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPPDKQ/zwyks88MqM/PD
189 | KjPzwyoz88MqM/PDKjPzwyoz88MqM/PDKjPzwyoz88MqM/PDKjPzwyoz88MqM/PDKjPzwyoz88MqM/PD
190 | KjPzwyoz88MqM/PDKjPzwyoz88MqM/PDKjPzwyoz88MqM/PDKjPzwyoz88MqM/PDKjPzwyoz88MqM/PD
191 | KjPzwyoz88MqM/PDKjPzwyoz88MqM/PDKjPzwyks88MpDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
192 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
193 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
194 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
195 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
196 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
197 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADalQAf2pUAP9qVAD/alQA/2pUAP9qVAD/alQA/2pUAP9qV
198 | AD/alQA/2pUAP9qVAD/alQA/2pUAP9qVAD/alQA/2pUAP9qVAD/alQA/2pUAP9qVAD/alQA/2pUAP9qV
199 | AD/alQA/2pUAP9qVAD/alQA/2pUAP9qVAD/alQA/2pUAP9qVAD/alQA/2pUAP9qVAD/alQA/2pUAHwAA
200 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
201 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANuWAE/alQDf2pUA/9qVAP/alQD/2pUA/9qV
202 | AP/alQD/2pUA/9qVAP/alQD/2pUA/9qVAP/alQD/2pUA/9qVAP/alQD/2pUA/9qVAP/alQD/2pUA/9qV
203 | AP/alQD/2pUA/9qVAP/alQD/2pUA/9qVAP/alQD/2pUA/9qVAP/alQD/2pUA/9qVAP/alQD/2pUA/9qV
204 | AP/alQD/2pUA/9qVAP/alQDf25YATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
205 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANyXAE/blwD/25cA/9uX
206 | AP/blwD/25cA/9uXAP/blwD/25cA/9uXAP/blwD/25cA/9uXAP/blwD/25cA/9uXAP/blwD/25cA/9uX
207 | AP/blwD/25cA/9uXAP/blwD/25cA/9uXAP/blwD/25cA/9uXAP/blwD/25cA/9uXAP/blwD/25cA/9uX
208 | AP/blwD/25cA/9uXAP/blwD/25cA/9uXAP/blwD/25cA/9uXAP/clwBPAAAAAAAAAAAAAAAAAAAAAAAA
209 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
210 | AADcmADf3JgA/9yYAP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yY
211 | AP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yY
212 | AP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yYAP/cmAD/3JgA/9yYAP/cmAD/3JgA3wAA
213 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
214 | AAAAAAAAAAAAAAAAAADemgAf3ZkA/92ZAP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92Z
215 | AP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92Z
216 | AP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92ZAP/dmQD/3ZkA/92Z
217 | AP/dmQD/3ZkA/92ZAP/emgAfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
218 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3psAP96bAP/emwD/3psA/96bAP/emwDP3psATwAA
219 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
220 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
221 | 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
249 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
250 | AAAAAAAAAAAAAAAAAAAAAAAA4p8Ar+KfAP/inwD/4p8A3wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
251 | AAAAAAAA5qQA/+akAP/mpAD/5qQA/+akAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
252 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADnpQA/56UA/+elAP/npQD/56UA/wAA
253 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
254 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOOhAL/joQD/46EA/+OhAP/kogAPAAAAAAAA
255 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAOelAP/npQD/56UA/+elAP/npQA/AAAAAAAAAAAAAAAAAAAAAAAA
256 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6KYAP+im
257 | AP/opgD/6KYA/+imAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
258 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADlowD/5aMA/+Wj
259 | AP/lowD/5aMAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADopgD/6KYA/+imAP/opgD/6KYAPwAA
260 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
261 | AAAAAAAAAAAAAOmoAD/pqAD/6agA/+moAP/pqAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
262 | AAAAAAAAAAAAAAAAAAAAAAAA6KYAD+elAO/npQDv6KYADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
263 | AADopgAP56UA/+elAP/npQD/56UA/+elAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6agA/+mo
264 | AP/pqAD/6agA/+moAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
265 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADqqQA/6qkA/+qpAP/qqQD/6qkA/wAAAAAAAAAAAAAAAAAA
266 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOmoAE/ppwD/6acA/+moAH8AAAAAAAAAAAAA
267 | AAAAAAAAAAAAAAAAAAAAAAAA6acAP+mnAP/ppwD/6KcAv+mnAP/ppwCvAAAAAAAAAAAAAAAAAAAAAAAA
268 | AAAAAAAAAAAAAOqpAP/qqQD/6qkA/+qpAP/qqQA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
269 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA66oAP+uqAP/rqgD/66oA/+uq
270 | AP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADqqgCf6qoA/+qq
271 | AP/qqgDv66sADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOqqAF/qqgD/6qoA/+qqAH/qqgD/6qoA3+ur
272 | AD/rqwA/66sAP+urAD/rqwA/AAAAAAAAAADrqgD/66oA/+uqAP/rqgD/66oAPwAAAAAAAAAAAAAAAAAA
273 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOys
274 | AD/srAD/7KwA/+ysAP/srAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
275 | AAAAAAAA7KwA3+ysAP/srAD/7KwA/+ysAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADsrAB/7KwA/+ys
276 | AL/srAA/7KwA/+ysAP/srAD/7KwA/+ysAP/srAD/7KwA/+ysAO8AAAAA7KwA/+ysAP/srAD/7KwA/+ys
277 | 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
333 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8bwcP/G8HP/xvBz/8bwc//G8
334 | HP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
335 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
336 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPG9HQ/xvBz/8bwc//G8HP/xvBz/8bwcPwAAAAAAAAAAAAAAAAAA
337 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPG9
338 | Hz/xvR//8b0f//G9H//xvR//8b0fTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
339 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
340 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADxvR9P8b0f//G9H//xvR//8b0f//G9
341 | Hz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
342 | AAAAAAAAAAAAAAAAAADyviE/8r4h//K+If/yviH/8r4h//K+Ic/yvyFP8r8iP/K/Ij/yvyI/8r8iP/K/
343 | Ij/yvyI/8r8iP/K/Ij/yvyI/8r8iP/K/Ij/yvyI/8r8iP/K/Ij/yvyI/8r8iP/K/Ij/yvyI/8r8iP/K/
344 | Ij/yvyI/8r8iP/K/Ij/yvyI/8r8iP/K/Ij/yvyI/8r8iP/K/Ij/yvyI/8r8iP/K/Ij/yvyFP8r4hz/K+
345 | If/yviH/8r4h//K+If/yviE/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
346 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8sAiH/LAI//ywCP/8sAj//LAI//ywCP/8sAj//LA
347 | I//ywCP/8sAj//LAI//ywCP/8sAj//LAI//ywCP/8sAj//LAI//ywCP/8sAj//LAI//ywCP/8sAj//LA
348 | I//ywCP/8sAj//LAI//ywCP/8sAj//LAI//ywCP/8sAj//LAI//ywCP/8sAj//LAI//ywCP/8sAj//LA
349 | I//ywCP/8sAj//LAI//ywCP/8sAj//LAI//ywCP/8sAiHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
350 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADywSXf8sEl//LB
351 | Jf/ywSX/8sEl//LBJf/ywSX/8sEl//LBJf/ywSX/8sEl//LBJf/ywSX/8sEl//LBJf/ywSX/8sEl//LB
352 | Jf/ywSX/8sEl//LBJf/ywSX/8sEl//LBJf/ywSX/8sEl//LBJf/ywSX/8sEl//LBJf/ywSX/8sEl//LB
353 | Jf/ywSX/8sEl//LBJf/ywSX/8sEl//LBJf/ywSX/8sEl//LBJf/ywSX/8sEl3wAAAAAAAAAAAAAAAAAA
354 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
355 | AAAAAAAA88InT/PCKP/zwij/88Io//PCKP/zwij/88Io//PCKP/zwij/88Io//PCKP/zwij/88Io//PC
356 | KP/zwij/88Io//PCKP/zwij/88Io//PCKP/zwij/88Io//PCKP/zwij/88Io//PCKP/zwij/88Io//PC
357 | KP/zwij/88Io//PCKP/zwij/88Io//PCKP/zwij/88Io//PCKP/zwij/88Io//PCKP/zwij/88Io//PC
358 | J08AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
359 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzwylP88Mp3/PDKv/zwyr/88Mq//PDKv/zwyr/88Mq//PD
360 | Kv/zwyr/88Mq//PDKv/zwyr/88Mq//PDKv/zwyr/88Mq//PDKv/zwyr/88Mq//PDKv/zwyr/88Mq//PD
361 | Kv/zwyr/88Mq//PDKv/zwyr/88Mq//PDKv/zwyr/88Mq//PDKv/zwyr/88Mq//PDKv/zwyr/88Mq//PD
362 | Kv/zwyr/88Mp3/PDKU8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
363 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzxCsf88QrP/PE
364 | Kz/zxCs/88QrP/PEKz/zxCs/88QrP/PEKz/zxCs/88QrP/PEKz/zxCs/88QrP/PEKz/zxCs/88QrP/PE
365 | Kz/zxCs/88QrP/PEKz/zxCs/88QrP/PEKz/zxCs/88QrP/PEKz/zxCs/88QrP/PEKz/zxCs/88QrP/PE
366 | Kz/zxCs/88QrP/PEKz/zxCs/88QrHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
367 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
368 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
369 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
370 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
371 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
372 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
373 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
374 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
375 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
376 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
377 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
378 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
379 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
380 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
381 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
382 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
383 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
384 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
385 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
386 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
387 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
388 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
389 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
390 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
391 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
392 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
393 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
394 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
395 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
396 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
397 | AAAAAAAA/////////////////////////////////8P///w/w///g////D+D//+D///8P4P//4P///w/
398 | g///g////D+D//+D///8P4P//4P/////g///gf////+D//+AAAAAAAP//4AAAAAAA///wAAAAAAD///A
399 | AAAAAAP//+AAAAAAB//////////////4AAAAAB///+AAAAAAB///wAAAAAAD///AAAAAAAP//4AAAAAA
400 | Af//gP////4B//+B/////4H//4P/////wf//g////D/B//+D///8P8H//4P///w/wf//g////D/B//+D
401 | ///8P8H//4P///wfwf//g////B/B//+D/8P4H8H//4P/w/gfwf//g//B+ADB//+D/8H4AEH//4IAgPgA
402 | Qf//ggCA+P/B//+D+IgY/8H//4P4CAD/wf//g/wMAP/B//+D/B+B/8H//4P+H4H/wf//g/4fwf/B//+D
403 | /h/B/8H//4P//+H/wf//g///4f/B//+D///h/8H//4P/////wf//g/////+B//+B/////4H//4AAAAAA
404 | Af//gAAAAAAB///AAAAAAAP//8AAAAAAA///4AAAAAAH///4AAAAAB//////////////////////////
405 | //////////////////////////////////////////////////8=
406 |
407 |
408 |
--------------------------------------------------------------------------------
/OscilloscopeGUI/OscilloscopeGUI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {ADFC469D-78BB-415D-AE23-B6F5D5A5BDFC}
8 | WinExe
9 | Properties
10 | OscilloscopeGUI
11 | OscilloscopeGUI
12 | v4.8
13 | 512
14 |
15 | false
16 | publish\
17 | true
18 | Disk
19 | false
20 | Foreground
21 | 7
22 | Days
23 | false
24 | false
25 | true
26 | 1
27 | 1.0.0.%2a
28 | false
29 | true
30 | true
31 |
32 |
33 | AnyCPU
34 | true
35 | full
36 | false
37 | bin\Debug\
38 | DEBUG;TRACE
39 | prompt
40 | 4
41 | false
42 | Auto
43 |
44 |
45 | AnyCPU
46 | pdbonly
47 | true
48 | bin\Release\
49 | TRACE
50 | prompt
51 | 4
52 | false
53 | false
54 |
55 |
56 | 5D4142EB70B461762E16F05A5C0356043FBFBF57
57 |
58 |
59 | OscilloscopeGUI_TemporaryKey.pfx
60 |
61 |
62 | false
63 |
64 |
65 | LocalIntranet
66 |
67 |
68 | Properties\app.manifest
69 |
70 |
71 | false
72 |
73 |
74 | oscilloscope.ico
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | Form
91 |
92 |
93 | FrmMain.cs
94 |
95 |
96 |
97 |
98 | FrmMain.cs
99 |
100 |
101 | Designer
102 |
103 |
104 |
105 |
106 |
107 | {6bea399d-cd60-4af9-8499-3f720a5ede80}
108 | Oscilloscope
109 |
110 |
111 |
112 |
113 | False
114 | Microsoft .NET Framework 4 %28x86 and x64%29
115 | true
116 |
117 |
118 | False
119 | .NET Framework 3.5 SP1 Client Profile
120 | false
121 |
122 |
123 | False
124 | .NET Framework 3.5 SP1
125 | false
126 |
127 |
128 | False
129 | Windows Installer 4.5
130 | true
131 |
132 |
133 |
134 |
135 | False
136 |
137 |
138 |
139 |
140 | Include
141 | True
142 | Assembly
143 |
144 |
145 | False
146 |
147 |
148 |
149 |
150 | Include
151 | True
152 | Assembly
153 |
154 |
155 | False
156 |
157 |
158 |
159 |
160 | Include
161 | True
162 | Assembly
163 |
164 |
165 | False
166 |
167 |
168 |
169 |
170 | Include
171 | True
172 | Assembly
173 |
174 |
175 |
176 |
177 |
178 |
179 |
186 |
--------------------------------------------------------------------------------
/OscilloscopeGUI/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Threading;
4 | using System.Windows.Forms;
5 |
6 | namespace OscilloscopeGUI
7 | {
8 | static class Program
9 | {
10 | ///
11 | /// The main entry point for the application.
12 | ///
13 | [STAThread]
14 | static void Main()
15 | {
16 | // Decimal separator is '.'
17 | Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
18 |
19 | Application.EnableVisualStyles();
20 | Application.SetCompatibleTextRenderingDefault(false);
21 | Application.Run(new FrmMain());
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/OscilloscopeGUI/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Oscilloscope GUI")]
9 | [assembly: AssemblyProduct("Oscilloscope GUI")]
10 | [assembly: AssemblyCopyright("Copyright © Leonardo Tazzini 2014")]
11 |
12 | // Setting ComVisible to false makes the types in this assembly not visible
13 | // to COM components. If you need to access a type in this assembly from
14 | // COM, set the ComVisible attribute to true on that type.
15 | [assembly: ComVisible(false)]
16 |
17 | // The following GUID is for the ID of the typelib if this project is exposed to COM
18 | [assembly: Guid("1587975a-0749-4064-90ed-a2f23e105380")]
19 |
20 | // Version information for an assembly consists of the following four values:
21 | //
22 | // Major Version
23 | // Minor Version
24 | // Build Number
25 | // Revision
26 | //
27 | // You can specify all the values or you can default the Build and Revision Numbers
28 | // by using the '*' as shown below:
29 | // [assembly: AssemblyVersion("1.0.*")]
30 | [assembly: AssemblyVersion("1.1.0.0")]
31 | [assembly: AssemblyFileVersion("1.1.0.0")]
--------------------------------------------------------------------------------
/OscilloscopeGUI/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
54 |
--------------------------------------------------------------------------------
/OscilloscopeGUI/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/OscilloscopeGUI/oscilloscope.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electro-logic/Oscilloscope/0e2c02bed0aebfc0c84ac1a4b7d9095409adec9f/OscilloscopeGUI/oscilloscope.ico
--------------------------------------------------------------------------------
/OscilloscopeTest/OscilloscopeTest.cs:
--------------------------------------------------------------------------------
1 | // Author: Leonardo Tazzini
2 |
3 | using System;
4 | using Microsoft.VisualStudio.TestTools.UnitTesting;
5 | using System.Globalization;
6 | using System.Threading;
7 |
8 | namespace OscilloscopeTest
9 | {
10 | [TestClass]
11 | public class UnitTestOscilloscope
12 | {
13 | Oscilloscope _osc = new Oscilloscope();
14 |
15 | [TestCleanup]
16 | [TestInitialize]
17 | [TestMethod]
18 | public void Initialize()
19 | {
20 | Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
21 | _osc.SetAcquireAverages(AcquireAverages.Average16);
22 | _osc.SetAcquireMemoryDepth(AcquireMemoryDepth.Normal);
23 | _osc.SetAcquireMode(AcquireMode.EquiTime);
24 | _osc.SetAcquireType(AcquireType.Normal);
25 | _osc.SetTimebaseFormat(TimebaseFormat.YT);
26 | _osc.SetTimebaseMode(TimebaseMode.Main);
27 | _osc.SetTriggerSweep(TriggerSweep.Normal);
28 | _osc.SetWaveformPointsMode(PointsMode.Normal);
29 | _osc.SetTimebaseScale(0.001);
30 | _osc.SetTimebaseOffset(0);
31 | }
32 |
33 | ///
34 | /// TODO: Document
35 | ///
36 | public void TestGetterSetter(Func getter, Action setter)
37 | {
38 | Array enums = Enum.GetValues(typeof(T));
39 | foreach (T enumObj in enums)
40 | {
41 | setter(enumObj);
42 | Assert.AreEqual(enumObj, getter());
43 | }
44 |
45 | // Test first Setter in case of already set enum
46 | T firstEnumObj = (T)enums.GetValue(0);
47 | setter(firstEnumObj);
48 | Assert.AreEqual(firstEnumObj, getter());
49 | }
50 |
51 | [TestMethod]
52 | public void TestAcquire()
53 | {
54 | TestGetterSetter(_osc.GetAcquireType, _osc.SetAcquireType);
55 | TestGetterSetter(_osc.GetAcquireMode, _osc.SetAcquireMode);
56 | TestGetterSetter(_osc.GetAcquireAverages, _osc.SetAcquireAverages);
57 | TestGetterSetter(_osc.GetAcquireMemoryDepth, _osc.SetAcquireMemoryDepth);
58 | }
59 |
60 | //[TestMethod]
61 | //public void TestAcquireSamplingRate()
62 | //{
63 | // // TODO: Set sampling rate changing timebase scale
64 | // double samplingRate = _osc.GetAcquireSamplingRate(1);
65 | // Assert.AreEqual(1.0, samplingRate);
66 | //}
67 |
68 | [TestMethod]
69 | public void TestTimebase()
70 | {
71 | //TestGetterSetter(_osc.GetTimebaseMode, _osc.SetTimebaseMode);
72 | // TODO
73 | // _osc.GetTimebaseOffset
74 | // _osc.GetTimebaseScale
75 | TestGetterSetter(_osc.GetTimebaseFormat, _osc.SetTimebaseFormat);
76 | }
77 |
78 | [TestMethod]
79 | public void TestTrigger()
80 | {
81 | TestGetterSetter(_osc.GetTriggerSweep, _osc.SetTriggerSweep);
82 | // TODO others
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/OscilloscopeTest/OscilloscopeTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {38B8E55F-06FF-435F-8D4A-0967A9B94F4F}
7 | Library
8 | Properties
9 | OscilloscopeTest
10 | OscilloscopeTest
11 | v4.8
12 | 512
13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 10.0
15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
17 | False
18 | UnitTest
19 |
20 |
21 |
22 | true
23 | full
24 | false
25 | bin\Debug\
26 | DEBUG;TRACE
27 | prompt
28 | 4
29 | false
30 |
31 |
32 | pdbonly
33 | true
34 | bin\Release\
35 | TRACE
36 | prompt
37 | 4
38 | false
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | {6bea399d-cd60-4af9-8499-3f720a5ede80}
62 | Oscilloscope
63 |
64 |
65 |
66 |
67 |
68 |
69 | False
70 |
71 |
72 | False
73 |
74 |
75 | False
76 |
77 |
78 | False
79 |
80 |
81 |
82 |
83 |
84 |
85 |
92 |
--------------------------------------------------------------------------------
/OscilloscopeTest/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("OscilloscopeTest")]
9 | [assembly: AssemblyProduct("OscilloscopeTest")]
10 | [assembly: AssemblyCopyright("Copyright © Leonardo Tazzini 2014")]
11 |
12 | // Setting ComVisible to false makes the types in this assembly not visible
13 | // to COM components. If you need to access a type in this assembly from
14 | // COM, set the ComVisible attribute to true on that type.
15 | [assembly: ComVisible(false)]
16 |
17 | // The following GUID is for the ID of the typelib if this project is exposed to COM
18 | [assembly: Guid("eb70b576-f8c1-4023-8e6a-256c455d3ce8")]
19 |
20 | // Version information for an assembly consists of the following four values:
21 | //
22 | // Major Version
23 | // Minor Version
24 | // Build Number
25 | // Revision
26 | //
27 | // You can specify all the values or you can default the Build and Revision Numbers
28 | // by using the '*' as shown below:
29 | // [assembly: AssemblyVersion("1.0.*")]
30 | [assembly: AssemblyVersion("1.1.0.0")]
31 | [assembly: AssemblyFileVersion("1.1.0.0")]
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # C# Oscilloscope Library and GUI (tested with Rigol DS1102E)
2 |
3 | Remote control your oscilloscope, configure settings and acquire data points
4 |
5 |
6 | ## Projects
7 |
8 | - OscilloscopeLib is an object-oriented library for managing Rigol's Oscilloscopes (tested with DS1102E only, but should works with other models too)
9 |
10 | - OscilloscopeCLI is a command line sample, showing how to use OscilloscopeLib
11 |
12 | - OscilloscopeGUI is a GUI for easy data acquisition and display
13 |
14 | - OscilloscopeTest contains Unit Tests for easily checking if your own oscilloscope model is compliant with library
15 |
16 |
17 | ## Requirements
18 |
19 | To compile the project you need:
20 |
21 | - .NET Framework 4.8
22 |
23 | - Visual Studio 2022 with .NET desktop development workload installed
24 |
25 | - NI-VISA .NET SDK 2024 Q4 [http://www.ni.com/download/ni-visa-run-time-engine](https://www.ni.com/en/support/downloads/drivers/download.ni-visa.html)
26 |
27 | To run the project you need:
28 |
29 | - NI-VISA .NET Runtime 2024 Q4 [http://www.ni.com/download/ni-visa-run-time-engine](https://www.ni.com/en/support/downloads/drivers/download.ni-visa.html)
30 |
31 | - Gnuplot 5.2 (optional for graphs, 25 MB) http://www.gnuplot.info/ see GNUPLOT section for more informations
32 |
33 |
34 | ## Screenshoots
35 |
36 | 
37 |
38 | *OscilloscopeGUI*
39 |
40 | 
41 |
42 | *Automatically generated Gnuplot graph (zoomable)*
43 |
44 |
45 | ## Example of OscilloscopeLib usage (from OscilloscopeCLI)
46 |
47 | ```
48 | // 1M data point acquisition
49 | void LongMemoryAcquisitionExample()
50 | {
51 | var rigol = new Oscilloscope();
52 | rigol.Run();
53 | rigol.SetWaveformPointsMode(PointsMode.Maximum);
54 | rigol.SetAcquireMemoryDepth(AcquireMemoryDepth.Long);
55 | rigol.SetTriggerSweep(TriggerSweep.Single);
56 | rigol.WaitTriggerStop();
57 | rigol.Stop();
58 | var wave = rigol.Channel1.GetWaveform();
59 | wave.SaveCSV(csvFileName);
60 | rigol.Close();
61 | }
62 | ```
63 |
64 | Then you can graph your acquired data with Excel or GnuPlot
65 |
66 | ```
67 | // Display acquired data with Excel (or any other installed software that can handle CSV)
68 | Process.Start(csvFileName);
69 |
70 | // Draw a graph with GNU Plot and save it as .png image
71 | GnuPlot gnuPlot = new GnuPlot();
72 | gnuPlot.DrawGraph(csvFileName, 1); // only channel 1
73 | ```
74 |
75 |
76 | ## Notes
77 |
78 | This project started as auxiliary tool for a bigger project, so code may not be production-quality. If there is interest I can improve it, anyway any contribution is welcome.
79 |
80 | I initially wrote this library in 2014 to track the velocity profile of a stepper motor, driven by a real-time driver that I have built.
81 |
82 | I think that this project can be useful to people who own a Rigol oscilloscope, so I updated it with NI-VISA 2024 Q4 to support Windows 11.
83 |
84 |
85 | Here are some images to better understand what this library allow you to do with very little work.
86 |
87 |
88 | 
89 |
90 | *Oscilloscope display*
91 |
92 |
93 | 
94 |
95 | *Data acquired and processed with the aid of this library and a graph of velocity of the system produced*
96 |
97 |
98 | You can also write some C# code to post-process CSV data and extrapolate relevant information for your application (ex. I used it to get velocity profile of my system from the waveform of a revolution detector).
99 |
100 |
101 | ## VISA SDK
102 |
103 | Rigol oscilloscope support Virtual Instrument Software Architecture (VISA) standard for configuring, programming, and troubleshooting instrumentation systems.
104 |
105 | To create software that support VISA devices you need to install the NI-VISA SDK:
106 |
107 |
108 | Assembly referenced by OscilloscopeLib are located into:
109 |
110 | - C:\Program Files (x86)\IVI Foundation\VISA\Microsoft.NET\Framework32\v2.0.50727\VISA.NET Shared Components 7.2.0\Ivi.Visa.dll v7.2.0.0
111 |
112 | - C:\Program Files (x86)\IVI Foundation\VISA\Microsoft.NET\Framework32\v4.0.30319\NI VISA.NET 23.3\NationalInstruments.Visa.dll v23.3.0.49276
113 |
114 |
115 | Documentation and Programming Guide:
116 |
117 | [Rigol Prograrmming Guide](https://eu.rigol.com/eu/Images/DS1000E_ProgrammingGuide_EN_tcm30-2863.pdf)
118 |
119 | [DS1000E Waveform Data Formatting Guide](https://rigol.my.site.com/support/s/article/DS1000E-Waveform-Data-Formatting-Guide)
120 |
121 |
122 | ## GNUPLOT
123 |
124 | Graphs are generated with Gnuplot to avoid reinventing the wheel. Data can be analyzed and graphed also with Excel or any software that can open CSV files.
125 |
126 | Gnuplot 5.2 (for graphs, optional)
127 |
128 | http://www.gnuplot.info/
129 |
130 | **NB:** Gnuplot keyboard commands to interact with graph are available at Gnuplot command line (just launch gnuplot.exe from Start) with the command "show bind", here are reported some:
131 |
132 | - a autoscale
133 | - \+ zoom in
134 | - \- zoom out
135 |
136 | Right click with the mouse to zoom a section of the graph
137 |
138 | *Warning:* Graph with 1M points can be slow to display and interact, another way can be analyzing data with Excel or another software
139 |
140 |
141 | ## ADDITIONAL NOTES
142 |
143 | For legacy systems (Windows XP, etc..) an old NI-VISA 3.0 Runtime download (3 MBytes) is distributed by Rigol with the UltraSigma software and can avoid downloading the most recent package that is much larger. NI-VISA 5.4.1 Runtime download (74 MBytes) is available for OS up to Windows 8. To avoid the NI-VISA Runtime (few Gigabytes), please have a look at the branch https://github.com/electro-logic/Oscilloscope/tree/TinyDriver that needs a tiny driver (24 KBytes) only.
144 |
145 | DS1102E firmware v00.04.04.00.00 (AUG 2020) is breaking the "Long Memory", it's advised to NOT update the firmware. Please also see https://www.eevblog.com/forum/testgear/rigol-ds1052e-firmware-v00-04-04-00-00-from-20200827
146 |
147 |
148 | ## OSZI WAVEFORM ANALYZER
149 |
150 | Another interesting project to capture and analyze data from Rigol oscilloscopes: https://github.com/Elmue/Oszi-Waveform-Analyzer
151 |
--------------------------------------------------------------------------------