import smbus2
import time
# MAX30105 default I2C address
MAX30105_I2C_ADDR = 0x57
# Register addresses
REG_INT_STATUS = 0x00
REG_MODE_CONFIG = 0x09
REG_SPO2_CONFIG = 0x0A
REG_LED_CONFIG = 0x0C
REG_FIFO_WR_PTR = 0x04
REG_FIFO_RD_PTR = 0x06
REG_FIFO_DATA = 0x07
# Initialize I2C
bus = smbus2.SMBus(1) # 1 indicates /dev/i2c-1
def write_register(reg, value):
bus.write_byte_data(MAX30105_I2C_ADDR, reg, value)
def read_register(reg):
return bus.read_byte_data(MAX30105_I2C_ADDR, reg)
def reset_sensor():
write_register(REG_MODE_CONFIG, 0x40) # Reset command
time.sleep(0.1)
def setup_sensor():
reset_sensor()
write_register(REG_MODE_CONFIG, 0x03) # Heart rate + SpO2 mode
write_register(REG_SPO2_CONFIG, 0x27) # ADC range, sample rate
write_register(REG_LED_CONFIG, 0x24) # LED1 & LED2 pulse amplitude
def read_fifo():
red_data = bus.read_i2c_block_data(MAX30105_I2C_ADDR, REG_FIFO_DATA, 6)
red = (red_data[0] << 16) | (red_data[1] << 8) | red_data[2]
ir = (red_data[3] << 16) | (red_data[4] << 8) | red_data[5]
return red & 0x3FFFF, ir & 0x3FFFF # 18-bit values
# Main loop
setup_sensor()
print("Reading MAX30105 data...")
try:
while True:
red, ir = read_fifo()
print(f"Red: {red}, IR: {ir}")
time.sleep(0.5)
except KeyboardInterrupt:
print("Exiting...")
bus.close()
____________________________________________________________________________________________
import time
from sensirion_i2c_driver import I2cConnection
from sensirion_i2c_scd4x import Scd4xI2cDevice
import smbus2
# Initialize I2C connection
bus = smbus2.SMBus(1)
scd41 = Scd4xI2cDevice(I2cConnection(bus))
# Start periodic measurement
scd41.start_periodic_measurement()
print("Waiting for first measurement...")
while True:
time.sleep(5)
# Read CO2, temperature, and humidity
co2, temperature, humidity = scd41.read_measurement()
if co2 is not None:
print(f"CO2: {co2} ppm, Temperature: {temperature:.2f} °C, Humidity: {humidity:.2f} %RH")
else:
print("No valid measurement yet.")
____________________________________________________________________________________________
Adafruit MPL3115A2 - I2C Barometric
import time
import board
import busio
import adafruit_mpl3115a2
# Initialize I2C bus
i2c = busio.I2C(board.SCL, board.SDA)
# Create sensor object
sensor = adafruit_mpl3115a2.MPL3115A2(i2c)
# Set sensor mode (Pressure or Altitude)
sensor.sealevel_pressure = 1013.25 # Adjust based on local sea-level pressure
while True:
try:
pressure = sensor.pressure # Pressure in hPa
altitude = sensor.altitude # Altitude in meters
temperature = sensor.temperature # Temperature in Celsius
print(f"Pressure: {pressure:.2f} hPa")
print(f"Altitude: {altitude:.2f} m")
print(f"Temperature: {temperature:.2f} °C")
print("---------------------------")
time.sleep(2) # Wait for 2 seconds
except KeyboardInterrupt:
print("Exiting...")
break
____________________________________________________________________________________________
MQ-135 Air quality gas sensor module
Setup:
Hardware Setup:
● MQ-135 Sensor has 4 pins: VCC (5V), GND, AOUT (analog output), and DOUT (digital output).
● Raspberry Pi GPIO pins will be used to read the sensor's output.
Connection Details:
● VCC of the MQ-135 to 5V pin of the Raspberry Pi.
● GND of the MQ-135 to GND pin of the Raspberry Pi.
● AOUT to an Analog-to-Digital Converter (ADC) pin (since Raspberry Pi doesn't have built-in
ADC).
○ You can use a module like the MCP3008 ADC for this.
● DOUT is a digital output pin (usually used for threshold-based alarm triggering, but in this case,
it's not essential for analog reading).
Additional Requirement:
● MCP3008 ADC to read the analog values from the MQ-135 sensor since the Raspberry Pi
does not have analog input.
Code:
import spidev
import time
import RPi.GPIO as GPIO
# Setup SPI (Serial Peripheral Interface) for MCP3008 ADC
spi = spidev.SpiDev()
spi.open(0, 0) # bus 0, device 0 (you can change these depending on your wiring)
# MCP3008 channel for reading the sensor value
MQ135_CHANNEL = 0 # Select the channel for MQ-135 (e.g., channel 0 for A0)
# Function to read the analog value from MCP3008
def read_adc(channel):
# Make sure channel is between 0 and 7
if channel < 0 or channel > 7:
return -1
# Send the start bit and channel information to MCP3008
r = spi.xfer2([1, (8 + channel) << 4, 0])
# Combine the two bytes and return the result
data = ((r[1] & 3) << 8) + r[2]
return data
# Function to calculate the air quality from the analog value
def read_air_quality():
sensor_value = read_adc(MQ135_CHANNEL)
if sensor_value == -1:
print("Failed to read data from sensor.")
return
# The sensor's value may need calibration to convert to real air quality levels.
# This formula depends on your MQ-135 calibration and datasheet.
# Example: Assuming the value range is from 0-1023 (10-bit resolution)
air_quality = sensor_value / 1023.0 * 5.0 # Normalize to 0-5V
print(f"Sensor Value: {sensor_value}, Air Quality (Voltage): {air_quality:.2f}V")
# Run the script
if __name__ == "__main__":
try:
while True:
read_air_quality()
time.sleep(1) # Delay between readings
except KeyboardInterrupt:
print("Program stopped.")
spi.close()
GPIO.cleanup()