Jump to content


Photo

Reading Quadrature encoder and analogoes input simultaneously


  • Please log in to reply
12 replies to this topic

#1 anon82

anon82
  • Members
  • 11 posts

Posted 14 February 2013 - 07:47 AM

Hello I've been searching the LabJack U3 documentation, but there's one thing I don't find/understand. I would like to read quadrature encoder inputs and after a certain amount of ticks have arrived I would then read the input from AIN0. What I'm concerned is the delay in reading. If I build a code which polls the ticks from the quadrature input continuously and then reads the value of AIN0 input, the reading interval will change depending on processor load in PC. So ticks may not be in synchronize to AIN0. So what would be the best method to read the inputs "simultaneously"? Can I use some method to read AIN0 internally in Labjack each time when encoder gives a pulse and store the AIN0 values to some register? Then I would just need to read the register values with my code, which is not as time critical as sensor reading.

#2 LabJack Support

LabJack Support
  • Admin
  • 8449 posts

Posted 14 February 2013 - 01:01 PM

There is no way in hardware to trigger an AIN reading based on the quadrature timer value. What you can do is have hardware acquire quadrature and analog readings at the same time: Command/Response: If you use an Add/Go/Get block to combine an AIN read and timer value read, the will happen in the same low-level packet and thus at virtually the same time. Stream: If you are using AIN0 and Timer0/Timer1, then do a stream with 3 channels: 0, 200, and 224. This is the fastest method, so you will get lots of AIN/Timer pairs that happen at about the same time.

#3 anon82

anon82
  • Members
  • 11 posts

Posted 19 February 2013 - 08:54 AM

There is no way in hardware to trigger an AIN reading based on the quadrature timer value. What you can do is have hardware acquire quadrature and analog readings at the same time:

Command/Response: If you use an Add/Go/Get block to combine an AIN read and timer value read, the will happen in the same low-level packet and thus at virtually the same time.

Stream: If you are using AIN0 and Timer0/Timer1, then do a stream with 3 channels: 0, 200, and 224. This is the fastest method, so you will get lots of AIN/Timer pairs that happen at about the same time.


Thank you for quick response.

I think the Stream mode is the best method for this.

I'm not just exactly sure, do I need to do any other configurations than these:

# Device U3.__init__(debug = False, autoOpen = True, **openArgs)	  
			d = u3.U3(debug = True)

			# Read System information
			# {'SerialNumber': 320032102, ... , 'FirmwareVersion': '1.26'}
			d.configU3()
			
			print "Configure Timers for Quadratic Encoder and FIO2 to Analog"
			d.configIO(NumberOfTimersEnabled = 2, TimerCounterPinOffset = 0, 
					   FIOAnalog = 0x02 )
			
			#d.getFeedback(u3.Timer0Config(8), u3.Timer1Config(8))
			
			print "configuring U3 stream, Channels 0=AIN0, 200=Timer0 LSW, 224=MSW, \
				NegChannel 30=vref"
			d.streamConfig( NumChannels = 3, PChannels = [ 0, 200, 224 ], 
				NChannels = [ 30 ], Resolution = 0, SampleFrequency = 1000 )

			srd = StreamReader(d, samples)

Do I need to call any other functions to configure stream + channels?

d.getFeedback uses Timer0/1 to Quadrature mode attributes, but does getFeedback actually
configure anything, just reads the values?

Any comments are welcome, thanks.

#4 LabJack Support

LabJack Support
  • Admin
  • 8449 posts

Posted 19 February 2013 - 06:04 PM

This is in regards to the LabJackPython interface and streaming analog inputs and timers.

Before streaming you first need to configure which FIO/EIO lines will be analog (FIO/EIOAnalog), enable your timers (NumberOfTimersEnabled) and set the pin offset (TimerCounterPinOffset) the timers will start on. On a U3 the pin offset starts at 4 (FIO4), so consider a configIO call like:
# Enabling 2 timers starting at pin offset 4.  FIO0-3 will be analog (AIN0-3), FIO4-7 are digital.
d.configIO(NumberOfTimersEnabled = 2, TimerCounterPinOffset = 4, FIOAnalog = 0x0F )
After that use getFeedback to configure the two timers as quadrature inputs:
# Set both timer modes to quad. input in one call
d.getFeedback([u3.TimerConfig(timer = 0, TimerMode = 8, Value = 0), u3.TimerConfig(timer = 1, TimerMode = 8, Value = 0)])
So the timers should be running on FIO4 and FIO5 now and ready to stream. You are close on how to configure the stream. For every PChannel you need a NChannel as well:
d.streamConfig( NumChannels = 3, PChannels = [ 0, 200, 224 ], NChannels = [ 30, 30, 30 ], Resolution = 0, ScanFrequency = 1000 )
The streamTest.py example in the LabJackPython download should help with starting and reading data from the stream. If you intended on reading AIN2/FIO2 for your analog input change the first PChannels element to 2. Note that the stream samples are 16-bit, and the values for channels 200 and 224 are the LSW and MSW of the 32-bit timer value. Also, for quadrature inputs the 32-bit value is signed. Here is some documentation on streaming timers:

http://labjack.com/s...ers-guide/3.2.1

#5 anon82

anon82
  • Members
  • 11 posts

Posted 20 February 2013 - 02:33 PM

This is in regards to the LabJackPython interface and streaming analog inputs and timers.

Before streaming you first need to configure which FIO/EIO lines will be analog (FIO/EIOAnalog), enable your timers (NumberOfTimersEnabled) and set the pin offset (TimerCounterPinOffset) the timers will start on. On a U3 the pin offset starts at 4 (FIO4), so consider a configIO call like:

# Enabling 2 timers starting at pin offset 4.  FIO0-3 will be analog (AIN0-3), FIO4-7 are digital.
d.configIO(NumberOfTimersEnabled = 2, TimerCounterPinOffset = 4, FIOAnalog = 0x0F )
After that use getFeedback to configure the two timers as quadrature inputs:
# Set both timer modes to quad. input in one call
d.getFeedback([u3.TimerConfig(timer = 0, TimerMode = 8, Value = 0), u3.TimerConfig(timer = 1, TimerMode = 8, Value = 0)])
So the timers should be running on FIO4 and FIO5 now and ready to stream. You are close on how to configure the stream. For every PChannel you need a NChannel as well:
d.streamConfig( NumChannels = 3, PChannels = [ 0, 200, 224 ], NChannels = [ 30, 30, 30 ], Resolution = 0, ScanFrequency = 1000 )
The streamTest.py example in the LabJackPython download should help with starting and reading data from the stream. If you intended on reading AIN2/FIO2 for your analog input change the first PChannels element to 2. Note that the stream samples are 16-bit, and the values for channels 200 and 224 are the LSW and MSW of the 32-bit timer value. Also, for quadrature inputs the 32-bit value is signed. Here is some documentation on streaming timers:

http://labjack.com/s...ers-guide/3.2.1


Thank you very much. This clarified the configuration steps. Yep, and the AIN0 is the one to use == 0.
I don't have a labjack myself, I'm building the software for another guy, so I'm not able to test the functionality at every stage. But with this help, I'm sure I get quite much working code for first test setup.

I have one question still. Here we deteminer scanFrequency, which means that I get one sample set containing samples from linear sensor in AIN0 + quadratic encoder in FIO4-5 each millisecond? And Labjack has buffer which holds a little bit under 1000 samples, so I should call streamData().next(), e.g. each 500millisecods, to not to lose any samples, if I'm able to read the buffer empty at once? Or should I consider doing multiple reads with smaller packet sizes?

Thank you very much for your great support :)

#6 LabJack Support

LabJack Support
  • Admin
  • 8449 posts

Posted 20 February 2013 - 04:18 PM

Yes, if scan frequency is set to 1000 then a sample set (scan) read is performed every 1 millisecond and buffered on the U3. Ideally you will want to do stream reads as fast as you can to ensure the U3's stream buffer doesn't overflow. Reading every 500 ms will be too slow since the sample rate is 3000 samples/sec at a scan frequency of 1000 Hz with 3 channels. If you want a delay between reads you should keep it under 200 ms. The lower the delay the better. streamData() looks like it will read enough packets to clear out the U3 buffer.

#7 anon82

anon82
  • Members
  • 11 posts

Posted 27 February 2013 - 12:16 AM

Thank you. I didn't thought that it's giving 1000x3 samples. Thanks for the clarification

#8 anon82

anon82
  • Members
  • 11 posts

Posted 28 February 2013 - 12:12 PM

Hi, I'm still getting some errors, but I don't understand what could be causing these? File "D:\CamAnalyzer\LabJack.py", line 112, in read print d.processStreamData(result['result']) File "D:\Python27\lib\site-packages\u3.py", line 1097, in processStreamData value = self.binaryToCalibratedAnalogVoltage(value, isLowVoltage = lvChannel , isSingleEnded = singleEnded, channelNumber = self.streamChannelNumbers[self.st reamPacketOffset], isSpecialSetting = isSpecial) File "D:\Python27\lib\site-packages\u3.py", line 1591, in binaryToCalibratedAn alogVoltage #raise Exception, "Can't do differential on high voltage channels" Stream stopped.Exception : Can't do differential on high voltage channels Check attached log and codes for more details.

Attached Files



#9 LabJack Support

LabJack Support
  • Admin
  • 8449 posts

Posted 28 February 2013 - 01:55 PM

Oops. I was going off the negative channel you passed in your original code. The negative channels during stream config should be "NChannels = [ 31, 31, 31 ]" for a single ended readings. Here's a list of positive and negative channels:

http://labjack.com/s...ers-guide/2.6.1

#10 anon82

anon82
  • Members
  • 11 posts

Posted 07 March 2013 - 10:32 AM

Thanks. Now this is working quite nicely in overall. I just have one question/problem. Why I don't get equal amount of samples from each channel every time. For example, this is something I've got: DEBUG:ProcessedData: defaultdict(<type 'list'>, {'AIN200': [0], 'AIN0': [3.370303999999999, 3.370303999999999], 'AIN224': [0, 0]}) AIN200 had only one sample, while AIN0 and 224 had two. If I assume, that I always have equal amount of each sample, then the calculations go out of the sync. What could make this happen?

#11 LabJack Support

LabJack Support
  • Admin
  • 8449 posts

Posted 07 March 2013 - 02:06 PM

This can happen depending on the combination of NumChannels and SamplesPerPacket settings. When SamplesPerPackets is not a multiple of NumChannels this occurs. Basically a full scan of samples could not be read in a streamData call. The following stream data call will contain the rest of the scan samples. You're not missing data, but do not depend on the U3.processData results being synchronized. You'll want to keep track of all processed data to keep data synchronized. For example if your first read stream data is:

{'AIN0': [1.21, 1.22], 'AIN200': [1], 'AIN224': [2]} #one scan and part of the second scan

and the following is:

{'AIN0': [1.23], 'AIN200': [3, 5], 'AIN224': [4]} #rest of second scan and part of third scan

your overall, synchronized data so far is:

{'AIN0': [1.21, 1.22, 1.23], 'AIN200': [1, 3, 5], 'AIN224': [2, 4]} #read overall 2 scans and 2 samples of third scan

Note by default SamplesPerPacket is 25 and multiple StreamData packets are read per U3.streamData call for data transfer efficiency. For simplicity, the above example is doing streamData reads with SamplesPerPacket = 4, one stream packet and NumChannels = 3.

#12 anon82

anon82
  • Members
  • 11 posts

Posted 11 March 2013 - 04:16 AM

Thank you. So in general, packets are only in sync when first packets are read. After that I can't be sure anymore which packet belongs to which streaming round. I should use e.g. some packet counters to be able to know the streaming state.

#13 LabJack Support

LabJack Support
  • Admin
  • 8449 posts

Posted 11 March 2013 - 11:10 AM

Mostly. Some packets might have the scans aligned again, but yes you should keep track with your own counter on each individual channel. So there is no confusion, scan data is in order in the StreamData packets. So in my previous example's reads, the StreamData packets came in this channel order where AIN0 begins the start of a new scan set: [AIN0, AIN200, AIN224, AIN0] [AIN200, AIN224, AIN0, AIN200] This data is passed to processData where it converts the binary data to a voltage and groups it into lists for the individual channels, as seen in my previous post.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users