- Driver for phytron MCC-2 motor controller

This commit is contained in:
koennecke
2009-06-30 06:45:17 +00:00
parent f6b7e4fe20
commit e4119bfce5

209
tcl/phytron.tcl Normal file
View File

@ -0,0 +1,209 @@
#------------------------------------------------------------------
# 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
# <STX> data <ETX> 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
}