labjack: actually initialize digital outputs

I had some testing code that did this and then I got rid of it because
I thought I didn't need it, but it turns out it is actually necessary
because AISample does not do any digital direction setup.

Anyway, this has been tested on (basic) hardware now, and it appears to
even work. It needs two main things to be truly prime-time capable: a
calibration process and output debouncing. When it is approaching the
target, the relays will get toggled very rapidly a few times, which is
not particularly good for them. Operating on a moving average of the
feedback may be a simple way to address this (effectively acts as a
low-pass filter). Slowing down the control loop may also work well and
would be much simpler.
This commit is contained in:
torque 2024-07-08 18:22:20 -07:00
parent dbb076f69b
commit d5f0727517
Signed by: torque
SSH Key Fingerprint: SHA256:nCrXefBNo6EbjNSQhv0nXmEg/VuNq3sMF5b8zETw3Tk
2 changed files with 40 additions and 4 deletions

View File

@ -159,6 +159,7 @@ const Controller = struct {
fn connectLabjack(self: *Controller) !void {
const info = try self.labjack.connect();
try self.labjack.setAllDigitalOutputLow();
self.labjack.id = info.local_id;
}

View File

@ -6,7 +6,7 @@ pub fn getDriverVersion() f32 {
pub const Labjack = struct {
id: ?i32 = null,
demo: bool = false,
demobit: bool = false,
pub fn autodetect() Labjack {
return .{};
@ -36,6 +36,37 @@ pub const Labjack = struct {
version;
}
pub fn setAllDigitalOutputLow(self: Labjack) LabjackError!void {
var id = self.cId();
// bitmask. D0 to D15 (LSB is D0). 0 is input, 1 is output
var d_modes: c_long = 0xFF_FF;
// bitmask. D0 to D15 (LSB is D0). 0 is output low, 1 is output high
var d_outputs: c_long = 0;
// bitmask. D0 to D15 (LSB is D0). 0 is output low, 1 is output high
// the actual pin states read back from the device. an outvar from the API call.
var d_states: c_long = 0;
// bitmask. IO0 to IO3 (LSB is IO0). 0 is input, 1 is output
const io_modes: c_long = 0b1111;
// bitmask. IO0 to IO3 (LSB is IO0). 0 is output low, 1 is output high
var io_outputs: c_long = 0;
const status = c_api.DigitalIO(
&id,
self.demo(),
&d_modes,
io_modes,
&d_outputs,
&io_outputs,
1, // actually update the pin modes
&d_states,
);
if (!status.okay())
return status.toError();
}
/// Read one analog input channel, either single-ended or differential
pub fn analogReadOne(self: Labjack, input: AnalogInput) LabjackError!AnalogReadResult {
if (!input.channel.isDifferential() and input.gain_index != 0) {
@ -48,7 +79,7 @@ pub const Labjack = struct {
const status = c_api.EAnalogIn(
&id,
@intFromBool(self.demo),
self.demo(),
input.channelNumber(),
input.gainIndex(),
&over_v,
@ -67,7 +98,7 @@ pub const Labjack = struct {
var id = self.cId();
const status = c_api.EDigitalOut(
&id,
@intFromBool(self.demo),
self.demo(),
output.channelNumber(),
@intFromBool(output.isDLine()),
@intFromBool(output.level),
@ -100,7 +131,7 @@ pub const Labjack = struct {
const status = c_api.AISample(
&id,
@intFromBool(self.demo),
self.demo(),
&out_states,
@intFromBool(outputs != null),
@intFromBool(ledOn),
@ -129,6 +160,10 @@ pub const Labjack = struct {
fn cId(self: Labjack) c_long {
return self.id orelse -1;
}
fn demo(self: Labjack) c_long {
return @intFromBool(self.demobit);
}
};
pub const AnalogInput = struct {