Stack error - more nested gosubs than the stack allows

Not sure how to correct this error in the following code (stack error more nested gosubs than stack allows)......any suggestions
Code:
main: Symbol cycle = b50
       Symbol rsteps = b49
       Symbol lsteps = b48 
       Symbol pin1 = 1
       Symbol pin2 = 2
      
  do
      if pinc.1 = 1 then 'move stepper left
        pause 2000
       gosub moveleft
      endif
    if pinc.2 = 1 then 'move stepper right
      pause 2000
       gosub moveright
      endif
    if pinc.3 = 1 then 'teach mode left
      pause 1000
      b0=0
       gosub teachleft
      endif
      if pinc.4 = 1 then 'teach mode right
      pause 1000
      b0=0
       gosub teachright
    
      
     
      endif
       
    loop

moveleft:
       pause 1000
       b1 = b1 + 1 & %00000011
       let b0 = b0 + 1
    if b0 < 5 then moveleft 'step multiplier for gear ratio
       b0=0
      return

moveright:
      pause 1000
      b1 = b1 - 1 & %00000011
      let b0 = b0 + 1
    if b0 < 5 then moveright 'step multiplier for gear ratio
      b0=0
    return 
    
teachleft:
     do
       IF  pinc.1 = 1  THEN
          b1 = b1 + 1 & %00000011
          let b0 = b0 + 1
        if b0<5  then teachleft 'step multiplier for gear ratio 
          lsteps=lsteps+1 

       ELSEIF pinc.5 = 1  THEN 
           gosub writeleft
       ELSE
            pinc.1 = 0
       ENDIF
    loop
      
teachright: 
       do
       IF  pinc.2 = 1  THEN
          b1 = b1 + 1 & %00000011
          let b0 = b0 + 1
        if b0<5  then teachright 'step multiplier for gear ratio 
          rsteps=rsteps+1 

       ELSEIF pinc.5 = 1  THEN 
           gosub writeright
       ELSE
            pinc.2 = 0
       ENDIF
    loop  
   
    
    


writeleft:rsteps=2
      
      write cycle,pin1,lsteps,rsteps
      cycle= cycle+1 
      gosub main
      
writeright:lsteps=0
      write cycle,pin1,lsteps,rsteps
      cycle= cycle+1
       
      gosub main



 cyclestart:'code to be added
 
Last edited:

tiscando

Senior Member
Hi triton,

In the code, I can see that there is no return command on the subs 'teachleft' and 'teachright'.

Also, you have some 'gosub's which should be 'goto's. Do not confuse 'gosub' with 'goto'.
 
hi
using a input pinc.5 for the return to main.....was looping until the the stepper reaches disired postion then pinc.5 = 1 will write the steps and direction....well in theroy anyways
 

MartinM57

Moderator
Yes, but your code is fatally flawed :(

moveleft: and moveright: are subroutines (you gosub to them) and they end with a return.

teachleft: and teachright: are subroutines (you gosub to them), but don't have any returns at the end

writeleft: and writeright: are subroutines (you gosub to them), but don't have any returns at the end - you have "gosub main" though - which is no good at all.

Just step through the code manually (i.e print it out and follow it with your finger) and you'll soon see how the compiler/PICAXE get confused....
 

lbenson

Senior Member
As an example, here is your "teachright" realigned to make the structure more clear.
Code:
teachright: 
       do
         IF  pinc.2 = 1  THEN
           b1 = b1 + 1 & %00000011
           let b0 = b0 + 1
           if b0<5  then teachright 'step multiplier for gear ratio 
           rsteps=rsteps+1 
         ELSEIF pinc.5 = 1  THEN 
           gosub writeright
         ELSE
           pinc.2 = 0
         ENDIF
       loop
There are several problems here. The first, as pointed out above, is that this subroutine has no return. Another is "if b0<5...". This make a "goto" jump out of the loop to the beginning of the subroutine. This is not necessarily wrong, but it might be more clear if the test were reversed as follows, which has the same effect (starting the loop over when b0 < 5.

Code:
teachright: 
       do
         IF  pinc.2 = 1  THEN
           b1 = b1 + 1 & %00000011
           b0 = b0 + 1
           IF b0 > 4 then  'step multiplier for gear ratio 
             rsteps=rsteps+1 
           ENDIF
         ELSEIF pinc.5 = 1  THEN 
           gosub writeright
         ELSE
           pinc.2 = 0
         ENDIF
       loop
But the big problem is, how do you get out of this loop.

Try your whole program in the simulator to see where it goes when the different inputs are on or off.
 
Top