setInterval hanging and USB connection on Pico?

Posted on
  • An odd but very reproducible issue here. The following very simple code runs flawlessly on Picos (2v01 and 1v99) when powered by USB connected to a computer (with or without IDE). But when powered by battery (5-6V), or a 5V (250mA) breadboard power supply, or USB connected to a 5V (1A or 2.4A output) wall wart, it will hang for about 0.5 seconds, either in the on or off state, then continue to run normally. This hanging first occurs within about 20 seconds and continues to occur periodically, typically within 20 second intervals. I have reproduced this on 4 different Picos.

    let on = true;
    function toggle() {
      on = !on;
      digitalWrite(LED1, on);
    }
    setInterval(toggle, 50);
    

    The code itself, which is from the "Getting Started" code on the Espriuno.com website, is not of interest to me, but I am trying to track down the cause of a similar hanging issue in a project I am working on. My project works fine until I run it apart from the computer. I kept stripping code and hardware away trying to find the source of the hanging until no hardware and virtually no code was left, just a setInterval(myFunction, 50) statement. Is there some issue with the Pico itself and moderately rapid setInterval calls, and if so, how does keeping a USB connection to a computer overcome that issue? The hanging is clearly detectable at faster intervals as well. Not sure about slower ones.

  • If it works when connected to USB, but behaves differently when running without USB, maybe take a look at this section in Troubleshooting. And the next maybe.
    Or it's a bug :)

  • Yes, I did setConsole() thing but it made no difference. I don't think it should apply anyhow since there are no console.log's in the code. It also doesn't matter whether I use save(), save on send, or just send the code without saving and keep the power on while switching between different power sources. Even without the Web IDE running, I get no hanging when powered by USB plugged in to computer. If I switch to any other power source (without stopping the program execution) hanging starts. If I switch back to USB/computer power (without stopping the program execution) hanging stops. I'm hoping someone else will confirm that they can see this happening.

  • The initial pause a few seconds after power-on is to be expected I'm afraid. I believe it's a side effect of the way the Pico has to handle timing - the RTC is only 32kHz so to get timing accurate to more than that that also follows the RTC, it has to 'follow' the RTC time with a high-res timer, and it takes a while to keep in sync.

    It doesn't pause when connected to the computer because it doesn't attempt to enter any kind of sleep mode when it has an active USB connection.

    However, I've just set up something to detect if LED pulses are out of range and I haven't got any long pulses in over 30 minutes. Is it possible that something could be causing the Pico to restart, which is causing the repeated pause?

    To avoid that initial pause, could you wait for a few seconds after boot before starting what you need?

    Also, I know you say this is part of a bigger project (thanks for narrowing it down!) so you may be doing more complex stuff but if you do need a pin to be pulsed at an accurate interval then you could use the PWM hardware with analogWrite.

  • Ok, I left it running and got one or two glitches - a 0.2 sec delay as opposed to 0.05 sec, followed by 3 faster iterations as it tries to catch up.

    I'm not too sure why this would be happening and it's going to be a pain to track down, but I'm just trying a change now to see if that has any effect.

    Adding something along the lines of analogWrite(pin_a_dont_care_about, 0.5, {freq:200,forceSoft:true}) should work as a stopgap I think - it basically forces the board to wake up every so often, so that occasional glitch (where it seems to miss a wakeup event) shouldn't happen.

    The other thing you can do is setDeepSleep(1) if you're not using Serial ports. That uses a different sleep mechanism which has way better power consumption, but which may not suffer from whatever issue is hitting us here

  • Thanks! Your stopgap seems to be solving my problem. I can definitely wait a few seconds after boot before starting the loop. I can't use the setDeepSleep because I'm using a Serial port for radio. I'm considering switching to the analogWrite strategy that you suggest as well because I do need to pulse a pin in my actual project. Pulling a pin down is what triggers a read on a Lidar unit. Anyhow, I think I'm back in business. I know it isn't an energy efficient solution, but my unit will be plugged into wall power, so energy efficiency isn't my main concern. Thanks again.

  • Ok, great! I guess the other solution is for me to add a setting in Espruino that allows you to completely disable sleep.

    I have made a few changes now which I hope will make this better in the 'cutting edge' build, but somehow I'm still seeing it happen (but just extremely rarely now).

    But yes, if you need a reliable pulse sent out, I'd definitely say use analogWrite (without forceSoft) so you're then using a hardware timer. It'll be completely rock solid then.

  • To close out this thread, I'd like to suggest an addition to documentation in relation to the page AkosLukacs mentioned above . At least for Pico users, Serial2 is also available as per the hardware reference, in case Serial1 is being used for something else, as was my case. Also it should be noted that while the Serial ports can receive occasional console data, they don't seem capable of keeping up with a constant stream, for instance sensor data that's being polled every few milliseconds. We may be used to watching that data scroll quickly down the console window of a PC, but it seems to overload a Serial port rather quickly. I think that sort of console.log just needs to be turned off. Thanks again for helping me get my project working.

  • Thanks! I'll update that.

    Yes, depending on the baud rate of the serial port you'll find that it'll struggle to transfer significant amounts of data. For example 9600 baud is only around 1000 bytes/second.

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

setInterval hanging and USB connection on Pico?

Posted by Avatar for jeffs @jeffs

Actions