0

WiFi coming out of deep sleep
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

WiFi coming out of deep sleep

by jfabernathy on Sat Jan 09, 2021 8:37 am

I finally have a working solution on my Metro ESP32-S2 for reading AHT20 data, posting to my server, and deep sleeping for most of the time. This cycles about 1/minute.

So what I've discovered is I could make this work plugged into my laptop for monitoring the serial port and things were fine. Note, the deep sleep is only simulated in this mode.

However, when I unplugged from the laptop and plugged into a power adapter. It would run for about 15-20 minutes before a crash that I could not observe since no serial port.

There seems to be some issue with coming out of deep sleep and immediately trying to setup the WiFi.

What I finally got to work was putting the some logic from the test programs where I scan the available networks, stop scanning, then connect to my WiFi Access point followed by uploading the data.

I don't know if this scanning was needed or if it was a need for some delay in time before connecting to the WiFi AP?

Any ideas?

jfabernathy
 
Posts: 45
Joined: Thu Dec 17, 2020 10:58 pm

Re: WiFi coming out of deep sleep

by jfabernathy on Sun Jan 10, 2021 8:08 am

Maybe it would be helpful if I attach the code to see what I'm talking about:

Code: Select all | TOGGLE FULL SIZE
import socketpool
import ssl
import adafruit_requests as requests
import wifi
import secrets
import time
import board
import adafruit_ahtx0
import alarm

def post_data(msg):
    socket = socketpool.SocketPool(wifi.radio)
    https = requests.Session(socket, ssl.create_default_context())
    response = https.post(JSON_POST_URL, data=data)
    json_resp = response.json()

# Create the sensor object using I2C
sensor = adafruit_ahtx0.AHTx0(board.I2C())

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise
"""
This section of retreiving and printing the mac address,
scanning the wifi network for access points, and then stopping the scan was
taken from several Adafruit example programs.

It's only value in this program is it seems to get the wifi working after
a cold boot from the deep sleep call at the end of the program,
I could not find a way to make my code reliable without this logic.
"""
print("My MAC addr:", [hex(i) for i in wifi.radio.mac_address])

print("Available WiFi networks:")
for network in wifi.radio.start_scanning_networks():
    print("\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
            network.rssi, network.channel))
wifi.radio.stop_scanning_networks()

# end of special code to prep the wifi after recovery from deep sleep.

print ("Connecting to %s"%secrets["ssid"])
try:
    wifi.radio.connect(secrets["ssid"], secrets["password"])
except (ConnectionError, ValueError, RuntimeError):
    print("error on wifi.radio.connect")
#     If we get an error, set to be awakened from deep sleep in 2 seonds and try again.
    time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 2)
    alarm.exit_and_deep_sleep_until_alarms(time_alarm)

print ("Connected to %s!"%secrets["ssid"])
print("My IP address is", wifi.radio.ipv4_address)

JSON_POST_URL = "http://192.168.0.25:1880/myserver" # URL for my NodeRed server

x = round(sensor.temperature * 1.8 + 32.0,1)
y = round(sensor.relative_humidity,1)
temp = str(x)
humid = str(y)
# format the readings data as  InfluxDB expects: Array of 2 object:
# 1st is readings, 2nd is tag

data = """[{"Temperature": """ + temp + """ , "Humidity": """ + humid + """}, {"Location": "Back_Porch"}]"""
post_data(data)

# Create a an alarm that will trigger 60 seconds from now.
time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 60)
# Exit the program, and then deep sleep until the alarm wakes us.
alarm.exit_and_deep_sleep_until_alarms(time_alarm)
# Does not return, so we never get here.

jfabernathy
 
Posts: 45
Joined: Thu Dec 17, 2020 10:58 pm

Re: WiFi coming out of deep sleep

by tannewt on Mon Jan 11, 2021 6:50 pm

It's really hard to tell without serial. Could you attach a display or monitor the debug UART? The debug UART will have messages if you load a debug CircuitPython build onto it.

tannewt
 
Posts: 2034
Joined: Thu Oct 06, 2016 8:48 pm

Re: WiFi coming out of deep sleep

by jfabernathy on Mon Jan 11, 2021 7:49 pm

tannewt wrote:It's really hard to tell without serial. Could you attach a display or monitor the debug UART? The debug UART will have messages if you load a debug CircuitPython build onto it.

This maybe a dumb question by where do I get a debug CircuitPython build?

jfabernathy
 
Posts: 45
Joined: Thu Dec 17, 2020 10:58 pm

Re: WiFi coming out of deep sleep

by tannewt on Mon Jan 11, 2021 8:49 pm

Not a dumb question! You can build one yourself by doing DEBUG=1 on the make line. Or, you might be able to get help on the Discord. https://adafru.it/discord

How do you know it's crashing?

tannewt
 
Posts: 2034
Joined: Thu Oct 06, 2016 8:48 pm

Re: WiFi coming out of deep sleep

by jfabernathy on Mon Jan 11, 2021 9:03 pm

tannewt wrote:Not a dumb question! You can build one yourself by doing DEBUG=1 on the make line. Or, you might be able to get help on the Discord. https://adafru.it/discord

How do you know it's crashing?

The Neopixel is blinking and my server quits getting update. If I hit reset it starts up correctly. Now that I have the frontend scan of the APs, it doesn't fail very often. Today it failed when I screwed up on the Server and crashed it. I would just like to trap all errors on the Metro and set an alarm for a few seconds and deep sleep again. It usually comes up fine, so that would probably work

jfabernathy
 
Posts: 45
Joined: Thu Dec 17, 2020 10:58 pm

Re: WiFi coming out of deep sleep

by jfabernathy on Mon Jan 11, 2021 9:05 pm

I did get advice on Discord that I could solder in jumpers for the debug uart port and use prints to that port with debug data

jfabernathy
 
Posts: 45
Joined: Thu Dec 17, 2020 10:58 pm

Re: WiFi coming out of deep sleep

by jfabernathy on Tue Jan 12, 2021 9:20 am

I was able to determine that I can try/except a lot of the errors I'm getting and just set an alarm for 2 seconds and deep sleep. If the errors are a fluke, then it recovers nicely. Only real problem with this is if the error is caused by a server being down, it could be a while before it gets fixed and I'd be using a lot more battery. I'll try to improve that.

I've also reduced the amount of wifi access prior to connecting to just the retrieving of the MAC address. This seems to be enough to get things working.

I've attached the latest code.
code.py
test code I'm running
(3.03 KiB) Downloaded 4 times

jfabernathy
 
Posts: 45
Joined: Thu Dec 17, 2020 10:58 pm

Re: WiFi coming out of deep sleep

by jfabernathy on Tue Jan 12, 2021 10:08 pm

So that I could debug any issue that come up while not connected to the laptop via USB, I put in some debugging logic using the UART on pins 5 and 6. This allows the Metro to truly get into deep sleep which I feel affect how the WiFi starts up. What I have runs many hours without issues. At least if anything happens, it recovers without missing any reading on the 1 per minute basis.

In case this helps others, I've attached this code with the uart debug logic.
code.py
code with UART debug logic
(3.43 KiB) Downloaded 2 times

jfabernathy
 
Posts: 45
Joined: Thu Dec 17, 2020 10:58 pm

Re: WiFi coming out of deep sleep

by jfabernathy on Sat Jan 16, 2021 9:58 pm

Well I spoke too soon. The Metro ESP32-S2 ran for 3 days without locking up. However tonight I noticed that I was starting to miss readings and then it just completely stopped. I thought I had trapped the errors I could get to just deep sleep which would just wake up in a few seconds and effectively reset. I know it was mostly working because I occasionally missed reading and it recovered on the next cycle. The problem with this situation is I can't leave the laptop connected and running 24/7 because it's a battery operation. While the Metro can run on battery forever, the laptop can't. So tonight when I went out to the Metro, it was doing the flashing neopixel trick it does when you breakout to REPL.

Is there a way that instead of breaking to REPL, it will just reset the Metro???

Here is the code.
Code: Select all | TOGGLE FULL SIZE
import socketpool
import ssl
import adafruit_requests as requests
import wifi
import secrets
import time
import board
import adafruit_ahtx0
import alarm
import busio

def post_data(msg):
    try:
        socket = socketpool.SocketPool(wifi.radio)
        https = requests.Session(socket, ssl.create_default_context())
        response = https.post(JSON_POST_URL, data=data)
        json_resp = response.json()
    except RuntimeError:
        print("RuntimeError in post_data")
        uart.write(bytearray("\n\rRuntimeError in post_data"))
# If we get an error, set to be awakened from deep sleep in 2 seonds and try again.
        time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 2)
        alarm.exit_and_deep_sleep_until_alarms(time_alarm)

# Create the sensor object using I2C
sensor = adafruit_ahtx0.AHTx0(board.I2C())

uart = busio.UART(board.TX, board.RX, baudrate=115200)

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise
"""
This section of retreiving and printing the mac address,
scanning the wifi network for access points, and then stopping the scan was
taken from several Adafruit example programs.

It's only value in this program is it seems to get the wifi working after
a cold boot from the deep sleep call at the end of the program,
I could not find a way to make my code reliable without this logic.
"""
uart.write(bytearray("\n\rJust out of deep sleep, checking mac address"))
print("My MAC addr:", [hex(i) for i in wifi.radio.mac_address])
"""
After testing I eliminated the scanning of the wifi network but kept the
reading of the MAC address. Seems to work with just that.
"""
print("Available WiFi networks:")
uart.write(bytearray("\n\rAvailable WiFi networks: "))
for network in wifi.radio.start_scanning_networks():
    print("\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
            network.rssi, network.channel))
    uart.write(bytearray("\n\r\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
            network.rssi, network.channel)))
wifi.radio.stop_scanning_networks()

#end of special code to prep the wifi after recovery from deep sleep.

#print ("Connecting to %s"%secrets["ssid"])
uart.write(bytearray("\n\rConnecting to %s"%secrets["ssid"]))

try:
    wifi.radio.connect(secrets["ssid"], secrets["password"])
except (ConnectionError, ValueError, RuntimeError):
    print("Error on wifi.radio.connect")
    uart.write(bytearray("\n\rError on wifi.radio.connect"))
#     If we get an error, set to be awakened from deep sleep in 2 seonds and try again.
    time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 2)
    alarm.exit_and_deep_sleep_until_alarms(time_alarm)

#print ("Connected to %s!"%secrets["ssid"])
uart.write(bytearray("\n\rConnected to %s!"%secrets["ssid"]))
#print("My IP address is ", wifi.radio.ipv4_address)
uart.write(bytearray("\n\rMy IP address is " + str(wifi.radio.ipv4_address)))
JSON_POST_URL = "http://192.168.0.25:1880/myserver" # URL for my NodeRed server

x = round(sensor.temperature * 1.8 + 32.0,1)
y = round(sensor.relative_humidity,1)
temp = str(x)
humid = str(y)
# format the readings data as  InfluxDB expects: Array of 2 object:
# 1st is readings, 2nd is tag

data = """[{"Temperature": """ + temp + """ , "Humidity": """ + humid + """}, {"Location": "5th_wheel"}]"""
post_data(data)
uart.write(bytearray("\n\rJust posted data, now into deep sleep!\n\n"))
#print("Just posted data, now into deep sleep!")
# Create a an alarm that will trigger 60 seconds from now.
time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 60)
# Exit the program, and then deep sleep until the alarm wakes us.
alarm.exit_and_deep_sleep_until_alarms(time_alarm)
# Does not return, so we never get here.

jfabernathy
 
Posts: 45
Joined: Thu Dec 17, 2020 10:58 pm

Re: WiFi coming out of deep sleep

by jfabernathy on Sun Jan 17, 2021 7:59 pm

I got some good help on the Discord channel and I think I have a much better solution. I was using try/except loops but I called out the exception codes I was wanting to trap. Bad idea. I changed it to a try: Exception as e: and then just printed e. Then I could reset but still have an idea of what error I was getting. example:
Code: Select all | TOGGLE FULL SIZE
try:
    wifi.radio.connect(secrets["ssid"], secrets["password"])
except Exception as e:
    print("Exception on wifi.radio.connect ", str(e))
    uart.write(bytearray("\n\rError on wifi.radio.connect " + str(e)))
    time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 2)
    alarm.exit_and_deep_sleep_until_alarms(time_alarm)

jfabernathy
 
Posts: 45
Joined: Thu Dec 17, 2020 10:58 pm

Please be positive and constructive with your questions and comments.