CircuitPython-compatible microcontrollers show up as a CIRCUITPY drive when plugged into your computer, allowing you to edit code directly on the board. Perhaps you've wondered whether or not you can write data from CircuitPython directly to the board to act as a data logger. The answer is yes!
The storage
module in CircuitPython enables you to write code that allows CircuitPython to write data to the CIRCUITPY drive. This process requires you to include a boot.py file on your CIRCUITPY drive, along side your code.py file.
The boot.py file is special - the code within it is executed when CircuitPython starts up, either from a hard reset or powering up the board. It is not run on soft reset, for example, if you reload the board from the serial console or the REPL. This is in contrast to the code within code.py, which is executed after CircuitPython is already running.
The CIRCUITPY drive is typically writable by your computer; this is what allows you to edit your code directly on the board. The reason you need a boot.py file is that you have to set the filesystem to be read-only by your computer to allow it to be writable by CircuitPython. This is because CircuitPython cannot write to the filesystem at the same time as your computer. Doing so can lead to filesystem corruption and loss of all content on the drive, so CircuitPython is designed to only allow one at at time.
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries # SPDX-License-Identifier: MIT """ CircuitPython Essentials Storage CP Filesystem boot.py file """ import time import board import digitalio import storage import neopixel pixel = neopixel.NeoPixel(board.NEOPIXEL, 1) button = digitalio.DigitalInOut(board.BUTTON) button.switch_to_input(pull=digitalio.Pull.UP) # Turn the NeoPixel white for one second to indicate when to press the boot button. pixel.fill((255, 255, 255)) time.sleep(1) # If the button is connected to ground, the filesystem is writable by CircuitPython storage.remount("/", readonly=button.value)
The storage.remount()
command has a readonly
keyword argument. This argument refers to the read/write state of CircuitPython. It does NOT refer to the read/write state of your computer.
When the button is pressed, it returns False
. The readonly
argument in boot.py is set to the value
of the button. When the value=True
, the CIRCUITPY drive is read-only to CircuitPython (and writable by your computer). When the value=False
, the CIRCUITPY drive is writable by CircuitPython (and read-only by your computer).
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries # SPDX-License-Identifier: MIT """ CircuitPython Essentials Storage CP Filesystem code.py file For use with boards with a built-in red LED. """ import time import board import digitalio import microcontroller led = digitalio.DigitalInOut(board.LED) led.switch_to_output() try: with open("/temperature.txt", "a") as temp_log: while True: # The microcontroller temperature in Celsius. Include the # math to do the C to F conversion here, if desired. temperature = microcontroller.cpu.temperature # Write the temperature to the temperature.txt file every 10 seconds. temp_log.write('{0:.2f}\n'.format(temperature)) temp_log.flush() # Blink the LED on every write... led.value = True time.sleep(1) # ...for one second. led.value = False # Then turn it off... time.sleep(9) # ...for the other 9 seconds. except OSError as e: # When the filesystem is NOT writable by CircuitPython... delay = 0.5 # ...blink the LED every half second. if e.args[0] == 28: # If the file system is full... delay = 0.15 # ...blink the LED every 0.15 seconds! while True: led.value = not led.value time.sleep(delay)
First you import the necessary modules to make them available to your code, and you set up the LED.
Next you have a try
/except
block, which is used to handle the three potential states of the board: read/write, read-only, or filesystem full. The code in the try
block will run if the filesystem is writable by CircuitPython. The code in the except
block will run if the filesystem is read-only to CircuitPython OR if the filesystem is full.
Under the try
, you open a temperature.txt log file. If it is the first time, it will create the file. For all subsequent times, it opens the file and appends data. Inside the loop, you get the microcontroller temperature value and assign it to a temperature
variable. Then, you write the temperature value to the log file, followed by clearing the buffer for the next time through the loop. The temperature data is limited to two decimal points to save space for more data. Finally, you turn the LED on for one second, and then turn it off for the next nine seconds. Essentially, you blink the LED for one second every time the temperature is logged to the file which happens every ten seconds.
Next you except
an OSError
. An OSError
number 30 is raised when trying to create, open or write to a file on a filesystem that is read-only to CircuitPython. If any OSError
other than 28 is raised (e.g. 30), the delay
is set to 0.5 seconds. If the filesystem fills up, CircuitPython raises OSError
number 28. If OSError
number 28 is raised, the delay
is set to 0.15 seconds. Inside the loop, the LED is turned on for the duration of the delay
, and turned off for the duration of the delay
, effectively blinking the LED at the speed of the delay
.
At the moment, the LED on your board should be blinking once every half second. This indicates that the board is currently read-only to CircuitPython, and writable to your computer, allowing you to update the files on your CIRCUITPY drive as needed.
The way the code in boot.py works is, it checks to see if the button is pressed when the board is powered on and boot.py is run. To begin logging the temperature, you must press the button.
The boot button (highlighted in blue), labeled D0 on the board silk, is located at the lower left corner of the board and display.
While holding down the button, you need to either hard reset the board by pressing the reset button, or by unplugging the USB cable and plugging it back in. This will run the code within boot.py and set your board to writable by CircuitPython, and therefore, read-only by the computer.
For the Feather ESP32-S2 Reverse TFT, it's difficult to get the timing right for when to press the boot button. So, the boot.py file includes turning the NeoPixel on bright white for one second. Press the boot button when the NeoPixel is white!
The red blinking will slow down to one second long, every 10 seconds. This indicates that the board is currently logging the temperature, once every 10 seconds.
As long as the button is pressed, you can plug the board in anywhere you have USB power, and log the temperature in that location! The temperature is not the ambient temperature; it is the temperature inside the microcontroller, which will typically be higher than ambient temperature. However, running only this code, once the microcontroller temperature stabilises, it should at least be consistent, and therefore usable for tracking changes in ambient temperature.
If the LED starts blinking really quickly, it means the filesystem is full! You'll need to get your temperature data and delete the temperature log file to begin again.
That's all there is to logging the temperature using CircuitPython!
Recovering a Read-Only Filesystem
In the event that you make your CIRCUITPY drive read-only to your computer, and for some reason, it doesn't easily switch back to writable, there are a couple of things you can do to recover the filesystem.
Even when the CIRCUITPY drive is read-only to your computer, you can still access the serial console and REPL. If you connect to the serial console and enter the REPL, you can run either of the following two sets of commands at the >>>
prompt. You do not need to run both.
First, you can rename your boot.py file to something other than boot.py.
import os os.rename("boot.py", "something_else.py")
Alternatively, you can remove the boot.py file altogether.
import os os.remove("boot.py")
Then, restart the board by either hitting the reset button or unplugging USB and plugging it back in. CIRCUITPY should show up on your computer as usual, but now it should be writable by your computer.
Text editor powered by tinymce.