Hi all,
I am developing a python code to scan a laser beam over a transparent material and measure the transmitted intensity using a photodetector, which sends the intensity as counts.
I am using two analog outputs to control two galvanometers (one for x-direction control and one for y-direction control of laser). I am able to successfully control the galvanometers using the analog output channels of the usb-6211, and the following code is the short description of how I am scanning the sample.
from nidaqmx import stream_writers, Task
from nidaqmx.constants import AcquisitionType
import numpy as np
taskxy = Task()
taskxy.ao_channels.add_ao_voltage_chan('Dev1/ao0:1')
scanrate = 100 # the maximum scan rate I would be using is about 250
xarr = np.linspace(-3,3,50)
yarr = np.linspace(-3,3,9)
# xarr contains array of points to scan along x-direction (fast scan direction)
# yarr contains array of points to scan along y-direction (slow scan direction)
# scanning takes place by going through all values of xarr for fixed y-position of yarr[0] (line 1)
# then again scan over all x of fixed y-position yarr[1] (line 2), and so on...
def scanxy(xarr,yarr):
t = 10 # default timeout = 10 seconds
sample = getxyarray(xarr,yarr) # this function returns the full 2xn array of points, to scan the whole X*Y area
sam_pc = np.shape(sample)[1]
total_time = sam_pc*len(sample)/scanrate
if t < total_time + 1:
t = total_time + 2 # make sure that wait_until_done() works even when scanning takes more than 10 seconds
taskxy.timing.cfg_samp_clk_timing(rate = scanrate+1, sample_mode = AcquisitionType.FINITE, samps_per_chan = sam_pc)
taskxy.timing.cfg_samp_clk_timing(rate = scanrate, sample_mode = AcquisitionType.FINITE, samps_per_chan = sam_pc)
"""Note: I need to do the above step step twice due to some hardware glitch, which results in wait_until_done() function useless if the function is called second time with the same scan parameters. So here, I change the scanrate to scanrate+1, and then again change it back to scanrate, so that the system thinks that I have changed the scan parameters. With this hack, I am able to run the function any number of times with or without changing the scan parameters"""
writer = stream_writers.AnalogMultiChannelWriter(taskxy.out_stream,auto_start=False)
writer.write_many_sample(sample,timeout=t)
taskxy.start()
taskxy.wait_until_done(timeout = t)
taskxy.stop()
Now, I need to configure the counter input, to collect the intensity of the transmitted beam over each position of the material. I just started reading about using counters, and currently, I am only able to collect the counts from the photodetector as on-demand edge-counting.
However, I need to synchronize the scanning of the laser with collection of the intensity from each point on the material.
After reading many topics in this forum, I realize that I need to use a buffered counting method. I think the best approach would be to collect the intensities of all points in one line and then collect the intensities from next line, and so on..
However, I am not sure how to synchronize the analog output and the counter input.
The whole deal about sample clock, gate, etc. is making me very confused. I my current code, the analog output is using internal timing, but I read that I cannot use the same internal timer for the counter input. Is this correct? If this is true, then I need to use an external sample clock for analog output and also use the same sample clock for the counter as well. But I am not sure how to do this. Can anyone please guide me how to do it correctly?
Thanks in advance!
Badari