Soft and hard limits


Senior Member
Dear all,

I'm continuing to work on the magnet follower. One problem I need to tackle is to limit the steering being pushed too far to either end by the stepper motor, because when that happens, most of the time the slider is tightened against the mechanism in a way the stepper motor itself is not able to unwind it.

I have added a hall sensor at one end of the stepper motor screw and a tiny magnet to the slider today and successfully created a function that puts the wheels straight from any position when powered up (unless they are stuck as per above). This is the only 'hard limit' I can put in there, as placing a hall sensor directly adjacent to the stepper motor (the other end) is useless because of strong magnetic disturbances while the motor operates.

#macro InitSteering
  sertxd("Init Steering",CR,LF)
  steer_input = 1                              'Set steer_input to a single step per loop
    low DIR                                    'Pick DIR for 'to the right' to look to move closer to the hall sensor
    RunSteeringStepper(steer_input)            'Move motor one step
    sertxd("In the loop",CR,LF)
    readadc10 18,steer_sense                   'Read how close is the magnet
  loop while steer_sense > steer_limit_left    'Continue like this until at the end of the screw and on top of the sensor
  steer_input = steer_max                      'Set steer input to max number of pulses from centre
  high DIR                                     'Pick DIR for 'to the left
  sertxd("Returning to centre",CR,LF)
  RunSteeringStepper(steer_input)              'Move the wheels to the centre position
Assuming my motor does not miss any steps, I should be able to run happily with 'soft limits' only as I should be able to keep track of steering position and stop steering in the direction there is no more left to steer. And use the hard limit pretty automatically during operation to 're-calibrate' if any steps were missed. I have been thinking about it and coding a couple of options, but no success so far.

I think the magic should happen in these functions, namely GetSteerInput(steer_input).

#macro GetSignedPLine()
  if ELine >= $8000 then
    PLine = -ELine * KpELine
    PLine = -PLine
    PLine = ELine * KpEline

#macro GetSignedDLine()
  if d_error >= $8000 then
    DLine = -d_error * KdELine
    DLine = -DLine
    DLine = d_error * KdEline

#macro GetSteerInput()
  steer_input = PLine + DLine          'Add everything up into a steering input
  if steer_input >= $8000 then
    low DIR : steer_input = -steer_input / InputDiv
    high DIR  : steer_input = steer_input / InputDiv
Here is my main loop:

  gosub MagLine
  if No_magnet = 0 then
    GetSignedPLine                  'Calculate P term
    d_error = ELine - OldELine      'Calculate error trend (derivative)
    GetSignedDLine                  'Calculate D term
    OldELine = ELine                'Set the old error the current error
    GetSteerInput                   'Calculate the steering input, number of stp pulses
    RunSteeringStepper(steer_input) 'Relay the steer_input to the motor controller
;  gosub CheckForCharging
goto main
Because of signed numbers, I cannot figure out where and how to put in the limits. Even building an accumulator is tricky, because error calculator keeps pushing out max steer_input value as long as the 'line' does not move closer/past center of the car and this would fill the variable up sooner or later.

Help, please, if anyone has time for this :).

Thank you and full program file attached,



Last edited: