• 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?

  • I just checked and Serial1 does have an _options as well - but perhaps it doesn't have it if it was auto-initialised at boot.

    setup serial again when the watch triggers (rx goes high).

    You will likely lose the first byte when this happens... but otherwise it'd be ok. Other option is to use Software serial, which won't draw extra power.

    will this actually save power?

    Yes :)

    why the uart eats power anyway - because of TX?

    It's the RX I believe - the UART has to keep the high speed oscillator on, and that eats loads of power.

  • 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.

  • 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.

  • That's great - just a quick note though. 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?

    rising will work, but it'll be triggering on something in the middle of the first byte, not the Start bit :)

    Is there some timestamp of last console input?

    I'm afraid not... I guess you could put the console on Loopback and manually forward any characters - then you'd know when it was busy or not.

  • 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?

  • I'm not sure if it is a bug - it's not like _options is publicised, and it's easy to manually set serial up at boot yourself and get it created.

    I guess the question is, does everyone want ~6 of their variables to be used up all the time on Serial1._options when a very small percentage of people will use it.

    The other bad point is if it was set and then you saved, Espruino would detect that it was there and would then automatically set up the Serial port at boot from then on - wasting power until you explicitly disabled it even if you hadn't connected serial.

    I think on balance it's better as-is. You can always do Serial1.options||{}

  • 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.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

close and reopen Serial with same parameters to save power (Serial._options missing)

Posted by Avatar for fanoush @fanoush

Actions