Humidity Sensor

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

https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-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 

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)

        )


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.

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

https://www.homedepot.com/p/Hillman-1-4-I-D-x-3-8-O-D-x-3-4-in-Seamless-Steel-Spacer-5-Pack-880415/204726297   to hold?


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

https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-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;