Some things to mention first:
Unexpectedly I found that the reboot problem was worse when my 4Mb ESPs were formatted for the full 4Mb than if they were formatted for 1Mb.
I often use GPIO01 blue LED to show what's happening, but this also shows up interpreter/browser interactions. It seemed that the problems started happening after the script caused the interpreter to do Timer and Interrupt type stuff, which it seemed to still be trying to do even when in the Edit window and trying to Save.
This script is at some unknown stage of an old project that I haven't worked on for a couple of months, it just happened to be the first script of the many I've just tried while looking for an example of the 'reboot when Saved' problem.
I was developing a FIFO queue using a circular array to feed individual mp3 words (local IP address in this instance) via serial2 to a JQ6500-28P voice module - I don't have the voice module attached now, but the script and ESP will not be affected by transmitting serial2 out into thin air. I did eventually get the voice FIFO project to work, but I don't know at what stage this script is at.
The important point for our purposes here is that it does exhibit the 'reboot when saved' symptoms for me. I should mention that the chip I just used is V3A60 12F4mb
I just Saved the script, then Ran it but without clicking any buttons, then did a browser back to the Edit page, then did Save again, and it got partially through the save then rebooted. I think it was a version of this script which I originally posted the problem about having the 'reboot when saved' problem.
One caveat that I can't be 100% sure of, but I think perhaps the 'Speak Local IP' button (second from bottom) may need to be clicked once before the symptoms start to show. But then the symptoms should persist even through the reboots without clicking any more buttons again.
memclear
title = "Voice Announcer - Version 1b - Developed on V3:A49 "
'Requires JQ6500-28P module, using RX for serial control mode to play selected files.
ledpin = 1
ledlogic = 1 'Default led pin off state
buttonpin = 0
busypin = 5
qpin = 12
qlogic = 1
interrupt busypin, [CHANGED]
localIP = ip()
'100=zero, 101=this ip address is, 102=dot,
'this, local, IP, address, subnet, broadcast, udp port, local, node, name, group, global, is, equals, set, select, use, 'up, down, volume, level, left, right, next, previous, first, last, start, stop, pause, led, blink, on, off,
'IR remote control, button, number, voice, language, custom
'trigger, triggered, channel, zone, input, output, relay, sensor, switch, changed,
'voicemsg = "101 1 9 2 102 1 6 8 102 4 102 1"
voicemsg = "1 2 3 4 5 6 7 8 9"
subnetmask = "255.255.255.0"
'broadcast = "255.255.255.255"
udpport = 5001
udpbegin udpport
'udpwrite broadcast, udpport, "Started"
[VOICEINIT]
serial2begin 9600,4,13 'Only needs JQ6500 RX pin (5)
'Note: to avoid possible confusion, remember that some ESP devices incorrectly depict gpio04 and gpio05 reversed.
vdir = 1 ' Default audio folder
vfile = 1 ' Default audio file (rather than risk complications by specifying an empty filename). Change to suit.
vol = 15 'Default to mid-volume (max=30)
'Obscure JQ6500 serial codes are defined below into more intuitive names for convenience.
vstart = 126 'Serial command start byte
vend = 239 'Serial command end byte
vplay = 13
vpause = 14
vnext = 1
vprev = 2
volup = 4
voldown = 5
vset = 6
vreset = hextoint("0C")
vdirfile = hextoint("12")
vloopmode = hextoint("11")
vdchange = hextoint("0F")
vdnext = hextoint("01")
vdprev = hextoint("00")
gosub [VOICERESET]
voicemsg = ""
qsize = 20
qfront = -1
qrear = -1
qitems = 0
dim queue$(20)
'Paint the screen
print title
print
if io(laststat,busypin) = 0 then html "<BR> NOT Busy <BR>" else html "<BR>Busy <BR>"
html "<BR><BR>"
html "Folder "
textbox vdir
html " File "
textbox vfile
button "Play selected file", [PLAYFILE]
html "<BR><BR>"
button "<", [PREV]
button "Play", [PLAY]
button ">", [NEXT]
html "<BR><BR>"
button "< Folder", [DPREV]
button "Folder >", [DNEXT]
html "<BR><BR>"
button "< Vol", [VOL<]
button "Vol >", [VOL>]
html "<BR><BR>"
slider vol, 0, 30
button "Set Volume", [SETVOL]
html "<BR><BR>"
button "Feed", [FEED]
html " "
button "Show", [QSHOW]
html "<BR><BR>"
button "Speak Local IP", [SPEAKIP]
html "<BR><BR>"
button "Speak", [SPEAK]
html "<BR><BR>"
'drops through to [HOME] page after inititialisation and screen painting.
[HOME]
delay 100
if io(pi,busypin) = 0 and qitems > 0 then goto [DQ]
wait
[CHANGED]
delay 100
if io(pi,busypin) = 0 and qitems > 0 then goto [DQ]
goto [HOME]
[SPEAKIP]
voicemsg = "101"
msg = ip()
for c = 1 to len(msg)
dun = false
char = mid(msg,c,1)
if char = "." then
voicemsg = voicemsg & " 102"
dun = true
endif
if char = "0" then
voicemsg = voicemsg & " 100"
dun = true
endif
if dun = false then voicemsg = voicemsg & " " & char
next c
html voicemsg & "<BR>"
goto [FEED]
[FEED]
vdir = 1
pos = 0
do
pos = pos + 1
w = word(voicemsg,pos)
if w <> "" then
html "word=" & w & ".<BR>"
qitem = w
gosub [Q]
endif
loop while w <> ""
pos = pos - 1
qitems = gitems + pos
html "Elements=" & pos & "<BR>"
goto [HOME]
[Q]
if (((qfront == 0) and (qrear == qsize - 1)) or (qfront == qrear+1)) then goto [QFULL]
'gosub [DISPLAYIT]
qitems = qitems + 1
'html "Qitems=" & qitems & "<BR>"
'gosub [DISPLAYIT]
if (qrear == -1) then
qrear = 0
qfront = 0
else
if (qrear == qsize -1) then
qrear = 0
else
qrear = qrear + 1
endif
endif
queue$(qrear) = qitem
return
[DQ]
if qitems > 0 then vfile = val(queue$(qfront)) else goto [QEMPTY]
'html "<BR> vfile=" & vfile & "<BR>"
serial2println chr(vstart) & chr(4) & chr(vdirfile) & chr(vdir) & chr(vfile) & chr(vend)
'html " vfile=" & vfile & "<BR>"
qitems = qitems - 1
if (qfront == qrear) then
qfront = -1
qrear = -1
else
if (qfront == qsize -1) then
qfront = 0
else
qfront = qfront + 1
endif
endif
html "Qitems=" & qitems & "<BR>"
goto [HOME]
[ENQUEUE]
if (((qfront == 0) and (qrear == qsize - 1)) or (qfront == qrear+1)) then goto [QFULL]
'gosub [DISPLAYIT]
qitems = qitems + 1
html "Qitems=" & qitems & "<BR>"
'gosub [DISPLAYIT]
if (qrear == -1) then
qrear = 0
qfront = 0
else
if (qrear == qsize -1) then
qrear = 0
else
qrear = qrear + 1
endif
endif
queue$(qrear) = qitem
return
goto [DQ]
[DEQUEUE]
'f qitems == 0 then goto [QEMPTY]
' html "<BR>Playing " & val(queue$(qfront)) & "<BR>"
if qitems > 0 then vfile = val(queue$(qfront)) else goto [QEMPTY]
html "<BR> vfile=" & vfile & "<BR>"
if io(pi,busypin) = 1 then
html "NOT Busy, so speaking " & vfile & "<BR>"
serial2println chr(vstart) & chr(4) & chr(vdirfile) & chr(vdir) & chr(vfile) & chr(vend)
qitems = qitems - 1
'endif
if (qfront == qrear) then
qfront = -1
qrear = -1
else
if (qfront == qsize -1) then
qfront = 0
else
qfront = qfront + 1
endif
endif
endif
'html " item deleted. <BR>"
'return
wait
goto [HOME]
[TOGGLE]
if io(laststat,ledpin) = 0 then io(po,ledpin,1) else io(po,ledpin,0)
udpwrite net, udpport, "toggle On"
goto [HOME]
[SPEAK]
vdir = 4
vfile = 101
serial2println chr(vstart) & chr(4) & chr(vdirfile) & chr(vdir) & chr(vfile) & chr(vend)
goto [HOME]
[QFULL]
html "Queue is full. <BR>"
gosub [DISPLAYIT]
goto [HOME]
[QEMPTY]
html "Queue is empty. <BR>"
gosub [DISPLAYIT]
goto [HOME]
[QSHOW]
gosub [DISPLAYIT]
if (qfront == -1) or (qfront == qrear + 1) then
html "Queue is empty. <BR>"
else
gosub [DISPLAYIT]
for count = qfront to qrear
html queue$(count)
html ".<BR>"
next count
endif
return
goto [HOME]
[DISPLAYIT]
html "Items=" & qitems
html ", Front=" & qfront
html ", Rear=" & qrear
html "<BR>"
return
[SETVOL]
'Set absolute volume value
serial2println chr(vstart) & chr(3) & chr(vset) & chr(vol) & chr(vend)
goto [HOME]
[VOL<]
'Relative volume decrease
serial2println chr(vstart) & chr(2) & chr(voldown) & chr(vend)
goto [HOME]
[VOL>]
'Relative volume increase
serial2println chr(vstart) & chr(2) & chr(volup) & chr(vend)
goto [HOME]
[PLAYFILE]
'Play specified 'vfile' audio file from 'vdir' folder
serial2println chr(vstart) & chr(4) & chr(vdirfile) & chr(vdir) & chr(vfile) & chr(vend)
goto [HOME]
[PLAY]
'Play current (last played) file
serial2println chr(vstart) & chr(2) & chr(vplay) & chr(vend)
goto [HOME]
[NEXT]
'Play next file
serial2println chr(vstart) & chr(2) & chr(vnext) & chr(vend)
goto [HOME]
[PREV]
'Play previous file
serial2println chr(vstart) & chr(2) & chr(vprev) & chr(vend)
goto [HOME]
[DNEXT]
'Select next folder
serial2println chr(vstart) & chr(3) & chr(vdchange) & chr(vdnext) & chr(vend)
goto [HOME]
[DPREV]
'Select previous folder
serial2println chr(vstart) & chr(3) & chr(vdchange) & chr(vdprev) & chr(vend)
goto [HOME]
[VOICERESET]
'Reset JQ6500
serial2println chr(vstart) & chr(2) & chr(vreset) & chr(vend)
delay 500
'Set volume
serial2println chr(vstart) & chr(3) & chr(vset) & chr(vol) & chr(vend)
return