Your Pages‎ > ‎

Hints Tips Gotcha's

Please add any of your Hints, Tips and Gotchas below...

Hint - If the Toolkit Serial Flasher does not register a subsequently opened com port, close the Toolkit and re-open it again. Electroguard 24/3/18
Tip - remember to include ONHTMLRELOAD command to all scripts using web pages that you may need to re-connect to.  Electroguard 1/4/18
Tip - To avoid losing unsaved edits after losing connection, do Select All and Copy, then Paste back again AFTER browser reconnection.
- When clicking Reconnect in browser after losing browser connection, the script showing in the editor has already lost its association with the ESP file, so remember to click Save (or Open then reload) to link the editor script back to the file again or it will not Run.  Electroguard 2/4/18
Gotcha - If you see the popup message "Not Saved" after saving a script, it is likely that your SPIFFS file system has become corrupted.
  Don't Worry... it should be recoverable without anything being lost.
First thing to do is Copy & Paste your latest unsaved edited script to a computer file (which you should be doing periodically anyway).
SPIFFS copes with a lot, but if it has a 'nervous breakdown' it is not able to recover by itself, so it needs your help.
And remember that once SPIFFS has been corrupted, anything else you try to make it do is likely to just make matters worse.
So don't 'flap', just calmly use the...
Magic Button
- Right-click and open a new File Manager tab, then click the 'Repair Disk' button. There is no feedback, so you will need to be sensible and allow it a minute to work its magic. I have not needed to use it often, but when I have, it has always fixed SPIFFS every time.
Next, try to understand what caused the problem, so you can prevent the same thing from happening again straight away.
Perhaps the maximum number of filename characters was exceeded... maybe with an embedded font or image name - so obviously shorten it.
But 99% of times it will be because SPIFFS ran out of available free space - and don't be fooled that Flash Free reports more available than your file size ... because SPIFFS must dynamically use different parts of flash memory to avoid exceeding the maximum number of flash writes in any one area, plus it also needs its own buffer requirements. As a safe rule of thumb you should keep 100K of free Flash available to avoid problems.
Obviously you must claw back sufficient free space for SPIFFS to be able to save your file, but equally obviously that means deleting files.
So I suggest you take whatever precautions you think appropriate to back up your device contents before you start deleting them.
Make sure you don't do anything that causes SPIFFS to write any file details, else you will probably give it another nervous breakdown.
Use the Toolkit to download all files to a selected downloads folder or zip. If you have serial connection you could take a binary data backup.
Aim to free up at least 100K of available Free Flash, then it would be prudent to use the 'Repair Disk' Magic Button again, just to make sure SPIFFS is still ok before trying to Save your file again.   Electroguard 2/5/18
Gotcha - Never use REFRESH before clearing the previous HTML page.  Otherwise, the previous HTML page will request variables not existing in the code and you may experience unjustified "NO SUCH VARIABLE" errors.   ciccioCB 19/05/18
Gotcha - The Block Comments feature is great - drag the cursor down to select lines for commenting out, then click the green comment button.
If only 1 line needs commenting out, then simply place the cursor at the beginning of the line without needing to drag it down to select the line.
BUT ... there-in lies the gotcha trap... cos if you drag the cursor down to select lines, it also affects the next line below the selected lines.
Doesn't matter when it's a blank line (as below), but when it accidentally comments out a necessary line of your code it can really mess things up !

So remember not to include the last line to be commented with your selection drag, else it will comment the next line also.  Electroguard  22/05/18
TIP - Debugging run-rime errors:
Most script lines will include a mixture of commands or functions, and string$ or numeric data, but incorrectly trying to manipulate the wrong sort of data for a command or function can cause what may seem like command or function errors - so here's how I find my mistakes.
Firstly, I split up the error line into smaller multi-line morsels if possible, eg: IF expression THEN do_this ELSE do_that  can be split over several lines to help pinpoint the culprit line - the lines can easily be optimised again after finding and fixing the problem.
IF expression THEN

Sometimes I cannot see the wood for the trees, and the harder I stare at the problem, the harder it can be to spot.
It may sound simple and obvious, but I am regularly tripping myself up by omitting the $ from a string variable, thus treating it as numeric - which obviously does not go down well with any string function which is trying to process it.
Similarly, I often carelessly omit the $ from a string function, which results in a function that does not exist.
Missing a dot from between a double.barrel instruction is another common mistake which can be hard to notice until it becomes a familiar suspect.
So a good tip is to use the Online Help - and it can be surprising how obvious the mistake may be after pressing F2 on an instruction and discovering the Online Help does not recognise and jump to the entry because of (eg:) an omitted $ or dot (period).

If all the instructions are recognised by Online Help, and therefore correct, it's time to ensure all the data is correct for those instructions.
A test PRINT of a variable name will show if that variable is valid, but bear in mind that PRINT will work with a mixture of string$ and numeric data.
Which can be misleading, because WLOG will print time$ which is a character string$, but not timeunix(time$) which evaluates to a number.
The same holds true for html which also can only handle text characters - so if you want to display numeric values you need to break the string, add the string equivalent of the converted numeric value, eg:str$(number), then add back the remainder of the html line afterwards.

Sometimes my IF THEN ELSE ENDIF 'logic' may be wrong, which can give misleading symptoms on some lines which are actually ok.
A tip I use to keep logical track is to add a matching comment to the ENDIF (and perhaps ELSE) which refers to what IF THEN it relates to.
This also makes my forgotten 'weird' logic a bit easier to re-understand later:

IF buttonpress THEN
  IF pin(buttonpin) = 0 THEN
  ENDIF 'pin(buttonpin)
ELSE  'buttonpress
ENDIF  'buttonpress

Don't forget you can insert an END wherever you wish to prematurely terminate, to (eg:) isolate where a data problem may be creeping in.
I've learned that the problem is inevitably my fault (usually carelessness) even though it may take a while to find it... so to just keep on looking.
Electroguard 29/5/18
Gotcha - I know from past experiences over a year ago that these cheap little radar modules worked great.

So I couldn't understand why they did not work well with Annex.
Until I remembered that in the past people had problems with other radar sensors which operated at different frequencies, Hmm...  over a year ago I had been using these modules on 40Mhz espbasic, but now Annex defaults to 80Mhz.
So I tried a green button firmware update, flashing to 40Mhz instead of 80Mhz, and the modules now work great with Annex.

In a nutshell, any device which will be using these radar modules should be flashed to 40Mhz rather than the default of 80Mhz.

It may also help to increase separation by using use longer connecting cables. 

Electroguard 11/7/18
TIP - Scripts Running Scripts:
Annex cannot yet 'Run' a script from another script - but it can be done... by hijacking the Autorun feature.

Basically, the running script inserts the name of the 'file to be run' into the config.ini Autorun field, then reboots.
If the 'file to be run' needs to return to the original calling script again afterwards, it simply inserts the name of the original calling file back into config.ini Autorun, then it will return when rebooted. Obviously all variables are lost at power-on or reboot, but it is easy enough to save any needed variables into a 'persistent' parameters file if wished.

The 'mechanism' to read 'Autorun=' value from config.ini and write back a different value is quite straight-forward.
The same mechanism can also be used to save your own parameter=value pairs into config.ini if you wish, or into any other chosen data file for that matter.
This allows different scripts to share data.

Selecting different scripts to Autorun can offer some interesting possibilities, such as a 'Main' script which can run different 'Modules' when needed.
It also offers potential for a files 'Menu' which can run different selected Basic scripts, or "Apps"..
Consider a device with tft or oled display and perhaps a rotary encoder or buttons for menu navigation and selection.
Include all your favourite scripts on it (wifi scanner, i2c scanner, etc), and create a menu which autoruns for choosing a selected script.
When a script is selected from the menu it inserts the appropriate script name into the config.ini Autorun entry then reboots the device to autorun the selected script.

In the example snippet below, the menu script initially reads config.ini into config$ using the line...
 config$ =$("/config.ini")

Then, let's assume a menu choice of...
 selection$ = "/program/wifiscanner.bas"

Now it's just a matter of updating config.ini with the selected filename to be autorun...
 word.setparam config$, "Autorun", selection$, ":" "/config.ini", config$

All scripts selected from the menu can include code to revert config.ini back to autorun the original menu again, so when finished with a  selected script, just reboot to re-run the menu...
 config$ =$("/config.ini"):  word.setparam config$, "Autorun", "/program/menu.bas", ":": "/config.ini", config$
If you are adventurous, you might list all files from a specified folder into your menu - selecting a chosen file could then RUN it if a .bas script, or display its contents if .txt or .ini or .log, or any other action based on recognised extention association.
Electroguard 24/9/18
HINT - Memory Leaks
CiccioCB has done an excellent job of finding and fixing most memory leaks, so if you have a 'leaky' script it's most likely the programming, rather than the firmware. Memory is mostly used by your data variables, so if you don't keep flushing them and re-using them, they will be using up unnecessary memory. The only way to claw back memory being used by your variables is to lose the data they contain... I sometimes schedule a reboot, saving any important data to file first, for reloading after the reboot.

But obviously it is better to find and fix the cause of the problem.

First, set Option.lowmem to something above the default threshold of 10,000 (ie: 12000) - this won't prevent it running out of memory, but at least it will end in an orderly manner rather than crashing from corruption.

Second, create a subdir to do a RAMFREE check, which you can then call from various points in the script to see where it gets affected most... so you also want to show what parts of the script are calling it, ie:
  wlog "Area51": gosub RAMCHECK
(see next tip - Breadcrumb Trail)

Third, I said do ramfree from a subroutine because you can then read the value into a variable each time, and only flag up significant changes from previous, to prevent being overloaded by clutter.
Therefore you can flag up only drops in memory which are outside a threshold level you specify.
Then you can pay special attention to just those culprit areas.
It also allows you to take 'avoiding action' before the brown stuff hits the fan... perhaps save important variables to file then instigate a REBOOT, then reload the important variables when the script is run again by the autorun facility.
Electroguard 2/10/18

TIP - Breadcrumb Trail
To aid debugging, after each subroutine declaration (eg: buttonpress:) add (eg) branch$= plus the name of the subroutine (eg: branch$="buttonpress"), then you can add wlog branch$ for any subroutines that you want to keep track of, eg:
  branch$ = "buttonpress":  wlog branch$
It is quick and simple to do, and allows you to leave a convenient 'breadcrumb trail' of your scripts movements.

You don't have to wlog branch$ every time. A more selective way to use it would be to wlog branch$ from elsewhere on an 'as-needed' basis... such as for the previous Memory Leaks tip. So you could add the ramcheck user sub below, then simply add the line ramcheck to various 'suspect' locations in your script to show the status of memory from those locations.
 sub ramcheck
 wlog "Ramfree from " + branch$ + " = " + str$(ramfree)
 end sub

The 'breadcrumb trail' can also be used selectively to allow taking different actions depending on location...which comes in VERY handy for button presses.
Instead of re-assigning button interrupts to different event handler branches according to different parts of your script, the breadcrumbs allow just having one event handler per button, which simply branches according to the value of the subroutine branch$ which invoked it.

For debugging purposes, you might add...
 wlog "buttonpress from " + branch$
at the top of your event handler to flag where each buttonpress originated from.
Then for operational purposes you could use either IFs or Select Case statements to branch as appropriate depending on the value of branch$..

To emphasis that usefulness...
I am using the breadcrumb trail with 3 different buttons to provide menu navigation and selections, plus each button is able to differentiate between short or long presses to take different actions for any branch$ locations. Each button uses 2 sets of CASE branch$ statements, one for any short-press branch$ of interest, another for any long-press branch$ of interest. Additionally the breadcrumb trail offers the debugging bonus of being able to clearly see which button causes what branching to where.
Electroguard 5/10/18

TIP - ADC function not work if the NodeMCU (v0.9) is mounted on NodeMcu Base (v1.0)

The ADC function of the analog signal does not work if the NodeMCU (v0.9) is mounted on NodeMcu Base (v1.0).The ADC function of the analog signal does not work if the NodeMCU (v0.9) is mounted on NodeMcu Base (v1.0).

The pin of the NodeMCU named "reserved" (the one next to "adc0") is directly connected to the ADC pin of the ESP12,
the corresponding pin of the NodeMcu Base is connected to ground so that the ADC input of the ESP12 will always be kept at zero potential.

Cut the "Reserved" pin (the one next to "adc0") of the NodeMCU to use the ADC0 input and the conversion function with 3.3V full scale.

Mario L. 2/5/19

TIP - How To Backup Original Firmware

It is possible to take a backup of original firmware from a device before installing Annex.
This then offers possibility to restore the original firmware again if ever needed.
You'll need to discover some info about the device in order to save an image dump of its flash to computer.
The flash size is the most essential bit of info, because it dictates the size of the resulting bin file.

The best way to 'discover' the device info is to use the Toolkit Blue Button and make a note of the flash memory size plus the flash mode and frequency, and the correct Com port number.
So let's assume you've already done that and have the required info.

You need to run esptool from a command prompt window in the Annex parent directory where it resides SHIFT+RightMouse on Win7), so open a cmd window then CD (change directory) into the Annex folder.
To make things easier, slide the command prompt window to one side so you can still see these instructions showing from behind.

NOTE1:  If the device is not capable of autoflash you will need to manually enter flashing mode before each use of esptool (same as you would if using Toolkit).
NOTE2:  Notice that "--port" has 2 preceding dashes

If a 4MB device, type in "esptool --port com4 read_flash 0x00000 0x400000 image4M.bin"  
(substituting your  com port and preferred filename instead of image4M.bin)

If 2MB, type in "esptool --port com4 read_flash 0x00000 0x200000 image2M.bin"
(substituting your com port and preferred filename instead of image2M.bin)

If 1MB, type in "esptool --port com4 read_flash 0x00000 0x100000 image1M.bin"
(substituting your com port and preferred filename instead of image1M.bin)

After a few minutes it will complete the dump, then you can type in "dir *.bin" to show the resulting file and its size.

When you need to restore a file, type in "esptool --port com4 write_flash -fs 4MB -fm dout 0x0 filename.bin"
where filename.bin is the file to restore, -fs specifies the appropriate file size (4MB, 2MB, 1MB), and -fm is the flash mode (dout, or whatever the original mode shown by the Blue Button).
If you include any necessary info in the actual filename it will not get lost or forgotten and will be obvious if ever it is needed.

Doesn't just apply to original firmware of course, can also be used for taking complete Annex backups if wished.

Electroguard 8/6/19