Limiting signed numbers to some value

edmunds

Senior Member
#1
Dear all,

I have a problem I have attempted to address a few times now with limited success. I think I even tried to ask this forum once or at least seriously considered it before :) - I will try to be more clear about what I'm trying to do this time.

There is a signed word variable (steer_input) with $8000 representing 0 returned by a piece of code. Negative number means steer right is requested, positive - steer left. I need to set up accumulator to monitor how big the number has grown to either side from 0 to stop it from growing past, say, dec200 to stop issuing stepper motor commands past that number in that direction. So, limits would be $7F38 (dec32568) and $80C8 (dec32968). On top of that, I do want to reach the limits, so in case the next addition to the accumulator would add up to more than the limit, I would like to calculate the remainder within the limit and output that in steer_input. I have coded this, which seem to make sense, but pushes the steering to one side and is stuck there. I have tried to debug this in the simulator, but I'm just lost as to what the numbers should be after a couple of iterations.

Code:
Symbol rght_str_lim = $7F38   '(32568; -200)
Symbol left_str_lim = $80C8 '(32968; +200)

#macro RunSteering()
  steer_input = PLine + DLine                                   'Add everything up into a steering input
  if steer_input >= $8000 then
    steer_input = -steer_input / InputDiv
    acc_str_input = prv_acc_str_input + steer_input       'add up accumulated steer input in a different variable [adding a negative number?! CHECK!!!]
    if acc_str_input > rght_str_lim then                          'check if accumulated value within limits, if YES...
        clear StrRghtLimFlag                                               '... clear right limit flag
      clear StrLeftLimFlag                                              'stepping right, so there is some space to the left now
        low DIR                                                                   'set steering direction to RIGHT
        prv_acc_str_input = acc_str_input                            'set the old variable to a new value
      RunSteeringStepper
  else                                                                             'check if accumulated value within limits, if NO...
      if prv_acc_str_input != rght_str_lim then                 'if there is still space within the limit ...
          steer_input = prv_acc_str_input - rght_str_limit   '...set steer_input to that space
          clear StrRghtLimFlag                                            '... clear right limit flag
        clear StrLeftLimFlag                                             'stepping right, so there is some space to the left now
          low DIR                                                                'set steering direction to RIGHT
          prv_acc_str_input = rght_str_limit                        'set the old variable to a new value
        RunSteeringStepper
        else                                                                        'if there is no space within the limit...
          set    StrRghtLimFlag                                             '... set right limit flag
          clear StrLeftLimFlag                                              'should not be possible, but just in case
        endif
    endif
  else
    steer_input = steer_input / InputDiv
    acc_str_input = prv_acc_str_input + steer_input
    if acc_str_input < left_str_lim then
        clear StrLeftLimFlag
        clear StrRghtLimFlag
        high DIR
        prv_acc_str_input = acc_str_input
      RunSteeringStepper
    else
        if prv_acc_str_input != left_str_lim then
            steer_input = left_str_lim - prv_acc_str_input
            clear StrLeftLimFlag
          clear StrRghtLimFlag
            high DIR
            prv_acc_str_input = left_str_limit
        RunSteeringStepper
        else
            set    StrLeftLimFlag
            clear StrRghtLimFlag
        endif
    endif
  endif
#endmacro

#macro RunSteeringStepper(steer_input)
  high EN                                          'Enable the device to steer, disable to save power and limit heat
  for counter0 = 0 to steer_input      'Increase the number of loops to steer 'more' per cycle or decrease for 'less'
    pulsout STCK, 200                       'About a minimum to get decent power
    pauseus 120                                'pauseus is double the length of pulsout
  next
  low EN
#endmacro
Thank you all for your time,

Edmunds
 
Last edited:

Aries

New Member
#2
Code:
  if steer_input >= $8000 then
    steer_input = -steer_input / InputDiv
Do you mean that $8000 is zero - i.e. $8001 is +1, $7FFF is -1 and so on? Normally, $0000 is zero, with those numbers greater than $8000 being negative (counting down from $FFFF). However, if $8000 is zero, then ...

if steer_input = $8001, your code uses 32767 for the rest of the calculations. I've not looked at them in detail, but if you are expecting 1 and get 32767, then you could well find yourself at the limit one side or the other.
 

hippy

Technical Support
Staff member
#3
I would split the limiting code and the code which handles the result. This will limit a $8000 offset number to +/-200 and deliver an excess of that ...
Code:
Symbol POS_LIMIT   = 200
Symbol NEG_LIMIT   = 200

Symbol steer_input = w1
Symbol steer       = w2
Symbol excess      = w3

steer_input = $8000 - 350 : Gosub Limit
steer_input = $8000 - 250 : Gosub Limit
steer_input = $8000 - 150 : Gosub Limit
steer_input = $8000       : Gosub Limit
steer_input = $8000 + 150 : Gosub Limit
steer_input = $8000 + 250 : Gosub Limit
steer_input = $8000 + 350 : Gosub Limit
End

Limit:
  If steer_input >= $8000 Then
    steer = steer_input - $8000
    If steer <= POS_LIMIT Then
      excess = 0
    Else
      excess = steer - POS_LIMIT
      steer  = POS_LIMIT
    End If
    SerTxd( "+", #steer, TAB, #excess, CR, LF ) 
  Else
    steer = $8000 - steer_input
    If steer <= NEG_LIMIT Then
      excess = 0
    Else
      excess = steer - NEG_LIMIT
      steer  = NEG_LIMIT
    End If
    SerTxd( "-", #steer, TAB, #excess, CR, LF ) 
    steer = -steer
  End If
  Return
 

edmunds

Senior Member
#4
I would split the limiting code and the code which handles the result. This will limit a $8000 offset number to +/-200 and deliver an excess of that ...
Code:
steer_input = $8000 - 350 : Gosub Limit
steer_input = $8000 - 250 : Gosub Limit
steer_input = $8000 - 150 : Gosub Limit
steer_input = $8000       : Gosub Limit
steer_input = $8000 + 150 : Gosub Limit
steer_input = $8000 + 250 : Gosub Limit
steer_input = $8000 + 350 : Gosub Limit
End
Great :). Thank you, @hippy.

Edmunds
 

edmunds

Senior Member
#5
Dear @hippy,

Thank you once again for showing the way with how to feed some string of values to the function for testing. I'm now playing with the code and I can see this will not give up so easily. What you are doing now, is, you are capping the value of steer to not go over the limit on a per loop basis.

The requirement is to stop issuing steering commands of the same direction, when steering is already in its final position (or actually - very close to it). This means, if the limit is 200, we start from 0 and the input is 200, the code should execute it to pos +200, but pass if the next loop requires to steer in the same direction, because the steering is now maxed out. If, on the other hand, the opposite direction steering command of -150 is received, this should be executed. Now the position is +50. If the next command is -150 again, it should be executed, because the final position will now be -100, which is allowed with a limit of -200. If one more -150 is received, the code should take into account there is only -100 more remaining to the limit and execute that out of requested -150. And so on. I don't see how to extend your example into this without totally rewriting it and then I'm back to my own not working thing :).

I will try to come up with 'boxes and arrows' thing [again] for this.


Thank you for your time,

Edmunds
 

edmunds

Senior Member
#6
Code:
  if steer_input >= $8000 then
    steer_input = -steer_input / InputDiv
Do you mean that $8000 is zero - i.e. $8001 is +1, $7FFF is -1 and so on? Normally, $0000 is zero, with those numbers greater than $8000 being negative (counting down from $FFFF). However, if $8000 is zero, then ...

if steer_input = $8001, your code uses 32767 for the rest of the calculations. I've not looked at them in detail, but if you are expecting 1 and get 32767, then you could well find yourself at the limit one side or the other.
The inputs are decent controlled values, coming out of a PID algorithm, overflow risks are being controlled. 0 is $0000, sorry, my bad. Over $8000 are negative and counting backwards exactly as you say.


Thank you for your input,

Edmunds
 

edmunds

Senior Member
#7
I replaced all the macroses with code for now, so now the main loop is pretty understandable and should compile with MagLine function removed.

Code:
Symbol No_magnet = bit30     'No magnet [1], magnet present [0]

Symbol counter0 = w17        'b34:b33; Just a counter

Symbol ELine = w15           'b30:b29; Line position error
Symbol PLine = w14           'b28:b27; P term, PID
Symbol DLine = w13           'b26:b25; D term, PID
Symbol Steer_input = w12     'b24:b23; Steer input, number of stp pulses to STSPIN220
Symbol D_error = w11         'b22:b21; Derivative error for D term calculation
Symbol OldELine = w10        'b20:b19; Old line position error

Symbol line_pos = w0         'b0:b1; MagLine position

Symbol EN = D.4                   'EN output/input motor controller
Symbol DIR = D.6                 'DIR input, motor controller, LOW to the right, HIGH to the left

Symbol KpELine = 26    '26       'P coefficient/multiplier for line position error correction
Symbol KdEline = 900   '900      'D coefficient for line error corrections
Symbol InputDiv = 30   '30       'Input divider to go down to reasonable value for number of steps for the motor

main:
  gosub MagLine                            'Find if and where a magnet is, return ELine
  if No_magnet = 0 then                 'Steer only in case magnet present
;GetSignedPLine                            'Calculate P term
    if ELine >= $8000 then                 'ELine is +/-7 or 0
      PLine = -ELine * KpELine
      PLine = -PLine
    else
      PLine = ELine * KpEline
    endif
    d_error = ELine - OldELine             'Calculate error trend (derivative)
;GetSignedDLine                            'Calculate D term
    if ELine >= $8000 then
      PLine = -ELine * KpELine
      PLine = -PLine
    else
      PLine = ELine * KpEline
    endif
    OldELine = ELine                       'Set the old error the current error
;GetSteerInput                             'Calculate the steering input, number of stp pulses
    steer_input = PLine + DLine            'Add everything up into a steering input
    if steer_input >= $8000 then
      low DIR
      steer_input = -steer_input / InputDiv
    else
      high DIR
      steer_input = steer_input / InputDiv
    endif
;RunSteeringStepper
    high EN                                'Enable the device to steer, disable to save power and limit heat
    for counter0 = 0 to steer_input        'Increase the number of loops to steer 'more' per cycle or decrease for 'less'
      pulsout STCK, 200                    'About a minimum to get decent power
      pauseus 120                          'pauseus is double the length of pulsout
    next
    low EN
  endif
;  gosub CheckForCharging
goto main
Edmunds
 

Aries

New Member
#8
Is this the sort of thing you have in mind?

The "main section" is where the action happens. The requested movement is compared against (1) the maximum allowed (200) and (2) the remaining distance to the limit. The smallest value is then used to make the move (which will be zero if the limit has been reached and the movenent is in the same direction).

The bit between GetNextValue and the main section is just getting a random value for Movement (between -249 and + 249) and printing it out together with the current position.
Code:
symbol PosLimit = w6
symbol NegLimit = w7
symbol CurrentPos = w8
symbol Movement = w9
symbol RandomSeed = w10


    PosLimit = 200                                        ' set limits
    NegLimit = -200
    CurrentPos = 0                                        ' and current position
    RandomSeed = 34073                                ' set a non-trivial initial value

GetNextValue:
    random RandomSeed                                    ' get a random number
    Movement = 250 ** RandomSeed            ' Movement is (positive) random value in range 0-249
    b0 = RandomSeed                                        ' LSB of seed to get a random sign
    if bit0 = 1 then                                    ' change sign if LSB is 1
        Movement = - Movement
    endif

    w1 = CurrentPos
    b0 = " "
    if w1 > $8000 then
        w1 = - w1
        b0= "-"
    endif
    w2 = Movement
    b1 = " "
    if w2 > $8000 then
        w2 = - w2
        b1= "-"
    endif
    
    sertxd(13,10,"Current=",b0,#w1," Movement=",b1,#w2)
' main section
    if Movement > $8000 then                    ' movement is negative
        Movement = - Movement                        ' make it positive
        Movement = CurrentPos - NegLimit MAX 200 MAX Movement
        Movement = - Movement                        ' and return sign
    else
        Movement = PosLimit - CurrentPos MAX 200 MAX Movement
    endif
    
    CurrentPos = CurrentPos + Movement
    goto GetNextValue[\CODE]
 

hippy

Technical Support
Staff member
#9
The requirement is to stop issuing steering commands of the same direction
So, analogy-wise, you're playing cat and mouse with a vehicle, you're the cat trying to chase the mouse down. There's a guy on top of the vehicle watching where the target is and shouting forward, forward, turn left, more left, lots more left, lots more left, turn right, etc.

Meanwhile there's a guy in the vehicle working the steering blind, aiming to deliver what's being shouted but limiting steering so it isn't excessive. So lots or 'lots of more left' will have the vehicle steered left, but not as hard as the target observer might like.

So basically it's an additive and limiting function, rather than just a limiting function you are after. That should be doable.

But a quick question on what happens before I head down the wrong road. You are heading on a straight path, target going forward, you are steering forward, then the target makes a run for it way to the left. The observer will issue a 'hard left', and 'more hard left' commands and you'll gently steer left as much as you allow rather than slam it hard left.

If the target turned hard left then kept going forward, you'll eventually have it directly in front. But you'll still be steering as hard left as allowed. You will over-shoot the target, and the observer will start shouting 'turn right'.

At that point; do you reduce the left turn a bit, or do you instantly cancel the left turn and set steering to the right of straight forward ?

Or will you have started to reduce the amount of left turn before then ?
 
Last edited:

hippy

Technical Support
Staff member
#10
Maybe closer ...
Code:
Symbol told     = w1
Symbol steering = w2

Symbol LIMIT   = 200

#Define Negative(wVar) wVar >= $8000
#Define Positive(wVar) wVar <  $8000

told =  -50 : Gosub Steer : Gosub Report
told = -100 : Gosub Steer : Gosub Report
told = -150 : Gosub Steer : Gosub Report
told = -150 : Gosub Steer : Gosub Report
told =  -50 : Gosub Steer : Gosub Report
told =   50 : Gosub Steer : Gosub Report
told =  100 : Gosub Steer : Gosub Report
told =  150 : Gosub Steer : Gosub Report
told =  150 : Gosub Steer : Gosub Report
End

Steer:
  If Negative(told) Then
    If Positive(steering) Then
      steering = 0
    End If
    steering = -steering - told Max LIMIT
    steering = -steering  
  Else
    If Negative(steering) Then
      steering = 0
    End If
    steering = steering + told Max LIMIT
  End If
  Return

Report:
  SerTxd(      "Told"     ) : w0 = told     : Gosub ShowSignedW0
  SerTxd( TAB, "Steering" ) : w0 = steering : Gosub ShowSignedW0
  SerTxd( CR, LF )
  Return

ShowSignedW0:
  If Positive(w0) Then
    SerTxd( " +", #w0 )
  Else
    w0 = -w0
    SerTxd( " -", #w0 )
  End If
  Return
Code:
Told -50    Steering -50
Told -100   Steering -150
Told -150   Steering -200
Told -150   Steering -200
Told -50    Steering -200
Told +50    Steering +50
Told +100   Steering +150
Told +150   Steering +200
Told +150   Steering +200
 

edmunds

Senior Member
#11
So, analogy-wise, you're playing cat and mouse with a vehicle, you're the cat trying to chase the mouse down. There's a guy on top of the vehicle watching where the target is and shouting forward, forward, turn left, more left, lots more left, lots more left, turn right, etc.

Meanwhile there's a guy in the vehicle working the steering blind, aiming to deliver what's being shouted but limiting steering so it isn't excessive. So lots or 'lots of more left' will have the vehicle steered left, but not as hard as the target observer might like.
That is a good summary, I think with exception of this
So lots or 'lots of more left' will have the vehicle steered left, but not as hard as the target observer might like.
Above is done by P(I)D algorithm and while it might not look like much, is reasonably tuned for the chassis I'm working with through many painful iterations. I would like to avoid touching it, so I want to stick addition and limiting on top of it. The function I'm after is in no way soft. It is hard as a ton of bricks and should just stop commands that keep pushing in the directions steering wheels are already maxed out in.

But a quick question on what happens before I head down the wrong road. You are heading on a straight path, target going forward, you are steering forward, then the target makes a run for it way to the left. The observer will issue a 'hard left', and 'more hard left' commands and you'll gently steer left as much as you allow rather than slam it hard left.
Equally here, I do not want to fiddle with the response. I only want to cap it once the accumulated "hard left" is past where the wheels can physically go.

A picture (or two) is maybe worth more than a thousand words, so two pictures coming in the next post.

I have not tested your code suggestion yet, will try to do that tonight.

Thank you for your time,

Edmunds
 
Last edited:

edmunds

Senior Member
#14
I added a few numbers to @hippy's input data and made a table of what the position and outputs need to be with limits set at -200 and +200

Code:
Input         Position         Output
0               0                   0               'all zero for start
-350          -200             -200          'sorry, mate, can only do -200
-250          -200             0               'sorry, mate, doing what I can already
-150          -200             0               'sorry, mate, doing what I can already
0               -200             0               'sorry, mate, doing what I can already
+150         -50              +150          'that direction is perfectly possible, here you are
+250         +200           +250          'ok, I'll take that, but only that
+350         +200           0                'what did I just say?
-250          -50              -250           'thank you, that will work
-150          -200            -150           'ok, but that is it
+150         -50             +150           'that way - no problem
+250        +200           +250           'just what I can offer
+350        +200           0                 'nope, no more, doing what I can already
When spelled out like this, it seems possible to code again :).

Edmunds
 

edmunds

Senior Member
#15
Dear @hippy,

I got your code working on top of mine (i.e. in the vehicle) and what it seems to be doing is limiting the steering response per loop to what the limit is. Not quite there yet, but closing in :).


Thank you for your input,

Edmunds
 

edmunds

Senior Member
#16
Dear @Aries ,

Not there yet either :). I have successfully ported your code on top of mine, figured out how it works and while it tracks current_pos, which could be used to know that no more Movement commands should be accepted, the MAX operators only deal with immediate inputs, not the accumulated situation.

This should be a pretty easy modification, but I have to call it a day today.


Thank you for your inputs and lets see what we can do tomorrow,

Edmunds
 

Aries

New Member
#17
There are two MAX operators in each expression. The "200" in my original code was because I (mistakenly) believed you had a limit on the amount of movement in one go, as well as the stop limits at +/-200. In the code below, I have simply replaced the "200" with LargestMovement which I have set to 500 (so that it will do nothing in this case). The whole expression takes the smallest of:
(1) The distance to the stop in the direction of movement
(2) The maximum allowable movement in one go
(3) The amount of movement requested

(1) is the test which deals with the accumulated situation.

Using your table for input, the code becomes:

Code:
symbol PosLimit = w6
symbol NegLimit = w7
symbol CurrentPos = w8
symbol Movement = w9
symbol RandomSeed = w10
symbol LargestMovement = 500

#rem
Input         Position         Output
0               0                   0               'all zero for start
-350          -200             -200          'sorry, mate, can only do -200
-250          -200             0               'sorry, mate, doing what I can already
-150          -200             0               'sorry, mate, doing what I can already
0               -200             0               'sorry, mate, doing what I can already
+150         -50              +150          'that direction is perfectly possible, here you are
+250         +200           +250          'ok, I'll take that, but only that
+350         +200           0                'what did I just say?
-250          -50              -250           'thank you, that will work
-150          -200            -150           'ok, but that is it
+150         -50             +150           'that way - no problem
+250        +200           +250           'just what I can offer
+350        +200           0                 'nope, no more, doing what I can already
#endrem
    PosLimit = 200                                        ' set limits
    NegLimit = -200
    CurrentPos = 0                                        ' and current position
    RandomSeed = 34073                                ' set a non-trivial initial value

GetNextValue:
    for b22 = 0 to 11
        lookup b22,(  0,  0,  0,  0,150,250,350,  0,  0,150,250,350),w1
        lookup b22,(350,250,150,  0,  0,  0,  0,250,150,  0,  0,  0),w2
        Movement = w1 - w2

    w1 = CurrentPos
    b0 = "+"
    if w1 > $8000 then
        w1 = - w1
        b0= "-"
        endif
        if w1 = 0 then
            b0 = " "
        endif
       
    w2 = Movement
    b1 = "+"
    if w2 > $8000 then
        w2 = - w2
        b1= "-"
    endif
        if w2 = 0 then
            b1 = " "
        endif
   
    sertxd(13,10," Input=",b1,#w2," Position=",b0,#w1)
' main section
    if Movement > $8000 then                    ' movement is negative
        Movement = - Movement                        ' make it positive
        Movement = CurrentPos - NegLimit MAX LargestMovement MAX Movement
        Movement = - Movement                        ' and return sign
    else
        Movement = PosLimit - CurrentPos MAX LargestMovement MAX Movement
    endif
   
    CurrentPos = CurrentPos + Movement
    w1 = CurrentPos
    b0 = "+"
    if w1 > $8000 then
        w1 = - w1
        b0= "-"
    endif
        if w1 = 0 then
            b0 = " "
        endif

        w2 = Movement
    b1 = "+"
    if w2 > $8000 then
        w2 = - w2
        b1= "-"
    endif
        if w2 = 0 then
            b1 = " "
        endif

        sertxd(" Output=",b1,#w2," New position=",b0,#w1)
    next b22
and the output is
Code:
Input=-350 Position= 0 Output=-200 New position=-200
Input=-250 Position=-200 Output= 0 New position=-200
Input=-150 Position=-200 Output= 0 New position=-200
Input= 0 Position=-200 Output= 0 New position=-200
Input=+150 Position=-200 Output=+150 New position=-50
Input=+250 Position=-50 Output=+250 New position=+200
Input=+350 Position=+200 Output= 0 New position=+200
Input=-250 Position=+200 Output=-250 New position=-50
Input=-150 Position=-50 Output=-150 New position=-200
Input=+150 Position=-200 Output=+150 New position=-50
Input=+250 Position=-50 Output=+250 New position=+200
Input=+350 Position=+200 Output= 0 New position=+200
which matches your table
 
Last edited:

hippy

Technical Support
Staff member
#18
The list in Post #14 was useful. Aries beat me to it but here's my version of the code -
Code:
Symbol position   = w1
Symbol wanted     = w2
Symbol maxAllowed = w3
Symbol allowed    = w4
Symbol new        = w5

Symbol LIMIT      = 200

#Define Negative(wVar) wVar >= $8000
#Define Positive(wVar) wVar <  $8000

SerTxd( "Pstn",    TAB )
SerTxd( "Want",    TAB, TAB )
SerTxd( "Pstn",    TAB )
SerTxd( "Allowed", CR, LF )

wanted =    0 : Gosub Adjust
wanted = -350 : Gosub Adjust
wanted = -250 : Gosub Adjust
wanted = -150 : Gosub Adjust
wanted =    0 : Gosub Adjust
wanted =  150 : Gosub Adjust
wanted =  250 : Gosub Adjust
wanted =  350 : Gosub Adjust
wanted = -250 : Gosub Adjust
wanted = -150 : Gosub Adjust
wanted =  150 : Gosub Adjust
wanted =  250 : Gosub Adjust
wanted =  350 : Gosub Adjust
End

Adjust:
  If Positive(wanted) Then
    maxAllowed = LIMIT - position
    allowed    = wanted Max maxAllowed
  Else
    maxAllowed = position + LIMIT
    allowed    = -wanted Max maxAllowed
    allowed    = -allowed
  End If
  new = position + allowed
  Gosub Report
  position = new
  Return

Report:
  w0 = position : Gosub ShowSignedW0 : SerTxd( TAB )
  w0 = wanted   : Gosub ShowSignedW0 : SerTxd( TAB, "->", TAB )
  w0 = new      : Gosub ShowSignedW0 : SerTxd( TAB )
  w0 = allowed  : Gosub ShowSignedW0 : SerTxd( TAB )
  If allowed = wanted Then
    w0 = -LIMIT
    Select Case new
      Case LIMIT : SerTxd( "Ok, but that's it, at +", #LIMIT )
      Case w0    : SerTxd( "Ok, but that's it, at -", #LIMIT )
      Else       : SerTxd( "Ok" )
    End Select
  Else If allowed = 0 Then
    If Positive(new) Then
      SerTxd( "Nope, can't go above +", #LIMIT )
    Else
      SerTxd( "Nope, can't go below -", #LIMIT )
    End If
  Else
    SerTxd( "Can only do " )
    w0 = allowed : Gosub ShowSignedW0
  End If
  SerTxd( CR, LF )
  Return

ShowSignedW0:
  If w0 = 0 Then
    SerTxd( "0" )
  Else If Positive(w0) Then
    SerTxd( "+", #w0 )
  Else
    w0 = -w0
    SerTxd( "-", #w0 )
  End If
  Return
And that matches your table -
Code:
Pstn  Want        Pstn  Allowed
0     0     ->    0     0     Ok
0     -350  ->    -200  -200  Can only do -200
-200  -250  ->    -200  0     Nope, can't go below -200
-200  -150  ->    -200  0     Nope, can't go below -200
-200  0     ->    -200  0     Ok, but that's it, at -200
-200  +150  ->    -50   +150  Ok
-50   +250  ->    +200  +250  Ok, but that's it, at +200
+200  +350  ->    +200  0     Nope, can't go above +200
+200  -250  ->    -50   -250  Ok
-50   -150  ->    -200  -150  Ok, but that's it, at -200
-200  +150  ->    -50   +150  Ok
-50   +250  ->    +200  +250  Ok, but that's it, at +200
+200  +350  ->    +200  0     Nope, can't go above +200
 

edmunds

Senior Member
#19
Dear all,

I have been fiddling with this for a few evenings, but had nothing to report.

Tonight, I did a fresh attempt and got everything to work as expected. The problem so far [also with my own initial attempt] was I was trying to re-use variables. There were places where this was OK and then - there were places it was not. So, it all started working, when I introduced all new variables and went on from there, carefully replacing backwards - one by one with a re-used variable.

I have now tweaked the maximum limit for the steering not to get stuck at either end to be 223 steps.

Now, the next challenge is, I have used up all the 'normal' variables for line finding, limiting steering mechanics and controlling wireless charging (including detecting electromagnetic field from a charging station and automatic positioning on it), but there are so many more things to do. So I will have to put some things away to scratchpad and eeprom storage locations to continue.

Another improvement on this would be to add a 're-align routine' for every time steering ends up in right-most [left-most with new chassis as in photos above] position, since I have hall sensor there I'm using for initial steering alignment. This could re-set the position to a correct one in case some steps were missed due to mechanical issues along the road.


Thank you all for your valuable inputs,

Edmunds
 

Aries

New Member
#20
I would be dubious about using EEPROM for temporary storage, because there is a limit on how often a variable can be re-written. I would only use it for items which are only changed occasionally; my own practice is to check if the value has changed and only write it if it is different. If you are using temporary variables, use scratchpad (@ptr) or RAM (@bptr), not EEPROM.
 

edmunds

Senior Member
#21
I would be dubious about using EEPROM for temporary storage, because there is a limit on how often a variable can be re-written. I would only use it for items which are only changed occasionally; my own practice is to check if the value has changed and only write it if it is different. If you are using temporary variables, use scratchpad (@ptr) or RAM (@bptr), not EEPROM.
True, thanks for the reminder. Had slipped out of my head totally.

Edmunds
 

techElder

Well-known member
#22
My code doesn't seem to be very popular, but ...

You might try looking at this code from the forum's code snippet repository. I've used it extensively in a few programs where I needed a better way to handle data several levels deep into GOSUBS. It uses upper RAM for temporary storage.

PUSH/POP macros
 
Top