Novice Question

Scott Thomas

New Member
Hi Folks,

I'm new to this and this is my first post. My program was progressing well then I found a loop in it. I skinnied it down so I could post it and it looks nothing like it did, but the loop is still there. I must be doing something silly. Please point me in the right direction. I'm using an 18x.

symbol Speaker = 3
symbol i = b2

main:
for i = 1 to 60

SerTxD ("Pausing", 13, 10)

pause 5000 'There should be a 5 sec pause between sounds

SerTxD ("Calling Cycle_Relay", 13, 10)

gosub Sub_1

SerTxD ("Returned from Cycle_Relay", 13, 10)

next

end


Sub_1: 'This is where it get's stuck looping and does not return. When working properly they'll be a pause
' between the beeps.
SerTxD ("Sub_1", 13, 10)

gosub Sub_2

gosub A_sound ' short sound

SerTxD ("Returning from Sub_1", 13, 10)
return


Sub_2:
SerTxD ("Entered Sub_2", 13, 10)
gosub Sub_3
Return


Sub_3:
SerTxD ("Entered Sub_3", 13, 10)
gosub Sub_4
return


Sub_4:
SerTxD ("Entered Sub_4", 13, 10)
gosub a_sound
return


A_sound:
sound Speaker,(70, 100)
return
 

Dippy

Moderator
Scott,
you are bit keen on calling subroutines within subroutines within subroutines within subroutines.
Poor thing won't know where its coming from.
Both it and you can easily end up in a big heap (I won't say stack) ;)

Honest, have another go planning this out with paper and pen as a flowchart.
Try and sequence things.

And honest again, I took one look at it and went cross-eyed :)

It's sometimes better to have a main loop and pop out into a subroutine and back.
Remember, there is a limit to how 'deep' subroutines can go. Go beyond that and baaarff!
Poor thing can't remember where it came from.

Honest, just once again. Have another go at writing it.
When it's a more logical sequence you (and we) will be able to understand the flow.
AND it's more likely to work.

And believe me, you will NOT follow that code when you look a it again in a months time.
...especially as there are so few comments ;)
 

Andrew Cowan

Senior Member
In the subroutines, do you mean gosub Sub_[number] or goto? If it gosub, then the program is really complicated.

Print it off, and use a pencil to point to where the program is. Run through that, and see where it loops.

A

Edit - like a flowchart, as Dippy said.
 
Last edited:

Scott Thomas

New Member
Yes these are meant to be GOSUBs. It may seem silly in this context, but the real program has this level of nesting and needs it for clarity, so I wanted to preserve this level of nesting.

In summary, Main calls 1 within a loop, 1 calls 2, 2 calls 3 then calls a procedure to make a sound, 3 calls 4, and 4 calls the procedure to make a sound. When run, control makes it's way down to to 4 then backup to 1 but loops within 1 without ever getting back up to Main.

Do I have a syntax problem or is there a limit in the chip's nesting capabilities? Or is it something else?
 

Andrew Cowan

Senior Member
I can't see any obvious problems, so I would guess it is reaching its nesting limit. You could do an easy test:

Code:
main:
gosub test1
sertxd ("one")
goto main

test1:
gosub test2
sertxd ("two")
return
etc - see how many you can add before it stops working.

A
 

lbenson

Senior Member
Did you try it in the simulator? At "gosub a_sound" from "Sub_4" I get "Stack error: More nested gosubs than the stack allows". You may be up against a hard constraint--perhaps others can explain or provide a workaround. Unwinding your code may be necessary.
 

Scott Thomas

New Member
I could have saved myself hours if I had known that the simulator would tell me that. I had a similar problem with interupts returning to the twilight zone yet it would run the code in the interrupt properly. I guess that was the same issue. Thanks guys.
 

westaust55

Moderator
PICAXE MAnual 2 page 49 GOSUB command.

18X can have 255/256 GOSUBS but is limited to 4 deep nesting of GOSUBS.

You have 5 levels of GOSUB so the first is overwritten (stack overflow) and the program will not know how to get back to the main code part.
 
Last edited:
Top