Raspberry Pi OS Setup
First, get the latest release of Raspberry Pi OS installed on your Pi and update all of the built-in software with apt. If you are comfortable with the Raspberry Pi imaging and setup process, you can follow the steps listed here under the quick start prerequisites. If you'd like more details, a more thorough guide page can be found here.
Virtual Environment
This project will require installing several different Python libraries into the same virtual environment. You must always be sure to activate the environment before installing libraries or running the scripts that use them.
I've used a venv at ~/venvs/sensor_llm_venv/. Subsequent guide pages and instructions will all use the same venv created here. Use the exact same one if you want to follow along by copy/pasting commands or note the name of your own venv and substitute when appropriate.
Here are the commands to create, then activate a virtual environment.
cd ~ sudo apt install python3-venv python3 -m venv ~/venvs/sensor_llm_venv --system-site-packages source ~/venvs/sensor_llm_venv/bin/activate
Blinka Setup
The Blinka setup process is documented on this guide page. Refer to it if you've never done the process before. For this guide I used the automated install instructions from that page.
Install Blinka with these commands.
source ~/venvs/sensor_llm_venv/bin/activate cd ~ pip3 install --upgrade adafruit-python-shell wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.py sudo -E env PATH=$PATH python3 raspi-blinka.py
At the end of the install it will prompt for Y/N to reboot the Pi. Press 'Y' and enter to go ahead with the reboot.
SEN6x Setup & Test
If you are using a different sensor, then refer to the guide or documentation for your device to get it setup and make sure it can successfully get data readings.
Wiring
Connect the SEN6x breakout to the Raspberry Pi 5 via I2C pins, and connect the SEN6x node to the breakout with the 6 pin JST GH cable.
-
Pi 3V to breakout VIN (red wire)
-
Pi GND to breakout GND (black wire)
-
Pi SCL to breakout SCL (yellow wire)
- Pi SDA to breakout SDA (blue wire)
- SEN66 sensor to breakout JST GH port
The Adafruit Pi Stemma QT Breakout makes it easy to connect the the SEN6x breakout using a standard STEMMA QT cable.
Python Installation of SEN6x Library
Activate the same virtual environment created in the Blinka Setup step if it is not already active.
From your command line run the following command:
pip3 install adafruit-circuitpython-sen6x
If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!
Verify Sensor Data Readings
Test that everything is setup properly with the following script, or a similar one modified for your sensor if you're using something other than the SEN6x.
# SPDX-FileCopyrightText: Copyright (c) 2025 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# Simpletest for the SEN6x Driver
# Uncomment the init for your SEN6x sensor
import time
import board
import adafruit_sen6x
# Initialize I2C
i2c = board.I2C()
# Initialize the sensor:
sensor = adafruit_sen6x.SEN66(i2c) # SEN66 sensors
# sensor = adafruit_sen6x.SEN63C(i2c) # SEN63C sensors
# Read sensor info
print(f"Product: {sensor.product_name}")
print(f"Serial: {sensor.serial_number}")
# Check device status
status = sensor.device_status
print(f"Device {status}")
# Optional: Configure sensor before starting
# sensor.temperature_offset(offset=-2.0, slot=0) # Apply -2°C offset
# sensor.voc_algorithm_tuning(index_offset=100) # Adjust VOC baseline
# print(sensor.voc_algorithm) # Print VOC baseline
# CO2 configuration examples:
# sensor.co2_automatic_self_calibration = False # Disable ASC for greenhouses
# sensor.ambient_pressure = 1020 # Set pressure in hPa
# sensor.sensor_altitude = 500 # Or set altitude in meters
# Start measurements
sensor.start_measurement()
# Wait for first measurement to be ready
print("Waiting for first measurement...")
time.sleep(2)
print("-" * 40)
# Read data continuously
while True:
if sensor.data_ready:
# Check for errors before reading
sensor.check_sensor_errors()
# Read all measurements
data = sensor.all_measurements()
# Display values (None = sensor still initializing)
print(
f"Temperature: {data['temperature']:.1f}°C"
if data["temperature"]
else "Temperature: initializing..."
)
print(
f"Humidity: {data['humidity']:.1f}%"
if data["humidity"]
else "Humidity: initializing..."
)
print(f"PM2.5: {data['pm2_5']:.1f} µg/m³" if data["pm2_5"] else "PM2.5: initializing...")
try: # if sensor does not have VOC/NOx readings, skip
print(
f"VOC Index: {data['voc_index']:.1f}"
if data["voc_index"]
else "VOC Index: initializing..."
)
print(
f"NOx Index: {data['nox_index']:.1f}"
if data["nox_index"]
else "NOx Index: initializing..."
)
except KeyError:
pass
print(f"CO2: {data['co2']} ppm" if data["co2"] else "CO2: initializing...")
print("-" * 40)
time.sleep(2)
The sensor takes several seconds to initialize and start giving readings for all of the different values. After a moment you should be seeing outputs similar to below being printed in your terminal.
If you see zeros for some values, wait a few moments longer. If you see an exception traceback or have some other problem running the demo script, stop and troubleshoot that before moving on to the next pages.
Page last edited September 23, 2025
Text editor powered by tinymce.