Hello everyone, i just signed up for this forum, i am currently working with the LabJack U6 device, i have downloaded the java library wrapper and been able to run the example code just fine, however i was wondering if there is a way to add a callback function to read the results of a Analog Input channel, I need to make this an asynchronous function so that I don't have to read the results inside a while loop becauses it locks the main thread, I know there's a a callback function in the phython library but have not been able to find anything for the Java wrapper.
Thanks everyone for your help in advance, i'm using the LabJack U6 and all i'm trying to do is read current from one of the Analog Input channels, i followed the simpleStream Example which works very good but it would be even better if there was a callback function that could be used.
Here is the code i currently have:
[code]
public void Initialize(BA ba, String EventName, long loopAmount) {
try {
int intErrorcode = 0;
IntByReference refHandle = new IntByReference(0);
int intHandle = 0;
int i = 0, k = 0;
IntByReference refIOType = new IntByReference(0);
IntByReference refChannel = new IntByReference(0);
DoubleByReference refValue = new DoubleByReference(0);
DoubleByReference refBacklog = new DoubleByReference(0.0);
double scanRate = 1000;
long delayms = 1000;
double numScans = 2000; //2x the expected # of scans (2*scanRate*delayms/1000)
DoubleByReference refNumScansRequested = new DoubleByReference(0.0);
double[] adblData = new double[2*(int)numScans]; //Max buffer size (#channels*numScansRequested)
IntByReference dummyInt = new IntByReference(0);
DoubleByReference dummyDouble = new DoubleByReference(0.0);
NumberFormat formatter = new DecimalFormat("0.000");
Boolean isDone = false;
//Read and display the UD and LJUDJava versions.
BA.Log("UD Driver Version = " + formatter.format(LJUD.getDriverVersion()));
//Open the first found LabJack U6.
intErrorcode = LJUD.openLabJack(LJUD.Constants.dtU6, LJUD.Constants.ctUSB, "1", 1, refHandle);
checkForWarning(intErrorcode);
intHandle = refHandle.getValue();
//Configure the stream:
//Configure all analog inputs for 12-bit resolution
LJUD.addRequest(intHandle, LJUD.Constants.ioPUT_CONFIG, LJUD.Constants.chAIN_RESOLUTION, 12, 0, 0);
//Configure the analog input range on channel 0 for bipolar +-10 volts.
LJUD.addRequest(intHandle, LJUD.Constants.ioPUT_AIN_RANGE, 0, LJUD.Constants.rgBIP10V, 0, 0);
//Set the scan rate.
LJUD.addRequest(intHandle, LJUD.Constants.ioPUT_CONFIG, LJUD.Constants.chSTREAM_SCAN_FREQUENCY, scanRate, 0, 0);
//Give the driver a 5 second buffer (scanRate * 2 channels * 5 seconds).
LJUD.addRequest(intHandle, LJUD.Constants.ioPUT_CONFIG, LJUD.Constants.chSTREAM_BUFFER_SIZE, scanRate*2*5, 0, 0);
//Configure reads to retrieve whatever data is available without waiting (wait mode LJ_swNONE).
//See comments below to change this program to use LJ_swSLEEP mode.
LJUD.addRequest(intHandle, LJUD.Constants.ioPUT_CONFIG, LJUD.Constants.chSTREAM_WAIT_MODE, LJUD.Constants.swNONE, 0, 0);
//Define the scan list as AIN0 then FIOEIO.
LJUD.addRequest(intHandle, LJUD.Constants.ioCLEAR_STREAM_CHANNELS, 0, 0, 0, 0);
LJUD.addRequest(intHandle, LJUD.Constants.ioADD_STREAM_CHANNEL, 0, 0, 0, 0);
LJUD.addRequest(intHandle, LJUD.Constants.ioADD_STREAM_CHANNEL, 193, 0, 0, 0);
//Execute the list of requests.
LJUD.goOne(intHandle);
//Get all the results just to check for errors.
LJUD.getFirstResult(intHandle, refIOType, refChannel, refValue, dummyInt, dummyDouble);
isDone = false;
while(!isDone) {
try {
LJUD.getNextResult(intHandle, refIOType, refChannel, refValue, dummyInt, dummyDouble);
}
catch(LJUDException le) {
if(le.getError() == LJUD.Errors.NO_MORE_DATA_AVAILABLE.getValue()) {
isDone = true;
}
else {
throw le;
}
}
}
//Start the stream.
LJUD.eGet(intHandle, LJUD.Constants.ioSTART_STREAM, 0, refValue, 0);
//The actual scan rate is dependent on how the desired scan rate divides into
//the LabJack clock. The actual scan rate is returned in the value parameter
//from the start stream command.
BA.Log("Actual Scan Rate = " + formatter.format(refValue.getValue()));
BA.Log("Actual Sample Rate = " + formatter.format(2 * refValue.getValue()));
//Read data
while (System.in.available() <= 0) { //Loop will run until Enter is hit
//Since we are using wait mode LJ_swNONE, we will wait a little, then
//read however much data is available. Thus this delay will control how
//fast the program loops and how much data is read each loop. An
//alternative common method is to use wait mode LJ_swSLEEP where the
//stream read waits for a certain number of scans. In such a case
//you would not have a delay here, since the stream read will actually
//control how fast the program loops.
//
//To change this program to use sleep mode,
// -change numScans to the actual number of scans desired per read,
// -change wait mode AddRequest value to LJ_swSLEEP,
// -comment out the following Sleep command.
Thread.sleep(delayms); //Remove if using LJ_swSLEEP.
//init array so we can easily tell if it has changed
Arrays.fill(adblData, 9999.0);
//Read the data. We will request twice the number we expect, to
//make sure we get everything that is available.
//Note that the array we pass must be sized to hold enough SAMPLES, and
//the Value we pass specifies the number of SCANS to read.
refNumScansRequested.setValue(numScans);
LJUD.eGet(intHandle, LJUD.Constants.ioGET_STREAM_DATA,
LJUD.Constants.chALL_CHANNELS, refNumScansRequested, adblData);
//The displays the number of scans that were actually read.
BA.Log("\nIteration # " + i);
BA.Log("Number read = " + (long)refNumScansRequested.getValue());
//This displays just the first scan.
BA.Log("First scan = " + formatter.format(adblData[0])
+ ", " + formatter.format(adblData[1]));
//Retrieve the current Comm backlog. The UD driver retrieves stream data from
//the U6 in the background, but if the computer is too slow for some reason
//the driver might not be able to read the data as fast as the U6 is
//acquiring it, and thus there will be data left over in the U6 buffer.
LJUD.eGet(intHandle, LJUD.Constants.ioGET_CONFIG,
LJUD.Constants.chSTREAM_BACKLOG_COMM, refBacklog, 0);
BA.Log("Comm Backlog = " + refBacklog.getValue());
//Retrieve the current UD driver backlog. If this is growing,
//then the application software is not pulling data from the UD
//driver fast enough.
LJUD.eGet(intHandle, LJUD.Constants.ioGET_CONFIG,
LJUD.Constants.chSTREAM_BACKLOG_UD, refBacklog, 0);
BA.Log("UD Backlog = " + refBacklog.getValue());
i++;
}
//Stop the stream
LJUD.eGet(intHandle, LJUD.Constants.ioSTOP_STREAM, 0, dummyDouble, 0);
}
catch(LJUDException le) {
handleLJUDException(le);
}
catch (Exception e) {
e.printStackTrace();
}
}
//Displays warning message if there is one. Error values < 0 are warnings
//and do not cause a LJUDException in the LJUD class.
private void checkForWarning(int error) {
Pointer errorStringPtr = new Memory(256);
if(error < 0) {
LJUD.errorToString(error, errorStringPtr);
BA.Log("Warning: " + errorStringPtr.getString(0).trim());
}
}
private void handleLJUDException(LJUDException e) {
e.printStackTrace();
if(e.getError() > LJUD.Errors.MIN_GROUP_ERROR.getValue()) {
System.exit(-1);
}
}
[/code]
Thanks,
Walter
I recommend using a new thread for reading analog inputs in a loop so it does not block the main thread.
The Java interface does not provide Java specific callback functionality. With normal operations (non stream mode), there are no UD driver callbacks. There is a stream mode callback in the UD driver, but it is not supported in the Java interface.