Smart Exhaust Fan — Arduino Uno simulation

An interactive Arduino Uno circuit simulation you can run free in your browser on Velxio, by johnlawrencetamio.

Components

Sketch code

// Import necessary libraries
#include <DHT.h>
#include <LiquidCrystal.h>
#include <Arduino.h>
#include <RTClib.h>
#include <SensirionI2cScd4x.h>
#include <Wire.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

// Creation of macros
#define NO_ERROR 0

// Initialize pins to be used
#define RELAY_PIN 13
#define DHT22_PIN 8

// Declare variables
uint16_t co2Concentration = 0;
float humidity, temperature, scd41_humidity, scd41_temperature;
String humidity_text, temperature_text, co2Concentration_text, time_text, time_symbol;
int hour, min;
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
static char errorMessage[64];
static int16_t error;
bool dataReady = false;
volatile bool wdtTriggered = false;

// Create objects
DHT dht22(DHT22_PIN, DHT22);
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
SensirionI2cScd4x sensor;
RTC_DS3231 rtc;

// Watchdog Timer interrupt service routine
ISR(WDT_vect) {
  wdtTriggered = true;  // Set flag
}

// Prepare pins
void setup() {
  Serial.begin(115200);  // Prepare serial monitor

  // Prepare components
  dht22.begin();
  lcd.begin(16, 2);
  Wire.begin();
  sensor.begin(Wire, SCD41_I2C_ADDR_62);
  pinMode(RELAY_PIN, OUTPUT);
  delay(30);

  // Prepare RTC module
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));


  // Ensure sensor is in clean state
  error = sensor.wakeUp();
  if (error != NO_ERROR) {
    Serial.print("Error trying to execute wakeUp(): ");
    errorToString(error, errorMessage, sizeof errorMessage);
    Serial.println(errorMessage);
  }
  error = sensor.stopPeriodicMeasurement();
  if (error != NO_ERROR) {
    Serial.print("Error trying to execute stopPeriodicMeasurement(): ");
    errorToString(error, errorMessage, sizeof errorMessage);
    Serial.println(errorMessage);
  }
  error = sensor.reinit();
  if (error != NO_ERROR) {
    Serial.print("Error trying to execute reinit(): ");
    errorToString(error, errorMessage, sizeof errorMessage);
    Serial.println(errorMessage);
  }

  error = sensor.startPeriodicMeasurement();
  if (error != NO_ERROR) {
    Serial.print("Error trying to execute startPeriodicMeasurement(): ");
    errorToString(error, errorMessage, sizeof errorMessage);
    Serial.println(errorMessage);
    return;
  }
}

// Main feedback loop
void loop() {
  // Wait for 3 seconds before continuing
  delay(3000);

  // Check for errors
  error = sensor.getDataReadyStatus(dataReady);
  if (error != NO_ERROR) {
    Serial.print("Error trying to execute getDataReadyStatus(): ");
    errorToString(error, errorMessage, sizeof errorMessage);
    Serial.println(errorMessage);
    return;
  }
  while (!dataReady) {
    delay(100);
    error = sensor.getDataReadyStatus(dataReady);
    if (error != NO_ERROR) {
      Serial.print("Error trying to execute getDataReadyStatus(): ");
      errorToString(error, errorMessage, sizeof errorMessage);
      Serial.println(errorMessage);
      return