2D graph, quad encoder and analog in


Recommended Posts

New to labjack and daq express.

I am building a camshaftprofile meter, encoder to cound rotation and

a linearsensor follows the camlobe. The encoder has 2048 ppr or (8192 edges?)

I have both quad encoder and analogin to work with my U3-HV on singel variable

value on my page, with timing set to 0.1S.

The speed of the rotation on the encoder is not fast, about 15 rpm.

1. I would like to use streaming on both channels, so I dont miss any edge.

But I can't get them work.

2. how can I get this into a 2d graph, enodercount on X and linearsensors length on Y.

3. Maybe a button that starts a sequence and turns the dc motor on that turns

the camshaft, encoder, and the same time draws the profile in a 2d graph.


Link to comment
Share on other sites

Lets start with 1 and 2 before you get advanced and get 3.

1) Try one of the stream samples and check the DAQFactory - LabJack application guide. I believe the sample reads two inputs, so it should work "out-of-the-box" so to speak.

2) Just put these into the X and Y expressions, then make sure the bottom axis is marked Lin and not Date/Time, turn off Use Time Width, and set your scaling (or autoscale it).

Link to comment
Share on other sites

I got the stream to work during the weekend. So now I have a graph and are plotting a nice line when turning the encoder and moving the linear sensor.

Question, I have 0 - 10V over the linearsensor and the signal is a bit jumpy(noise). Even when I do a voltage divider with resistors the signal has noise.

I have tried the average funktion but it is to slow so I get over 2 degree jump on X axis, even if I only use 2 points average or 10 points, is this a speed problem, is there any better way to take 2-3 points and make a average.

1 point is ~0,04 degree.


Link to comment
Share on other sites

Ah, the challenges of noise reduction. The easiest way to reduce the noise is actually to figure out what the source is. Is the linear sensor mechanical? If so, perhaps there is dirt in the wiper. Anyhow, if you can't figure out the source, or it can't be reduced, the easiest way to reduce it in software is to oversample. This means you acquire data faster than average it down to the desired rate.

You can also use the smooth() function, which does a running average. So if your graph had: "mychannel" as the expression, change it to, say, "smooth(mychannel,10)" The 10 is how many data points to smooth over. The bigger it is, the smoother the graph, but the less responsive the signal.

Link to comment
Share on other sites

the smooth thing works greate in my case, much better than the average in my graph.

next problem :)

The linear sensor I have is no so linear but it has good repetability. It has FS 0.25mm linear error but

has a repetability of 0,05mm.

What's a klever way to calibrate/correct that linear error on the software?


Link to comment
Share on other sites


Either use a conversion, or put the correction right in the graph expression. The formula is something like:

reading + reading / FSReading * 0.25


I don't know how you get Duration from your readings. If you just want to subtract 1.25 from your measurement, just put this in the expression. If its some other calc, again you can either use a Conversion or just put the formula in the graph Expression.

Link to comment
Share on other sites

the correction is not linear. it may evev every singel tenth of a mm be different, and I am measuring 30mm.

Is it possilbe to make any type of variable that knows when the ain0 reads 1.333 volts it must be corrected to 1,339 or if ain is 1,400 it is corrected to 1.390. a non linear correction (all this is because the linear sensors fullscal linearity is not very good.)

A correction graph with about 20 points / mm would be the best Any ide how to solve this?

The duration thing. The X axis has duration in degrees, the measured lift goes on Y axis from 0 up to 10mm and back to 0mm . say I want to measure duration @ 1.25mm, that is the lengt in X (rotation) of the encoder in degrees from that point where lift is over1.25 to the point it goes under 1.25mm when its on the way down from 10mm.

the picture link in the previous post shows a graph.

it is not the area under the curve. its the lengt of the curve in degrees X from a known Y to the same Y.


Link to comment
Share on other sites

Non linear calibrations that also don't fit into any nice function can be corrected using a lookup table. If your voltage, for example, goes from 0 to 5, you could make a lookup table of 50 values by creating a global variable with the values, then using floor(in * 10) to index into it:

global mycal = {0,0.1,0.2,0.3, etc....}

adjustedval = mycal[floor(in * 10)]

If you need more detail, make it 500 points by doing floor(in *100) instead. This would mean you would need steps of 0.01 volts instead.

Duration: wouldn't that be the total degrees at full length - the degrees at 1.25 times 2?

Link to comment
Share on other sites

I will try that floor thing...

hmm, hard to explain in english that duration thing, I'll try again:

x y

0 0

10 0.6

20 1.2

30 3

40 4

45 4.8

50 5

45 4.8

60 4

70 3

80 1.2

90 0.6

100 0

x = degree (quad encoder)

y = lift (lift linearsensor)

this example is simple, duration for 1.2mm lift is

80 degree - 20 degree = 60 degrees duration.

When I turn the camshaft by hand encoder reads

rotation (x) and the linearsensor reads the lift (y).

First up then down.

I want to count pulses from my quad encoder from where the liftcurve

exceeds 1.2mm until it comes falls back to 1.2mm. on a real camshaft

this could be anywhere between 0 and 360 degrees depending on at

what lift a want to know the duration.

Or take that X point in graph where falls under 1.2mm minus that point

where it rised over 1.2mm.

did you check that picture in the link above?


Link to comment
Share on other sites

I did check the picture, but that didn't help. However, I understand now. I thought you were trying measure peak height. You actually are measuring cross-over distance. The most flexible way is to do it after the fact. This will allow it to work in both streaming and non-streaming mode. You could also possibly do it with an event.

First, you need to record the start time of the run. Presumably you have a button to start the experiment and you can just add this line to the quick sequence action of the button:

global st = systime()

Then, you can create a sequence that scans the data. I'll call your two channels LiftChannel and DegreesChannel

// subset the channel to just get this run:
private lift = LiftChannel[st, systime()]
private degrees = DegreesChannel[st,systime()]

private sd = -1
private ed = -1
private thresh = 1.2
for (private i = 0, i < numrows(lift), i++)
   if (sd == -1)
	  if (lift[i] >= thresh)
		 sd = degrees[i]
	  if (lift[i] <= thresh)
		 ed = degrees[i]

global final = -1
if (sd == -1)
	? "start point never found"
if (ed == -1)
	? "end point never found"

final = ed - sd

Link to comment
Share on other sites

  • 4 weeks later...

Next question.

I measure velocity in a pipe with a pitot-tube (probe on analog in) , 9 points, first I move the probe to left uppercorner then center roof then rightupper corner, left middle, center, rigth middle, bottom left and so on.

I want to get the the mean value of these 9 points.

This is the function I want:

start button then this then move to left uppercorner, push a button, program stores that value and shows it on screen. I move the probe to center roof, push same button, program stores the value shows it on screen to th right of the first, then I move to right upper corner same thing here, through all 9 points. On the final push program takes the mean value of theese 9 points an shows it on screen, and does some other math, but that's simple.

Thanks for all answers so far. Got everything working so far!!


Link to comment
Share on other sites

I'd probably skip the start button and just jump to the first reading. If you agree, remove the "return" in the 4th line below.

You'll need a global variable, say, "reading". Then in the button quick sequence action put:

if (numrows(reading) == 9)
	// start button
   reading = null
reading[numrows(reading)] = datain[0]

Then just display reading in a table. To take the mean, just do mean(reading). If you only want it to appear at 9 readings, set the visibility parameter of the variable value control to: numrows(reading) == 9

Anytime you want to restart, just set reading to null ("reading = null")

Link to comment
Share on other sites


This topic is now archived and is closed to further replies.