ghubcoder / micropython-pico-deepsleep

MicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems
https://micropython.org
Other
30 stars 2 forks source link

Raspberry Pi Pico getting an One-Time-Programmable when using picosleep #1

Closed flashbtw closed 2 years ago

flashbtw commented 2 years ago

Firstly, I want to appreciate your work.

But now to my problem. When I have this code as main.py:

from machine import *
import picosleep

led = Pin(25, Pin.OUT)

def blink():
    led.toggle()

while True:
    picosleep.seconds(3)
    blink()

my Pico doesn't seem to be accessible when connecting it to the computer. So when I want to make changes to the program, I have to flash_nuke it in order to function.

Maybe this is my error, I'm just new to this subject :) Anyways, any help would be appreciated!

flashbtw commented 2 years ago

apparently, the raspberry pico turns completely off when using picosleep as the voltage goes "through it" and activates the MOSFET, even it shouldn't be activated. So Picosleep doesn't work for me. Any suggestions?

aiya70 commented 2 years ago

Likewise, I can't wake up after sleeping. Help!

ghubcoder commented 2 years ago

@flashbtw @aiya70 sorry to hear you are both having issues.

@flashbtw with the example you have posted in your first comment, does the Pico onboard LED blink as expected?

You have both mentioned that after sleeping the Pico does not respond. Unfortunately I think that when the deep sleep code executes, the connection to the computer is lost, the only way to reset it is to power cycle it by unplugging or perhaps by using a reset button such as here.

To work around this, when developing I would use:

import time
time.sleep(3)

Then when you are ready for this to be run standalone, replace these sleep calls with the picosleep.seconds(3) ones. That way everything should still work as expected, and you can develop your code without the pico locking up.

If your programme needs to interact with your computer over USB then sleeping using deep sleep is going to cause problems. Communication over UART and I2C does appear to still work fine following deep sleeping, with perhaps a few tweaks, see this comment and thread for an example. I have tried to work around these issues with the REPL/USB but unfortunately have not found a solution.

@flashbtw it's interesting that it's allowing voltage to pass through it when sleeping, have you got a wiring example for that?

flashbtw commented 2 years ago

The one-time-programmable thing put aside; I'll use time.sleep(time) for developing now. But there is another problem:

The Pico seems to have control over Port 25 (internal LED) but not the other GPIO Ports/Pins including mine (0). The Circuit looks like this: https://imgur.com/a/RRt5qVO My Code is exactly this (unoptimized I know lol):

import picosleep
from machine import Pin

led_onboard = Pin(25, Pin.OUT)
led_not_onboard = Pin(0, Pin.OUT)

def test():
    led_onboard.toggle()
    picosleep.seconds(3)
    led_onboard.toggle()
    picosleep.seconds(3)
    led_onboard.toggle()
    picosleep.seconds(3)
    led_onboard.toggle()
    picosleep.seconds(3)
    led_not_onboard.toggle()
    picosleep.seconds(3)
    led_not_onboard.toggle()
    picosleep.seconds(3)
    led_not_onboard.toggle()
    picosleep.seconds(3)
    led_not_onboard.toggle()

test()

The behavior of it seems strange. It can be seen on youtube Also, it seems Pin 1 is "always down". Even when toggling it, it doesn't want to do anything. I also tried connecting + to VBUS and - to other GND Pins. No changes

I appreciate your help!

ghubcoder commented 2 years ago

@flashbtw Apologies for the difficulties you have had with this.

I was able to replicate your issue, not sure why it's happening but adding a time.sleep(1) before starting executing the rest of the program appears to solve the issue. Honestly not sure why though, must be a timing problem.

import picosleep
from machine import Pin
import time
import os

led_onboard = Pin(25, Pin.OUT)
led_not_onboard = Pin(15, Pin.OUT)

# Make sure this is present
time.sleep(1)

def flash(times,sleep,led):
    num = 0
    while num < times:
        led.toggle()
        time.sleep_ms(sleep)
        num=num+1

def led_toggle(led):
    led.toggle()
    picosleep.seconds(2)

for x in range(0, 8):
    led_toggle(led_onboard)

for x in range(0, 8):
    led_toggle(led_not_onboard)

flash(4,500,led_onboard)
flash(4,500,led_not_onboard)

# !!!! be careful here this will remove main.py on your pico !!!!
os.remove("main.py")

That seems to work for me. If I save this to the pico as "main.py" using Thonny, and then reset the pico, it runs the code and the led's flash as expected.

I've also added a os.remove("main.py") right at the end. This will mean it will only run once and then you can reset your pico, and you will be able to connect to it again as normal without it going into a deep sleep.

Please be careful with that, as it will wipe "main.py" on your pico, make sure you have saved anything you want to keep on there.

Remove that line once you have everything setup and you want to be able to reset it by power cycling it, but continue to run your code on the next reboot.

Another option is to have a long time.sleep(20) at the start so you can connect to the pico before it deep sleeps, halting execution, and allowing you to connect via Thonny after a reset.

Also it doesn't seem to work for me using gpio 0, not sure if that is a special pin. At least for me using a "Maker Pi Pico", that pin is already high for me when the Pico starts. Using Pin 15 works fine.

Let me know if this works for you.

flashbtw commented 2 years ago

Yeah, Pin 1 has got me wondering because it also just wasn't working (always off). My biggest guess is, with no sleep before picosleep, the pico doesn't have time to initiate itself.

Huge Thanks for your help! It'll make my battery last much longer :) Also, it wakes up, after the script was executed and gets accessible via USB.

ghubcoder commented 2 years ago

Ah great to hear! Thanks for closing the issue 👍

flashbtw commented 2 years ago

No problem 😄 I also created a PR #2 to inform the user about this "bug" and that using time.sleep(1) is recommended.

Have a great day!