Skip to content

Commit c22cf83

Browse files
authored
Merge pull request #436 from open-ephys/issue-429
Display automatically set port voltage value
2 parents 8207420 + fae89aa commit c22cf83

12 files changed

+193
-72
lines changed

OpenEphys.Onix1/AutoPortVoltage.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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 last 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+
return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
49+
}
50+
51+
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
52+
{
53+
if (destinationType == typeof(string) && value is AutoPortVoltage portVoltage)
54+
{
55+
if (portVoltage.Requested.HasValue)
56+
{
57+
return string.Format($"{portVoltage.Requested:0.0}");
58+
}
59+
else if (portVoltage.Applied.HasValue)
60+
{
61+
return $"{portVoltage.Applied:0.0} (Auto)";
62+
}
63+
else
64+
{
65+
return "";
66+
}
67+
}
68+
69+
return base.ConvertTo(context, culture, value, destinationType);
70+
}
71+
72+
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
73+
{
74+
if (sourceType == typeof(string))
75+
return true;
76+
77+
return base.CanConvertFrom(context, sourceType);
78+
}
79+
80+
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
81+
{
82+
if (value is string stringValue)
83+
{
84+
85+
if (string.IsNullOrEmpty(stringValue))
86+
{
87+
return new AutoPortVoltage(null);
88+
}
89+
else if (double.TryParse(stringValue, NumberStyles.Number, culture ?? CultureInfo.CurrentCulture, out double result))
90+
{
91+
return new AutoPortVoltage(result);
92+
}
93+
94+
throw new FormatException($"'{stringValue}' is not a valid value for PortVoltage.");
95+
}
96+
97+
return base.ConvertFrom(context, culture, value);
98+
}
99+
}
100+
}

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 & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,29 @@ 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
}
2426

2527
return false;
2628
}
2729

28-
2930
void SetVoltage(DeviceContext device, double voltage)
3031
{
3132
device.WriteRegister(PortController.PORTVOLTAGE, 0);

0 commit comments

Comments
 (0)