# three axis PyVCP/HAL DRO configuration
# this uses HAL and PyVCP only, no EMC
# this assumes software encoder counting, with the encoder
# signals coming in through the parallel port. If you have
# hardware encoder counters, you would load the appropriate
# driver instead
# load parport driver
loadrt hal_parport cfg="0x0378 in"
# load encoder counters
loadrt encoder num_chan=3
# load mux and sum blocks
loadrt mux2 count=3
loadrt sum2 count=3
# load PyVCP
loadusr -W pyvcp -c ncs pyvcp-dro.xml
show pins
# create 20uS and 1mS realtime threads
# the 20uS fast thread means that the DRO can keep
# up with encoder rates of 10-15KHz
loadrt threads name1=fast period1=20000 name2=slow period2=1000000
# add realtime functions to threads
# fast thread first:
addf parport.0.read fast
addf encoder.update-counters
# slow thread next:
addf encoder.capture-position slow
addf mux2.0 slow
addf mux2.1 slow
addf mux2.2 slow
addf sum2.0 slow
addf sum2.1 slow
addf sum2.2 slow
show
# interconnections
# NOTE: for demo purposes, I used the old (and still valid)
# "newsig+linksp" syntax for X, and the new "net" syntax
# for Y and Z. The resulting connections are the same, but
# you can see that the "net" syntax is much more compact.
# It is only available in CVS HEAD, but the same is true of
# PyVCP.
# encoder phase A and B from parport to encoder counter
# X - old syntax:
newsig XphaseA bit
linksp XphaseA <= parport.0.pin-02-in
linksp XphaseA => encoder.0.phase-A
newsig XphaseB bit
linksp XphaseB <= parport.0.pin-03-in
linksp XphaseB => encoder.0.phase-B
# Y - new syntax:
net YphaseA parport.0.pin-04-in => encoder.1.phase-A
net YphaseB parport.0.pin-05-in => encoder.1.phase-B
# Z - new syntax:
net ZphaseA parport.0.pin-06-in => encoder.2.phase-A
net ZphaseB parport.0.pin-07-in => encoder.2.phase-B
# raw positions from encoders to one input of mux and summer
newsig Xpos-raw float
linksp Xpos-raw <= encoder.0.position
linksp Xpos-raw => mux2.0.in1
linksp Xpos-raw => sum2.0.in0
net Ypos-raw encoder.1.position => mux2.1.in1 sum2.1.in0
net Zpos-raw encoder.2.position => mux2.2.in1 sum2.2.in0
# offset position from mux output to other input of mux and summer
newsig Xoffset float
linksp Xoffset <= mux2.0.out
linksp Xoffset => mux2.0.in0
linksp Xoffset => sum2.0.in1
net Yoffset mux2.1.out => mux2.1.in0 sum2.1.in1
net Zoffset mux2.2.out => mux2.2.in0 sum2.2.in1
# output of summer is corrected position for display
newsig Xpos-corr float
linksp Xpos-corr <= sum2.0.out
linksp Xpos-corr => ncs.Xdisplay
net Ypos-corr sum2.1.out => ncs.Ydisplay
net Zpos-corr sum2.2.out => ncs.Zdisplay
# select input of mux comes from "zero" button
newsig Xzero bit
linksp Xzero <= ncs.Xzerobutton
linksp Xzero => mux2.0.sel
net Yzero ncs.Yzerobutton => mux2.1.sel
net Zzero ncs.Zzerobutton => mux2.2.sel
# finally, we need to set a few parameters
# set the scaling for X, Y, and Z
setp encoder.0.position-scale 20000
setp encoder.1.position-scale 20000
setp encoder.2.position-scale 10000
# we want the summer to subtract the offset from the
# raw position, so we set the gains appropriately
setp sum2.0.gain0 1.0
setp sum2.0.gain1 -1.0
setp sum2.1.gain0 1.0
setp sum2.1.gain1 -1.0
setp sum2.2.gain0 1.0
setp sum2.2.gain1 -1.0
# start realtime execution
start
<?xml version='1.0' encoding='UTF-8'?>
<pyvcp>
<vbox>
<label><text>"X axis"</text></label>
<hbox>
<number>
<halpin>"Xdisplay"</halpin>
<format>"+004.4f"</format>
<font>('Helvetica',60)</font>
</number>
<button>
<text>"Zero"</text>
<halpin>"Xzerobutton"</halpin>
</button>
</hbox>
<label><text>"Y axis"</text></label>
<hbox>
<number>
<halpin>"Ydisplay"</halpin>
<format>"+004.4f"</format>
<font>('Helvetica',60)</font>
</number>
<button>
<text>"Zero"</text>
<halpin>"Yzerobutton"</halpin>
</button>
</hbox>
<label><text>"Z axis"</text></label>
<hbox>
<number>
<halpin>"Zdisplay"</halpin>
<format>"+004.4f"</format>
<font>('Helvetica',60)</font>
</number>
<button>
<text>"Zero"</text>
<halpin>"Zzerobutton"</halpin>
</button>
</hbox>
</vbox>
</pyvcp>
Initiating command is : scripts/halrun -I pyvcp-dor.hal