Avatar for fanoush

fanoush

Member since Jul 2018 • Last active Jan 2019
  • 2 conversations
  • 52 comments

Most recent activity

    • 5 comments
    • 96 views
  • in General
    Avatar for fanoush

    If you think that could have anything added that cleared up the situation a bit then I'd be really interested to hear

    Well after also reading the Saving page it is a bit more clear but still from all of this I did not get the idea that it is dangerous and definitely not what I wanted to use or that I should be extra careful before using it. The Summary in Saving page starts with

    Just type save() on the left-hand side of the IDE and the current state of Espruino including all saved code will be written so that it is loaded at boot time.

    and then hints that there are maybe better ways and then pros and cons are discussed but nothing that would warn me that this automatic save needs serious thinking when to call it in all but nontrivial cases. So I'd like to see some bigger warning there.

    The API reference says

    When Espruino powers on, it will resume from where it was when you typed save(). If you want code to be executed right after loading (for instance to initialise devices connected to Espruino), add an init event handler to E with E.on('init', function() { ... your_code ... });. This will then be automatically executed by Espruino every time it starts.

    This does not explain potential issues. Also BTW is the on init function always guaranteed to run before e.g. my just restored setInterval will fire? Should I set E.on(init) before calling save() so it gets saved too? This may not be clear from those sentences.

    I would add something like this to save() API reference

    Please note that if you have watches and intervals already set at the time of save, they will continue to run after resume so use the on init method to restore hardware to expected state before they will run again. If you omit this it may lead to unexpected and possibly serious failures if your code does not handle such state properly. This method is targeted for simple use cases where it will 'just work' however it may not be the best for more complex scenarios. For more details and alternatives see page Saving. See dump() to understand what gets saved.

  • in General
    Avatar for fanoush

    I think on balance it's better as-is.

    Currently together with missing _option and the powersaving feature it is not possible to find out if serial is really initialized or not. So I may or may not save power (depending on whether serial was attached at boot time) but cannot figure it out later from code.

    But yes, the solution to make it deterministic is to setup() it always again at boot time to have it enabled or setup() and immediately unsetup() to have it disabled.

  • in General
    Avatar for fanoush

    I tried for the first time to call save() when my code in DS-D6 watch is somewhat usable but after saving, the console and my code stopped working. When connecting via Bluetooth I see ->Bluetooth on serial and I can also see switching back message when disconnecting bluetooth but I cannot enter any commands (both in serial and bluetooth console) and also my code (setWatch - touch button to show time) is not working anymore.

    After power cycle it boots into console prompt but after few seconds it freezes.So I guess it is maybe some setWatch which is triggering something not initialized? I managed to type reset() quickly after another powercycle so it is OK now.

    The answer in FAQ says that timers, watches, and even pin state is restored however it also says " For certain things (like initialising connected hardware like displays) you'll want to run some code when Espruino starts up".

    This feature of restoring "timers, watches, and even pin state" seems a bit dangerous to me because even some pin state may make sense only with some prior hardware initialization.

    Would it be useful or even doable for save() to just save code without any other state that runs code (timers,..)?

    To me it means that I should be either extra careful in all my watches and timers to check for uninitialized or simply random state (which could be tricky with attached hardware with its own state) or better I should not start anything before running save() - just call reset(), load pure code without starting/initializing anything and then run save(). Also I see command history is saved too probably eating memory (as all my code is pasted there line by line), can this be cleared before running save?

    Apart from the faq question there is also https://www.espruino.com/Reference#l__gl­obal_save with no hints or more details. Is there some other turorial or ducumentation related to this?

    EDIT: BTW, the saving and loading itself went fine, when saving it compressed fine and did fit into memory so there was no issue with that.

    EDIT2: Oh, found also this https://www.espruino.com/Saving with some Gotchas
    but still I don't understand why it stopped working imediatelly after calling save()

  • in General
    Avatar for fanoush

    I believe the default idle state of Serial is High, not Low (you could check with a digitalRead?). So probably you want to setWatch on the falling edge?

    Yes, idle TX is high and only when data is sent it goes low. However my idea was to detect when I attach serial adapter so RX on device input gets high signal from idle TX. That's why RX as GPIO input is "input_pulldown" and watch is on "rising". So Serial is initialized earlier before any data is sent. Also with this setup I can first put console to sleep (still by using the console) and then detach adapter and it does not get triggered on this falling edge.

    When serial is disabled in this way while devices are still connected then it unfortunately triggers on first change from 0 to 1 so I miss the start bit of first character, yes.

    BTW is missing _options when setup at boot time a bug? Should I make issue on github for this?

  • in General
    Avatar for fanoush

    Confirming that Serial1 does not have _options when it is set as boot console but when later calling setup() it creates it.
    Also resuming console works when just attached to serial without sending any data. And when it went to sleep while attached and not removed, it resumes when any key is pressed (then first character is lost). Quick and dirty code

    function resumeConsole(serial){serial.setup(38400­,{rx:D22,tx:D23});serial.setConsole();}
    function pauseConsole(serial){
    Bluetooth.setConsole(1);if(serial._optio­ns){serial.unsetup()};D22.mode("input_pu­lldown");
    setWatch(()=>{setTimeout(()=>{resumeCons­ole(serial)},300)},D22,{debounce:10,edge­:'rising'})
    }
    

    After calling pauseConsole(Serial1) it goes to sleep and I can remove serial adapter and when later reattached, it resumes.

    So last piece of puzzle is to figure out when console is idle for x minutes. Is there some timestamp of last console input? Otherwise I can at least periodically check whether serial is current console (process.env.CONSOLE) and if not then pause it.

  • in General
    Avatar for fanoush

    but honestly just a flag to ditch the console reassignment messages would probably be fine?

    Yes. perhaps with some harmless Null device that would just drop the bytes if LoopbackA is not harmless (i.e. buffering the data for LoopbackB, eating memory).

  • in General
    Avatar for fanoush

    perhaps it doesn't have it if it was auto-initialised at boot

    oh, I see, that might be it, will check, thanks, I certainly remember not seeing it

    You will likely lose the first byte when this happens... but otherwise it'd be ok

    Never mind, I always press enter anyway when attaching serial adapter Also I hoped RX might go high even when just attaching the adapter so it could be ready before typing anything but it really does not matter if first byte is lost.

    Will try software serial too, interesting idea.

  • in General
    Avatar for fanoush

    I2C and SPI objects have setup(options), unsetup() and ._options property so one can find out current state.

    Serial class has baudrate as extra parameter and no _options after setup. I'd like to close console/UART to save power and reopen it later with same options but don't know how to do it as I cannot determine whether serial is already open and what are current parameters.

    This is on nrf52 and my idea is to unsetup Serial1 and reconfigure RX pin as gpio with setWatch() and setup serial again when the watch triggers (rx goes high). BTW, will this actually save power? why the uart eats power anyway - because of TX? In that case can I just unconfigure TX pin when not sending directly in UART driver?

Actions