Once you've finished setting up your Feather RP2040 with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.
To do this, click on the Download Project Bundle button in the window below. It will download as a zipped folder.
# SPDX-FileCopyrightText: 2021 Liz Clark for Adafruit Industries # # SPDX-License-Identifier: MIT import time import board import adafruit_scd4x import sdcardio import busio import storage from adafruit_pcf8523.pcf8523 import PCF8523 # setup for I2C i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller # setup for SCD40 scd4x = adafruit_scd4x.SCD4X(i2c) # setup for RTC rtc = PCF8523(i2c) # start measuring co2 with SCD40 scd4x.start_periodic_measurement() # list of days to print to the text file on boot days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday") # SPI SD_CS pin SD_CS = board.D10 # SPI setup for SD card spi = busio.SPI(board.SCK, board.MOSI, board.MISO) sdcard = sdcardio.SDCard(spi, SD_CS) vfs = storage.VfsFat(sdcard) try: storage.mount(vfs, "/sd") print("sd card mounted") except ValueError: print("no SD card") # to update the RTC, change set_clock to True # otherwise RTC will remain set # it should only be needed after the initial set # if you've removed the coincell battery set_clock = False if set_clock: # year, mon, date, hour, min, sec, wday, yday, isdst t = time.struct_time((2021, 10, 31, 00, 00, 00, 0, -1, -1)) print("Setting time to:", t) rtc.datetime = t print() # variable to hold RTC datetime t = rtc.datetime time.sleep(1) # initial write to the SD card on startup try: with open("/sd/co2.txt", "a") as f: # writes the date f.write('The date is {} {}/{}/{}\n'.format(days[t.tm_wday], t.tm_mday, t.tm_mon, t.tm_year)) # writes the start time f.write('Start time: {}:{}:{}\n'.format(t.tm_hour, t.tm_min, t.tm_sec)) # headers for data, comma-delimited f.write('CO2,Time\n') # debug statement for REPL print("initial write to SD card complete, starting to log") except ValueError: print("initial write to SD card failed - check card") while True: try: # variable for RTC datetime t = rtc.datetime # append SD card text file with open("/sd/co2.txt", "a") as f: # read co2 data from SCD40 co2 = scd4x.CO2 # write co2 data followed by the time, comma-delimited f.write('{},{}:{}:{}\n'.format(co2, t.tm_hour, t.tm_min, t.tm_sec)) print("data written to sd card") # repeat every 30 seconds time.sleep(30) except ValueError: print("data error - cannot write to SD card") time.sleep(10)
After downloading the Project Bundle, plug your Feather RP2040 into the computer's USB port. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the Feather RP2040's CIRCUITPY drive.
- lib folder
- code.py
Your Feather RP2040 CIRCUITPY drive should look like this after copying the lib folder and the code.py file.

The SCD-40 and RTC are controlled over I2C. The SCD-40 begins measuring CO2 levels with start_periodic_measurement()
.
# setup for I2C i2c = board.I2C() # setup for SCD40 scd4x = adafruit_scd4x.SCD4X(i2c) # setup for RTC rtc = adafruit_pcf8523.PCF8523(i2c) # start measuring co2 with SCD40 scd4x.start_periodic_measurement()
The SD card is accessed using SPI. board.D10
is used for the SD_CS
pin on the RP2040 boards.
# SPI SD_CS pin SD_CS = board.D10 # SPI setup for SD card spi = busio.SPI(board.SCK, board.MOSI, board.MISO) sdcard = sdcardio.SDCard(spi, SD_CS) vfs = storage.VfsFat(sdcard) try: storage.mount(vfs, "/sd") print("sd card mounted") except ValueError: print("no SD card")
The RTC is set using the set_clock
variable. If set_clock
is True
, then the date and time is set to reflect what is entered in the time.struct_time()
function. If set_clock
is False
, then the RTC is not reset.
# to update the RTC, change set_clock to True # otherwise RTC will remain set # it should only be needed after the initial set # if you've removed the coincell battery set_clock = False if set_clock: # year, mon, date, hour, min, sec, wday, yday, isdst t = time.struct_time((2021, 10, 31, 00, 00, 00, 0, -1, -1)) print("Setting time to:", t) rtc.datetime = t print()
Before the loop, some data is written to the SD card's text file to assist in separating the data from different logging sessions. First, the date is written, followed by the time. Then, header labels are added, which will be useful when importing the data into a spreadsheet.
# initial write to the SD card on startup with open("/sd/co2.txt", "a") as f: # writes the date f.write('The date is {} {}/{}/{}\n'.format(days[t.tm_wday], t.tm_mday, t.tm_mon, t.tm_year)) # writes the start time f.write('Start time: {}:{}:{}\n'.format(t.tm_hour, t.tm_min, t.tm_sec)) # headers for data, comma-delimited f.write('CO2,Time\n') # debug statement for REPL print("initial write to SD card complete, starting to log")
In the loop, the CO2 level from the SCD-40, along with the current time, is written to the SD card's text file every 30 seconds.
while True: # variable for RTC datetime t = rtc.datetime # append SD card text file with open("/sd/co2.txt", "a") as f: # read co2 data from SCD40 co2 = scd4x.CO2 # write co2 data followed by the time, comma-delimited f.write('{},{}:{}:{}\n'.format(co2, t.tm_hour, t.tm_min, t.tm_sec)) # repeat every 30 seconds time.sleep(30)
Page last edited January 21, 2025
Text editor powered by tinymce.