I have a project that detects the water level + temperature + humidity, Whenever something goes too low, high, or very high, the buzzer will turn on, if I click a button on the IR the buzzer will turn off, but the problem is that when I click before the buzzer is turned on it shows the correct HEX value, but when the buzzer is turned on and I click the button it shows some random values each time.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
#include <IRremote.h>
#define Type DHT11
// Sensors pins
int DHTPin = 7;
int waterP = A3;
int BuzzerPin = 2;
int IRPin = 3;
DHT HT(DHTPin, Type);
// Initialize the LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Define variables for sensor values
int waterV = 0;
float humid;
float tempC;
float tempF;
// Warning messagges variables
String humidV;
String tempFV;
String tempCV;
String waterVW;
// Define variables for timing
unsigned long previousMillis = 0;
const long sensorreadtime = 100; // Update every 1 second
const long displayTime = 3000; // Common display time for all sensors in milliseconds
const long transitionTime = 2000; // Transition time between states in milliseconds
// Define states for the state machine
enum State
{
Humidity,
Water,
TempC,
TempF
};
State currentState = Humidity; // Initial state
unsigned long displayStartTime = 0; // Variable to store the start time for displaying each sensor
// IR sensor
IRrecv IR(IRPin);
decode_results results;
// Define a variable for IR signal filtering
unsigned long irFilterDelay = 500; // Set the filter delay to 1 second
unsigned long lastIRMillis = 0;
void setup(){
// Initialize LCD
lcd.begin();
lcd.backlight();
// Initialize sensors
pinMode(waterP, INPUT);
HT.begin();
pinMode(BuzzerPin, OUTPUT);
digitalWrite(BuzzerPin,LOW);
IR.enableIRIn();
// Serial start
Serial.begin(115200);
}
void loop(){
//current time
unsigned long currentMillis = millis();
// IR Manager
if (IR.decode(&results)) {
// Check if enough time has passed since the last valid IR signal
if (currentMillis - lastIRMillis >= irFilterDelay) {
Serial.println(results.value, HEX);
// Handle the remote input
handleRemoteInput(results.value);
// Update the last valid IR time
lastIRMillis = currentMillis;
}
// Resume IR receiver
IR.resume();
}
// Check if the sensorreadtime has passed
if (currentMillis - previousMillis >= sensorreadtime){
// Save the current time
previousMillis = currentMillis;
// Handle the state transitions and display sensor readings
handleState(currentMillis);
}
}
// Function to handle state transitions + display sensor readings
void handleState(unsigned long currentMillis)
{
switch (currentState)
{
case Humidity:
if (currentMillis - displayStartTime >= displayTime)
{
humid = HT.readHumidity();
humid = round(humid); // Round the humidity value
Serial.print("Humidity is being read. Humidity: ");
Serial.println(humid);
if (humid >= 60 && humid <= 80)
{
humidV = "Good - " + String(humid);
}
if (humid <= 60)
{
humidV = "Low - " + String(humid);
startBuzzer(500); // Beep for low humidity
}
if (humid >= 80)
{
humidV = "High - " + String(humid);
startBuzzer(1000); // Beep for high humidity
}
displaySensorReading("Humidity", humidV);
currentState = Water;
displayStartTime = currentMillis;
}
break;
case Water:
if (currentMillis - displayStartTime >= displayTime)
{
waterV = analogRead(waterP);
Serial.print("Water is being read. Water Value: ");
Serial.println(waterV);
if (waterV < 60)
{
waterVW = "LOW - " + String(waterV);
startBuzzer(500); // Beep for low water level
}
displaySensorReading("Water Value", waterVW);
currentState = TempC;
displayStartTime = currentMillis;
}
break;
case TempC:
if (currentMillis - displayStartTime >= displayTime)
{
tempC = HT.readTemperature();
tempC = round(tempC); // Round the temperature value
Serial.print("TempC is being read. TempC: ");
Serial.println(tempC);
if (tempC >= 16 && tempC <= 25)
{
tempCV = "Good - " + String(tempC);
}
if (tempC <= 15)
{
tempCV = "LOW - " + String(tempC);
startBuzzer(500); // Beep for low temperature
}
if (tempC >= 25)
{
tempCV = "HIGH - " + String(tempC);
startBuzzer(1000); // Beep for high temperature
}
displaySensorReading("TempC", tempCV);
currentState = TempF;
displayStartTime = currentMillis;
}
break;
case TempF:
if (currentMillis - displayStartTime >= displayTime)
{
tempF = HT.readTemperature(true);
tempF = round(tempF); // Round the temperature value
Serial.print("TempF is being read. TempF: ");
Serial.println(tempF);
if (tempF >= 59 && tempF <= 77)
{
tempFV = "Good - " + String(tempF);
}
if (tempF <= 59)
{
tempFV = "LOW - " + String(tempF);
startBuzzer(500); // Beep for low temperature
}
if (tempF >= 77)
{
tempFV = "HIGH - " + String(tempF);
startBuzzer(1000); // Beep for high temperature
}
displaySensorReading("TempF", tempFV);
currentState = Humidity;
displayStartTime = currentMillis;
}
break;
}
}
// Function to display sensor reading on the LCD
void displaySensorReading(const char *sensorName, String sensorValue)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(sensorName);
lcd.setCursor(0, 1);
lcd.print(sensorValue);
}
// Function to handle IR remote input
void handleRemoteInput(unsigned long value){
if(value == 0xFFA25D){
stopBuzzer();
}
}
// Function to start buzzer with specific frequency
void startBuzzer(int frequency){
Serial.println("Buzzer On");
tone(BuzzerPin, frequency);
}
// Function to stop buzzer
void stopBuzzer(){
Serial.println("Buzzer Stopped");
noTone(BuzzerPin);
}