Skip to content

Commit c370c58

Browse files
committed
Display automatically set port voltage value
- When the PortVoltage is null, the port voltage will be set automatically. If this procedure succeeds, the voltage will be displayed in the text box as "X.X (Auto)" where X.X is the voltage that is applied to the port. - This text will only appear while the workflow is running. It will revert back to null after the workflow is stopped. - If the voltage is set manually, the value will persist.
1 parent cdc835e commit c370c58

13 files changed

+192
-70
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<PackageLicenseFile>LICENSE</PackageLicenseFile>
1414
<UseArtifactsOutput>true</UseArtifactsOutput>
1515
<PackageIcon>icon.png</PackageIcon>
16-
<VersionPrefix>0.4.5</VersionPrefix>
16+
<VersionPrefix>0.5.0</VersionPrefix>
1717
<VersionSuffix></VersionSuffix>
1818
<LangVersion>10.0</LangVersion>
1919
<Features>strict</Features>

OpenEphys.Onix1/AutoPortVoltage.cs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Globalization;
4+
using System.Xml.Serialization;
5+
6+
namespace OpenEphys.Onix1
7+
{
8+
/// <summary>
9+
/// Represents a, possibly automatically set, port voltage.
10+
/// </summary>
11+
public class AutoPortVoltage
12+
{
13+
/// <summary>
14+
/// Gets or sets a value the requested port voltage. If null, the voltage will be set automatically.
15+
/// </summary>
16+
public double? Requested { get; set; }
17+
18+
/// <summary>
19+
/// Gets or sets the currently applied port voltage
20+
/// </summary>
21+
[XmlIgnore]
22+
public double? Applied { get; internal set; }
23+
24+
/// <summary>
25+
/// Initializes a new instance of the <see cref="AutoPortVoltage"/> class.
26+
/// </summary>
27+
public AutoPortVoltage()
28+
{
29+
Requested = null;
30+
Applied = null;
31+
}
32+
33+
/// <summary>
34+
/// Initializes a new instance of the <see cref="AutoPortVoltage"/> class.
35+
/// </summary>
36+
/// <param name="value">A value determining the requested port voltage</param>
37+
public AutoPortVoltage(double? value)
38+
{
39+
Requested = value;
40+
Applied = null;
41+
}
42+
}
43+
44+
internal class PortVoltageConverter : TypeConverter
45+
{
46+
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
47+
{
48+
if (destinationType == typeof(string))
49+
return true;
50+
51+
return base.CanConvertTo(context, destinationType);
52+
}
53+
54+
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
55+
{
56+
if (destinationType == typeof(string) && value is AutoPortVoltage portVoltage)
57+
{
58+
if (portVoltage.Requested.HasValue)
59+
{
60+
return string.Format($"{portVoltage.Requested:0.0}");
61+
}
62+
else if (portVoltage.Applied.HasValue)
63+
{
64+
return $"{portVoltage.Applied:0.0} (Auto)";
65+
}
66+
else
67+
{
68+
return "";
69+
}
70+
}
71+
72+
return base.ConvertTo(context, culture, value, destinationType);
73+
}
74+
75+
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
76+
{
77+
if (sourceType == typeof(string))
78+
return true;
79+
80+
return base.CanConvertFrom(context, sourceType);
81+
}
82+
83+
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
84+
{
85+
if (value is string stringValue)
86+
{
87+
88+
if (string.IsNullOrEmpty(stringValue))
89+
{
90+
return new AutoPortVoltage(null);
91+
}
92+
else if (double.TryParse(stringValue, NumberStyles.Number, culture ?? CultureInfo.CurrentCulture, out double result))
93+
{
94+
return new AutoPortVoltage(result);
95+
}
96+
97+
throw new FormatException($"'{stringValue}' is not a valid value for PortVoltage.");
98+
}
99+
100+
return base.ConvertFrom(context, culture, value);
101+
}
102+
}
103+
}

OpenEphys.Onix1/ConfigureHeadstage64.cs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,12 @@ public PortName Port
125125
/// Supplying higher voltages may result in damage.
126126
/// </para>
127127
/// </remarks>
128-
[Description("If defined, it will override automated voltage discovery and apply the specified voltage" +
129-
"to the headstage. Warning: this device requires 5.5V to 6.0V for proper operation." +
130-
"Supplying higher voltages may result in damage to the headstage.")]
128+
[Description("If defined, it will override automated voltage discovery and apply the specified voltage " +
129+
"to the headstage. Warning: this device requires 5.5V to 6.0V, measured at the headstage, " +
130+
"for proper operation. Supplying higher voltages may result in damage to the headstage.")]
131131
[Category(ConfigurationCategory)]
132-
public double? PortVoltage
132+
[TypeConverter(typeof(PortVoltageConverter))]
133+
public AutoPortVoltage PortVoltage
133134
{
134135
get => PortControl.PortVoltage;
135136
set => PortControl.PortVoltage = value;
@@ -147,34 +148,38 @@ internal override IEnumerable<IDeviceConfiguration> GetDevices()
147148

148149
class ConfigureHeadstage64PortController : ConfigurePortController
149150
{
150-
protected override bool ConfigurePortVoltage(DeviceContext device)
151+
protected override bool ConfigurePortVoltage(DeviceContext device, out double voltage)
151152
{
152153
// WONTFIX: It takes a huge amount of time to get to 0, almost 10 seconds. The best we can do
153154
// at the moment is drive port voltage to minimum which is an active process and then settle
154155
// from there to zero volts. This requires a hardware revision that discharges the headstage
155156
// between cycles to fix.
156-
const uint MinVoltage = 33;
157-
const uint MaxVoltage = 60;
158-
const uint VoltageOffset = 34;
159-
const uint VoltageIncrement = 02;
157+
const double MinVoltage = 3.3;
158+
const double MaxVoltage = 6.0;
159+
const double VoltageOffset = 3.4;
160+
const double VoltageIncrement = 0.2;
160161

161162
// Start with highest voltage and ramp it down to find lowest lock voltage
162-
var voltage = MaxVoltage;
163+
voltage = MaxVoltage;
163164
for (; voltage >= MinVoltage; voltage -= VoltageIncrement)
164165
{
165-
device.WriteRegister(PortController.PORTVOLTAGE, voltage);
166+
device.WriteRegister(PortController.PORTVOLTAGE, (uint)(10 * voltage));
166167
Thread.Sleep(200);
167168
if (!CheckLinkState(device))
168169
{
169-
if (voltage == MaxVoltage) return false;
170+
if (voltage == MaxVoltage)
171+
{
172+
return false;
173+
}
170174
else break;
171175
}
172176
}
173177

174-
device.WriteRegister(PortController.PORTVOLTAGE, MinVoltage);
178+
device.WriteRegister(PortController.PORTVOLTAGE, (uint)(10 * MinVoltage));
175179
device.WriteRegister(PortController.PORTVOLTAGE, 0);
176180
Thread.Sleep(1000);
177-
device.WriteRegister(PortController.PORTVOLTAGE, voltage + VoltageOffset);
181+
voltage += VoltageOffset;
182+
device.WriteRegister(PortController.PORTVOLTAGE, (uint)(10 * voltage));
178183
Thread.Sleep(200);
179184
return CheckLinkState(device);
180185
}

OpenEphys.Onix1/ConfigureHeadstageNeuropixelsV1e.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ public PortName Port
8989
"the specified voltage to the headstage. Warning: this device requires 3.8V to 5.0V " +
9090
"for proper operation. Higher voltages can damage the headstage.")]
9191
[Category(ConfigurationCategory)]
92-
public double? PortVoltage
92+
[TypeConverter(typeof(PortVoltageConverter))]
93+
public AutoPortVoltage PortVoltage
9394
{
9495
get => PortControl.PortVoltage;
9596
set => PortControl.PortVoltage = value;
@@ -104,20 +105,22 @@ internal override IEnumerable<IDeviceConfiguration> GetDevices()
104105

105106
class ConfigureNeuropixelsV1ePortController : ConfigurePortController
106107
{
107-
protected override bool ConfigurePortVoltage(DeviceContext device)
108+
protected override bool ConfigurePortVoltage(DeviceContext device, out double voltage)
108109
{
109110
const double MinVoltage = 3.3;
110111
const double MaxVoltage = 5.5;
111112
const double VoltageOffset = 1.0;
112113
const double VoltageIncrement = 0.2;
113114

114-
for (double voltage = MinVoltage; voltage <= MaxVoltage; voltage += VoltageIncrement)
115+
voltage = MinVoltage;
116+
for (; voltage <= MaxVoltage; voltage += VoltageIncrement)
115117
{
116118
SetVoltage(device, voltage);
117119

118120
if (CheckLinkState(device))
119121
{
120-
SetVoltage(device, voltage + VoltageOffset);
122+
voltage += VoltageOffset;
123+
SetVoltage(device, voltage);
121124
return CheckLinkState(device);
122125
}
123126
}

OpenEphys.Onix1/ConfigureHeadstageNeuropixelsV1f.cs

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ public PortName Port
117117
"the specified voltage to the headstage. Warning: this device requires 4.5V to 5.5V " +
118118
"for proper operation. Higher voltages can damage the headstage.")]
119119
[Category(ConfigurationCategory)]
120-
public double? PortVoltage
120+
[TypeConverter(typeof(PortVoltageConverter))]
121+
public AutoPortVoltage PortVoltage
121122
{
122123
get => PortControl.PortVoltage;
123124
set => PortControl.PortVoltage = value;
@@ -134,39 +135,24 @@ internal override IEnumerable<IDeviceConfiguration> GetDevices()
134135

135136
class ConfigureNeuropixels1fHeadstageLinkController : ConfigurePortController
136137
{
137-
// TODO: Needs more testing
138-
protected override bool ConfigurePortVoltage(DeviceContext device)
138+
protected override bool ConfigurePortVoltage(DeviceContext device, out double voltage)
139139
{
140-
if (PortVoltage == null)
141-
{
142-
const double MinVoltage = 5.0;
143-
const double MaxVoltage = 7.0;
144-
const double VoltageOffset = 1.0;
145-
const double VoltageIncrement = 0.2;
140+
const double MinVoltage = 5.0;
141+
const double MaxVoltage = 7.0;
142+
const double VoltageOffset = 1.0;
143+
const double VoltageIncrement = 0.2;
146144

147-
for (double voltage = MinVoltage; voltage <= MaxVoltage; voltage += VoltageIncrement)
145+
voltage = MinVoltage;
146+
for (; voltage <= MaxVoltage; voltage += VoltageIncrement)
147+
{
148+
SetVoltage(device, voltage);
149+
if (CheckLinkState(device))
148150
{
151+
voltage += VoltageOffset;
149152
SetVoltage(device, voltage);
150-
if (CheckLinkState(device))
151-
{
152-
SetVoltage(device, voltage + VoltageOffset);
153-
return CheckLinkState(device);
154-
}
153+
return CheckLinkState(device);
155154
}
156-
return false;
157-
}
158-
else
159-
{
160-
SetVoltage(device, (double)PortVoltage);
161155
}
162-
163-
if (CheckLinkState(device))
164-
{
165-
device.Context.Reset();
166-
Thread.Sleep(200);
167-
return true;
168-
}
169-
170156
return false;
171157
}
172158

OpenEphys.Onix1/ConfigureHeadstageNeuropixelsV2e.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ public PortName Port
8888
"the specified voltage to the headstage. Warning: this device requires 3.0V to 5.5V " +
8989
"for proper operation. Higher voltages can damage the headstage.")]
9090
[Category(ConfigurationCategory)]
91-
public double? PortVoltage
91+
[TypeConverter(typeof(PortVoltageConverter))]
92+
public AutoPortVoltage PortVoltage
9293
{
9394
get => PortControl.PortVoltage;
9495
set => PortControl.PortVoltage = value;

OpenEphys.Onix1/ConfigureHeadstageNeuropixelsV2eBeta.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ public PortName Port
8888
"the specified voltage to the headstage. Warning: this device requires 3.0V to 5.0V " +
8989
"for proper operation. Higher voltages can damage the headstage.")]
9090
[Category(ConfigurationCategory)]
91-
public double? PortVoltage
91+
[TypeConverter(typeof(PortVoltageConverter))]
92+
public AutoPortVoltage PortVoltage
9293
{
9394
get => PortControl.PortVoltage;
9495
set => PortControl.PortVoltage = value;

OpenEphys.Onix1/ConfigureHeadstageNric1384.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ public PortName Port
9595
"the specified voltage to the headstage. Warning: this device requires 3.8V to 5.5V " +
9696
"for proper operation. Higher voltages can damage the headstage.")]
9797
[Category(ConfigurationCategory)]
98-
public double? PortVoltage
98+
[TypeConverter(typeof(PortVoltageConverter))]
99+
public AutoPortVoltage PortVoltage
99100
{
100101
get => PortControl.PortVoltage;
101102
set => PortControl.PortVoltage = value;
@@ -110,19 +111,21 @@ internal override IEnumerable<IDeviceConfiguration> GetDevices()
110111

111112
class ConfigureHeadstageNric1384PortController : ConfigurePortController
112113
{
113-
protected override bool ConfigurePortVoltage(DeviceContext device)
114+
protected override bool ConfigurePortVoltage(DeviceContext device, out double voltage)
114115
{
115116
const double MinVoltage = 3.8;
116117
const double MaxVoltage = 5.5;
117118
const double VoltageOffset = 0.7;
118119
const double VoltageIncrement = 0.2;
119120

120-
for (var voltage = MinVoltage; voltage <= MaxVoltage; voltage += VoltageIncrement)
121+
voltage = MinVoltage;
122+
for (; voltage <= MaxVoltage; voltage += VoltageIncrement)
121123
{
122124
SetPortVoltage(device, voltage);
123125
if (base.CheckLinkState(device))
124126
{
125-
SetPortVoltage(device, voltage + VoltageOffset);
127+
voltage += VoltageOffset;
128+
SetPortVoltage(device, voltage);
126129
return CheckLinkState(device);
127130
}
128131
}

OpenEphys.Onix1/ConfigureHeadstageRhs2116.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ public PortName Port
100100
"to the headstage. Warning: this device requires 3.4V to 4.4V for proper operation." +
101101
"Supplying higher voltages may result in damage to the headstage.")]
102102
[Category(ConfigurationCategory)]
103-
public double? PortVoltage
103+
[TypeConverter(typeof(PortVoltageConverter))]
104+
public AutoPortVoltage PortVoltage
104105
{
105106
get => LinkController.PortVoltage;
106107
set => LinkController.PortVoltage = value;
@@ -115,19 +116,21 @@ internal override IEnumerable<IDeviceConfiguration> GetDevices()
115116

116117
class ConfigureHeadstageRhs2116LinkController : ConfigurePortController
117118
{
118-
protected override bool ConfigurePortVoltage(DeviceContext device)
119+
protected override bool ConfigurePortVoltage(DeviceContext device, out double voltage)
119120
{
120121
const double MinVoltage = 3.3;
121122
const double MaxVoltage = 4.4;
122123
const double VoltageOffset = 2.0;
123124
const double VoltageIncrement = 0.2;
124125

125-
for (var voltage = MinVoltage; voltage <= MaxVoltage; voltage += VoltageIncrement)
126+
voltage = MinVoltage;
127+
for (; voltage <= MaxVoltage; voltage += VoltageIncrement)
126128
{
127129
SetPortVoltage(device, voltage);
128130
if (base.CheckLinkState(device))
129131
{
130-
SetPortVoltage(device, voltage + VoltageOffset);
132+
voltage += VoltageOffset;
133+
SetPortVoltage(device, voltage);
131134
return CheckLinkState(device);
132135
}
133136
}

OpenEphys.Onix1/ConfigureNeuropixelsV2ePortController.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,22 @@ namespace OpenEphys.Onix1
44
{
55
class ConfigureNeuropixelsV2ePortController : ConfigurePortController
66
{
7-
protected override bool ConfigurePortVoltage(DeviceContext device)
7+
protected override bool ConfigurePortVoltage(DeviceContext device, out double voltage)
88
{
99
const double MinVoltage = 3.3;
1010
const double MaxVoltage = 5.5;
1111
const double VoltageOffset = 1.0;
1212
const double VoltageIncrement = 0.2;
1313

14-
for (double voltage = MinVoltage; voltage <= MaxVoltage; voltage += VoltageIncrement)
14+
voltage = MinVoltage;
15+
for (; voltage <= MaxVoltage; voltage += VoltageIncrement)
1516
{
1617
SetVoltage(device, voltage);
1718

1819
if (CheckLinkState(device))
1920
{
20-
SetVoltage(device, voltage + VoltageOffset);
21+
voltage += VoltageOffset;
22+
SetVoltage(device, voltage);
2123
return CheckLinkState(device);
2224
}
2325
}

0 commit comments

Comments
 (0)