#------------------------------------------------------------------ # This is driver for the combination Phytron MCC-2 Motor Controller # and SICS using the scriptcontext asynchronous I/O system. The # MCC-2 has a funny protocl as that messages are enclosed into # data sequences. This protocol is handled by the # C-language phytron protocol handler. Per default, the MCC-2 is # configured to use 57600 baud. I have configured it to use 9600 # baud and it ought to remember this. The command to change this # 0IC1S9600, the command to read this is 0IC1R. # # There are surely many ways to use the MCC-2. It supports two axes, X and Y. # All examples below are given for X only. This driver uses it in # this way: # # Nothing works properly without a reference run. The reference run is done # in the following way: # 1) Send it into the negative limit switch with 0X0- # 2) Set the mechanical position with 0XP20Swert to the negative limit # 3) Set the encoder position with 0XP22Swert to the negative limit # # Position ever afterwards with 0XAwert, read encoder with 0XP22R # # While driving 0X=H return ACKN, else ACKE # # Stopping goes via 0XSN # # copyright: see file COPYRIGHT # # Script chains: # # - reading position: # readpos - posrcv # # - writing postion: # setpos - setrcv # # reading status: # sendstatus - rcvstatus - statpos # # Mark Koennecke, June 2009 #------------------------------------------------------------------------- namespace eval phytron {} #----------------------------------------------------------------------- proc phytron::check {} { set data [sct result] if {[string first AscErr $data] >= 0} { error $data } return $data } #------------------------------------------------------------------------ proc phytron::readpos {axis} { sct send "0${axis}P22R" return posrcv } #------------------------------------------------------------------------ proc phytron::posrcv {} { set data [phytron::check] set pos [string range $data 3 end] sct update $pos return idle } #------------------------------------------------------------------------ proc phytron::setpos {axis name} { set val [sct target] sct send "0${axis}A$val" hupdate /sics/${name}/status run return setrcv } #------------------------------------------------------------------------ proc phytron::setrcv {controller name} { set data [phytron::check] if {[string first NACK $data] >= 0} { error "Invalid command" } $controller queue /sics/${name}/status progress read return idle } #------------------------------------------------------------------------- proc phytron::sendstatus {axis} { sct send "0${axis}=H" return rcvstatus } #------------------------------------------------------------------------- proc phytron::rcvstatus {axis controller} { set status [catch {phytron::check} data] if {$status != 0} { sct update error clientput $error } if {[string first ACKN $data] >= 0} { sct update run $controller queue [sct] progress read } if {[string first ACKE $data] >= 0} { phytron::readpos $axis return posrcv } return idle } #------------------------------------------------------------------------- proc phytron::statpos {axis name} { set data [phytron::check] set pos [string range $data 3 end] hupdate /sics/${name}/hardposition $pos sct send "0${axis}=I+" return statposlim } #------------------------------------------------------------------------ proc phytron::statposlim {axis} { set data [phytron::check] if {[string first ACKE $data] >= 0} { sct update error clientput "Hit positive limit switch" return idle } sct send "0${axis}=I-" return statneglim } #------------------------------------------------------------------------ proc phytron::statneglim {axis} { set data [phytron::check] if {[string first ACKE $data] >= 0} { sct update error clientput "Hit negative limit switch" return idle } sct send "0${axis}=E" return statend } #------------------------------------------------------------------------ proc phytron::statend {axis} { set data [phytron::check] if {[string first ACKE $data] >= 0} { sct update error clientput "Electronics error" return idle } sct update idle return idle } #------------------------------------------------------------------------- proc phytron::halt {controller axis} { $controller send "0${axis}SN" return Done } #-------------------------------------------------------------------------- proc phytron::refrun {name controller axis lowlim} { set path /sics/${name}/status $controller send "0${axis}0-" hupdate $path run set motstat run wait 3 while {[string compare $motstat run] == 0} { $controller queue $path progress read wait 1 set motstat [string trim [hval $path]] } $controller transact "0${axis}P20S$lowlim" $controller transact "0${axis}P22S$lowlim" return Done } #------------------------------------------------------------------------- proc phytron::defpos {controller axis value} { $controller transact "0${axis}P20S$value" $controller transact "0${axis}P22S$value" return Done } #-------------------------------------------------------------------------- proc phytron::make {name axis controller lowlim upperlim} { MakeSecMotor $name hdel /sics/${name}/hardupperlim hdel /sics/${name}/hardlowerlim hfactory /sics/${name}/hardupperlim plain internal float hfactory /sics/${name}/hardlowerlim plain internal float $name hardlowerlim $lowlim $name softlowerlim $lowlim $name hardupperlim $upperlim $name softupperlim $upperlim hsetprop /sics/${name}/hardposition read phytron::readpos $axis hsetprop /sics/${name}/hardposition posrcv phytron::posrcv $controller poll /sics/${name}/hardposition 60 hsetprop /sics/${name}/hardposition write phytron::setpos $axis $name hsetprop /sics/${name}/hardposition setrcv phytron::setrcv $controller $name $controller write /sics/${name}/hardposition hsetprop /sics/${name}/status read phytron::sendstatus $axis hsetprop /sics/${name}/status rcvstatus phytron::rcvstatus $axis $controller hsetprop /sics/${name}/status posrcv phytron::statpos $axis $name hsetprop /sics/${name}/status statposlim phytron::statposlim $axis hsetprop /sics/${name}/status statneglim phytron::statneglim $axis hsetprop /sics/${name}/status statend phytron::statend $axis $controller poll /sics/${name}/status 60 $name makescriptfunc halt "phytron::halt $controller $axis" user $name makescriptfunc refrun "phytron::refrun $name $controller $axis $lowlim" user $name makescriptfunc setpos "phytron::defpos $controller $axis" user hfactory /sics/${name}/setpos/value plain user float hupdate /sics/{$name}/status idle $controller queue /sics/${name}/hardposition progress read }