mondal3011
Published © GPL3+

Spongebob that can detect drowsiness!

Usually, high CO2 in a room can cause drowsiness. This Spongebob gets sleepy as CO2 level in the room rises so you can open the windows!

AdvancedFull instructions provided10 hours265
Spongebob that can detect drowsiness!

Things used in this project

Hardware components

Seeed Studio XIAO ESP32S3 Sense
Seeed Studio XIAO ESP32S3 Sense
×1
mq135
×1
Jumper wires (generic)
Jumper wires (generic)
×1
DC motor (generic)
×1
m4 bolt
×1

Software apps and online services

Arduino IDE
Arduino IDE
JLCPCB easyeda

Hand tools and fabrication machines

Plier, Long Nose
Plier, Long Nose
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Schematic

Code

CO2_sensor

Arduino
This works along with the custom designed PCB
#include "MQ135.h"

// Define the pins for hall sensors, motor driver, and MQ135 sensor
const int hallSensors[] = {D1, D2, D3, D4, D5};
const int motorEnable = D8;
const int motorInput1 = D6;
const int motorInput2 = D7;
const int mq135Pin = A0;

MQ135 gasSensor = MQ135(mq135Pin);

// Define the CO2 ppm ranges for each hall sensor
const int ppmRanges[][2] = {
  {800, 1000},
  {1001, 1200},
  {1201, 1400},
  {1401, 1600},
  {1601, 1800}
};

// Store the CO2 ppm readings
const int maxReadings = 30; // 5 minutes / 10 seconds
float ppmReadings[maxReadings];
int readingIndex = 0;

void setup() {
  Serial.begin(115200);

  // Initialize the hall sensors as inputs
  for (int i = 0; i < 5; i++) {
    pinMode(hallSensors[i], INPUT);
  }

  // Initialize the motor driver pins as outputs
  pinMode(motorEnable, OUTPUT);
  pinMode(motorInput1, OUTPUT);
  pinMode(motorInput2, OUTPUT);

  // Initialize the motor to stop
  digitalWrite(motorEnable, LOW);
}

void loop() {
  // Read the CO2 ppm level from the MQ135 sensor
  float ppm = gasSensor.getPPM();

  // Store the CO2 ppm reading
  ppmReadings[readingIndex] = ppm;
  readingIndex = readingIndex + 1;
  
  if(readingIndex >= 30)
  {
    // Calculate the average CO2 ppm level
    int avgPPM = calculateAveragePPM();

    // Determine the target hall sensor based on the average CO2 ppm level
    int targetSensor = determineTargetSensor(avgPPM);

    // Move the motor to the target hall sensor
    moveMotorToTargetSensor(targetSensor);

    readingIndex = 0;
  }

  delay(10000); // wait 10 seconds
}

// Calculate the average CO2 ppm level from the stored readings
int calculateAveragePPM() {
  int sum = 0;
  for (int i = 0; i < maxReadings; i++) {
    sum += ppmReadings[i];
  }
  return sum / maxReadings;
}

// Determine the target hall sensor based on the average CO2 ppm level
int determineTargetSensor(int avgPPM) {
  for (int i = 0; i < 5; i++) {
    if (avgPPM >= ppmRanges[i][0] && avgPPM <= ppmRanges[i][1]) {
      return i;
    }
  }
  return 0; // default to the first sensor if the avgPPM is out of range
}

// Move the motor to the target hall sensor
void moveMotorToTargetSensor(int targetSensor) {
  int currentSensor = getCurrentSensor();
  if (currentSensor != targetSensor) {
    int direction = (targetSensor > currentSensor) ? 1 : -1;
    while (currentSensor != targetSensor) {
      moveMotor(direction);
      currentSensor = getCurrentSensor();
    }
    stopMotor();
  }
}

// Get the current hall sensor
int getCurrentSensor() {
  for (int i = 0; i < 5; i++) {
    if (digitalRead(hallSensors[i]) == LOW) {
      return i;
    }
  }
  return 0; // default to the first sensor if no sensor is active
}

// Move the motor in the specified direction
void moveMotor(int direction) {
  digitalWrite(motorEnable, HIGH);
  if (direction == 1) {
    digitalWrite(motorInput1, HIGH);
    digitalWrite(motorInput2, LOW);
  } else {
    digitalWrite(motorInput1, LOW);
    digitalWrite(motorInput2, HIGH);
  }
}

// Stop the motor
void stopMotor() {
  digitalWrite(motorEnable, LOW);
}

Credits

mondal3011

mondal3011

1 project • 1 follower

Comments