#include <Arduino.h>
#include <NewPing.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Pin Definitions from your diagram
#define HCSR04_PIN_TRIG 4
#define HCSR04_PIN_ECHO 3
#define LEDB_PIN_VIN 5 // Blue LED
#define LEDG_PIN_VIN 6 // Green LED
#define LEDR_PIN_VIN 9 // Red LED
#define PIR_PIN_SIG 7
#define POT_PIN A3
#define RELAY_PIN 8
#define SPEAKER_PIN 10
#define DS18B20_PIN 2
// LCD Configuration
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2
// Distance thresholds (in cm)
#define CLOSE_DISTANCE 100
#define MEDIUM_DISTANCE 200
// Object initialization
NewPing sonar(HCSR04_PIN_TRIG, HCSR04_PIN_ECHO, 200);
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);
OneWire oneWire(DS18B20_PIN);
DallasTemperature tempSensor(&oneWire);
// Global variables
const int timeout = 10000;
char menuOption = 0;
long time0;
unsigned long lastUpdate = 0;
const long updateInterval = 500; // Update every 500ms
int displayMode = 0; // Cycle through display modes (0: Distance, 1: Temp, 2: PIR/Relay)
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println(F("start"));
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
tempSensor.begin();
// Initialize pins
pinMode(LEDB_PIN_VIN, OUTPUT);
pinMode(LEDG_PIN_VIN, OUTPUT);
pinMode(LEDR_PIN_VIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(PIR_PIN_SIG, INPUT);
pinMode(SPEAKER_PIN, OUTPUT);
menuOption = menu();
}
void loop() {
unsigned long currentTime = millis();
// Update sensor data every updateInterval
if (currentTime - lastUpdate >= updateInterval) {
lastUpdate = currentTime;
// Read all sensor data
unsigned int distance = sonar.ping_cm();
tempSensor.requestTemperatures();
float temp = tempSensor.getTempCByIndex(0);
bool pirVal = digitalRead(PIR_PIN_SIG);
bool relayState = digitalRead(RELAY_PIN); // Reflects current relay state
int potVal = analogRead(POT_PIN); // Add potentiometer value
// Cycle through display modes every 2 seconds
if (currentTime % 2000 < 500) displayMode = 0; // Distance
else if (currentTime % 2000 < 1000) displayMode = 1; // Temperature
else if (currentTime % 2000 < 1500) displayMode = 2; // PIR and Relay
else displayMode = 3; // Potentiometer (optional)
// Update LCD based on display mode
lcd.clear();
switch (displayMode) {
case 0: // Distance
lcd.setCursor(0, 0);
lcd.print(F("Distance: "));
lcd.print(distance);
lcd.print(F("cm"));
lcd.setCursor(0, 1);
if (distance > 0 && distance <= CLOSE_DISTANCE) lcd.print(F("TOO CLOSE!"));
else if (distance > CLOSE_DISTANCE && distance <= MEDIUM_DISTANCE) lcd.print(F("Medium"));
else if (distance > MEDIUM_DISTANCE) lcd.print(F("Far"));
else lcd.print(F("No Reading"));
break;
case 1: // Temperature
lcd.setCursor(0, 0);
lcd.print(F("Temp: "));
if (temp != DEVICE_DISCONNECTED_C) {
lcd.print(temp, 1); // 1 decimal place
lcd.print(F("C"));
} else {
lcd.print(F("N/A"));
}
lcd.setCursor(0, 1);
lcd.print(F("DS18B20"));
break;
case 2: // PIR and Relay
lcd.setCursor(0, 0);
lcd.print(F("PIR: "));
lcd.print(pirVal ? F("Motion") : F("No Motion"));
lcd.setCursor(0, 1);
lcd.print(F("Relay: "));
lcd.print(relayState ? F("ON") : F("OFF"));
break;
case 3: // Potentiometer (optional)
lcd.setCursor(0, 0);
lcd.print(F("Pot: "));
lcd.print(potVal);
lcd.setCursor(0, 1);
lcd.print(F("0-1023"));
break;
}
// Update LEDs based on distance
if (distance > 0 && distance <= CLOSE_DISTANCE) {
digitalWrite(LEDR_PIN_VIN, HIGH); // Red for close
digitalWrite(LEDG_PIN_VIN, LOW);
digitalWrite(LEDB_PIN_VIN, LOW);
}
else if (distance > CLOSE_DISTANCE && distance <= MEDIUM_DISTANCE) {
digitalWrite(LEDR_PIN_VIN, LOW);
digitalWrite(LEDG_PIN_VIN, HIGH); // Green for medium
digitalWrite(LEDB_PIN_VIN, LOW);
}
else if (distance > MEDIUM_DISTANCE) {
digitalWrite(LEDR_PIN_VIN, LOW);
digitalWrite(LEDG_PIN_VIN, LOW);
digitalWrite(LEDB_PIN_VIN, HIGH); // Blue for far
}
else {
digitalWrite(LEDR_PIN_VIN, LOW);
digitalWrite(LEDG_PIN_VIN, LOW);
digitalWrite(LEDB_PIN_VIN, LOW);
}
Serial.print(F("Distance: ")); Serial.print(distance); Serial.print(F(" cm, "));
Serial.print(F("Temp: ")); Serial.print(temp); Serial.print(F(" C, "));
Serial.print(F("PIR: ")); Serial.print(pirVal ? F("Motion") : F("No Motion")); Serial.print(F(", "));
Serial.print(F("Pot: ")); Serial.println(potVal);
}
// Handle specific menu options
if (menuOption == '3') {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("LCD Test "));
lcd.setCursor(0, 1);
lcd.print(F("Working! "));
delay(1000);
}
else if (menuOption == '4') {
analogWrite(LEDB_PIN_VIN, 255);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Blue LED ON "));
delay(500);
analogWrite(LEDB_PIN_VIN, 0);
lcd.setCursor(0, 0);
lcd.print(F("Blue LED OFF "));
delay(500);
}
else if (menuOption == '5') {
analogWrite(LEDG_PIN_VIN, 255);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Green LED ON "));
delay(500);
analogWrite(LEDG_PIN_VIN, 0);
lcd.setCursor(0, 0);
lcd.print(F("Green LED OFF "));
delay(500);
}
else if (menuOption == '6') {
analogWrite(LEDR_PIN_VIN, 255);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Red LED ON "));
delay(500);
analogWrite(LEDR_PIN_VIN, 0);
lcd.setCursor(0, 0);
lcd.print(F("Red LED OFF "));
delay(500);
}
else if (menuOption == '9') {
digitalWrite(RELAY_PIN, !digitalRead(RELAY_PIN)); // Toggle relay
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Relay "));
lcd.print(digitalRead(RELAY_PIN) ? F("ON ") : F("OFF"));
delay(500);
}
else if (menuOption == '10') {
tone(SPEAKER_PIN, 262, 500); // C4 note
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Buzzer ON "));
delay(600);
noTone(SPEAKER_PIN);
lcd.setCursor(0, 0);
lcd.print(F("Buzzer OFF "));
delay(100);
}
if (millis() - time0 > timeout) {
menuOption = menu();
}
delay(100); // Small delay to stabilize display
}
char menu() {
Serial.println(F("\nWhich component would you like to test?"));
Serial.println(F("(1) Default All Sensors"));
Serial.println(F("(2) Default All Sensors"));
Serial.println(F("(3) LCD 16x2 I2C"));
Serial.println(F("(4) Blue LED"));
Serial.println(F("(5) Green LED"));
Serial.println(F("(6) Red LED"));
Serial.println(F("(7) PIR Motion Sensor"));
Serial.println(F("(8) Potentiometer"));
Serial.println(F("(9) Relay"));
Serial.println(F("(10) Buzzer"));
Serial.println(F("(menu) send anything else\n"));
while (!Serial.available());
char c = Serial.read();
while (Serial.available()) Serial.read(); // Clear buffer
if (c >= '1' && c <= '9') {
Serial.print(F("Now Testing Option "));
Serial.println(c);
}
else if (c == '10') {
Serial.println(F("Now Testing Buzzer"));
}
else {
Serial.println(F("illegal input!"));
return 0;
}
time0 = millis();
return c;
}