Automatic bathroom/shower fan controller

About 10 years ago I build a bathroom fan controller with a 555 and a dew sensor from an old VCR.
Time to modernise, so I dug into the parts box and came up with an ATtiny85 and Si7021.
Currently working on a breadboard on a 5volt supply,
but it probably will have a capacitive supply once inside the fan.
No library used, so very light on memory (56 bytes of dynamic).
First time using a bare ATtiny85, so I hope I’ve done it right.
Same sketch can be used on an Uno/Nano, with some pin modifications.

// Bathroom Fan Control with teflon-covered Si7021 RH sensor and Attiny85
#include <Wire.h>
const byte outPin = 1; // chip pin6, for G3MB-202P SSR
const byte ledPin = 3; // chip pin2
const byte thresholdPin = 4; // chip pin3
unsigned long prevMillis; // timing
byte threshold; // RH switch point
bool ledState; // 'off' with flashes, or 'on' with flashes

void setup() {
  Wire.begin(); // SCL chip pin7, SDA chip pin5
  pinMode(outPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(thresholdPin, INPUT_PULLUP); // 'normally open' solder bridge
  Wire.beginTransmission(0x40); // Si7021 address
  Wire.write(0xFE); // reset on bootup
  if (digitalRead(thresholdPin)) threshold = 65; // normal 65%RH
  else threshold = 70; // 70%RH fan switch point when grounded
} // fan test-runs 30sec before the first measurement

void loop() {
  if (millis() - prevMillis > 30000UL) { // measuring interval
    prevMillis = millis();
    Wire.beginTransmission(0x40); // address
    Wire.write(0xE5); // RH measure/hold command
    Wire.requestFrom(0x40, 2); // get the two RH bytes
    unsigned int raw = << 8 |; // join
    byte humidity = (float)raw * 125 / 65536 - 6; // process
    if (humidity >= threshold) {
      digitalWrite(outPin, LOW); // SSR/fan on
      digitalWrite (ledPin, LOW); // LED off
      ledState = false; // pin low, LED mostly off
    } else {
      digitalWrite(outPin, HIGH); // SSR/fan off
      digitalWrite (ledPin, HIGH); // LED on
      ledState = true; // pin high, LED mostly on
    if (humidity >= 80) { // dew prevention
      Wire.write(0xE6); // register1
      Wire.write(0x3E); // heater on
    } else {
      Wire.write(0xE6); // register1
      Wire.write(0x3A); // heater off
    byte tens = humidity / 10;
    byte units = humidity % 10;
    delay(2000); // LED mode separator
    for (byte i = 0; i < tens; i++) { // flash LED 'tens' times
      digitalWrite(ledPin, !ledState);
      delay(20); // flash time
      digitalWrite(ledPin, ledState);
      delay(480); // pause time
    delay(500); // tens/units separator
    for (byte i = 0; i < units; i++) { // flash LED 'units' times
      digitalWrite(ledPin, !ledState);
      digitalWrite(ledPin, ledState);

   compiled with IDE: 1.8.12
   drazzy boards manager
   bootloader and sketch at 1Mhz internal
   SSR LED between 5volt and pin (default on)
   indicator LED between pin and ground (default off)
   indicator LED current calculated to match SSR LED current (balance load for capacitive supply)
   total current draw: MCU~1.5mA, SSR~7mA, heater~3mA
   connect threshold pin to ground in higher average humidity environments

What does the test run show?

Currently testing with a 5volt cellphone power bank in the bathroom, and it seems to work fine.
Wasn't sure yet what the relative humidity would be with a shower/bath, but it seems to be in the high seventies.
Well above the set 65% for the fan to come on.
I guess I will be cleaner than normal during the next few days :slight_smile:

Be aware of regulations about electricity in bathrooms - if you are switching a mains fan, there are regulations about where parts can be installed - you don’t want someone in the bath to be able to touch it !

Don’t worry, I know about regulations and safety.
This sensor will be fully enclosed inside a ceiling fan, without any user controls.