ESP32 Save problems in Editor
- Electroguard
- Posts: 867
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 278 times
- Been thanked: 324 times
ESP32 Save problems in Editor
Since using Annex32 WiFi BLE CAN 1.43.5 I have become aware of definite problems when saving a script to SD from the Editor (about 650 lines)
The symptoms are that the Save can be very delayed, or sometimes may not happen at all.
Sometimes the Save pauses a few seconds during the Save progress bar, before continuing on to complete the Save .
But often (perhaps 1 in 10) the Save does not even get as far as the progress bar.
If the Save fails to start within about 20 secs I prepare to reboot by doing 'Select All' (Ctl A) then 'Copy' (Ctl C) before I reboot the device by powering it Off then back On followed by Ctl A and Ctl V to paste the latest contents back into the Editor after reconnecting which reloads the browsers cached copy.
Occasionally, just before rebooting I sometimes notice a very late blue successful Save popup just before actually doing the reboot.
This proves that the interpreter had not locked up completely, but was waiting for some sort of response… presumably from the filing system.
So there is most definitely an inconsistent Save to SD delay problem occurring - which can be brief, long, or indefinite - but the interpreter does not appear to crash, because sometimes it actually recovers and completes the Save successfully.
I suspect it may actually be the same problem with the implementation of the FAT32 filing system which has been causing other file-related problems.
The symptoms are that the Save can be very delayed, or sometimes may not happen at all.
Sometimes the Save pauses a few seconds during the Save progress bar, before continuing on to complete the Save .
But often (perhaps 1 in 10) the Save does not even get as far as the progress bar.
If the Save fails to start within about 20 secs I prepare to reboot by doing 'Select All' (Ctl A) then 'Copy' (Ctl C) before I reboot the device by powering it Off then back On followed by Ctl A and Ctl V to paste the latest contents back into the Editor after reconnecting which reloads the browsers cached copy.
Occasionally, just before rebooting I sometimes notice a very late blue successful Save popup just before actually doing the reboot.
This proves that the interpreter had not locked up completely, but was waiting for some sort of response… presumably from the filing system.
So there is most definitely an inconsistent Save to SD delay problem occurring - which can be brief, long, or indefinite - but the interpreter does not appear to crash, because sometimes it actually recovers and completes the Save successfully.
I suspect it may actually be the same problem with the implementation of the FAT32 filing system which has been causing other file-related problems.
- cicciocb
- Site Admin
- Posts: 2069
- Joined: Mon Feb 03, 2020 1:15 pm
- Location: Toulouse
- Has thanked: 441 times
- Been thanked: 1364 times
- Contact:
Re: ESP32 Save problems in Editor
Hi Robin,
I don't know if this problem is specific to this version as I already noticed some delay in the past when using the internal storage (not the SD).
I determined that this could be related to a kind of fragmentation of the internal storage area but I never investigated deeply.
Now, if the problem appears on the SDCARD, except if your SDCARD is almost full (very improbable), I must investigate it.
However, this could be a regression caused by the addition of the newest functionalities.
By the way, I'm curious to know if this happens also on the previous version.
How can I try to reproduce the problem? Simply saving a file with more than 650 lines ?
Thanks
I don't know if this problem is specific to this version as I already noticed some delay in the past when using the internal storage (not the SD).
I determined that this could be related to a kind of fragmentation of the internal storage area but I never investigated deeply.
Now, if the problem appears on the SDCARD, except if your SDCARD is almost full (very improbable), I must investigate it.
I don't see what problem you are referring to as the file system have not been changed / modified, and the SDK version is still the same.[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Fri Sep 10, 2021 12:29 pm I suspect it may actually be the same problem with the implementation of the FAT32 filing system which has been causing other file-related problems.
However, this could be a regression caused by the addition of the newest functionalities.
By the way, I'm curious to know if this happens also on the previous version.
How can I try to reproduce the problem? Simply saving a file with more than 650 lines ?
Thanks
- Electroguard
- Posts: 867
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 278 times
- Been thanked: 324 times
Re: ESP32 Save problems in Editor
Hi CiccioCB,
I had not used TFT's for a very long time, so when I did start re-using them to upgrade the syntax of your gui examples to work on the latest firmware, the first thing I did was upgrade to the latest firmware… so I don't know if the previous version also had the same problem or not.
Although it may only be a coincidence, the reason I posted about this bug now (knowing you are tied up with the website rewrite) was because I thought that the file-related delays sounded suspiciously similar to the "Very Slow FATFS" write on ESP32" [Local Link Removed for Guests] which you had responded to.
So none of this is more important than what you've been doing, but it provides more ammunition for when you are ready.
The FileManager screen dump is to give an idea of SD card contents, and how much free space is available.
The new 8Gb SD has all your gui demo files, plus all my edited copies of them, plus all required graphics (img & icons),
It also has all my ancient TFT File Menu and Apps, along with relevant graphics and fonts and demos.
So although there are a lot of files, there is nothing out of the ordinary, and they take up less than 1Gb, leaving over 7Gb free.
And below is the menu script I've been working on which has shown up the Editor Save problems.
Some things to point out:
FlexyMenu is an attempt to create a re-usable menu that can dynamically resize to differing TFT screen sizes and orientations.
It also has capability to use either gui touch buttons, or hardware buttons (eg:M5stack), or both (using the gui touch buttons as labels for the hardware buttons).
Because of the gui/hardware schizophrenia, the menu options need to be capable of being button navigated up and down to select a desired option, or alternatively any visible option can be touch-selected using the gui.target instruction, irrespective of the currently highlighted item.
Also it needs to be capable of multiple pagefuls of menu items.
But it kept eluding me, so after many days (weeks) of frustration I was forced to give up on my non-working existing code and start again from scratch in a more diagnostic manner immediately above the old code. This allowed me to run my new test code at the top of the script, while building it up slowly from the non-working remnants below.
So although the total script length is about 650 lines, the actual live script length referenced by the interpreter is only the top 242 lines, with everything below it just being unused junk - which I've included for reproducing the problem scenario as accurately as possible.
This strategy did allow me to pin down a gui.handler bug which had been causing the gui.target selection problems.
It seems that the gui handler uses an array for storing the gui item handles, but the gui handler and gui.target instructions seem to have problems when referencing the gui array... and which can be demonstrated by uncommenting line 97. This adds a gui header item in front of the item line handlers, but the bug causes gui.target to reference the handler array absolutely from 0, rather than relatively plus 1, thereby returning the incorrect gui handler (ie: gui.target returns item 2 when item 3 is touched).
Now that the bug is known I can avoid it - so instead of using a gui.textline for displaying the title (as previously) the title is displayed using tft.print (which also has the benefit of allowing transparent text background).
Another symptom of the gui handler array bug is that every gui item creates a new gui handler, rather than re-using previously used gui handlers.
So it is not possible to eg:
items=10
pagelength=3
dim gui_handler(pagelength)
gui.init pagelength+1
item=1
while item < items
for c = 1 to pagelength
line(c) = gui.textline(10,20 * c, 30, 20, str$(item)
item = item + 1
next c
wend
That was just an example off the top of my head to demonstrate that the gui.handler array does not get re-used, but instead will keep using up another new gui handle until it runs out and starts assigning -1
But these are merely problems I expect you would want to be aware of, not problems you are expected to look into.
The menu script works, and is quite impressive even though needing to side-step some limitations.
What Annex CAN do is far more significant than anything it cannot do.
Anyway, if you want to reproduce the Save problems, try changing the numerous user options at the top of the script, then Saving... eventually it should fail.
The variable tb=1 shows nav buttons (which wrap around between beginning and end), tb=2 shows additional page buttons (don't wrap around), tb=3 show reboot button (for gui emulation of M5stack hardware reboot to different Apps etc) and also a Screen dump gui button (but nothing sensible is displayed from the resulting file in Gimp).
The rows of similar variables allow just about everything to be tailored.
The first row of h_variables is for the top header bar (halign=3 is left align title$, 4=centre, 5=right align)
Second row of m_vars control the menu lines (malign=0 gives full page width menu, 3 is left, 4 centre, 5 right)
mh vars are menu hilite options
f vars are footer showing the 3 standard nav buttons.
p vars are for the page buttons
o vars ar for the other buttons (reboot and screen dump)
I was using a wallpaper most of the time, so you might want to add the filename of an available image somewhere around line 17.
It is still a work in progress, but hopefully it can be helpful in tracking down the Save bug, and perhaps even the gui handler bug, if time permits.
I had not used TFT's for a very long time, so when I did start re-using them to upgrade the syntax of your gui examples to work on the latest firmware, the first thing I did was upgrade to the latest firmware… so I don't know if the previous version also had the same problem or not.
Although it may only be a coincidence, the reason I posted about this bug now (knowing you are tied up with the website rewrite) was because I thought that the file-related delays sounded suspiciously similar to the "Very Slow FATFS" write on ESP32" [Local Link Removed for Guests] which you had responded to.
So none of this is more important than what you've been doing, but it provides more ammunition for when you are ready.
The FileManager screen dump is to give an idea of SD card contents, and how much free space is available.
The new 8Gb SD has all your gui demo files, plus all my edited copies of them, plus all required graphics (img & icons),
It also has all my ancient TFT File Menu and Apps, along with relevant graphics and fonts and demos.
So although there are a lot of files, there is nothing out of the ordinary, and they take up less than 1Gb, leaving over 7Gb free.
And below is the menu script I've been working on which has shown up the Editor Save problems.
Some things to point out:
FlexyMenu is an attempt to create a re-usable menu that can dynamically resize to differing TFT screen sizes and orientations.
It also has capability to use either gui touch buttons, or hardware buttons (eg:M5stack), or both (using the gui touch buttons as labels for the hardware buttons).
Because of the gui/hardware schizophrenia, the menu options need to be capable of being button navigated up and down to select a desired option, or alternatively any visible option can be touch-selected using the gui.target instruction, irrespective of the currently highlighted item.
Also it needs to be capable of multiple pagefuls of menu items.
But it kept eluding me, so after many days (weeks) of frustration I was forced to give up on my non-working existing code and start again from scratch in a more diagnostic manner immediately above the old code. This allowed me to run my new test code at the top of the script, while building it up slowly from the non-working remnants below.
So although the total script length is about 650 lines, the actual live script length referenced by the interpreter is only the top 242 lines, with everything below it just being unused junk - which I've included for reproducing the problem scenario as accurately as possible.
This strategy did allow me to pin down a gui.handler bug which had been causing the gui.target selection problems.
It seems that the gui handler uses an array for storing the gui item handles, but the gui handler and gui.target instructions seem to have problems when referencing the gui array... and which can be demonstrated by uncommenting line 97. This adds a gui header item in front of the item line handlers, but the bug causes gui.target to reference the handler array absolutely from 0, rather than relatively plus 1, thereby returning the incorrect gui handler (ie: gui.target returns item 2 when item 3 is touched).
Now that the bug is known I can avoid it - so instead of using a gui.textline for displaying the title (as previously) the title is displayed using tft.print (which also has the benefit of allowing transparent text background).
Another symptom of the gui handler array bug is that every gui item creates a new gui handler, rather than re-using previously used gui handlers.
So it is not possible to eg:
items=10
pagelength=3
dim gui_handler(pagelength)
gui.init pagelength+1
item=1
while item < items
for c = 1 to pagelength
line(c) = gui.textline(10,20 * c, 30, 20, str$(item)
item = item + 1
next c
wend
That was just an example off the top of my head to demonstrate that the gui.handler array does not get re-used, but instead will keep using up another new gui handle until it runs out and starts assigning -1
But these are merely problems I expect you would want to be aware of, not problems you are expected to look into.
The menu script works, and is quite impressive even though needing to side-step some limitations.
What Annex CAN do is far more significant than anything it cannot do.
Anyway, if you want to reproduce the Save problems, try changing the numerous user options at the top of the script, then Saving... eventually it should fail.
The variable tb=1 shows nav buttons (which wrap around between beginning and end), tb=2 shows additional page buttons (don't wrap around), tb=3 show reboot button (for gui emulation of M5stack hardware reboot to different Apps etc) and also a Screen dump gui button (but nothing sensible is displayed from the resulting file in Gimp).
The rows of similar variables allow just about everything to be tailored.
The first row of h_variables is for the top header bar (halign=3 is left align title$, 4=centre, 5=right align)
Second row of m_vars control the menu lines (malign=0 gives full page width menu, 3 is left, 4 centre, 5 right)
mh vars are menu hilite options
f vars are footer showing the 3 standard nav buttons.
p vars are for the page buttons
o vars ar for the other buttons (reboot and screen dump)
I was using a wallpaper most of the time, so you might want to add the filename of an available image somewhere around line 17.
It is still a work in progress, but hopefully it can be helpful in tracking down the Save bug, and perhaps even the gui handler bug, if time permits.
Code: [Local Link Removed for Guests]
'gui handler test
' uses a pagelength array of handlers to re-use the same few lines of gui handlers for displaying multiple pages of items
' but instead of re-using, the handler keeps using up extra reserved gui handlers until it runs out and fails with -1
title$="Menu" 'leave blank for no header
menu$="one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen,twenty"
' getfiles "/*" 'causes rebooting
xres=320: yres=240: orientation=1
'xres=240: yres=320: orientation=0
M5stack=2 '0=touch buttons only, 1=M5stack hardware buttons only, 2=both hardware and touch buttons
tb=1 '1=nav only, 2=page also, 3=plua reset & printscreen
black=0: white=tft.rgb(255,255,255): red=tft.rgb(255,0,0): green=tft.rgb(0,255,0): blue=tft.rgb(0,0,255)
cyan=green+blue: pink=red+blue: yellow=tft.rgb(255,255,5): orange=tft.rgb(255,165,0)
lightgrey=tft.rgb(200,200,200): darkgrey=tft.rgb(128,128,128): clear=-1
background=blue
wallpaper$= ""
'wallpaper$= "/img/handy.bmp" 'optional, leave blank if not needed
'wallpaper$= "/img/babys.bmp" 'optional, leave blank if not needed
wallpaperXoffset=0: if (orientation=1) or (orientation=3) then wallpaperYoffset=0 else wallpaperYoffset=44 'wallpaperYoffset=44
hcol=white: hbak=clear: hbor=hbak: hfont=4: halign=4: hxmargin=0: hymargin=2: hxpadding=20: hypadding=0: hxoffset=0: hyoffset=0 'header specs
mcol=black: mbak=white: mpre=red: mbor=white: mfont=3: malign=4: mxmargin=2: mymargin=0: mxpadding=0: mypadding=0: mxoffset=0: myoffset=0 ' menu specs
mhicol=white: mhibak=darkgrey: mhibor=black: mhipre=red 'menu hilite colours
fcol=white: fbak=blue: fpre=red: fbor=white: ffont=4: falign=4: fxmargin=60: fymargin=4: fxpadding=6: fypadding=0: fxoffset=0: fyoffset=0: frad=5 'footer specs
pcol=white: pbak=blue: ppre=red: pbor=white: pfont=4: palign=4: pxmargin=0: pxpadding=10: pxoffset=0: prad=5 'footer specs
ocol=white: obak=blue: opre=red: obor=white: ofont=3: oalign=4: oxmargin=4: oxpadding=8: oxoffset=-0: orad=5 'footer specs
L$="<": M$="=": R$=">": pL$="<<": pR$=">>": RST$="RST": DMP$="DMP" 'nav button texts
if M5stack>0 then 'use hardware buttons
lpin=39: pin.mode lpin,input,pullup: interrupt lpin,lpress
mpin=38: pin.mode mpin,input,pullup: interrupt mpin,mpress
rpin=37: pin.mode rpin,input,pullup: interrupt rpin,rpress
endif
debounce=100
gui_items=30
' no user configuration below this only - all user variables above this line
items=word.count(menu$,",")
dim item$(items)
dim handler(gui_items)
longest=0
for item=1 to items
item$(item) = word$(menu$,item,",") 'or populate item$ array with whatever you prefer
if len(item$(item)) > longest then longest=len(item$(item)) 'record the longest item length
next item
item=1: pageoffset=0 'each offset is a pagelength page of items
tft.init orientation
'gui.init 30, 0 'background '********* check max gui lines needed
'onerror skip
'tft.image wallpaper$,wallpaperXoffset, wallpaperYoffset
'gui.autorefresh 50, 1
'if (orientation=0) or (orientation=2) then sx=Yres: sy=Xres else sx=Xres: sy=Yres
'gui.init gui_items, background 'reserving more than enough gui handlers to re-use for the page lines
gui.autorefresh 50, 1
xsf=0: ysf=0
gosub showit
wait
sub getfiles(search$)
menu$=""
f$=file.dir$(search$)
menu$=f$
wlog f$
while f$ <> ""
f$=file.dir$
wlog f$
menu$=menu$+","+f$
pause 15
wend
pause 9000
end sub
showit:
lookup mfont
mb=yres-mymargin: fh=(8*ffont)+(fypadding*2): if M5stack <> 1 then mb=mb-fyoffset-fymargin-fh
my=mymargin+myoffset
if malign=0 then mw=xres-(mxmargin*2) else mw=(longest+(mxpadding*2))*xsf*mfont
mx=fix((xres)/2) - fix(mw/2)
mh=(ysf*mfont)+mypadding
gui.init gui_items, background
tft.image wallpaper$,wallpaperXoffset, wallpaperYoffset
header$=title$
if header$ > ""
lookup hfont
hw=(len(header$)*hfont*xsf)
if halign=3 then hx=hxmargin
if halign=4 then hx=fix(xres/2) - fix(hw/2)
if halign=5 then hx=xres-hxmargin-hw
hh=(ysf*hfont)+(hypadding*2)
hy=hymargin+hypadding+hyoffset
tft.text.font hfont
tft.text.color hcol,hbak
tft.text.pos hx,hy
tft.print header$
my=hy+hh+mymargin+myoffset
' gui.line(0,my,320,my,yellow) 'if this line is uncommented to add a gui item it makes the gui.target item incorrect
endif
pagelength=cint((mb-my-(mymargin*2))/mh)
lines=pagelength
if (lines+pageoffset) > items then lines = (items-pageoffset)
lookup mfont
for line = 0 to lines-1
pos = line+1+(pageoffset*pagelength)
if items >= pos then
line$=item$(pos)
if malign=3 then mx=mxmargin+mxoffset
if malign=4 then mx=(fix(xres/2)) - (fix(mw/2))
if malign=5 then mx=xres-mxmargin-mxpadding-mxoffset-mw
mh=(ysf*mfont)
handler(line) = GUI.button(mx,my+(mh*(line)),mw, mh, line$, mfont)
gui.setevent handler(line),1,selected
else
handler(line) = GUI.button(mx, my+(mh*(line)), mw, mh, string$(longest," "), mfont)
endif
if pos=item then Gui.SetColor handler(line),mhicol,mhibak,mhipre,mhibor else Gui.SetColor handler(line),mcol,mbak,mpre,mbor'
next line
if M5stack <> 1 then
fy=yres-fymargin-fyoffset-fh
if tb=3 then
lookup ofont
ow=(len(rst$)*ofont*xsf)+(fxpadding*2): ox=oxmargin+oxoffset
rst=GUI.button(ox,fy,ow,fh,rst$,ofont,orad,0,1,ocol,obak,opre,obor): gui.setevent rst,1,Reset
ow=(len(dmp$)*ofont*xsf)+(fxpadding*2): ox=xres-ow-oxmargin-oxoffset
dmp=GUI.button(ox,fy,ow,fh,dmp$,ofont,orad,0,1,ocol,obak,opre,obor): gui.setevent dmp,1,ScreenDump
pxmargin=oxmargin+ow+oxpadding
endif
if tb>1 then
lookup pfont
pw=(len(pL$)*pfont*xsf)+(fxpadding*2): px=pxmargin+pxoffset
plbut=GUI.button(px,fy,pw,fh,pL$,pfont,prad,0,1,pcol,pbak,ppre,pbor): gui.setevent plbut,1,PageLeft
pw=(len(pR$)*pfont*xsf)+(fxpadding*2): px=xres-pw-pxmargin-pxoffset
prbut=GUI.button(px,fy,pw,fh,pR$,pfont,prad,0,1,pcol,pbak,ppre,pbor): gui.setevent prbut,1,PageRight
fxmargin=pxmargin+pw+pxpadding
endif
lookup ffont
fw=(len(L$)*ffont*xsf)+(fxpadding*2): fx=fxmargin+fxoffset
lbut=GUI.button(fx,fy,fw,fh,L$,ffont,frad,0,1,fcol,fbak,fpre,fbor): gui.setevent lbut,1,NavLeft
fw=(len(R$)*ffont*xsf)+(fxpadding*2): fx=xres-fw-fxmargin-fxoffset
rbut=GUI.button(fx,fy,fw,fh,R$,ffont,frad,0,1,fcol,fbak,fpre,fbor): gui.setevent rbut,1,NavRight
fw=(len(M$)*ffont*xsf)+(fxpadding*2): fx=fix(xres/2)-fix(fw/2)
mbut=GUI.button(fx,fy,fw,fh,M$,ffont,frad,0,1,fcol,fbak,fpre,fbor): gui.setevent mbut,1,NavMid
endif
wlog "ramfree="+str$(ramfree)
pause debounce
return
sub lookup(font) 'the following scale factors work for me, but can be changed to suit if preferred
Select case font
case 1: xsf=6.6: ysf=8
case 2: xsf=3.7: ysf=8
case 3: xsf=4.0: ysf=8
case 4: xsf=3.5: ysf=8
case 5: xsf=3.7: ysf=8
case else: xsf=6: ysf=8
end select
end sub
PageLeft:
item=item-pagelength: dec pageoffset
if item < 1 then item=1: pageoffset=0
if pageoffset < 0 then pageoffset=0
gosub showit
return
PageRight:
item=item+pagelength
if item > items then item = items
pageoffset=fix(item/pagelength)
gosub showit
return
Reset:
wlog "Rebooting"
pause 3000
reboot
gosub showit
return
ScreenDump:
wlog "Save screen to file"
tft.save "/dumpfile.dat"
pause 3000
gosub showit
return
NavLeft:
dec item
if item < 1 then item = items: pageoffset=fix(item/pagelength)
if (item mod pagelength) = 0 then dec pageoffset
gosub showit
return
NavRight:
inc item
if item > items then item = 1: pageoffset=0
if (item mod pagelength) > 0 then pageoffset=fix(item/pagelength)
gosub showit
return
NavMid:
gui.init 5,yellow
wlog "selected="+item$(item)
'do soething with the selected item$(item)
line$=" "+item$(item)+" "
sfont=5: lookup sfont
sw=(len(line$)*sfont*xsf)
sx=fix(xres/2)-fix(sw/2)
sh=(8*sfont)
sy=fix(yres/2)-fix(sh/2)
sel=GUI.button(sx,sy,sw,sh,line$,sfont,0,1,1,yellow,black,red,magenta)
pause 3000
gosub showit
return
selected:
gui.init 5,red
wlog "target="+str$(gui.target)
item = gui.target+1+(pageoffset*pagelength)
wlog "selected="+item$(item)
'do soething with the selected item$(item)
line$=" "+item$(item)+" "
sfont=5: lookup sfont
sw=(len(line$)*sfont*xsf)
sx=fix(xres/2)-fix(sw/2)
sh=(8*sfont)
sy=fix(yres/2)-fix(sh/2)
sel=GUI.button(sx,sy,sw,sh,line$,sfont,0,1,1,yellow,black,red)
pause 3000
gosub showit
return
sub inc(it)
it=it+1
end sub
sub dec(it)
it=it-1
end sub
END '------------------ END -------------------
'touch.calib: reboot 'uncomment to run once and re-calibrate after changing screen orientation
M5stack=2 '0 for touch buttons only, 1 for M5stack hardware buttons only, 2 for both
Xres=320: Yres=240 'TFT screen size
'Xres=480: Yres=320 'TFT screen size for 4"
orientation=1 '0=Portrait, 1=Landscape, 2=Portrait reversed, 3=Landscape reversed
'pre-define some useful colours
black=0: white=tft.rgb(255,255,255): red=tft.rgb(255,0,0): green=tft.rgb(0,255,0): blue=tft.rgb(0,0,255)
cyan=green+blue: pink=red+blue: orange=tft.rgb(255,165,0): yellow=tft.rgb(255,255,5)
lightgrey=tft.rgb(200,200,200): darkgrey=tft.rgb(128,128,128): clear=-1
background=black: buttoncolour=black: buttonbackground=lightgrey: buttontouched=darkgrey
background=blue '*****************
wallpaper$= "/img/handy.bmp" 'optional, leave blank if not needed
'wallpaper$= "/img/babys.bmp" 'optional, leave blank if not needed
wallpaperXoffset=0: if (orientation=1) or (orientation=3) then wallpaperYoffset=0 else wallpaperYoffset=44 'wallpaperYoffset=44
title$="" 'leave blank to omit top headet
title$=" Flexy Menu " 'leave blank to omit top headet
titleFont=4
titleAlign=3 '3 for left, 4 for middle, 5 for right
titleColour=yellow
titleBackground=blue
titleBorder=white
titleXmargin=0
titleYmargin=0
titleXpadding=0
titleYpadding=3
titleYoffset=0
buttonFont=3
LeftTouch$="<"
MidTouch$="OK"
RightTouch$=">"
buttonColour=blue'black
buttonBackground=lightgrey
buttonTouched=red
buttonborder=black
buttonRadius=6
buttonXmargin=10
buttonYmargin=1
buttonXpadding=16
buttonYpadding=2
windowBackground=clear 'can be clear or -1 for transparent, or any valid solid colour
'windowBackground=0 'darkgrey 'can be clear or -1 for transparent, or any valid solid colour
windowFrame=blue
windowXmargin=0
windowYmargin=0
windowXpadding=0
windowYpadding=0
windowYoffset=0
menu$="one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen"
menuFont=4
menuAlign=0 '0=full width-margins, 1=fit longest item
menuColour=cyan
menuBackground=blue
menuHiliteText=blue
menuHiliteBack=white
menuPressed=red
menuBorder=menuBackground
menuRadius=0
menuSelect=red
menuXmargin=2
menuYmargin=0
menuXpadding=2
menuYpadding=0
menuYoffset=1
stats=3 '0none, 1=pages,2=items, 3=pages+items, 4=items+pages, 5=clear line, 6 test numbers, 6 user info
statAlign=4 '0=top left, 1=top middle, 2=top right, 3=mid left, 4=mid middle, 5=mid right
statFont=3
statColour=blue
statBackground=clear
statBorder=statBackground
statwindow=clear
statXmargin=1
statYmargin=2
statXpadding=0
statYpadding=0
'statAlign=4
'------ script start -------
tft.init orientation
gui.init 30, background '********* check max gui lines needed
'onerror skip
tft.image wallpaper$,wallpaperXoffset, wallpaperYoffset
gui.autorefresh 50, 1
if (orientation=0) or (orientation=2) then sx=Yres: sy=Xres else sx=Xres: sy=Yres
xcentre=fix((sx/2)-1): ycentre=fix((sy/2)-1): 'screen centre coordinates
ww=sx-(windowXmargin*2) 'window width
wx=sx-ww-windowXmargin 'window horizontal origin
wh=sy-(windowYmargin*2) 'window height
wy=sy-wh-windowYmargin 'initial window vertical origin (will change if gui items added)
windowBackground=clear
if windowBackground=clear then window=gui.rect(wx,wy,ww,wh,windowFrame) else window=gui.box(wx,wy,ww,wh,windowBackground,windowFrame)
sf=0 'scale factor to adjust width of different fonts from sub lookup
debounce=100
line=0: lines=0: pos=1: offset=0
items=word.count(menu$,",")
dim item$(items)
'dim handler(items)
longest=0
for c=1 to items
item$(c) = word$(menu$,c,",")
if len(item$(c)) > longest then longest=len(item$(c))
next c
pagelength=0: line=0: page=0: pages=0
wlog "longest="+str$(longest)
wlog "ramfree="+str$(ramfree)+" flashfree="+str$(fix(flashfree/1000000))+"Mb"
if M5stack>0 then 'use hardware buttons
lpin=39: pin.mode lpin,input,pullup: interrupt lpin,lpress
mpin=38: pin.mode mpin,input,pullup: interrupt mpin,mpress
rpin=37: pin.mode rpin,input,pullup: interrupt rpin,rpress
endif
gosub display
'if menu$>"" then gosub menu
wait
display:
'title$=""
tx=0
if title$>"" then
lookup titlefont
tw=(len(title$) * titleFont * sf) + (titleXpadding * 2)
if titleAlign=3 then tx=titleXmargin
if titleAlign=4 then tx=xcentre-fix(len(title$)/2 * sf * titlefont) - titleXpadding
if titleAlign=5 then tx=sx-titleXmargin-tw
th=(8*titleFont) + (titleYpadding * 2)
ty=titleYmargin+titleYoffset
title=GUI.Textline(tx, ty, tw, th, title$, titleFont, titleColour, titleBackground, titleBorder)
gui.setstyle title, 4, titleXpadding
wy=wy+th
wh=wh-th
endif
if M5stack<>1 then gosub touchNav 'use touch buttons
if stats>0 then
item=1: page=1: pages=2
select case stats '0none, 1=pages,2=items, 3=pages+items, 4=items+pages, 5=clear line, 6 test numbers, 6 user info
case 1: stat$="Page "+str$(page)+" of "+str$(pages) 'Pages
case 2: stat$=str$(item)+" of "+str$(items) 'Items
case 3: stat$=time$ 'Time
case 4: stat$=" " 'blank
case 5: stat$="12345" 'test info
case else: stat$="enter your own User info here" 'user info
end select
lookup statFont
stat1$="Page "+str$(page)+" of "+str$(pages) 'Pages
stat2$="Item "+str$(item)+" of "+str$(items) 'Items
stat1w=(len(stat1$) * sf * statFont) + (statXmargin) 'stats width
stat2w=(len(stat2$) * sf * statFont) + (statXmargin)
if statAlign < 3 then
if stat1w > stat2w then statw=stat1w else statw=stat2w
else
statw=stat1w + statXpadding + stat2w
endif
stath=(8*statFont)+(statYpadding*2) 'stats height
select case statAlign
case 0: 'wlog "top left"
staty=ty+statYmargin: by=ty: bh=th
if titleAlign=3 then statX=tx+tw+statXmargin: bx=tx+tw: bw=sx else statx=statXmargin: bx=0: bw=sx-tx
case 1: 'wlog "top middle"
staty=ty+statYmargin: by=ty: bh=th
if titleAlign=3 then statX=fix(tw+((sx-tw)/2)) - fix(statw/2): bx=tx+tw: bw=sx else statX=fix(tx/2) - fix(statw/2): bx=0: bw=sx-tx
case 2: 'wlog "top right"
staty=ty+statYmargin: by=ty: bh=th
if titleAlign=3 then statX=sx-statw-(statXmargin*2): bx=tx+tw: bw=sx else statx=tx-statw-(statXmargin*2): bx=0: bw=sx-tx
case 3: 'middle left"
by=ty+th: bh=stath+(statYmargin*2): bx=0: bw=sx
statx=statXmargin
staty=ty+th+statYmargin
wh=wh-stath-statYmargin
wy=staty+stath+windowYmargin
case 4: 'middle middle
by=ty+th: bh=stath+(statYmargin*2): bx=0: bw=sx
statX=fix((sx)/2) - fix(statw/2)
staty=ty+th+statYmargin
wh=wh-stath-statYmargin
wy=staty+stath+windowYmargin
case 5: 'middle right
by=ty+th: bh=stath+(statYmargin*2): bx=0: bw=sx
statX=sx-statw-statXmargin
staty=ty+th+statYmargin
wh=wh-stath-statYmargin
wy=staty+stath+windowYmargin
case 6: 'bottom left
wh=wh-stath-statYmargin
by=by-stath-(statYmargin*2): bh=stath+(statYmargin*2): bx=0: bw=sx
statx=statXmargin
staty=by+statYmargin
case 7: 'bottom middle
wh=wh-stath-statYmargin
by=by-stath-(statYmargin*2): bh=stath+(statYmargin*2): bx=0: bw=sx
statX=fix((sx)/2) - fix(statw/2)
staty=by+statYmargin
case 8: 'bottom right
wh=wh-stath-statYmargin
by=by-stath-(statYmargin*2): bh=stath+(statYmargin*2): bx=0: bw=sx
statX=sx-statw-statXmargin
staty=by+statYmargin
case else
end select
'statwindow=green
if statwindow>0 then gui.box(bx+1,by,bw-1,bh,statwindow,windowframe) 'fill stat window with statwindow colour
if statAlign < 3 then
statw=(len(stat$) * sf * statFont) + (statXpadding)
if stat1$>"" then stat1=GUI.Textline(statx+statxmargin,staty, statw, stath, stat1$, statFont, statColour, statBackground, statBorder,4)
if stat2$>"" then stat2=GUI.Textline(statx+statxmargin,staty+stath+statypadding, statw, stath, stat2$, statFont, statColour)', statBackground, statBorder,4)
else
if stat1$>"" then stat1=GUI.Textline(statx+statxmargin,staty, stat1w, stath, stat1$, statFont, statColour, statBackground, statBorder,4)
if stat2$>"" then stat2=GUI.Textline(statx+stat1w+statxpadding,staty, stat2w, stath, stat2$, statFont, statColour)', statBackground, statBorder,4)
endif
gui.setcolor stat2,blue,cyan
endif
' windowBackground=red' darkgrey '*************************
if windowBackground=clear then window=gui.rect(wx,wy,ww,wh,windowFrame) else window=gui.box(wx,wy,ww,wh,windowBackground,windowFrame)
if menu$>"" then gosub menu
return
menu:
menufont=3
lookup menuFont
menuAlign=1
menuXmargin=4
menuXpadding=1
' menuBackground=clear
menuBorder=white
if menuAlign=0 then mw=sx-(menuXmargin*2) else mw=(longest+(menuXpadding*2)) * sf * menuFont
mx=fix((sx)/2) - fix(mw/2)
mh=(8*menuFont) + menuYpadding
my=wy+1+menuYmargin+menuYoffset
page=1:line=1
pagelength=fix((wh-2-(menuYmargin*2)-menuYpadding) / mh)
dim handler(pagelength)
pos=5
pages=fix(items / pagelength)
if items mod pagelength > 0 then pages=pages+1
'spy "276"
gosub showlist
' stat1$="Page "+str$(page)+" of "+str$(pages) 'Pages
' stat2$="Item "+str$(pos+offset)+" of "+str$(items) 'Items
'gui.settext stat1, stat1$
'gui.settext stat2, stat2$
return
showlist:
lines = pagelength' else lines=(items mod pagelength)
'wlog lines
if (lines+offset) > items then lines = (items-offset)
for c = 1 to pagelength
if items > (c + offset) then
line$ = string$(menuXpadding," ") + item$(c+offset) + string$(menuXpadding," ")
else
line$=string$(longest," ")
endif
wlog str$(c)+"," + line$
item=c+offset
handler(c)=GUI.button(mx+menuXpadding, my+(mh*(c-1)),mw-menuXpadding, mh, line$, menuFont, menuRadius, 0, 1, menuColour, menuBackground, menuPressed, white )'menuBorder)
'GUI.button(mx+menuXpadding, my+(mh*(c-1)),mw-menuXpadding, mh, str$(c), menuFont, menuRadius, 0, 1, menuColour, menuBackground, menuPressed, white )'menuBorder)
if c=pos then Gui.SetColor handler(c), menuHiliteText, menuHiliteBack, menuPressed', menuHiliteBorder
wlog "handler(c)="+str$(handler(c))
'pause 50
next c
stat1$="Page "+str$(page)+" of "+str$(pages) 'Pages
stat2$="Item "+str$(pos+offset)+" of "+str$(items) 'Items
gui.settext stat1, stat1$
gui.settext stat2, stat2$
spy "showlist"
'line=1
return
clearlist:
for c = 1 to pagelength 'lines
line$ = string$(longest," ")
handler(c)=GUI.button(mx+menuXpadding, my+(mh*(c-1)),mw-menuXpadding, mh, line$, menuFont, menuRadius, 0, 1, menuColour, menuBackground, menuPressed, white )'menuBorder)
next c
return
sub spy(from$)
wlog "spyig from "+from$
wlog " pos="+str$(pos)+", offset="+str$(offset)+", page="+str$(page)+", pages="+str$(pages)
wlog " line="+str$(line)+", lines="+str$(lines)+", pagelength="+str$(pagelength)+", items="+str$(items)
end sub
sub lookup(font) 'the following scale factors work for me, but can be changed to suit if preferred
if font=1 then sf=6.5 else if font=2 then sf=3.5 else if font=3 then sf=4.2 else if font=4 then sf=3.5 else sf=3.7
end sub
selected:
selection$ = word$(menu$,(item*page),",")
wlog selection$
return
ok:
gosub selected
return
xxxxleft:
' Gui.SetColor handler(line), menuColour, menuBackground, menuPressed, menuBorder
pos = pos-1
if pos<1 then pos=lines: offset=offset-1
if offset<0 then pos=lines: offset=items-lines: gosub clearlist
gosub showlist
spy " left after"
' Gui.SetColor handler(line), menuHiliteText, menuHiliteBack, menuPressed', menuHiliteBorder
' gosub display
return
right:
wlog line
' Gui.SetColor handler(line), menuColour, menuBackground, menuPressed, menuBorder
pos = pos + 1
if pos > items then pos = 1: offset = 0
if pos > lines then offset = offset+lines: pos = 1 ': gosub clearlist 'lines
if offset+lines > items then offset = 0: pos=1: gosub clearlist
gosub showlist
' line=1
' endif
spy "right"
' Gui.SetColor handler(line), menuHiliteText, menuHiliteBack, menuPressed', menuHiliteBorder
' gosub display
return
touchNav:
if (orientation=0) or (orientation=2) then buttonXmargin=buttonXmargin+18 else buttonXmargin=buttonXmargin+40
lookup buttonFont
'=1 then sf=6.5 else if buttonFont=2 then sf=3.5 else if buttonFont=3 then sf=4.3 else if buttonFont=4 then sf=3.5 else sf=3.7
bw=(len(MidTouch$) * sf * buttonFont) + (buttonXpadding * 2)
bx=Xcentre-fix(bw/2)
bh=(8*buttonFont) + (buttonYpadding * 2)
wh=wh-bh-buttonYpadding
by=sy-bh-buttonYmargin
mbut=GUI.button(bx,by,bw,bh,MidTouch$,buttonFont,buttonRadius)
gui.setcolor mbut, buttoncolour, buttonbackground, buttontouched, buttonborder
bw=(len(LeftTouch$) * sf * buttonFont) + (buttonXpadding * 2)
bx=buttonXmargin
lbut=GUI.button(bx,by,bw,bh,LeftTouch$,buttonFont,buttonRadius)
gui.setcolor lbut, buttoncolour, buttonbackground, buttontouched, buttonborder
bw=(len(RightTouch$) * sf * buttonFont) + (buttonXpadding * 2)
bx=sx-buttonXmargin-bw
rbut=GUI.button(bx,by,bw,bh,RightTouch$,buttonFont,buttonRadius)
gui.setcolor rbut, buttoncolour, buttonbackground, buttontouched, buttonborder
gui.setevent mbut,1,mtouch 'where to jump when middle button touched
gui.setevent lbut,1,ltouch 'where to jump when left button touched
gui.setevent rbut,1,rtouch 'where to jump when right button touched
return
mtouch:
gui.setcolor title, white, red 'changes title bar colours just to show some touch activity
gosub ok
pause debounce
return
ltouch:
gui.setcolor title, black, green 'changes title bar colours just to show some touch activity
gosub left
pause debounce
return
rtouch:
gui.setcolor title, black, yellow 'changes title bar colours just to show some touch activity
gosub right
pause debounce
return
mpress:
if (pin(mpin)=0) then gui.setcolor title, black, orange 'changes title colour to show button pressed
gosub ok
pause debounce
return
lpress:
if (pin(lpin)=0) then gui.setcolor title, black, cyan 'changes title colour to show button pressed
gosub left
pause debounce
return
rpress:
if (pin(rpin)=0) then gui.setcolor title, black, pink 'changes title colour to show button pressed
gosub right
pause debounce
return
end '------ End -------
You do not have the required permissions to view the files attached to this post.
- Electroguard
- Posts: 867
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 278 times
- Been thanked: 324 times
Re: ESP32 Save problems in Editor
I've been sick as a dog since the original post, so have not done anything.
But is not a problem for me to test future menu development using an earlier firmware, so what previous version do you want me to test with... would Annex32 1.43.3 CAN BLE be ok ? or do you want earlier ?
BTW, the problem seemed more noticeable when doing small quick parameter changes - which may have amplified the situation because the script had not halted on error, and I was too impatient to click Stop before Saving small variable changes. And although I can't be sure in hindsight, but I think I noticed delayed writes to the wlog window even after the script had been Stopped.
So to avoid bottlenecks, and give Annex the best chance of coping with the complex script, I changed my programming habits to click Stop, Clear Ram and clear the wlog window before Saving and Running any edits.
I must have thought it beneficial to give Annex that extra time to catch its breath, else I probably wouldn't have persevered doing it... which might be significant, because it could suggest the problem may not actually be file-related.
But is not a problem for me to test future menu development using an earlier firmware, so what previous version do you want me to test with... would Annex32 1.43.3 CAN BLE be ok ? or do you want earlier ?
BTW, the problem seemed more noticeable when doing small quick parameter changes - which may have amplified the situation because the script had not halted on error, and I was too impatient to click Stop before Saving small variable changes. And although I can't be sure in hindsight, but I think I noticed delayed writes to the wlog window even after the script had been Stopped.
So to avoid bottlenecks, and give Annex the best chance of coping with the complex script, I changed my programming habits to click Stop, Clear Ram and clear the wlog window before Saving and Running any edits.
I must have thought it beneficial to give Annex that extra time to catch its breath, else I probably wouldn't have persevered doing it... which might be significant, because it could suggest the problem may not actually be file-related.
- cicciocb
- Site Admin
- Posts: 2069
- Joined: Mon Feb 03, 2020 1:15 pm
- Location: Toulouse
- Has thanked: 441 times
- Been thanked: 1364 times
- Contact:
Re: ESP32 Save problems in Editor
Hi Robin,
sorry but I'm doing other stuff actually so cannot deeply investigate.
So far I cannot easily reproduce the problem, such it seems the case for you.
I'll continue to test
sorry but I'm doing other stuff actually so cannot deeply investigate.
So far I cannot easily reproduce the problem, such it seems the case for you.
I'll continue to test
- cicciocb
- Site Admin
- Posts: 2069
- Joined: Mon Feb 03, 2020 1:15 pm
- Location: Toulouse
- Has thanked: 441 times
- Been thanked: 1364 times
- Contact:
Re: ESP32 Save problems in Editor
HI Robin,
I did some tests with the version 1.43.5 with a 16GB SDCARD.
I cannot reproduce the problem .
See this video
I did some tests with the version 1.43.5 with a 16GB SDCARD.
I cannot reproduce the problem .
See this video
- Electroguard
- Posts: 867
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 278 times
- Been thanked: 324 times
Re: ESP32 Save problems in Editor
I suspect it is a busy Annex bottleneck delay Francesco (rather than File system), which can take several seconds (or sometimes never) to unravel.
When a script halts on error it is already halted, so there is nothing bottled up to get untangled.
But if the script is still running when (eg:) editing a variable, I suspect the Save causes Annex to queue up the request until after untangling the existing running script, but things may get scrambled.
I've made it happen on a completely different script which also has complex gui.component handling (the gui.handler bug won't be helping).
The obvious short-term answer is try to remember to Stop the script before Saving edits, but I find I am now frequently clicking the Stop button on an already stopped script because there is no obvious indication of whether the script is running or not.
So the addition of a 'script-running' indicator to the Editor might be useful (especially if coupled to a single combined Run/Stop toggle button).
Or perhaps some sort of Editor feedback might be available whereby editing a script could automatically stop the running script before the edits are Saved.
When a script halts on error it is already halted, so there is nothing bottled up to get untangled.
But if the script is still running when (eg:) editing a variable, I suspect the Save causes Annex to queue up the request until after untangling the existing running script, but things may get scrambled.
I've made it happen on a completely different script which also has complex gui.component handling (the gui.handler bug won't be helping).
The obvious short-term answer is try to remember to Stop the script before Saving edits, but I find I am now frequently clicking the Stop button on an already stopped script because there is no obvious indication of whether the script is running or not.
So the addition of a 'script-running' indicator to the Editor might be useful (especially if coupled to a single combined Run/Stop toggle button).
Or perhaps some sort of Editor feedback might be available whereby editing a script could automatically stop the running script before the edits are Saved.
- cicciocb
- Site Admin
- Posts: 2069
- Joined: Mon Feb 03, 2020 1:15 pm
- Location: Toulouse
- Has thanked: 441 times
- Been thanked: 1364 times
- Contact:
Re: ESP32 Save problems in Editor
Robin, It is probably a network problems, maybe the module is too far from the router or you have multiple subnets.
It could also be a power supply problem.
It could also be a power supply problem.
- Electroguard
- Posts: 867
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 278 times
- Been thanked: 324 times
Re: ESP32 Save problems in Editor
Thanks for the suggestions sir, but my development power supply is rock solid, as is my wifi connection (exactly because it is next to a subnet repeater).
As you know, rather than 'halt-on-error' I prefer seeking my own viable work-arounds to problems, then raise awareness of issues to potential benefit Annex in the future... so if I'm the only person affected it can be forgotten about, but if others experience similar problems then there's already been a 'heads up'.
The queued bottleneck delays are not holding me back, and maybe nobody else will ever be affected - but if it does ever need a fix, then a relatively simple future solution could be a toggle button to Stop or Run the script and which changes colour depending on whether the script is running or not.
I only briefly mentioned the gui.handler array referencing problems because I thought you might already be aware of it (due to the frequent use of gui.init in secondary gui example pages), but if you are not already aware I can raise a specific detailed bug report about it if you wish... else I will keep on tiptoing around the bug and move on, now that I have it pinned down. If not fixed though, the problem will probably affect others after your excellent gui examples are published which will make people want to start using the gui objects more.
As you know, rather than 'halt-on-error' I prefer seeking my own viable work-arounds to problems, then raise awareness of issues to potential benefit Annex in the future... so if I'm the only person affected it can be forgotten about, but if others experience similar problems then there's already been a 'heads up'.
The queued bottleneck delays are not holding me back, and maybe nobody else will ever be affected - but if it does ever need a fix, then a relatively simple future solution could be a toggle button to Stop or Run the script and which changes colour depending on whether the script is running or not.
I only briefly mentioned the gui.handler array referencing problems because I thought you might already be aware of it (due to the frequent use of gui.init in secondary gui example pages), but if you are not already aware I can raise a specific detailed bug report about it if you wish... else I will keep on tiptoing around the bug and move on, now that I have it pinned down. If not fixed though, the problem will probably affect others after your excellent gui examples are published which will make people want to start using the gui objects more.
- cicciocb
- Site Admin
- Posts: 2069
- Joined: Mon Feb 03, 2020 1:15 pm
- Location: Toulouse
- Has thanked: 441 times
- Been thanked: 1364 times
- Contact:
Re: ESP32 Save problems in Editor
Hi Robin,
about the file save delay, I hope that someone else will raise this problem as I cannot reproduce this problem on my configuration.
About the GUI, I still did not analysed your code (not very easy to understand) but I suppose that you are redrawing the objects each time when you want change any attribute.
I fact as soon as the objects are created, you can simply modify one of the parameters (text, color, border, etc) and it will be updated by the GUI when the gui.refresh command is run or automatically with gui.autorefresh.
So, for example, if you want change the text from black to white, you can simply use the command gui.setcolor and run a gui.refresh (or it will be done automatically by gui.autorefresh).
So the logic is :
- 1) create all the objects with the initial parameters
- 2) change any attribute during the execution of the code
- 3) refresh with gui.refresh or automatically with gui.autorefresh
As soon as the page changes, a new gui.init is required and the objects for the new page can be created taking into account that the new page will be drawn only when the command gui.refresh is executed.
about the file save delay, I hope that someone else will raise this problem as I cannot reproduce this problem on my configuration.
About the GUI, I still did not analysed your code (not very easy to understand) but I suppose that you are redrawing the objects each time when you want change any attribute.
I fact as soon as the objects are created, you can simply modify one of the parameters (text, color, border, etc) and it will be updated by the GUI when the gui.refresh command is run or automatically with gui.autorefresh.
So, for example, if you want change the text from black to white, you can simply use the command gui.setcolor and run a gui.refresh (or it will be done automatically by gui.autorefresh).
So the logic is :
- 1) create all the objects with the initial parameters
- 2) change any attribute during the execution of the code
- 3) refresh with gui.refresh or automatically with gui.autorefresh
As soon as the page changes, a new gui.init is required and the objects for the new page can be created taking into account that the new page will be drawn only when the command gui.refresh is executed.