├── .gitignore ├── KeysightInstrument.cs ├── KeysightInstrumentCommunication.sln ├── LabSupply ├── App.config ├── App.xaml ├── App.xaml.cs ├── LabSupply.csproj ├── LabSupply.csproj.user ├── MainWindow.xaml ├── MainWindow.xaml.cs └── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings └── Multimeter ├── App.config ├── App.xaml ├── App.xaml.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Multimeter.csproj ├── Multimeter.csproj.user └── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings /.gitignore: -------------------------------------------------------------------------------- 1 | */bin/* 2 | 3 | */obj/* 4 | .git/* 5 | .vs/* 6 | */Thumbs.db -------------------------------------------------------------------------------- /KeysightInstrument.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Runtime.InteropServices; 9 | using System.Management; 10 | using System.IO; 11 | using System.Windows.Input; 12 | using System.ComponentModel; 13 | using System.Windows.Threading; 14 | using Ivi.Visa.Interop; 15 | 16 | namespace Instrument 17 | { 18 | /// 19 | /// Interaction logic for App.xaml 20 | /// 21 | /// 22 | 23 | /* 24 | * E36103A 25 | * MY56476536 26 | * USB0::0x2A8D::0x0702::MY56476536::0::INSTR 27 | * 28 | * E36104A 29 | * MY55506105 30 | * USB0::0x2A8D::0x0802::MY55506105::0::INSTR 31 | * 32 | * E3633A 33 | * unknown 34 | * GPIB0::5::INSTR 35 | * 36 | * 34465A 37 | * MY54502615 38 | * USB0::0x2A8D::0x0101::MY54502615::0::INSTR 39 | */ 40 | 41 | public class KeysightInstrument 42 | { 43 | protected string ConnectionString; 44 | protected ResourceManager rm; 45 | public FormattedIO488 ioobj; 46 | 47 | protected KeysightInstrument() 48 | { 49 | 50 | } 51 | 52 | ~KeysightInstrument() 53 | { 54 | Close(); 55 | } 56 | 57 | protected void Open(string ConnectionString) 58 | { 59 | this.ConnectionString = ConnectionString; 60 | rm = new ResourceManager(); 61 | ioobj = new FormattedIO488(); 62 | ioobj.IO = (Ivi.Visa.Interop.IMessage)rm.Open(ConnectionString, AccessMode.NO_LOCK, 0, ""); 63 | } 64 | 65 | protected void Close() 66 | { 67 | try 68 | { 69 | ioobj.IO.Close(); 70 | } 71 | catch { } 72 | try 73 | { 74 | System.Runtime.InteropServices.Marshal.ReleaseComObject(ioobj); 75 | } 76 | catch { } 77 | try 78 | { 79 | System.Runtime.InteropServices.Marshal.ReleaseComObject(rm); 80 | } 81 | catch { } 82 | } 83 | 84 | public void SendString(string Message) 85 | { 86 | ioobj.WriteString(Message, true); 87 | } 88 | 89 | public string ReadString() 90 | { 91 | try 92 | { 93 | return ioobj.ReadString(); 94 | } 95 | catch (Exception e) 96 | { 97 | return e.Message; 98 | } 99 | } 100 | 101 | public double ReadDouble() 102 | { 103 | try 104 | { 105 | return (double) ioobj.ReadNumber(); 106 | } 107 | catch (Exception e) 108 | { 109 | return -9.999; 110 | } 111 | } 112 | 113 | public bool ReadBool() 114 | { 115 | try 116 | { 117 | if (ioobj.ReadNumber() == 1) 118 | return true; 119 | else 120 | return false; 121 | } 122 | catch (Exception e) 123 | { 124 | return false; 125 | } 126 | } 127 | } 128 | } 129 | 130 | -------------------------------------------------------------------------------- /KeysightInstrumentCommunication.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabSupply", "LabSupply\LabSupply.csproj", "{5E8BCA4E-A46A-4463-AAA2-2724439E68FA}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Multimeter", "Multimeter\Multimeter.csproj", "{EEE20860-C2BB-4045-A31F-551D648BC831}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {5E8BCA4E-A46A-4463-AAA2-2724439E68FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {5E8BCA4E-A46A-4463-AAA2-2724439E68FA}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {5E8BCA4E-A46A-4463-AAA2-2724439E68FA}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {5E8BCA4E-A46A-4463-AAA2-2724439E68FA}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {EEE20860-C2BB-4045-A31F-551D648BC831}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {EEE20860-C2BB-4045-A31F-551D648BC831}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {EEE20860-C2BB-4045-A31F-551D648BC831}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {EEE20860-C2BB-4045-A31F-551D648BC831}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /LabSupply/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LabSupply/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /LabSupply/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Runtime.InteropServices; 9 | using System.Management; 10 | using System.IO; 11 | using System.Windows.Input; 12 | using System.ComponentModel; 13 | using System.Windows.Threading; 14 | using Ivi.Visa.Interop; 15 | 16 | namespace LabSupply 17 | { 18 | /// 19 | /// Interaction logic for App.xaml 20 | /// 21 | /// 22 | 23 | public class KeySightLabSupply : Instrument.KeysightInstrument 24 | { 25 | 26 | public KeySightLabSupply(string ConnectionString) 27 | { 28 | Open(ConnectionString); 29 | } 30 | 31 | public double SetVoltage 32 | { 33 | get 34 | { 35 | SendString("VOLTAGE?"); 36 | return ReadDouble(); 37 | } 38 | set 39 | { 40 | string cmd = string.Format("VOLTAGE {0:0.000}", value); 41 | SendString(cmd); 42 | } 43 | } 44 | 45 | public double SetCurrent 46 | { 47 | get 48 | { 49 | SendString("CURRENT?"); 50 | return ReadDouble(); 51 | } 52 | set 53 | { 54 | string cmd = string.Format("CURRENT {0:0.000}", value); 55 | SendString(cmd); 56 | } 57 | } 58 | 59 | public bool OutputOn 60 | { 61 | get 62 | { 63 | SendString("OUTPUT?"); 64 | return ReadBool(); 65 | } 66 | set 67 | { 68 | if (value) 69 | SendString("OUTPUT ON"); 70 | else 71 | SendString("OUTPUT OFF"); 72 | } 73 | } 74 | 75 | public double MeasuredVoltage 76 | { 77 | get 78 | { 79 | SendString("MEASURE:VOLTAGE?"); 80 | return ReadDouble(); 81 | } 82 | } 83 | 84 | public double MeasuredCurrent 85 | { 86 | get 87 | { 88 | SendString("MEASURE:CURRENT?"); 89 | return ReadDouble(); 90 | } 91 | } 92 | } 93 | 94 | /* 95 | * The Command Class 96 | */ 97 | 98 | public class UiCommand : ICommand 99 | { 100 | private Action _Execute; 101 | private Func _CanExecute; 102 | public event EventHandler CanExecuteChanged; 103 | 104 | public UiCommand(Action Execute, Func CanExecute) 105 | { 106 | _Execute = Execute; 107 | _CanExecute = CanExecute; 108 | } 109 | public bool CanExecute(object parameter) 110 | { 111 | return _CanExecute(); 112 | } 113 | public void Execute(object parameter) 114 | { 115 | _Execute(); 116 | } 117 | } 118 | 119 | 120 | /* 121 | * The ViewModel 122 | */ 123 | public class LabSupplyViewModel : INotifyPropertyChanged 124 | { 125 | private KeySightLabSupply supply; 126 | DispatcherTimer timer; 127 | uint timerTickCount = 0; 128 | private UiCommand buttonCommand; 129 | private DateTime ConnectedTimestamp = DateTime.Now; 130 | public string ActivityLogTxt { get; private set; } 131 | 132 | private double SetVoltage; 133 | private double _SetVoltage; 134 | private double SetCurrent; 135 | private double _SetCurrent; 136 | 137 | public event PropertyChangedEventHandler PropertyChanged; 138 | 139 | public LabSupplyViewModel() 140 | { 141 | supply = new KeySightLabSupply("GPIB0::5::INSTR"); 142 | /* 143 | _SetCurrent = 0.0; 144 | SetCurrent = supply.SetCurrent; 145 | _SetVoltage = 0.0; 146 | SetVoltage = supply.SetVoltage; 147 | */ 148 | //WriteLog(supply.SetVoltageString, false); 149 | //communicator.HidUtil.RaiseDeviceAddedEvent += DeviceAddedEventHandler; 150 | //communicator.HidUtil.RaiseDeviceRemovedEvent += DeviceRemovedEventHandler; 151 | //communicator.HidUtil.RaiseConnectionStatusChangedEvent += ConnectionStatusChangedHandler; 152 | 153 | buttonCommand = new UiCommand(this.OnButtonClicked, this.ButtonClickValid); 154 | 155 | WriteLog("Program started", true); 156 | 157 | //Configure and start timer 158 | timer = new DispatcherTimer(); 159 | timer.Interval = TimeSpan.FromMilliseconds(50); 160 | timer.Tick += TimerTickHandler; 161 | timer.Start(); 162 | } 163 | 164 | /* 165 | * Local function definitions 166 | */ 167 | 168 | public void OnButtonClicked() 169 | { 170 | WriteLog("Button clicked", false); 171 | } 172 | 173 | public bool ButtonClickValid() 174 | { 175 | return true; 176 | } 177 | 178 | private double StringToDouble(string InputString) 179 | { 180 | try 181 | { 182 | InputString = InputString.Trim(); 183 | InputString = InputString.ToUpper(); 184 | InputString = InputString.Replace("A", ""); 185 | InputString = InputString.Replace("V", ""); 186 | return double.Parse(InputString); 187 | } 188 | catch 189 | { 190 | return -9.999; 191 | } 192 | } 193 | 194 | // Add a line to the activity log text box 195 | void WriteLog(string message, bool clear) 196 | { 197 | // Replace content 198 | if (clear) 199 | { 200 | ActivityLogTxt = string.Format("{0}: {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), message); 201 | } 202 | // Add new line 203 | else 204 | { 205 | ActivityLogTxt += Environment.NewLine + string.Format("{0}: {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), message); 206 | } 207 | } 208 | 209 | public string SetVoltageTxt 210 | { 211 | get 212 | { 213 | return string.Format("{0:0.000}V", SetVoltage); 214 | } 215 | set 216 | { 217 | double SetVoltage = StringToDouble(value); 218 | if (SetVoltage == -9.999) 219 | SetVoltage = _SetVoltage; 220 | else 221 | supply.SetVoltage = SetVoltage; 222 | } 223 | } 224 | 225 | public string SetCurrentTxt 226 | { 227 | get 228 | { 229 | return string.Format("{0:0.000}A", SetCurrent); 230 | } 231 | set 232 | { 233 | double SetCurrent = StringToDouble(value); 234 | if (SetCurrent == -9.999) 235 | SetCurrent = _SetCurrent; 236 | else 237 | supply.SetCurrent = SetCurrent; 238 | } 239 | } 240 | 241 | public bool OutputOn 242 | { 243 | get 244 | { 245 | return supply.OutputOn; 246 | } 247 | set 248 | { 249 | supply.OutputOn = value; 250 | } 251 | } 252 | 253 | public string MeasuredVoltageTxt 254 | { 255 | get 256 | { 257 | return string.Format("{0:0.000}V", supply.MeasuredVoltage); 258 | } 259 | } 260 | 261 | public string MeasuredCurrentTxt 262 | { 263 | get 264 | { 265 | double current = supply.MeasuredCurrent; 266 | if(current < 0.001) 267 | return string.Format("{0:0.000}mA", current*1000); 268 | else 269 | return string.Format("{0:0.000}A", current); 270 | } 271 | } 272 | 273 | public ICommand ToggleClick 274 | { 275 | get 276 | { 277 | return buttonCommand; 278 | } 279 | } 280 | 281 | 282 | public void TimerTickHandler(object sender, EventArgs e) 283 | { 284 | if (PropertyChanged != null) 285 | { 286 | SetVoltage = supply.SetVoltage; 287 | if(_SetVoltage!=SetVoltage) 288 | { 289 | PropertyChanged(this, new PropertyChangedEventArgs("SetVoltageTxt")); 290 | _SetVoltage = SetVoltage; 291 | } 292 | SetCurrent = supply.SetCurrent; 293 | if (_SetCurrent != SetCurrent) 294 | { 295 | PropertyChanged(this, new PropertyChangedEventArgs("SetCurrentTxt")); 296 | _SetCurrent = SetCurrent; 297 | } 298 | PropertyChanged(this, new PropertyChangedEventArgs("OutputOn")); 299 | PropertyChanged(this, new PropertyChangedEventArgs("ActivityLogTxt")); 300 | if (timerTickCount == 5) 301 | { 302 | PropertyChanged(this, new PropertyChangedEventArgs("MeasuredVoltageTxt")); 303 | } 304 | if(timerTickCount == 10) 305 | { 306 | PropertyChanged(this, new PropertyChangedEventArgs("MeasuredCurrentTxt")); 307 | timerTickCount = 0; 308 | } 309 | ++timerTickCount; 310 | } 311 | } 312 | 313 | } 314 | 315 | 316 | public partial class App : Application 317 | { 318 | 319 | } 320 | } 321 | 322 | -------------------------------------------------------------------------------- /LabSupply/LabSupply.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5E8BCA4E-A46A-4463-AAA2-2724439E68FA} 8 | WinExe 9 | Properties 10 | LabSupply 11 | LabSupply 12 | v4.5.2 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | true 17 | publish\ 18 | true 19 | Disk 20 | false 21 | Foreground 22 | 7 23 | Days 24 | false 25 | false 26 | true 27 | 0 28 | 1.0.0.%2a 29 | false 30 | false 31 | true 32 | 33 | 34 | AnyCPU 35 | true 36 | full 37 | false 38 | bin\Debug\ 39 | DEBUG;TRACE 40 | prompt 41 | 4 42 | 43 | 44 | AnyCPU 45 | pdbonly 46 | true 47 | bin\Release\ 48 | TRACE 49 | prompt 50 | 4 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 4.0 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | MSBuild:Compile 71 | Designer 72 | 73 | 74 | MSBuild:Compile 75 | Designer 76 | 77 | 78 | KeysightInstrument.cs 79 | 80 | 81 | Code 82 | App.xaml 83 | 84 | 85 | MainWindow.xaml 86 | Code 87 | 88 | 89 | 90 | 91 | Code 92 | 93 | 94 | True 95 | True 96 | Resources.resx 97 | 98 | 99 | True 100 | Settings.settings 101 | True 102 | 103 | 104 | ResXFileCodeGenerator 105 | Resources.Designer.cs 106 | 107 | 108 | SettingsSingleFileGenerator 109 | Settings.Designer.cs 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | {DB8CBF00-D6D3-11D4-AA51-00A024EE30BD} 119 | 5 120 | 5 121 | 0 122 | primary 123 | False 124 | True 125 | 126 | 127 | 128 | 129 | False 130 | Microsoft .NET Framework 4.5.2 %28x86 and x64%29 131 | true 132 | 133 | 134 | False 135 | .NET Framework 3.5 SP1 136 | false 137 | 138 | 139 | 140 | 147 | -------------------------------------------------------------------------------- /LabSupply/LabSupply.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | publish\ 5 | 6 | 7 | 8 | 9 | 10 | en-US 11 | false 12 | 13 | -------------------------------------------------------------------------------- /LabSupply/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 41 | 42 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 67 | 68 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 79 | 80 | 81 | 82 | 83 |