From d5f0727517ec23b49a13c4a1401045b6fbe475a0 Mon Sep 17 00:00:00 2001 From: torque Date: Mon, 8 Jul 2024 18:22:20 -0700 Subject: [PATCH] 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. --- src/LabjackYaesu.zig | 1 + src/labjack.zig | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/LabjackYaesu.zig b/src/LabjackYaesu.zig index bb46b01..984f55e 100644 --- a/src/LabjackYaesu.zig +++ b/src/LabjackYaesu.zig @@ -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; } diff --git a/src/labjack.zig b/src/labjack.zig index f350f7f..eb5240b 100644 --- a/src/labjack.zig +++ b/src/labjack.zig @@ -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 {