When a program goes into deep sleep, it exits and then sleeps. So all the information in its variables is lost. But the program might want to remember something for use when it restarts. It could write into a file onto the board CIRCUITPY drive, or it could write into internal flash using microcontroller.nvm. But flash has a limited lifetime, so it's better not to write it over and over. Instead, the program can write into a special part of memory (RAM) that is powered during deep sleep. In most microcontrollers, this kind of memory is called "backup RAM"; in CircuitPython, we call it alarm.sleep_memory. This memory requires very little power to maintain. If power is removed completely, then the memory is lost, but as long as USB power or a battery is connected, it will remember what is stored in it.

alarm.sleep_memory is just a byte array of a few thousand bytes. You can use it to store whatever you want, but you'll need to encode the data as bytes. You could use struct.pack and struct.unpack, or use JSON, or some other format that's convenient for you.

MagTag Example

Here's a simple example of using sleep memory, without any encoding. Each time the program wakes up, it increments a count kept in one byte in alarm.sleep_memory. This program displays the current battery voltage and the count on the MagTag display.

The very first time the program runs, we want to initialize the count. We can tell if this is the first time the program has run by checking alarm.wake_alarm. If it is None, then we know we have not done a deep sleep yet.

The video below shows the program running, with the long 60 second-sleeps elided.

import alarm
import microcontroller
import time
from adafruit_magtag.magtag import MagTag


magtag = MagTag()

magtag.add_text(
    text_scale=2,
    text_wrap=25,
    text_maxlen=300,
    text_position=(10, 10),
    text_anchor_point=(0, 0),
)

# Reset the count if we haven't slept yet.
if not alarm.wake_alarm:
    # Use byte 5 in sleep memory. This is just an example.
    alarm.sleep_memory[5] = 0

alarm.sleep_memory[5] = (alarm.sleep_memory[5] + 1) % 256

# Display the current battery voltage and the count.
magtag.set_text(
    "battery: {}V    count: {}".format(
        magtag.peripherals.battery, alarm.sleep_memory[5]
    )
)

magtag.refresh()

# Sleep for 60 seconds.
al = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 60)
alarm.exit_and_deep_sleep_until_alarms(al)
# Does not return. Exits, and restarts after 60 seconds.

This guide was first published on Dec 17, 2020. It was last updated on Dec 17, 2020.

This page (Sleep Memory) was last updated on Jun 16, 2021.

Text editor powered by tinymce.