This is basically the same idea as the Arduino sketch - just read the values and send over serial in a loop. There are CircuitPython libraries for the SCD40 and BME280, which makes this easy to implement.
The required libraries will be included with the project bundle download along with project code below.
Enable USB CDC Data
We could probably just send the data using the typical serial ouput via the typical print()
command. However, here we show how to enable and use the secondary USB CDC serial port available in CircuitPython:
As mentioned in that guide, this requires a special boot.py file to be located in the CIRCUITPY folder. Well, not too special, it's just a few lines of code:
# SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries # # SPDX-License-Identifier: MIT import usb_cdc usb_cdc.enable(data=True)
Copy that code and save it to CIRCUITPY/boot.py.
CircuitPython Code
Here is the project code. To get code and necessary libraries, click on the Download Project Bundle link below, and uncompress the .zip file. Once the sensors are connected and the modified boot.py has been put in place, simply save the project code as CIRCUITPY/code.py:
# SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries # # SPDX-License-Identifier: MIT import time import board import usb_cdc import adafruit_scd4x from adafruit_bme280 import basic as adafruit_bme280 import neopixel #--| User Config |----------------------------------- DATA_FORMAT = "JSON" # data format, CSV or JSON DATA_RATE = 5 # data read rate in secs BEAT_COLOR = 0xADAF00 # neopixel heart beat color BEAT_RATE = 1 # neopixel heart beat rate in secs, 0=none #---------------------------------------------------- # check that USB CDC data has been enabled if usb_cdc.data is None: print("Need to enable USB CDC serial data in boot.py.") while True: pass # setup stuff i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller scd = adafruit_scd4x.SCD4X(i2c) scd.start_periodic_measurement() bme = adafruit_bme280.Adafruit_BME280_I2C(i2c) pixel = neopixel.NeoPixel(board.NEOPIXEL, 1) # CSV output def send_csv_data(values): usb_cdc.data.write("{}, {}, {}, {}\n".format(*values).encode()) # JSON output def send_json_data(values): usb_cdc.data.write('{'.encode()) usb_cdc.data.write('"CO2" : {},'.format(values[0]).encode()) usb_cdc.data.write('"pressure" : {},'.format(values[1]).encode()) usb_cdc.data.write('"temperature" : {},'.format(values[2]).encode()) usb_cdc.data.write('"humidity" : {}'.format(values[3]).encode()) usb_cdc.data.write('}\n'.encode()) # init time tracking last_data = last_beat = time.monotonic() # loop forever! while True: current_time = time.monotonic() # data if current_time - last_data > DATA_RATE: data = (scd.CO2, bme.pressure, bme.temperature, bme.humidity) usb_cdc.data.reset_output_buffer() if DATA_FORMAT == "CSV": send_csv_data(data) elif DATA_FORMAT == "JSON": send_json_data(data) else: usb_cdc.data.write(b"Unknown data format.\n") last_data = current_time # heart beat if BEAT_RATE and current_time - last_beat > BEAT_RATE: if pixel[0][0]: pixel.fill(0) else: pixel.fill(BEAT_COLOR) last_beat = current_time
Page last edited January 22, 2025
Text editor powered by tinymce.