The quickest way to determine if the used FOC gains are suitable is to run the motor in Open Loop and confirm that the Flux amps are stable and close to zero. Another way is to see the actual response of the current when giving a steop command. The below script is giving a square wave input as a torque demand and prints the Flux and Torque current values. Then the parameters can be plotted in a data handling software to assess the FOC response. Ideally, the motor rotor should be locked with brake or with any other external tool, but the script will work both ways. In the case that the rotor is unlocked the current response will be a bit distorted.
Some inportant thing to take into consideration are below:
- The script will provide a current equal to 1/4 of the nominal motor power, as it is configured in the reference seek power parameter
- The script operation will bypass/disable the ramp command and will restor it after it finishes. If the script is paused then the internal ramp command of the controller will be off and this will have a big impact on the given motor command! If the script is paused for some reason, then restart it and let it finish its execution
- Depending on the configured settings, the rotor might vibrate or slightly mode in both directions. It is preferable to have the rotor locked by aplying load or brake
Script Parametrization
The following parameters must be set on the script:
CURRENT_PERIOD is the period of the provided waveform, in milliseconds.
AMP_LIMIT is the maximum allowed current, in Amps* 10 (eg. 100 equals 10 A)
REPEATS is the number of pulses will be given by the script
The script follows:
'************************************************************
' FOC EVALUATION SCRIPT
'************************************************************
'Purpose:
'-------
'This script can be used for the FOC loop evaluation
'It will drive the motor by giving a square wave current demand
'and print the actual current values. The amplitude of the given
'current will be equal to a quarter of the rated motor current
'(reference seek power / 4). The wavefor period and the number
'of periods that will be proivided ar econifgurable
'
' _____ _____ _____
' set | | | | | |
' _____| |_____| |____| |____
' ____ ____ ____
' actual / \ / \ / \
' ______/ \____/ \___/ \___
'Use:
'----
'After running the script, copy the printed values and plot in
'a data illustration software for validation.
'WARNING:
'---------
'The script will modify the controller settings at
'the beggining and will restore them before it ends. If the script
'is stopped early, some parameters will not be restored and
'the controller will malfunction. DON'T pause the script before it
'finishes and if for some reason this happens, ensure that you will
'load the previous profile configurations. Pay attention to the
'BPR configuration parameter, as if it is changed (value different
' than 1) the controller will behave in a very aggressive way.
'Disclaimer:
'----------
'The script is tested and validated by Roboteq and is believed to be fault-free.
'The possibility always exists, however, that the particular configuration and/or use
'condition uncovers a fault that escaped our validation test coverage. Always
'extensively test the script under your use conditions prior to deploying it in the field.
option explicit
'**************************************************
' MODIFY BELOW TO PARAMETRIZE THE SCRIPT
'**************************************************
'
#define
CURRENT_PERIOD
100
'Period of the set current waveform. Value in ms.
#define
AMP_LIMIT
200
'The maximum allowed motor current during the test. Value in amps*10
#define
REPEATS
10
'Number of current waveform periods
#define
CH
1
'Configure the test channel
'**************************************************
' SCRIPT STARTS HERE. DON'T MODIFY BELOW
'**************************************************
'------------------------------
' MAIN PROGRAM
'------------------------------
'Variable declarations
dim
setTorque
as integer
dim
setFlux
as integer
dim
actTorque
as integer
dim
actFlux
as integer
dim
i
as integer
dim
j
as integer
dim
prAmplimit
as integer
dim
prMode
as integer
' The previous operating mode used
dim
prRWD
as integer
dim
PH1
as integer
dim
PH2
as integer
dim
PH3
as integer
setTorque
=getconfig
(_BZPW
,1
)/4
' give a set torque equal to reference seek power / 5
setFlux
=0
' the target flux current will be zero
actTorque
=0
actFlux
=0
PH1
=PH2
=PH3
=0
gosub
modify_parameters
"Set Torque"
,"\t"
,"Act Torque"
,"\t"
,"Set Flux"
,"\t"
,"Act Flux"
,"\t"
,"PHA 1"
,"\t"
,"PHA 2"
,"\t"
,"PHA 3"
,"\n"
)
while
(j
<REPEATS
-1
)
gosub
give_positive
gosub
give_negative
j
++
end while
gosub
give_zero
gosub
restore_parameters
terminate
'-----------------------------
' ROUTINE
'-----------------------------
modify_parameters:
prAmplimit
=getconfig
(_ALIM
,CH
)'get the previous amplimit value
wait
(5
)
prMode
=getconfig
(_MMOD
,CH
)' get the previous operating mode used
wait
(5
)
prRWD
=getconfig
(_RWD
,1
)' get the previous watchdog timer value
wait
(5
)
setconfig
(_ALIM
,CH
,AMP_LIMIT
)'modify the amp limit value. For safety reasons, when the rotor is locked
wait
(5
)
setconfig
(_BPR
,CH
,1
)' enable the bypass ramp function
wait
(5
)
setconfig
(_MMOD
,CH
,5
)' configure torque mode
wait
(5
)
setconfig
(_RWD
,0
)' disable watchdog
wait
(5
)
return
'-----------------------------
' ROUTINE
'-----------------------------
restore_parameters:
setconfig
(_BPR
,CH
,0
)' restore bypass ramp
wait
(5
)
setconfig
(_ALIM
,CH
,prAmpLimit
)'restore previous amp limit
wait
(5
)
setconfig
(_RWD
,prRWD
)' restore previous watchdog timer value
wait
(5
)
setconfig
(_MMOD
,CH
,prMode
)'restore prvious operating mode
return
'-----------------------------
' ROUTINE
'-----------------------------
give_positive:
i
=0
setcommand
(_GIQ
,CH
,setTorque
)
setCommand
(_GID
,CH
,setFlux
)
while
(i
<CURRENT_PERIOD
/2
)
if
CH
=1
actTorque
=getValue
(_MA
,2
)
actFlux
=getValue
(_MA
,1
)
PH1
=getvalue
(_PHA
,1
)
PH2
=getvalue
(_PHA
,2
)
PH3
=getvalue
(_PHA
,3
)
elseif
CH
=2
actTorque
=getValue
(_MA
,4
)
actFlux
=getValue
(_MA
,3
)
PH1
=getvalue
(_PHA
,4
)
PH2
=getvalue
(_PHA
,5
)
PH3
=getvalue
(_PHA
,6
)
end if
setTorque
,"\t"
,actTorque
,"\t"
,setFlux
,"\t"
,actFlux
,"\t"
,PH1
,"\t"
,PH2
,"\t"
,PH3
,"\n"
)
i
++
wait
(1
)
end while
return
'-----------------------------
' ROUTINE
'-----------------------------
give_negative:
i
=0
setcommand
(_GIQ
,CH
,-setTorque
)
setCommand
(_GID
,CH
,-setFlux
)
while
(i
<CURRENT_PERIOD
/2
)
if
CH
=1
actTorque
=getValue
(_MA
,2
)
actFlux
=getValue
(_MA
,1
)
PH1
=getvalue
(_PHA
,1
)
PH2
=getvalue
(_PHA
,2
)
PH3
=getvalue
(_PHA
,3
)
elseif
CH
=2
actTorque
=getValue
(_MA
,4
)
actFlux
=getValue
(_MA
,3
)
PH1
=getvalue
(_PHA
,4
)
PH2
=getvalue
(_PHA
,5
)
PH3
=getvalue
(_PHA
,6
)
end if
setTorque
,"\t"
,actTorque
,"\t"
,-setFlux
,"\t"
,actFlux
,"\t"
,PH1
,"\t"
,PH2
,"\t"
,PH3
,"\n"
)
i
++
wait
(1
)
end while
return
'-----------------------------
' ROUTINE
'-----------------------------
give_zero:
i
=0
setcommand
(_GIQ
,CH
,0
)
setCommand
(_GID
,CH
,0
)
while
(i
<CURRENT_PERIOD
/2
)
if
CH
=1
actTorque
=getValue
(_MA
,2
)
actFlux
=getValue
(_MA
,1
)
PH1
=getvalue
(_PHA
,1
)
PH2
=getvalue
(_PHA
,2
)
PH3
=getvalue
(_PHA
,3
)
elseif
CH
=2
actTorque
=getValue
(_MA
,4
)
actFlux
=getValue
(_MA
,3
)
PH1
=getvalue
(_PHA
,4
)
PH2
=getvalue
(_PHA
,5
)
PH3
=getvalue
(_PHA
,6
)
end if
setTorque
,"\t"
,actTorque
,"\t"
,setFlux
,"\t"
,actFlux
,"\t"
,PH1
,"\t"
,PH2
,"\t"
,PH3
,"\n"
)
i
++
wait
(1
)
end while
return