prototype labjack API wrapper

The Labjack API provided by ljacklm is, quite frankly, dog doodoo. I
say this as disrespectfully as possible. A lot of the API calls take
specific (implictly sized) arrays that must be 0-filled just so the
API can loop over them and fill them with a different number.
Everything parameter is either long or a float (and I think the use of
long is a carryover from the insane Win32 ABI where long is a 32 bit
integer rather than 64 bit, which it is on most Posix platforms). The
functions have a tendency to do 15 different things in a single call,
and most of the function parameters are out parameters or even better,
inout parameters. Some functions take arrays where other ones require
the user to manually bitpack an integer.

I've got the source for it right here and could rewrite it, but I don't
hate myself enough to do that. The API surface I need is minimal, so
I've just wrapped the parts I will be using. Ideally I will not need
to touch this again, but it does still need to be tested with actual
hardware, so we're not out of the woods yet.
This commit is contained in:
torque 2024-06-29 17:44:52 -07:00
parent eace0bf8db
commit 7275d1c30e
Signed by: torque
SSH Key Fingerprint: SHA256:nCrXefBNo6EbjNSQhv0nXmEg/VuNq3sMF5b8zETw3Tk
4 changed files with 837 additions and 444 deletions

View File

@ -1471,6 +1471,84 @@ float GetDriverVersion( void)
return VERSION; return VERSION;
} }
const char *StaticErrorString(long errorcode) {
if(BitTst(errorcode,8))
{
errorcode -= STREAMBUFF_ERROR_OFFSET_LJ;
}
switch(errorcode)
{
case 0: return "No error";
case 1: return "Unknown error";
case 2: return "No LabJacks found";
case 3: return "LabJack n not found";
case 4: return "Set USB buffer error";
case 5: return "Open handle error";
case 6: return "Close handle error";
case 7: return "Invalid ID";
case 8: return "Invalid array size or value";
case 9: return "Invalid power index";
case 10: return "FCDD size too big";
case 11: return "HVC size too big";
case 12: return "Read error";
case 13: return "Read timeout error";
case 14: return "Write error";
case 15: return "Turbo error";
case 16: return "Illegal channel index";
case 17: return "Illegal gain index";
case 18: return "Illegal AI command";
case 19: return "Illegal AO command";
case 20: return "Bits out of range";
case 21: return "Illegal number of channels";
case 22: return "Illegal scan rate";
case 23: return "Illegal number of samples";
case 24: return "AI response error";
case 25: return "LabJack RAM checksum error";
case 26: return "AI sequence error";
case 27: return "Maximum number of streams reached";
case 28: return "AI stream start error";
case 29: return "PC buffer overflow";
case 30: return "LabJack buffer overflow";
case 31: return "Stream read timeout";
case 32: return "Illegal number of scans";
case 33: return "No stream was found";
case 40: return "Illegal input";
case 41: return "Echo error";
case 42: return "Data echo error";
case 43: return "Response error";
case 44: return "Asynch timeout error";
case 45: return "Asynch start bit error";
case 46: return "Asynch framing error";
case 47: return "Asynch digital I/O state or tris error";
case 48: return "Caps error";
case 49: return "Caps error";
case 50: return "Caps error";
case 51: return "HID number caps error";
case 52: return "HID get attributes warning";
case 57: return "Wrong firmware version error";
case 58: return "Digital I/O state or tris error";
case 64: return "Could not claim all LabJacks";
case 65: return "Error releasing all LabJacks";
case 66: return "Could not claim LabJack";
case 67: return "Error releasing LabJack";
case 68: return "Claimed abandoned LabJack";
case 69: return "Local ID -1 thread stopped";
case 70: return "Stop thread timeout";
case 71: return "Thread termination failed";
case 72: return "Feature handle creation failed";
case 73: return "Mutex creation failed";
case 80: return "Synch CS state or tris error";
case 81: return "Synch SCK tris error";
case 82: return "Synch MISO tris error";
case 83: return "Synch MOSI tris error";
case 89: return "SHT1X communication error - CRC";
case 90: return "SHT1X communication error - MeasReady";
case 91: return "SHT1X communication error - ACK";
case 92: return "SHT1X serial reset error";
default: return "Unknown error code";
}
}
//====================================================================== //======================================================================
//GetErrorString //GetErrorString
@ -1485,149 +1563,7 @@ float GetDriverVersion( void)
void GetErrorString( long errorcode, void GetErrorString( long errorcode,
char *errorString) char *errorString)
{ {
if(BitTst(errorcode,8)) errorString = strcpy(errorString, StaticErrorString(errorcode));
{
errorcode -= STREAMBUFF_ERROR_OFFSET_LJ;
}
switch(errorcode)
{
case 0: errorString = strcpy(errorString,"No error");
break;
case 1: errorString = strcpy(errorString,"Unknown error");
break;
case 2: errorString = strcpy(errorString,"No LabJacks found");
break;
case 3: errorString = strcpy(errorString,"LabJack n not found");
break;
case 4: errorString = strcpy(errorString,"Set USB buffer error");
break;
case 5: errorString = strcpy(errorString,"Open handle error");
break;
case 6: errorString = strcpy(errorString,"Close handle error");
break;
case 7: errorString = strcpy(errorString,"Invalid ID");
break;
case 8: errorString = strcpy(errorString,"Invalid array size or value");
break;
case 9: errorString = strcpy(errorString,"Invalid power index");
break;
case 10: errorString = strcpy(errorString,"FCDD size too big");
break;
case 11: errorString = strcpy(errorString,"HVC size too big");
break;
case 12: errorString = strcpy(errorString,"Read error");
break;
case 13: errorString = strcpy(errorString,"Read timeout error");
break;
case 14: errorString = strcpy(errorString,"Write error");
break;
case 15: errorString = strcpy(errorString,"Turbo error");
break;
case 16: errorString = strcpy(errorString,"Illegal channel index");
break;
case 17: errorString = strcpy(errorString,"Illegal gain index");
break;
case 18: errorString = strcpy(errorString,"Illegal AI command");
break;
case 19: errorString = strcpy(errorString,"Illegal AO command");
break;
case 20: errorString = strcpy(errorString,"Bits out of range");
break;
case 21: errorString = strcpy(errorString,"Illegal number of channels");
break;
case 22: errorString = strcpy(errorString,"Illegal scan rate");
break;
case 23: errorString = strcpy(errorString,"Illegal number of samples");
break;
case 24: errorString = strcpy(errorString,"AI response error");
break;
case 25: errorString = strcpy(errorString,"LabJack RAM checksum error");
break;
case 26: errorString = strcpy(errorString,"AI sequence error");
break;
case 27: errorString = strcpy(errorString,"Maximum number of streams reached");
break;
case 28: errorString = strcpy(errorString,"AI stream start error");
break;
case 29: errorString = strcpy(errorString,"PC buffer overflow");
break;
case 30: errorString = strcpy(errorString,"LabJack buffer overflow");
break;
case 31: errorString = strcpy(errorString,"Stream read timeout");
break;
case 32: errorString = strcpy(errorString,"Illegal number of scans");
break;
case 33: errorString = strcpy(errorString,"No stream was found");
break;
case 40: errorString = strcpy(errorString,"Illegal input");
break;
case 41: errorString = strcpy(errorString,"Echo error");
break;
case 42: errorString = strcpy(errorString,"Data echo error");
break;
case 43: errorString = strcpy(errorString,"Response error");
break;
case 44: errorString = strcpy(errorString,"Asynch timeout error");
break;
case 45: errorString = strcpy(errorString,"Asynch start bit error");
break;
case 46: errorString = strcpy(errorString,"Asynch framing error");
break;
case 47: errorString = strcpy(errorString,"Asynch digital I/O state or tris error");
break;
case 48: errorString = strcpy(errorString,"Caps error");
break;
case 49: errorString = strcpy(errorString,"Caps error");
break;
case 50: errorString = strcpy(errorString,"Caps error");
break;
case 51: errorString = strcpy(errorString,"HID number caps error");
break;
case 52: errorString = strcpy(errorString,"HID get attributes warning");
break;
case 57: errorString = strcpy(errorString,"Wrong firmware version error");
break;
case 58: errorString = strcpy(errorString,"Digital I/O state or tris error");
break;
case 64: errorString = strcpy(errorString,"Could not claim all LabJacks");
break;
case 65: errorString = strcpy(errorString,"Error releasing all LabJacks");
break;
case 66: errorString = strcpy(errorString,"Could not claim LabJack");
break;
case 67: errorString = strcpy(errorString,"Error releasing LabJack");
break;
case 68: errorString = strcpy(errorString,"Claimed abandoned LabJack");
break;
case 69: errorString = strcpy(errorString,"Local ID -1 thread stopped");
break;
case 70: errorString = strcpy(errorString,"Stop thread timeout");
break;
case 71: errorString = strcpy(errorString,"Thread termination failed");
break;
case 72: errorString = strcpy(errorString,"Feature handle creation failed");
break;
case 73: errorString = strcpy(errorString,"Mutex creation failed");
break;
case 80: errorString = strcpy(errorString,"Synch CS state or tris error");
break;
case 81: errorString = strcpy(errorString,"Synch SCK tris error");
break;
case 82: errorString = strcpy(errorString,"Synch MISO tris error");
break;
case 83: errorString = strcpy(errorString,"Synch MOSI tris error");
break;
case 89: errorString = strcpy(errorString,"SHT1X communication error - CRC");
break;
case 90: errorString = strcpy(errorString,"SHT1X communication error - MeasReady");
break;
case 91: errorString = strcpy(errorString,"SHT1X communication error - ACK");
break;
case 92: errorString = strcpy(errorString,"SHT1X serial reset error");
break;
default: errorString=strcpy(errorString,"Unknown error code");
}
return; return;
} }

View File

@ -798,6 +798,8 @@ long DigitalIO( long *idnum,
float GetDriverVersion( void); float GetDriverVersion( void);
const char *StaticErrorString(long errorcode);
//====================================================================== //======================================================================
//GetErrorString //GetErrorString
// //

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,23 @@ const std = @import("std");
const ljack = @import("./ljacklm.zig"); const ljack = @import("./ljacklm.zig");
pub fn main() !void { pub fn main() !void {
const ver = ljack.GetDriverVersion(); const ver = ljack.getDriverVersion();
std.debug.print("Driver version: {d}\n", .{ver}); std.debug.print("Driver version: {d}\n", .{ver});
const device = ljack.Labjack.autodetect();
const in = try device.analogReadOne(.{ .channel = .diff_01, .gain = 2 });
std.debug.print("Read voltage: {d}. Overvolt: {}\n", .{ in.voltage, in.over_voltage });
try device.digitalWriteOne(.{ .channel = .{ .io = 0 }, .level = true });
const sample = try device.readAnalogWriteDigital(
2,
.{ .{ .channel = .diff_01, .gain = 2 }, .{ .channel = .diff_23, .gain = 2 } },
.{false} ** 4,
true,
);
for (sample, 0..) |input, idx| {
std.debug.print(" channel {d}: {d} V\n", .{ idx, input.voltage });
}
} }