Humidity Sensor
Parts
Pump from HB thread
https://www.amazon.com/dp/B09FGMZL3S?_encoding=UTF8&ref_=cm_sw_r_cp_ud_dp_77518ZYDJWGJPP3R81RS&th=1
Model mpa2002t2
Used this pump: 6V DC Mini Micro Air Pump, Air Vacuum pump MP2005
Sensor
https://www.mouser.com/ProductDetail/485-4636
https://learn.adafruit.com/adafruit-sensirion-shtc3-temperature-humidity-sensor
adafruit SHTC3. bought from Mouser 4/2024
Pi
https://github.com/adafruit/Adafruit_CircuitPython_SHTC3
https://github.com/brainelectronics/micropython-i2c-lcd/blob/main/examples/main.py
Execute python at startup
https://www.instructables.com/Raspberry-Pi-Launch-Python-script-on-startup/
https://learn.sparkfun.com/tutorials/how-to-run-a-raspberry-pi-program-on-startup/all
write data to file
Make Pi (Bullseye)
https://www.tomshardware.com/reviews/raspberry-pi-headless-setup-how-to,6028.html
raspberry pi imager
Select pi type, I used lite image for Bullseye which is now the older OS
Setup user name and password, wifi info, turn on SSH in Services tab, then flash usd card
Boot up
sudo apt update
sudo apt upgrade -y
sudo apt-get install python3-pip
sudo apt install --upgrade python3-setuptools
sudo reboot
Now prepare pi
For bullseye, skip steps related to virtual environment
cd ~
pip3 install --upgrade adafruit-python-shell
wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.pywget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.py
sudo -E env PATH=$PATH python3 raspi-blinka.py
last command tooks a few mins to complete
reboot when it asks
Run this to test blinka installed ok:
ls /dev/i2c* /dev/spi*
/dev/i2c-1 /dev/i2c-2 /dev/spidev0.0 /dev/spidev0.1
Tried to compile a test py file, but had to fix this:
Traceback (most recent call last):
File "/home/pi/test.py", line 3, in <module>
import board
ModuleNotFoundError: No module named 'board'
install board package
sudo pip3 install --break-system-packages adafruit-blinka
install board package(s)
This one was just to test
pip3 install adafruit-circuitpython-lis3dh
https://github.com/adafruit/Adafruit_CircuitPython_SHTC3
pip3 install adafruit-circuitpython-shtc3
sudo nano sht.py
Inserted:
import time
import board
import adafruit_shtc3
i2c = board.I2C() # uses board.SCL and board.SDA
sht = adafruit_shtc3.SHTC3(i2c)
while True:
temperature, relative_humidity = sht.measurements
print("Temperature: %0.1f C" % temperature)
print("Humidity: %0.1f %%" % relative_humidity)
print("")
time.sleep(1)
if file is named sct.py
python3 sht.py
Will get errors if board is not connected
getttpsraw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.py
SHTC3 Info
https://learn.adafruit.com/adafruit-sensirion-shtc3-temperature-humidity-sensor
3Vo - this is the 3.3V output from the voltage regulator, you can grab up to 100mA from this if you like
SPG30 draws 48 mA in measurement mode
https://github.com/adafruit/Adafruit_CircuitPython_SHTC3
sudo pip3 install adafruit-circuitpython-shtc3
SGP30 Info
https://learn.adafruit.com/adafruit-sgp30-gas-tvoc-eco2-mox-sensor/circuitpython-wiring-test
pip3 install adafruit-circuitpython-sgp30
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
""" Example for using the SGP30 with CircuitPython and the Adafruit library"""
import time
import board
import busio
import adafruit_sgp30
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
# Create library object on our I2C port
sgp30 = adafruit_sgp30.Adafruit_SGP30(i2c)
print("SGP30 serial #", [hex(i) for i in sgp30.serial])
sgp30.set_iaq_baseline(0x8973, 0x8AAE)
sgp30.set_iaq_relative_humidity(celsius=22.1, relative_humidity=44)
elapsed_sec = 0
while True:
print("eCO2 = %d ppm \t TVOC = %d ppb" % (sgp30.eCO2, sgp30.TVOC))
time.sleep(1)
elapsed_sec += 1
if elapsed_sec > 10:
elapsed_sec = 0
print(
"**** Baseline values: eCO2 = 0x%x, TVOC = 0x%x"
% (sgp30.baseline_eCO2, sgp30.baseline_TVOC)
)
Example from Sparkfun to convert to absolute humidity
https://learn.sparkfun.com/tutorials/sparkfun-air-quality-sensor---sgp30-qwiic-hookup-guide/all
Sensor housing
Had a small project box with two holes in top, that had been used for switches in an old project.
Removed switches. One hole used for tube. In end of tube, added a 1/4" coupling (see pic below). I pushed hard on the coupling into the hole of my project box so it would stay in place. I was lucky, hole was right size to support a "press fit" connection. I'll add glue if it comes loose.
Used double sided 3m foam tape to mount sensor board in box across from coupling.
Sensor box has 2 holes. I tried covering one, but I get a better (faster) response if I leave the 2nd hole open for air to exhaust from box.
SGP30 info
https://learn.sparkfun.com/tutorials/sparkfun-air-quality-sensor---sgp30-qwiic-hookup-guide/all
https://www.amazon.com/EC-Buying-Formaldehyde-Monitoring-Multi-Pixel/dp/B0B389LQCQ
Model: GY-SGP30
Power supply compatible with 2v---5v
Dig 1/4 in. Barb Connectors used at sensor box
https://www.homedepot.com/p/DIG-1-4-in-Barb-Connectors-50-Pack-H80B/100112605
But I happend to have one so I didn't need to buy 50
Misc
Already have 1/8" or 3mm inner diameter silicone tubing
Filter
6 x 15 mm RAW slim natural unrefined cotton filter tips
0.6" long
No go
Ebay car gas filter "Clearview inline fuel filter 1/4" 3/8" 5/16" chrome hose barb Chrome Plated 9706"
Didn't work, trapped water during roast
Air path:
Roaster - end of hose to 1/8 to 1/4 adapter to 1/4 hose with cotton inside for filter to 1/4 to 1/8 adapter to 1/8 hose to pump in to pump out 1/8 hose to sensor housing
old Roaster - end of hose to filter in to filter out hose to pump in to pump out hose to sensor housing
- Connect VCC (power) to the 5V pin (pin 2 or 4)
- Connect GND (ground) to any GND pin (pin 6)
- Connect SDA (data) to GPIO 2 (pin 3) White wire
- Connect SCL (clock) to GPIO 3 (pin 5) brown wire
Power
LM2596HV AC/DC to DC Step Down Buck Converter Module,
LM7805 for 5VDC regulator
SHCT3 5V (works from either 5 or 3.3)
LCD 5V
SGP30 5V
Motor 5V
LM2937-3.3 for 3.3 VDC regulator did not use
LCD Info
2004 20X4 LCD Display LCD Screen Serial with IIC I2C Adapter Yellow Green Color
* Interface: I2C
* I2C Address: 0x27
* Pin Definition : GND、VCC、SDA、SCL
* Back lit (Yellow with Black char color)
* Supply voltage: 5V
I2C addresses
SHTC3 I2C address: 0x70.
SGP30's I2C address: 0x58
LCD I2C Address: 0x27
Revised code that works:
# Randy's version of HacKAWAnalyzer
# Just some rando code using open source software
import time
import board
import math
import numpy as np
import adafruit_shtc3
import busio
#import adafruit_sgp30
i2c = board.I2C() # uses board.SCL and board.SDA
# Create library object on shtc3 I2C port
sht = adafruit_shtc3.SHTC3(i2c)
# Create library object on sgp30 I2C port
# sgp30 = adafruit_sgp30.Adafruit_SGP30(i2c)
#randy changed to size from 6 to 3, length 1000=16.7 mins
LogArray, LogIndex, DropIndex = np.zeros([1000,3]), 0, 0
BaseTime = time.time()
while True:
Timestamp = time.time() - BaseTime
temperature, relative_humidity = sht.measurements
# Tgas, RH, VOC = temperature, relative_humidity, bme.gas
Tgas, RH = temperature, relative_humidity
AH = (6.112 * math.exp((17.67 * Tgas) / (Tgas + 243.5)) * RH * 2.1674) / ((273.15 + Tgas))
if LogIndex < 20 : MRoR = 0
# else: MRoR = np.polyfit(LogArray[(LogIndex - 20):LogIndex, 0], LogArray[(LogIndex - 20):LogIndex, 4], 1)[0]
else: MRoR = np.polyfit(LogArray[(LogIndex - 20):LogIndex, 0], LogArray[(LogIndex - 20):LogIndex, 2], 1)[0]
# print("%d %0.2f %0.2f %0.2f %0.2f %0.2f %d" % (LogIndex, Timestamp/60, BT, ET, MRoR, AH, VOC))
print("%d %0.2f %0.2f %0.2f" % (LogIndex, Timestamp/60, MRoR, AH))
# LogArray[LogIndex] = (Timestamp/60, BT, ET, MRoR, AH, VOC)
LogArray[LogIndex] = (Timestamp/60, MRoR, AH)
# LogArray[max(0, (LogIndex - 10)), 3] = MRoR
if (LogIndex > 998) :
LogArray[:, 0] -= LogArray[DropIndex, 0]
filename = time.strftime('Roast %b%d %I;%M%p.csv', time.localtime())
np.savetxt(str(filename), LogArray[0:LogIndex], fmt='%.2f', delimiter=',')
print("File Saved: ", filename)
LogArray, LogIndex, DropIndex = np.zeros([700,6]), 0, 0
# r, g, b, c = apd.color_data
# DropIndex = max(DropIndex, (LogIndex * (r > g)))
LogIndex = (LogIndex + 1)
time.sleep(max(0, 1 - (time.time() - BaseTime - Timestamp)))
# Randy's version of HacKAWAnalyzer
# Just some rando code using open source software
import time
import board
import math
import numpy as np
import adafruit_shtc3
import busio
#import adafruit_sgp30
i2c = board.I2C() # uses board.SCL and board.SDA
# Create library object on shtc3 I2C port
sht = adafruit_shtc3.SHTC3(i2c)
# Create library object on sgp30 I2C port
# sgp30 = adafruit_sgp30.Adafruit_SGP30(i2c)
LogArray, LogIndex, DropIndex = np.zeros([700,6]), 0, 0
BaseTime = time.time()
while True:
Timestamp = time.time() - BaseTime
temperature, relative_humidity = sht.measurements
# Tgas, RH, VOC = temperature, relative_humidity, bme.gas
Tgas, RH = temperature, relative_humidity
AH = (6.112 * math.exp((17.67 * Tgas) / (Tgas + 243.5)) * RH * 2.1674) / ((273.15 + Tgas))
if LogIndex < 20 : MRoR = 0
else: MRoR = np.polyfit(LogArray[(LogIndex - 20):LogIndex, 0], LogArray[(LogIndex - 20):LogIndex, 4], 1)[0]
# print("%d %0.2f %0.2f %0.2f %0.2f %0.2f %d" % (LogIndex, Timestamp/60, BT, ET, MRoR, AH, VOC))
print("%d %0.2f %0.2f %0.2f" % (LogIndex, Timestamp/60, MRoR, AH))
# LogArray[LogIndex] = (Timestamp/60, BT, ET, MRoR, AH, VOC)
LogArray[LogIndex] = (Timestamp/60, MRoR, AH,0,0,0)
LogArray[max(0, (LogIndex - 10)), 3] = MRoR
if (LogIndex > 900) :
LogArray[:, 0] -= LogArray[DropIndex, 0]
filename = time.strftime('Roast %b%d %I;%M%p.csv', time.localtime())
np.savetxt(str(filename), LogArray[0:LogIndex], fmt='%.2f', delimiter=',')
print("File Saved: ", filename)
LogArray, LogIndex, DropIndex = np.zeros([700,6]), 0, 0
# r, g, b, c = apd.color_data
# DropIndex = max(DropIndex, (LogIndex * (r > g)))
# LogIndex = (LogIndex + 1) * ((r > g) + ((LogIndex > 300) * (g > r)))
LogIndex = (LogIndex + 1)
time.sleep(max(0, 1 - (time.time() - BaseTime - Timestamp)))
Gary's code for a pi
# HacKAWAnalyzer
# Just some rando code using open source software
import time
import board
import math
import numpy as np
import adafruit_mcp9600
import adafruit_bme680
import adafruit_apds9960.apds9960
i2c = board.I2C()
mcp1 = adafruit_mcp9600.MCP9600(i2c, address = 0x67)
mcp2 = adafruit_mcp9600.MCP9600(i2c, address = 0x66)
bme = adafruit_bme680.Adafruit_BME680_I2C(i2c, address = 0x77)
bme.set_gas_heater(400, 900)
apd = adafruit_apds9960.apds9960.APDS9960(i2c)
apd.enable_color = True ; apd.color_integration_time = 72 ; apd.color_gain = 3
LogArray, LogIndex, DropIndex = np.zeros([700,6]), 0, 0
BaseTime = time.time()
while True:
Timestamp = time.time() - BaseTime
BT, ET, Tgas, RH, VOC = mcp1.temperature, mcp2.temperature, bme.temperature, bme.humidity, bme.gas
AH = (6.112 * math.exp((17.67 * Tgas) / (Tgas + 243.5)) * RH * 2.1674) / ((273.15 + Tgas))
if LogIndex < 20 : MRoR = 0
else: MRoR = np.polyfit(LogArray[(LogIndex - 20):LogIndex, 0], LogArray[(LogIndex - 20):LogIndex, 4], 1)[0]
print("%d %0.2f %0.2f %0.2f %0.2f %0.2f %d" % (LogIndex, Timestamp/60, BT, ET, MRoR, AH, VOC))
LogArray[LogIndex] = (Timestamp/60, BT, ET, MRoR, AH, VOC)
LogArray[max(0, (LogIndex - 10)), 3] = MRoR
if ((LogIndex > (DropIndex + 10)) or LogIndex > 699) :
LogArray[:, 0] -= LogArray[DropIndex, 0]
filename = time.strftime('Roast %b%d %I;%M%p.csv', time.localtime())
np.savetxt(str(filename), LogArray[0:LogIndex], fmt='%.2f', delimiter=',')
print("File Saved: ", filename)
LogArray, LogIndex, DropIndex = np.zeros([700,6]), 0, 0
r, g, b, c = apd.color_data
DropIndex = max(DropIndex, (LogIndex * (r > g)))
LogIndex = (LogIndex + 1) * ((r > g) + ((LogIndex > 300) * (g > r)))
time.sleep(max(0, 1 - (time.time() - BaseTime - Timestamp)))
Reference only
Rest of stuff below was info I looked at, but didn't use for the projet
Make Pi (bookworm, did not use)
https://www.tomshardware.com/reviews/raspberry-pi-headless-setup-how-to,6028.html
raspberry pi imager
Select pi type, I used lite image
Setup user name and password, wifi info, turn on SSH in Services tab, then flash usd card
Boot up
sudo apt update
sudo apt upgrade
reboot
Now prepare pi
sudo apt-get install python3-pip
sudo apt install --upgrade python3-setuptools
Install virtual environment
sudo apt install python3-venv
python3 -m venv env --system-site-packages
You will need to activate the virtual environment every time the Pi is rebooted. To activate it:
source env/bin/activate
and you will be in virtual env
cd ~
pip3 install --upgrade adafruit-python-shell
wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.pywget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.py
sudo -E env PATH=$PATH python3 raspi-blinka.py
last command tooks a few mins to complete
reboot when it asks
ls /dev/i2c* /dev/spi*
/dev/i2c-1 /dev/i2c-2 /dev/spidev0.0 /dev/spidev0.1
Tried to compile a test py file, but had to fix this:
Traceback (most recent call last):
File "/home/pi/test.py", line 3, in <module>
import board
ModuleNotFoundError: No module named 'board'
install board package
sudo pip3 install --break-system-packages adafruit-blinka
go to virtual env
source env/bin/activate
install board package(s)
This one was just to test
pip3 install adafruit-circuitpython-lis3dh
pip3 install adafruit-circuitpython-shtc3
make a .py file with this as first line. (Don't think you need to do this, will confirm)
#!/usr/bin/env python3
if file is named test.py
python3 test.py
Will get errors if board is not connected
getttpsraw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.py
ESP32 Pinout
GND to ground TXD NC RST GND
IO27 RXD NC SVP NC
IO25 I2C1 SDA NC IO22 I2C0 SCL Sensor/LCD IO26 I2C1 SCL SVN
IO32 IO21 I2C- SDA Sensor/LCD IO18 IO35
TDI IO17 IO19 IO33
IO4 IO16 IO23 IO34
IO0 GND IO5 TMS
IO2 VCC 5V Red, diode isolated 3.3V NC
SD1 TDO TCK SD2
CLK SD0 SD3 CMD
VCC is diode isolated from LCD and sensors
only use pins 11,12,13,18,23,24,25,26,29 and 30 as SDA or SCK
12, 18, 23, 25, 26,
SPI Pins
sck gpio5, cs gpio23, so gpio19
Time in filename
https://forums.raspberrypi.com/viewtopic.php?t=259796
import time
name = "/home/pi/" + time.strftime("%b-%d-%Y_%H:%M:%S") + ".txt"
print (name)
f = open(name,"w")
f.write("Some text\n")
f.close()
Sensor
https://www.mouser.com/ProductDetail/485-4636
https://learn.adafruit.com/adafruit-sensirion-shtc3-temperature-humidity-sensor
adafruit SHTC3. bought from Mouser 4/2024
Convert RH to absolute Humidity
double RHtoAbsolute (float relHumidity, float tempC) {
double eSat = 6.11 * pow(10.0, (7.5 * tempC / (237.7 + tempC)));
double vaporPressure = (relHumidity * eSat) / 100; //millibars
double absHumidity = 1000 * vaporPressure * 100 / ((tempC + 273) * 461.5); //Ideal gas law with unit conversions
return absHumidity;
}
https://github.com/adafruit/Adafruit_SHTC3/tree/master adafruit arduino library
from SHTC3.h
bool begin(TwoWire *theWire = &Wire);
uint16_t readID(void);
void reset(void);
void sleep(bool sleepmode);
void lowPowerMode(bool readmode);
// create variables for sensor
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();
sensors_event_t humidity, temp;
From example code to init sensor
if (! shtc3.begin()) {
Serial.println("Couldn't find SHTC3");
while (1) delay(1);
}
//my code to init sensor
uint32_t SCTCTime = 5000; //time to look for SHTC3 device
nextTime = millis();
while (millis() - nextTime <= SCTCTime) { //try to find for set time
if (! shtc3.begin()) {
TelnetStream.println("Couldn't find SHTC3 sensor");
Serial.println("Couldn't find SHTC3");
delay(100);
}
else {
Serial.println("Found SHTC3 sensor");
TelnetStream.println("Found SHTC3 sensor");
nextTime = millis() - SCTCTime; //leave while loop
}
}
//to turn off low power mode, use high accuracy mode (longer time to read) instead.
shtc3.lowPowerMode(false);
//read sensor
float humidity01 = 0;
//read humidity
shtc3.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
humidity01 = humidity.relative_humidity;