Maureen Rakotondraibe
Published © GPL3+

Digital pet - Indoor Air Quality gamified - SEN66

Taking care of this digital pet is taking care of you! Monitor your indoor air quality to keep it alive. IAQ gamified for kids.

IntermediateFull instructions provided8 hours204
Digital pet - Indoor Air Quality gamified - SEN66

Things used in this project

Hardware components

Raspberry Pi 5
Raspberry Pi 5
×1
Sensirion SEN66
×1
Seeed Studio Grove SEN5X
×1
Seeed Studio Grove SCD41
×1

Story

Read more

Schematics

Wiring diagram

Wiring diagram to connect the SEN66 and the Raspberry Pi 5.

Code

SEN66_sensor_readings

Python
Code to read from the sensor, the functions should be called from the user interface main code. It allows to de/initialize the sensor, read measurements and analyze them.
import time
from smbus2 import SMBus, i2c_msg

DEVICE_BUS = 1

# device address SEN66
DEVICE_ADDR = 0x6B

def sen66_init():
    global bus
    # init I2C
    bus = SMBus(DEVICE_BUS)

    # wait 1 s for sensor start up 
    time.sleep(1)

    # start continuous measurement in periodic mode, will update every s
    msg = i2c_msg.write(DEVICE_ADDR, [0x00, 0x21])
    bus.i2c_rdwr(msg)

    # wait for first measurement to be finished
    time.sleep(2)

def sen66_measure():
    global bus
    # read out sensor data
    msg = i2c_msg.write(DEVICE_ADDR, [0x03, 0x00])       
    bus.i2c_rdwr(msg)
    # wait 20 ms for data ready
    time.sleep(0.02)

    # read bytes; each three bytes in as a sequence of MSB, LSB, CRC
    msg = i2c_msg.read(DEVICE_ADDR,27)
    bus.i2c_rdwr(msg)

    # merge byte x and byte x+1 to integer
    pm1p0 = (msg.buf[0][0] << 8 | msg.buf[1][0])/10
    pm2p5 = (msg.buf[3][0] << 8 | msg.buf[4][0])/10
    pm4p0 = (msg.buf[6][0] << 8 | msg.buf[7][0])/10
    pm10p0 = (msg.buf[9][0] << 8 | msg.buf[10][0])/10

    humidity = msg.buf[12][0] << 8 | msg.buf[13][0]
    # calculate relative humidity according to datasheet in %
    humidity /= 100

    temperature = msg.buf[15][0] << 8 | msg.buf[16][0]
    # calculate temperature  according to datasheet in Celsius
    temperature /= 200

    voc = (msg.buf[18][0] << 8 | msg.buf[19][0]) / 10 #VOC index
    nox = (msg.buf[21][0] << 8 | msg.buf[22][0]) / 10 #NOX index
    co2 = (msg.buf[24][0] << 8 | msg.buf[25][0]) #ppm
    
    print("{:.2f},{:.2f},{:.2f},{:.2f},{:.2f},{:.2f}".format(voc, nox, temperature, humidity,co2,pm2p5))
    return voc, nox, temperature, humidity,co2,pm2p5

def sen66_analyze():
    voc, nox, temperature, humidity,co2,pm2p5 = sen66_measure()
    
    humidity = 1 if humidity < 40 else humidity = 0   
    co2 = 1 if co2 > 1000 else co2 = 0   
    voc = 1 if voc > 105 else voc = 0   
    nox = 1 if nox > 5 else nox = 0
    pm2p5 = 1 if pm2p5 > 35 else pm2p5 = 0
    print(voc, nox, humidity,co2,pm2p5)
    return voc, nox, humidity,co2,pm2p5
    
def sen66_deinit():
    global bus
    bus.close()
    

SCD41 - RPI library

Library to communicate with the SCD41

SEN55 - RPI library

Library to communicate with the SEN55

Credits

Maureen Rakotondraibe
5 projects • 8 followers
Embedded systems/software engineer / Passionate about interfacing technologies to create new solutions

Comments