LWDAQ Toolmaker Library

© 2004-2021 Kevan Hashemi, Brandeis University
© 2006-2025 Kevan Hashemi, Open Source Instruments Inc.

match-prompts-only section-chunk

Contents

Toolmaker Script Library
Gray-Scale Image TestByte Location TestAcquisition Averaging
Effect of Exposure TimeByte Write Execution TimeRAM Access Speed Test
Image Pixel Digitizer TestSimulated BCAM ReadoutRelay Buffer Stress Test
Random Location RAM TestSimplex Fitting DemonstrationImage Position
TCPIP Communication TemplateDevice Command TransmitterTest All Instruments
Database Package DemonstrationCircular Survey Target

Toolmaker Script Library

Gray-Scale Image Test

Gray-Scale Image Test, a LWDAQ Toolmaker Script. Writes a gray-scale image to a LWDAQ Controller RAM, reads it back, and displays the image within the Toolmaker execution window. Write a gray-scale image to LWDAQ controller's RAM, read it back, and display. The execution window for the script provides Acquire and Stop button. The offset entry allows us to specify the start address in controller RAM at which we should write the image. If we uncheck the Write flag, the routine reads the image repeatedly, but does not re-write it. Demonstrates how to draw a LWDAQ image in a label widget.

# Begin Toolmaker Script

frame $f.f
pack $f.f -side top
button $f.f.a -text Acquire -command "acquire $t"
button $f.f.s -text Stop -command "set stop 1"
label $f.f.ol -text Offset:
entry $f.f.oe -textvariable offset
label $f.f.ba -text BaseAddr:
entry $f.f.bae -textvariable base_addr
pack $f.f.a $f.f.s $f.f.ol $f.f.oe $f.f.ba $f.f.bae -side left
checkbutton $f.f.write -text "Write" -variable write
pack $f.f.write -side left
catch {image create photo data_photo}
label $f.il -image data_photo
pack $f.il -side top

set width 1000
set offset 0
set stop 0
set write 1
set base_addr 00800000
set value gray

proc acquire {t} {
	global stop offset width write base_addr value
	if {$stop || ![winfo exists $t]} {
		set stop 0
		return
	}
	
	set addr 10.0.0.37:90
	set sock [LWDAQ_socket_open $addr]
	LWDAQ_set_driver_mux $sock $base_addr:1 1

	if {$write} {
		LWDAQ_print $t "Creating image $width x $width..."
	  	LWDAQ_update
	  	for {set j 0} {$j < $width} {incr j} {
			LWDAQ_ram_delete $sock [expr $j*$width + $offset] \
				$width [expr round(256.0*$j/$width-0.5)]
		}
		LWDAQ_wait_for_driver $sock
	}

	LWDAQ_print $t "Downloading image..."
	LWDAQ_update
	set ta [clock microseconds]
	set data [LWDAQ_ram_read $sock $offset [expr $width*$width]]
	set tb [clock microseconds]
	LWDAQ_print $t "Downloaded at\
		[format %.2f [expr $width*$width*1.0/($tb-$ta)*1000]] kBytes/s."

	LWDAQ_socket_close $sock

	LWDAQ_print $t "Displaying image..."
	LWDAQ_update
	lwdaq_image_create -name data_image \
		-width $width -height $width -data $data
	lwdaq_draw data_image data_photo -zoom 0.5 -intensify none
	
	LWDAQ_print $t "Done."
	
	LWDAQ_post [list acquire $t]
}

# End Toolmaker Script

Byte Location Test

Byte Tester, a LWDAQ Toolmaker Script. Read from and write to locations in a LWDAQ Driver's control and data spaces. Allows us to read and write lists of bytes from and to the control and data spaces of a LWDAQ controller. Demonstrates the construction of a graphical user interface within the LWDAQ Toolmaker.

# Begin Toolmaker Script

proc Byte_Test_init {} {
	upvar #0 Byte_Test_config config
	global f t
	
	set config(t) $t
	set config(f) $f
	set config(control) "Idle"
	set config(ip) "10.0.0.37"
	set config(base) "00000000"
	set config(cont_value) "FF"
	set config(cont_addr) "0"
	set config(data_values) "0 1 2 3 4 5"
	set config(data_addr) "0"
	set config(data_portal) "63"
	set config(data_length) "6"
	set config(repeat) "0"
	set config(reps) "100"
}

proc Byte_Test_open {} {
	upvar #0 Byte_Test_config config

	set ff [frame $config(f).configure]
	pack $ff -side top -fill x

	label $ff.control -textvariable Byte_Test_config(control) -fg blue -width 10
	pack $ff.control -side left -expand yes

	label $ff.lip -text "ip:"
	entry $ff.eip -textvariable Byte_Test_config(ip) -width 15
	pack $ff.lip $ff.eip -side left -expand yes

	label $ff.lbase -text "base:"
	entry $ff.ebase -textvariable Byte_Test_config(base) -width 8
	pack $ff.lbase $ff.ebase -side left -expand yes
	
	checkbutton $ff.repeat -variable Byte_Test_config(repeat) -text "Repeat"
	pack $ff.repeat -side left -expand yes
	
	label $ff.lreps -text "reps:"
	entry $ff.ereps -textvariable Byte_Test_config(reps) -width 4
	pack $ff.lreps $ff.ereps -side left -expand yes

	set ff [frame $config(f).cspace]
	pack $ff -side top -fill x

	label $ff.title -text "Control Space:" -fg green
	pack $ff.title -side left -expand yes

	label $ff.lwa -text "address (dec)"
	entry $ff.ewa -textvariable Byte_Test_config(cont_addr) -width 3
	pack $ff.lwa $ff.ewa -side left -expand yes

	label $ff.lwv -text "value (dec)" 
	entry $ff.ewv -textvariable Byte_Test_config(cont_value) -width 3
	pack $ff.lwv $ff.ewv -side left -expand yes

	button $ff.read -text "Read" -command {Byte_Test cont_read}
	button $ff.write -text "Write" -command {Byte_Test cont_write}
	pack $ff.read $ff.write -side left -expand yes

	set ff [frame $config(f).dspace]
	pack $ff -side top -fill x

	label $ff.title -text "Data Space:" -fg green
	pack $ff.title -side left -expand yes

	label $ff.lwa -text "address (dec)"
	entry $ff.ewa -textvariable Byte_Test_config(data_addr) -width 10
	pack $ff.lwa $ff.ewa -side left -expand yes

	label $ff.lrl -text "length (dec)"
	entry $ff.erl -textvariable Byte_Test_config(data_length) -width 4
	pack $ff.lrl $ff.erl -side left -expand yes

	button $ff.read -text "Read" -command {Byte_Test data_read}
	button $ff.write -text "Write" -command {Byte_Test data_write}
	pack $ff.read $ff.write -side left -expand yes
	
	set ff [frame $config(f).vlist]
	pack $ff -side top -fill x

	label $ff.lwv -text "values (dec)" 
	entry $ff.ewv -textvariable Byte_Test_config(data_values) -width 80
	pack $ff.lwv $ff.ewv -side left -expand yes
	
	return ""
}

proc Byte_Test {action} {
	upvar #0 Byte_Test_config config

	set config(control) $action
	if {[catch {
		set sock [LWDAQ_socket_open $config(ip)]
		LWDAQ_set_base_addr_hex $sock $config(base)
		if {$action == "cont_write"} {
			LWDAQ_print -nonewline $config(t) \
				"Write to control address $config(cont_addr) "
			for {set i 0} {$i < $config(reps)} {incr i} {
				LWDAQ_byte_write $sock $config(cont_addr) $config(cont_value)
			}
			set id [LWDAQ_hardware_id $sock]
			LWDAQ_print $config(t) "done."
		} elseif {$action == "cont_read"}  {
			LWDAQ_print -nonewline $config(t) \
				"Read from control address $config(cont_addr) "
			for {set i 0} {$i < $config(reps)} {incr i} {
				set value [LWDAQ_byte_read $sock $config(cont_addr)]
			}
			set config(cont_value) [expr 0xFF & $value]
			LWDAQ_print $config(t) "value $config(cont_value)\
				= 0x[format %02X $value]."
		} elseif {$action == "data_write"}  {
			LWDAQ_print -nonewline $config(t) \
				"Stream write to data address $config(data_addr) "
			set config(data_length) [llength $config(data_values)]
			set data [binary format c* $config(data_values)]
			for {set i 0} {$i < $config(reps)} {incr i} {
				LWDAQ_set_data_addr $sock $config(data_addr)
				LWDAQ_stream_write $sock $config(data_portal) $data
			}
			set id [LWDAQ_hardware_id $sock]
			LWDAQ_print $config(t) "done."
		} elseif {$action == "data_read"}  {
			LWDAQ_print -nonewline $config(t) \
				"Stream read from data address $config(data_addr) "
			for {set i 0} {$i < $config(reps)} {incr i} {
				LWDAQ_set_data_addr $sock $config(data_addr)
				set data [LWDAQ_stream_read $sock \
					$config(data_portal) $config(data_length)]
			}
			binary scan $data c* signed_values
			set config(data_values) [list]
			foreach value $signed_values {
				lappend config(data_values) [expr 0xFF & $value]
			}
			LWDAQ_print $config(t) "done."
		} else {
			error "Unrecognised action \"$action\"."
		}
		LWDAQ_socket_close $sock
	} error_message]} {
		catch {LWDAQ_socket_close $sock}
		LWDAQ_print $config(t) 
		LWDAQ_print $config(t) "ERROR: $error_message"
	}
	if {$config(repeat)} {
		LWDAQ_post [list Byte_Test $action]
	} else {
		set config(control) "Idle"
	}
	return ""
}

Byte_Test_init 
Byte_Test_open

# End Toolmaker Script

Acquisition Averaging

Acquisition Averaging, a LWDAQ Toolmaker Script. Acquires multiple times from the BCAM Instrument and reports the average spot positions. Illustrates creation of a procedure that acquires from an instrument and is called by a button press. Creates a button that initiates the capture of multiple images from the BCAM Instrument. The routine assumes the BCAM Instrument is configured to obtain an image in which two light sources are visible. We configure the BCAM to look for two spots and to sort them in order of increasing x-coordinate. This sorting is effective when the two spots are separated horizontally in the image. The routine analyzes each image to obtain the x and y position of both spots. The number of images it captures is set by a parameter in an entry box in the Toolmaker execution window. Once it has captured the requested number of images, the routine calculates the average x and y positions and prints them to the Toolmaker execution window. The script illustrates the use of "upvar" commands to refer to the instrument configuration and information arrays within a Tcl procedure. Within the procedure we refer to the config and info arrays as config and info. We also see global declarations for the Toolmaker text window variable, "t", and a the number of images variable. The script illustrates how to create buttons and entry boxes in a Toolmaker script so that they appear in the execution window. We see the button posting the acquisition command to the LWDAQ event queue. We see colored printing into the text widget with the LWDAQ_print routine.

# Begin Toolmaker Script

# Create a button and entry box in the Toolmaker execution window. These widgets
# will go in the Toolmaker execution window's widget frame, which has global
# name "f". The button itself, when pressed, does not immediatly initiate
# acquisition, but instead posts the request for the averaging acquisition to
# the LWDAQ event queue. Posting to the queue stops the button press from
# interrupting and breaking a data acquisition that is already in progress.
button $f.button -text "BCAM_Average" -command "LWDAQ_post BCAM_Average"
pack $f.button -side left
label $f.nil -text "Number:" 
entry $f.nie -textvariable num_images 
pack $f.nil $f.nie -side left
set num_images 10

# This is the averaging procedure that gets called by the button press.
proc BCAM_Average {} {

	# We must declare global variables. Here we illustrate how a routine like
	# this, which acquires from an instrument, should declare the existence
	# of the global BCAM info and config arrays: using upvar commands. These
	# arrays will then be available with shorter names in the script.
	upvar #0 LWDAQ_info_BCAM info
	upvar #0 LWDAQ_config_BCAM config
	global num_images
	global t
	
    # Check the number of images requested and save locally.
    set num_images $num_images
    if {$num_images <= 0} {
    	LWDAQ_print $t "ERROR: Cannot capture and analyze \"$num_images\" images."
    	return ""
    }

	# Initialize the position variables.
    set sum_x1 0
    set sum_y1 0
    set sum_x2 0
    set sum_y2 0
    
	# Configure the BCAM Instrument.
	set config(num_spots) "2"
	set config(sort_code) "2"
    
	# Capture and analyze the requested number of images.
    for {set i 0} {$i < $num_images} {incr i} {
    
        # Acquire an image using the BCAM Instrument
        set result [LWDAQ_acquire BCAM]

        # Parse the result to get x and y positions of the two spots. Here we
        # are using the lassign command to assign the elements of the result
        # list to the x1, y1, x2, and y2 variables. We use underscores as dummy
        # variable names to skip over the elements of the BCAM result string
        # that we don't need.
        lassign $result _ x1 y1 _ _ _ _ x2 y2 _ _ _ _

        # Accumulate the x and y positions
        set sum_x1 [expr $sum_x1 + $x1]
        set sum_y1 [expr $sum_y1 + $y1]
        set sum_x2 [expr $sum_x2 + $x2]
        set sum_y2 [expr $sum_y2 + $y2]
    }

    # Calculate the average x and y positions for each spot
    set avg_x1 [format %.2f [expr $sum_x1 / $num_images]]
    set avg_y1 [format %.2f [expr $sum_y1 / $num_images]]
    set avg_x2 [format %.2f [expr $sum_x2 / $num_images]]
    set avg_y2 [format %.2f [expr $sum_y2 / $num_images]]

    # Print the average positions in the Toolmaker text window
    LWDAQ_print $t "$avg_x1 $avg_y1 $avg_x2 $avg_y2" purple
    
    # Return an empty string.
    return ""
}

# End Toolmaker Script

Effect of Exposure Time

Effect of Exposure Time, A LWDAQ Toolmaker Script. Studies the effect of exposure time upon the measurement we obtain from a metrology instrument. Acquires from the WPS Instrument for a range of exposure times and reports results to Toolmaker execution window. Acquires from the WPS Instrument and obtains measurements for a range of exposure times (values of daq_flash_seconds). The exposure time, the position of the wire, and the rotation of the wire are printed to the script output window during execution. You can watch the WPS activity by opening the WPS Instrument. When the script is done, you can copy the results from the output window and into a spreadsheet.

# Begin Toolmaker Script

for {set x 0.01} {$x <= 0.3} {set x [expr $x * 1.1]} {
	set LWDAQ_config_WPS(daq_flash_seconds) $x
	LWDAQ_print $t \
	"[format {%.3f} $x] \
	 [lrange [LWDAQ_acquire WPS] 1 2]"
}

# End Toolmaker Script

Byte Write Execution Time

Byte Write Execution Time, A LWDAQ Toolmaker Script. Connects to a LWDAQ Driver and measures how long the driver takes execute a byte write instruction. A LWDAQ Toolmaker Script that measures byte_write instruction execution time.

# Begin Toolmaker Script

while {[winfo exists $f]} {
set sock [LWDAQ_socket_open 10.0.0.37]
set ta [clock microseconds]
for {set j 0} {$j < 100} {incr j} {
  for {set i 0} {$i < 1000} {incr i} {
    LWDAQ_byte_write $sock 0 $j
  }
  LWDAQ_wait_for_driver $sock
}
set tb [clock microseconds]
LWDAQ_socket_close $sock
LWDAQ_print $t [expr ($tb-$ta)/100000]
LWDAQ_update
}

# End Toolmaker Script

RAM Access Speed Test

Delete and Write Execution Time, a LWDAQ Toolmaker Script. Connects to a LWDAQ Driver and measures how long the driver takes two write a block of data to memory and how long it takes to read a block of data from memory. Provides buttons and entry boxes. Measures the ram delete speed, and ram read and TCPIP transfer speed combined by instructing the relay to perform multiple ram delete instructions, and after that to read one block of readsize bytes from the relay ram. The script makes a button that you press to start the test. The IP address is hard-wired in the code.

# Begin Toolmaker Script

global p
set p(t) $t
set p(delsize) 1000
set p(numdels) 100
set p(readsize) 1000000
set p(daq_ip_addr) "10.0.0.37"

button $f.do -text Do -command "do"
pack $f.do -side left
foreach a {numdels delsize readsize} {
	label $f.l$a -text $a
	entry $f.e$a -textvariable p($a)
	pack $f.l$a $f.e$a -side left
}

proc do {} {
	global p
	set sock [LWDAQ_socket_open $p(daq_ip_addr):90]
	LWDAQ_print $p(t) "Software Version [LWDAQ_software_version $sock]"
	LWDAQ_print $p(t) "numdels = $p(numdels),\
		delsize = $p(delsize), readsize = $p(readsize)"
	LWDAQ_print $p(t) "START ram_delete"
	set ta [clock microseconds]
	for {set j 0} {$j < $p(numdels)} {incr j} {
		LWDAQ_ram_delete $sock 0 $p(delsize) 0
		if {[expr fmod($j,100)] == 0} {LWDAQ_wait_for_driver $sock}
	}
	LWDAQ_wait_for_driver $sock
	set tb [clock microseconds]
	LWDAQ_print $p(t) "DONE in [format %.2f [expr ($tb - $ta)/1000.0]] ms,\
		[format %.2f [expr 0.001*($tb-$ta)/$p(numdels)]] ms/delete,\
		[format %.2f [expr 1.0*($tb-$ta)/$p(numdels)/$p(delsize)]] us/byte"
	LWDAQ_print $p(t) "START LWDAQ_ram_read"
	LWDAQ_update
	set ta [clock microseconds]
	set data [LWDAQ_ram_read $sock 0 $p(readsize)]
	set tb [clock microseconds]
	LWDAQ_print $p(t) "DONE in [format %.2f [expr ($tb - $ta)/1000.0]] ms,\
		[format %.2f [expr $p(readsize)*1.0/($tb-$ta)*1000]] kBytes/s."
	LWDAQ_socket_close $sock
}

# End Toolmaker Script

Image Pixel Digitizer Test

Image Pixel Digitizer Test, a LWDAQ Toolmaker Script. Tests the fast eight-bit ADC on a LWDAQ Driver, which is the ADC we use to digitize image pixels. Tests the fast adc8 job on the LWDAQ driver. First we use the fast adc job to get some data. We must feed the signal into socket 1 on the driver if we are to see anything but a flat line with a glitch at the start.

# Begin Toolmaker Script

set sock [LWDAQ_socket_open 10.0.0.37:90]
LWDAQ_set_driver_mux $sock 1 15
LWDAQ_byte_write $sock $LWDAQ_Driver(clen_addr) 0
LWDAQ_set_data_addr $sock 0
LWDAQ_set_delay_seconds $sock 0.1
LWDAQ_execute_job $sock $LWDAQ_Driver(fast_adc_job)
LWDAQ_byte_write $sock $LWDAQ_Driver(clen_addr) 1
set data [LWDAQ_ram_read $sock 0 1000]
LWDAQ_socket_close $sock

# Determine the amplitude and average value.
LWDAQ_print $t "Read [string length $data] samples."
binary scan $data c* values
set data ""
foreach v $values {
	if {$v<0} {set v [expr 256 + $v]}
	append data "$v "
}
LWDAQ_print $t [lwdaq ave_stdev $data]

# Split the binary array into a sequence of x-y values
# we can plot.
set plot_points ""
set x 0
foreach v $data {
	append plot_points "$x $v "
	incr x
}

# Create graphical widgets to display the plot.
lwdaq_image_create -width 1000 -height 200 -name plot_image
image create photo plot_photo
label $f.plot -image plot_photo 
pack $f.plot -side top

# Plot the points in an image and draw the image on the screen.
lwdaq_graph $plot_points plot_image -fill 1 -y_max 255 -y_min 0
lwdaq_draw plot_image plot_photo

# End Toolmaker Script

Simulated BCAM Readout

Simulated BCAM Readout, a LWDAQ Toolmaker Script. Writes a simulated BCAM image to LWDAQ Driver RAM and reads the image back multiple times to check that the spot is in the same location. Uses the BCAM Instrument to analyze the image. Writes a simulated BCAM image to the memory on a LWDAQ driver. Read it back out again multiple times and check where the simulated spot is in the returned image. This code looks for write and read-back errors.

# Begin Toolmaker Script

set dim 256
set stop 0
set addr 10.0.0.37
set base 00E00000

button $f.a -text Acquire -command "acquire $dim $addr $base none $t"
pack $f.a -side left
button $f.s -text Stop -command "set stop 1"
pack $f.s -side left
button $f.r -text Refresh -command [list LWDAQ_post [list setup $dim $addr $base]]
pack $f.r -side left

proc setup {dim addr base} {
	set sock [LWDAQ_socket_open $addr]
	LWDAQ_set_base_addr_hex $sock $base
	LWDAQ_ram_delete $sock 0 [expr $dim * $dim] 0
	LWDAQ_ram_delete $sock [expr round(($dim+1)*$dim/2)] 1 255
	LWDAQ_wait_for_driver $sock
	LWDAQ_socket_close $sock
}

proc acquire {dim addr base last t} {
	global stop
	if {$stop} {
		set stop 0
		return
	}
	set sock [LWDAQ_socket_open $addr]
	LWDAQ_set_base_addr_hex $sock $base
	set data [LWDAQ_ram_read $sock 0 [expr $dim * $dim]]
	LWDAQ_socket_close $sock
	set image_name [lwdaq_image_create -data $data -name Camera_Test]
	upvar LWDAQ_config_BCAM config
	set config(image_source) memory
	set config(memory_name) $image_name
	set config(intensify) none
	set config(zoom) 1
	set config(daq_image_width) $dim
	set config(daq_image_height) $dim
	set result [LWDAQ_acquire BCAM]
	if {$last != $result} {
		LWDAQ_print $t $result
	}
	LWDAQ_post [list acquire $dim $addr $base $result $t]
}

setup $dim $addr $base

# End Toolmaker Script

Relay Buffer Stress Test

Relay Buffer Stress Test, a LWDAQ Toolmaker Script. Opens a socket to a LWDAQ Relay and writes a long message to test its resistance to input buffer overflow. Tests a LWDAQ Relay for resistance to a message that is longer than its incoming message buffer. When the buffer overflows, the driver must close the socket and return to its rest state.

# Begin Toolmaker Script

# Create buttons to test relay and close the opened socket if it remains
# open. Create entry box for IP address of the LWDAQ Relay.
button $f.test -text "Test Relay" -command "test_relay"
button $f.close -text "Close Socket" -command {LWDAQ_socket_close $sock}
entry $f.ip -textvariable ip
pack $f.test $f.close $f.ip -side left -expand yes

# Initialize global variables.
set ip "10.0.0.37"
set sock ""

# Procedure that tries to overflow the relay's input buffer and cause a problem.
proc test_relay {} {
	global ip sock t

	if {[catch {
		LWDAQ_print $t "Opening socket to $ip\..."
		set sock [LWDAQ_socket_open "$ip\:90"]
		set s ""
		for {set i 1} {$i < 2000} {incr i} {append s "A"}
		LWDAQ_print $t "Sending message with $i bytes in content\..."
		LWDAQ_transmit_message $sock 0 $s
		LWDAQ_print $t "Waiting for driver to respond\..."
		LWDAQ_wait_for_driver $sock
		LWDAQ_print $t "Closing socket\..."
		LWDAQ_socket_close $sock
	} error_message]} {
		if {[regexp {reset by peer} $error_message]} {
			LWDAQ_print $t "Connection closed and reset by peer."
		} else {
			LWDAQ_print $t $error_message
		}
	}
}

# End Toolmaker Script

Random Location RAM Test

Random Memory Location Test, a LWDAQ Toolmaker Script. Tests a LWDAQ Driver's RAM by writing bytes to random locations and reading them back. Tests a LWDAQ Driver's RAM by writing bytes to random locations in the data space and reading them back. To write to each location, we set the data address, write a byte to the RAM portal, set the data address again (because it will have been incremented by the write to the portal) and read back the byte. We compare the byte we wrote to the one we read back. Demonstrates the use of a global stop flag to break out of a loop. We set the stop flag with a button.

# Begin Toolmaker Script

button $f.a -text Acquire -command "acquire"
button $f.s -text Stop -command "set stop 1"
entry $f.ip -textvariable ip
pack $f.a $f.s $f.ip -side left -expand yes

set stop 0
set ip "10.0.0.37"

proc acquire {} {
	global stop ip t
	if {$stop || ![winfo exists $t]} {
		set stop 0
		return
	}
	
	set max_addr 8000000
	set num 100
	
	LWDAQ_print $t "Testing $num locations..."
	LWDAQ_update
	set count 0
	set sock [LWDAQ_socket_open $ip\:90]
	for {set j 0} {$j < $num} {incr j} {
		set addr [expr round(rand()*$max_addr)]
		set value [expr round(rand()*255)]
		LWDAQ_set_data_addr $sock $addr
		LWDAQ_byte_write $sock 63 $value
		LWDAQ_set_data_addr $sock $addr
		set read_value [LWDAQ_byte_read $sock 63]
		if {$read_value<0} {set read_value [expr 256+$read_value]}
		if {$value == $read_value} {
			incr count
		} {
			LWDAQ_print $t "ERROR: Wrote $value, read $read_value, at address $addr."
			LWDAQ_update
		}
		if {$stop} {break}
	}
	LWDAQ_socket_close $sock

	LWDAQ_print $t "SCORE: $count out of $num"
	LWDAQ_post [list acquire]
}

# End Toolmaker Script

Simplex Fitting Demonstration

Simplex Fitting Demonstration, a LWDAQ Toolmaker Script. Defines an altitude function and demonstrates the LWDAQ simplex fit command. Demonstrates the LWDAQ command-line simplex fitter. We define an altitude function and call the fitter with a starting point. The fitter returns with the coordinates of the point in the fitting space at which the altitude function is a minimum.

# Begin Toolmaker Script

proc altitude {params} {
	lassign $params u v w x y z
	set uu 10
	set vv 20
	set ww 30
	set xx 40
	set yy 50
	set zz 60
	LWDAQ_support
	return [expr ($x-$xx)*($x-$xx) + ($y-$yy)*($y-$yy) \
		+ ($z-$zz)*($z-$zz) \
		+ ($u-$uu)*($u-$uu) + ($v-$vv)*($v-$vv) + ($w-$ww)*($w-$ww)]
}

set minimum [lwdaq_simplex "0 0 0 0 0 0" altitude]
LWDAQ_print $t $minimum

# End Toolmaker Script

Image Position

Image Position, a LWDAQ Toolmaker Script. Configures an Instrument Panel so that clicking on the image prints the image position of the location clicked. Easily adaptable to any instrument with an image display. Sets up an instrument so that when we click on an image pixel with the mouse, the row and column of the pixel are printed to the instrument panel's text widget. In instruments where analysis_pixel_size_um is defined, we calculate the image coordinates of the mouse click as well.

# Begin Toolmaker Script

set instrument BCAM
LWDAQ_open $instrument
bind .[string tolower $instrument].ic.i.image  \
	[list image_point $instrument %x %y]

proc image_point {instrument x y} {
	upvar LWDAQ_config_$instrument config
	upvar LWDAQ_info_$instrument info
	set x_offset 3
	set y_offset 3
	set x [expr ($x-$x_offset) / $info(zoom)]
	set y [expr ($y-$y_offset) / $info(zoom)]
	LWDAQ_print -nonewline $info(text) "$instrument $x $y"
	if {[info exists info(analysis_pixel_size_um)]} {
		LWDAQ_print $info(text) "\
			[format %.2f [expr $info(analysis_pixel_size_um) * $x]]\
			[format %.2f [expr $info(analysis_pixel_size_um) * $y]]"
		} else {
			LWDAQ_print $info(text) ""
	}
}

# End Toolmaker Script

TCPIP Communication Template

TCP/IP Communication Template, a LWDAQ Toolmaker Script. Repeats a LWDAQ messaging job over and over to permit us to test the behavior of various LWDAQ Relays. Repeats a LWDAQ messaging job over and over to permit us to test the behavior of various LWDAQ Relays. Insert your own test procedure in the "go" routine. We use a global "p" array to handle starting and stopping the procedure, as well as carrying other global variables.

# Begin Toolmaker Script

global p
set p(t) $t
set p(location) "19"
set p(control) "Idle"
set p(ip) "10.0.0.37"
button $f.go -text Go -command "go"
button $f.stop -text Stop -command "stop"
label $f.control -textvariable p(control)
entry $f.ip -textvariable p(ip)
pack $f.go $f.stop $f.control $f.ip -side left -expand yes

# The go procedure executes in a while loop until we press the stop button. In
# our example, we open a socket and repeatedly read back the firmware version
# number until it's time to stop, then we close the socket. We include the
# LWDAQ_support routine so that we can receive and respond to mouse and keyboard
# events. One such event will cause the control variable to be set to Stop.
proc go {} {
  global p
  set p(control) "Run"
  set sock [LWDAQ_socket_open $p(ip)]
  set cnt 0
  LWDAQ_print $p(t) "Start $cnt" purple
  while {$p(control)!="Stop"} {
    set fv [LWDAQ_firmware_version $sock]
    incr cnt
    if {$cnt % 100 == 0} {LWDAQ_print $p(t) "Run $cnt"}
    LWDAQ_support
  }
  LWDAQ_socket_close $sock
  LWDAQ_print $p(t) "Done $cnt" purple
  set p(control) "Idle"
}

# The stop procedure, which will be executed when we press the stop button. Note
# that we must have LWDAQ_support or some equivalent Tcl update command in the
# go loop for our mouse click on the stop button to be effective.
proc stop {} {
  global p
  set p(control) "Stop"
}

# End Toolmaker Script

Device Command Transmitter

Device Command Transmitter, a LWDAQ Toolmaker Script. Sends a sequence of LWDAQ commands to a device, and does so repeatedly. Send a sequence of LWDAQ commands to a device repeatedly after pressing Transmit. Stop with stop button. List the commands in hex format.

# Begin Toolmaker Script

set p(commands) "0001 0000 AA02"
set p(text) $t
set p(ip) "10.0.0.37"
set p(driver_socket) 8
set p(mux_socket) 1
set p(stop) 0

button $f.transmit -text Transmit -command Transmit
entry $f.commands -textvariable p(commands) -width 50
button $f.stop -text Stop -command {set p(stop) 1}
entry $f.ip -textvariable p(ip)
pack $f.transmit $f.commands $f.stop $f.ip -side left -expand yes

proc Transmit {} {
	global p
	set cnt 0
	LWDAQ_print $p(t) "Start $cnt\: $p(commands)" purple
	set sock [LWDAQ_socket_open $p(ip)]
	LWDAQ_set_driver_mux $sock $p(driver_socket) $p(mux_socket)
	while {!$p(stop)} {
		incr cnt
		foreach c $p(commands) {
			LWDAQ_transmit_command_hex $sock $c
		}
		LWDAQ_wait_for_driver $sock
		if {$cnt % 100 == 0} {LWDAQ_print $p(t) "Run $cnt"}
		LWDAQ_support
	}
	LWDAQ_socket_close $sock
	LWDAQ_print $p(t) "Stop $cnt" purple
	set p(stop) 0
}

# End Toolmaker Script

Test All Instruments

Test All Instruments, a LWDAQ Toolmaker Script. Applies every LWDAQ Instrument to every image in the LWDAQ example image library. Uses every instrument analysis procedure to analyze every image in the Images directory. We use this script to check our error handling. If LWDAQ crashes during the execution, we know we have a bug in the analysis library.

# Begin Toolmaker Script

global LWDAQ_Info
set fl [glob [file join $LWDAQ_Info(program_dir) Images *]]
foreach i $LWDAQ_Info(instruments) {
	LWDAQ_update
	LWDAQ_print $t $i purple
	LWDAQ_print ~/analysis_log.txt $i
	foreach fn $fl {
		set image_name [LWDAQ_read_image_file $fn]
		set result "[file tail $fn] [LWDAQ_analysis_$i $image_name]"
		LWDAQ_print $t $result
		LWDAQ_print ~/analysis_log.txt $result
		lwdaq_image_destroy $image_name
	}
}

# End Toolmaker Script

Database Package Demonstration

Database Package Demonstration, a LWDAQ Toolmaker Script. Loads our DB package and demonstrates its use by opening an XML database file of the user's choice. Illustrates the use of our database package. Download our Devices.html page from our website and select when you run the script. The script opens and reads the file. It looks for devices with part number A3038 and customer name "Natalia", then lists them.

# Begin Toolmaker Script

package require DB
set devices [DB_read]
set devices [DB_get_list $devices device]
set count 0
foreach d $devices {
	set sn [DB_get_list $d sn]
	set pn [DB_get_list $d pn]
	set c [DB_get_list $d c]
	if {[regexp {A3038} $pn] && [regexp {Natalia} $c]} {
		LWDAQ_print $t "$sn $pn \"[lindex $c 0]\""
		incr count
	}
}
LWDAQ_print $t "Found $count matching devices."

# End Toolmaker Script

Circular Survey Target

Circular Survey Target, a LWDAQ Toolmaker Script. Displays camera image and overlays a red circle. Used to align circular targets in the field of view of a camera. A tool to align circular survey targets within the field of view of a BCAM. The script opens a canvas widget in the Toolmaker execution window. It draws the BCAM image photo in the canvas widget and a red circle on top of that. Whenever the BCAM instrument updates its bcam_photo, the same canvas widget re-draws the photo in the canvas widget.

# Begin Toolmaker Script

LWDAQ_open BCAM
canvas $f.survey -width 400 -height 400 -bd 2 -relief solid
pack $f.survey
$f.survey create image 200 200 -image bcam_photo
$f.survey create oval 130 130 250 250 -outline red

# End Toolmaker Script