Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
Lee3 Regular Member Joined: 17/09/2014 Location: AustraliaPosts: 57
Posted: 07:45am 26 Feb 2018
Copy link to clipboard
Print this post
I have been getting this error today.... My program is basically three subroutines, two of which loop depending on the input of a distance sensor. The program is a garage-door open sensor/alert.
I seem to have exceeded some limit... but I don't know what/where?
Please excuse the code, it is pretty clunky I'm sure, but it was tinkered up from scratch. It does work, the error is intermittent, which makes it more frustrating.....
The error:
[15] If d>25 Then doorclosed Error: Too many SUB and FUN
Here is the code....
SetPin 25,dout SetPin 26,dout SetPin 17,dout
doorclosed
Sub dooropen Do
time=time+1
Print "door open " time d = Distance(15,16) If d>25 Then doorclosed Pause 1000 If time=3 Then alert
Loop End Sub
Sub alert Pulse 17,buzz*50 time=0 buzz=buzz+1 dooropen End Sub
Sub doorclosed
Do time=0 buzz=1
d = Distance(15,16) Pause 200 If d<25 Then dooropen Print "checking" Pause 200
Loop
End Sub
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10569
Posted: 08:34am 26 Feb 2018
Copy link to clipboard
Print this post
You are calling dooropen from within doorclosed and visa versa so depending on the data this will create an avalanche of calls one to the other which will create the error (distance varying about 25). Also dooropen can be called from within itself via alert.
Suggest you put some more hysteresis in the code "distance>40" "distance<10" or similarEdited by matherp 2018-02-27
Lee3 Regular Member Joined: 17/09/2014 Location: AustraliaPosts: 57
Posted: 10:07am 26 Feb 2018
Copy link to clipboard
Print this post
Thanks very much for the reply. I've discarded the doorclosed sub, and just have that code as the main body. I'll take the dooropen call out of alert also, as it seems redundant in any case.... I was planning on working out some hysteresis when the sensor was installed in place over the door and better measurements made.... Cheers... Lee
Azure Guru Joined: 09/11/2017 Location: AustraliaPosts: 446
Posted: 10:32am 26 Feb 2018
Copy link to clipboard
Print this post
As well as what matherp suggested your dooropen is a continuous loop.
So once you call dooropen it will nest to a door closed as another level within the dooropen loop. This is what is causing your error. The dooropen never returns.
As a tip to check where your error is add a print at the start and end of each sub [code]Sub dooropen Print "entering dooropen" '.... Print "exiting dooropen" End Sub Sub alert Print "entering alert" '.... Print "exiting alert" End Sub Sub doorclosed Print "entering doorclosed" '.... Print "exiting doorclosed" End Sub [/code]
Your code would probably work better with one distance call in a main loop and then based on the distance and whether it was previously open or closed choose to call dooropen or doorclose.
Lee3 Regular Member Joined: 17/09/2014 Location: AustraliaPosts: 57
Posted: 11:07am 26 Feb 2018
Copy link to clipboard
Print this post
Thanks - I think its working fine now - I removed the call to doorclosed from dooropen, and changed it to EXIT SUB. Now I just need to wire up a second sensor for the second door, and try and incorporate a 'silence' alarm for when I work in the garage....
SetPin 25,dout SetPin 26,dout SetPin 17,dout
Sub dooropen Do
time=time+1
Print "door open " time d = Distance(15,16) Print d Pulse 26,50 Pause 1000 If d>25 Then Exit Sub If time=3 Then alert
Loop End Sub
Sub alert Pulse 17,buzz*50 time=0 buzz=buzz+1 End Sub
Do time=0 buzz=1
pause 1000 d = Distance(15,16) If d<25 Then dooropen Print "checking" Pulse 25,30
Loop
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9750
Posted: 09:18pm 26 Feb 2018
Copy link to clipboard
Print this post
Nice you got it sorted.
Generally speaking, I try to avoid calling one sub from within another. I call one sub from the main loop of code, then analyse the results from it in the main code when the sub returns. This is just me, others may say it's fine to call subs from within subs, but it makes it really hard to debug - as you have found out.
Smoke makes things work. When the smoke gets out, it stops!
Paul_L Guru Joined: 03/03/2016 Location: United StatesPosts: 769
Posted: 08:01am 27 Feb 2018
Copy link to clipboard
Print this post
@Lee3 -- Extemporaneous, convoluted, hidden logic should be relegated to deliberate attempts to obfuscate prose, not code. Use standard formatting to make the flow obvious, and add lots of comments. Forget about attempting to duplicate reverse polish notation, leave that to us Polacks. TassyJims excellent MMBasic editor MMEDIT will do the formatting for you. It might be a good idea to capitalize language defined commands and make all your variables lower case or find some other way to identify them.
Pavel Artur Jan Waclaw Lepkowski in NY
' this program is named XYZ.BAS by Lee3 on 2/26/18 ' explain what the program does at the start ' formatting the code something like this helps ' stick logically connected commands on the same line ' add lots of comments, when you look at the code next year they will help ' keep the mainline in one place
MainLineBegin: ' an unnecessary label marks the mainline and makes the automatic indenting consistent SetPin 25,dout : SetPin 26,dout : SetPin 17,dout Do time=0 : buzz=1 : pause 1000 d = Distance(15,16) : If d<25 Then dooropen Print "checking" : Pulse 25,30 Loop END ' a redundant END, the interpreter would have ended when it reached the SUB dooropen in three more lines MainLineEnd: ' another unnecessary label which helps preserve automatic indenting
Sub dooropen ' this opens the door and tests for d>25 which makes noise and returns Do time=time+1 : Print "door open " time d = Distance(15,16) : Print d Pulse 26,50 : Pause 1000 If d>25 Then Exit DO ' you're really exiting the loop here, not the Sub !!!! If time=3 Then alert Loop ' it falls out of the SUB after exiting the loop here. End Sub ' dooropen '' this tells you which sub just ended
Sub alert ' this just makes lots of noise Pulse 17,buzz*50 : time=0 : buzz=buzz+1 End Sub 'alert
'EOF XYZ.BAS '' this assures you that the editor didn't truncate the code somehow
Edited by Paul_L 2018-02-28
Lee3 Regular Member Joined: 17/09/2014 Location: AustraliaPosts: 57
Posted: 09:27am 27 Feb 2018
Copy link to clipboard
Print this post
Thanks for the detailed reply and lesson Paul. I'm a very much part-time coder, and this was my first hack for a few years, done in the few hours between dropping off and picking up my kids from school. The advice about exiting the sub is much appreciated..... When I edit the code again, I'll use your advice. I don't think MMEDIT runs on Macs, so I just use a serial port emulator and the editor on the chip. I do prefer RPN calculators, but must say the Natural VPAM Casios are fun to use too..... :)
Paul_L Guru Joined: 03/03/2016 Location: United StatesPosts: 769
Posted: 12:03pm 27 Feb 2018
Copy link to clipboard
Print this post
Have fun with basic Lee. I don't know anything about Macs. I generally use NotePad++ but I don't think that will run on Macs.
You'd are advised to ignore that other Polack guy who uses my login.
Paul in NY
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2171
Posted: 12:20pm 27 Feb 2018
Copy link to clipboard
Print this post
you'll be back
The on-chip editor is great but simple. If you want to use your favourite text editor, consider either the Xmodem transfer or Autosave - I use the latter most of all, just press F10 in the MM console, paste your code into the console, wait for it all to zoom up the screen then press Ctrl-Z