/*
Arduino | hardware-help
Fan controlled by motion and TMP36
Terminal_Dev — 6/15/24 at 8:48 PM
I am trying to make a fan that turns on when the temperature
is high enough AND when motion is detected (using PIR).
I would like to add a delay to the motion sensor so the fan
would turn off after no motion is detected.
If someone could edit my Tinkercad circuit, that'd be a great help.
Thanks Everyone!
https://www.tinkercad.com/things/0pDOYpaFk7r-copy-of-fan-temp-auto/editel?sharecode=ltQXD_uW-MruWrI8tI2qz5uSLB6Bdf1DAzjU60Wb1pI
*/
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const unsigned long SMPL_RATE = 1000;
const unsigned long FAN_DELAY = 10000;
const double MIN_LIMIT = 10;
const double MAX_LIMIT = 25;
const int RGB_PINS[] = {7, 6, 5};
const int PIR_PIN = 4;
const int TEMP_PIN = 3;
const int FAN_PIN = 2;
const int HEAT_PIN = A0;
const int MODE_PIN = A1;
unsigned long prevSenseTime = 0;
unsigned long prevMotionTime = 0;
int scaleMode = LOW; // low is deg C
int oldMotionState = LOW;
bool isTimerOn = false;
bool isTriggered = false;
OneWire oneWire(TEMP_PIN);
DallasTemperature sensors(&oneWire);
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
bool checkPIR() {
int motionState = digitalRead(PIR_PIN);
if (motionState != oldMotionState) {
oldMotionState = motionState;
if (motionState == HIGH) {
Serial.println("Motion detected!");
isTriggered = true;
} else {
Serial.println("Motion stopped");
isTriggered = false;
}
}
return isTriggered;
}
double getTemp() {
sensors.requestTemperatures();
double tempC = sensors.getTempCByIndex(0);
return tempC;
}
void updateDisplay(double temp, bool fan, bool heat) {
char dtosBuff[8];
char sTempBuff[16];
char lTempBuff[16];
char fanBuff[12];
char heatBuff[12];
double scaleTemp = scaleMode ? ((temp * 9 / 5) + 32) : temp;
dtostrf(scaleTemp, 2, 1, dtosBuff);
snprintf (sTempBuff, 16, "Temp: %s%c%s", dtosBuff, char(176), (scaleMode ? "F" : "C"));
snprintf (lTempBuff, 16, "Temp: %s%c%s ", dtosBuff, char(223), (scaleMode ? "F" : "C"));
snprintf(fanBuff, 12, "FAN %s ", fan ? "ON" : "OFF");
snprintf(heatBuff, 12, "HEAT %s ", heat ? "ON" : "OFF");
Serial.println(sTempBuff);
Serial.println(fanBuff);
Serial.println(heatBuff);
Serial.println();
lcd.setCursor(0, 0);
lcd.print(fanBuff);
lcd.setCursor(8, 0);
lcd.print(heatBuff);
lcd.setCursor(2, 1);
lcd.print(lTempBuff);
}
void setup() {
Serial.begin(115200);
sensors.begin();
lcd.begin(16, 2);
for (int i = 0; i < 3; i++) {
pinMode(RGB_PINS[i], OUTPUT);
}
pinMode(HEAT_PIN, OUTPUT);
pinMode(FAN_PIN, OUTPUT);
pinMode(MODE_PIN, INPUT_PULLUP);
pinMode(PIR_PIN, INPUT);
pinMode(TEMP_PIN, INPUT);
// splash screen
lcd.setCursor(2, 0);
lcd.print("Terminal_Dev");
lcd.setCursor(2, 1);
lcd.print("Device V1.00");
delay(2000);
lcd.clear();
Serial.println("System started\n");
}
void loop() {
int rgbIdx = 0;
bool fanState = false;
bool heatState = false;
bool motionState = false;
scaleMode = digitalRead(MODE_PIN);
//////////////////////////////////////////////////////////////////////
bool isMotion = checkPIR();
if (isMotion) {
isTimerOn = true;
prevMotionTime = millis();
}
// start the timer
if (millis() - prevMotionTime >= FAN_DELAY) {
isTimerOn = false;
}
//////////////////////////////////////////////////////////////////////
if (millis() - prevSenseTime >= SMPL_RATE) {
prevSenseTime = millis();
double currTemp = getTemp();
if (currTemp >= MAX_LIMIT) {
rgbIdx = 0;
if (isTimerOn) fanState = true;
heatState = false;
} else if (currTemp <= MIN_LIMIT) {
rgbIdx = 2;
fanState = false;
heatState = true;
} else {
rgbIdx = 1;
fanState = false;
heatState = false;
}
for (int i = 0; i < 3; i++) {
digitalWrite(RGB_PINS[i], LOW);
}
digitalWrite(RGB_PINS[rgbIdx], HIGH);
digitalWrite(FAN_PIN, fanState);
digitalWrite(HEAT_PIN, heatState);
updateDisplay(currTemp, fanState, heatState);
//Serial.print("Timer: ");
//Serial.println(isTimerOn ? "ON" : "OFF");
//Serial.println();
}
}
Fan
Heater
C - F