#include <Adafruit_GFX.h> // Library that provides basic graphics functions like shapes, lines, etc., for Adafruit displays.
#include <Adafruit_ILI9341.h> // Library specific to the ILI9341 TFT display, allowing us to control it easily.
#include <SD.h> // Library for interacting with an SD card, enabling read/write operations.
#include <DHT.h> // Library for working with DHT temperature and humidity sensors.
// Pin definitions for the ILI9341 TFT Display
#define TFT_CS 6 // Chip Select (CS) pin for the display; used to select this specific device on the SPI bus.
#define TFT_DC 4 // Data/Command (DC) pin; tells the display whether you're sending data or commands.
#define TFT_RST 5 // Reset (RST) pin; used to reset the display if needed.
Adafruit_ILI9341 tft(TFT_CS, TFT_DC, TFT_RST); // Create an object for the TFT display, specifying the pins it uses.
// SD Card Configuration
#define SD_CS 10 // Chip Select (CS) pin for the SD card module, used to enable communication with the card.
// DHT22 Sensor Configuration
#define DHTPIN 7 // Pin where the DHT22 sensor is connected.
#define DHTTYPE DHT22 // Specify the type of DHT sensor (in this case, DHT22 or AM2302).
DHT dht(DHTPIN, DHTTYPE); // Create an object for the DHT sensor, specifying its pin and type.
// Analog Sensor Pins
#define PHOTORESISTOR_PIN A1 // Pin connected to the photoresistor for measuring light intensity.
#define POTENTIOMETER_PIN A2 // Pin connected to the potentiometer, used to simulate oxygen levels.
// Ultrasonic Sensor Pins
#define TRIG_PIN 2 // Trigger pin for the ultrasonic sensor, used to send a pulse.
#define ECHO_PIN 3 // Echo pin for the ultrasonic sensor, used to receive the reflected pulse.
// Slide Switch Pin
#define SWITCH_PIN 8 // Pin connected to a slide switch for toggling certain system behaviors.
// LED Pins for Warnings
#define LED_TEMP 47 // Pin for the red LED, used for temperature warnings.
#define LED_HUMIDITY 45 // Pin for the yellow LED, used for humidity warnings.
#define LED_OXYGEN 43 // Pin for the green LED, used for oxygen level warnings.
#define LED_PRESSURE 41 // Pin for the blue LED, used for wire pressure warnings.
#define LED_DISTANCE 39 // Pin for the white LED, used for distance-related warnings.
// Variables for Simulated Wire Pressures
float wirePressures[4]; // Array to hold simulated pressure values for four wires.
unsigned long startTime; // Stores the time when the system starts, used to calculate uptime.
void setup() {
// Start the serial communication for debugging purposes.
Serial.begin(115200);
// Initialize the TFT display.
tft.begin(); // Begin communication with the display.
tft.fillScreen(ILI9341_BLACK); // Clear the screen and fill it with black.
tft.setTextColor(ILI9341_WHITE); // Set the text color to white.
tft.setTextSize(2); // Set the text size to medium.
tft.setCursor(10, 10); // Set the position where the text will start.
tft.println("OBD System Starting..."); // Display the initial startup message.
// Initialize the DHT sensor.
dht.begin();
// Initialize the SD card and check if it's working properly.
if (!SD.begin(SD_CS)) {
// If initialization fails, display an error message and stop the program.
tft.println("SD Card Failed!");
Serial.println("SD Card Initialization Failed! Check wiring and SD card.");
while (true); // Halt the program here.
} else {
// If initialization succeeds, display a success message.
Serial.println("SD Card Initialized Successfully!");
}
// Set the slide switch pin as an input with a pull-up resistor.
pinMode(SWITCH_PIN, INPUT_PULLUP);
// Configure the ultrasonic sensor pins.
pinMode(TRIG_PIN, OUTPUT); // Trigger pin will send a signal, so it's set as output.
pinMode(ECHO_PIN, INPUT); // Echo pin will receive the signal, so it's set as input.
// Configure each LED warning pin as an output.
pinMode(LED_TEMP, OUTPUT);
pinMode(LED_HUMIDITY, OUTPUT);
pinMode(LED_OXYGEN, OUTPUT);
pinMode(LED_PRESSURE, OUTPUT);
pinMode(LED_DISTANCE, OUTPUT);
// Turn off all LEDs initially to indicate no warnings.
turnOffAllLEDs();
// Record the system's start time to calculate uptime later.
startTime = millis();
}
void loop() {
// Calculate the elapsed time in seconds since the system started.
unsigned long currentTime = millis(); // Get the current time in milliseconds.
unsigned long elapsedTime = (currentTime - startTime) / 1000; // Convert milliseconds to seconds.
// Check if the slide switch is turned ON (active).
if (digitalRead(SWITCH_PIN) == LOW) { // If the switch is connected to ground (active).
Serial.println("Slide Switch ON! Reading SD Card..."); // Print a message to the serial monitor.
readSDCardContents(); // Call the function to read and display SD card contents.
delay(1000); // Wait for 1 second to debounce the switch.
}
// Read data from the photoresistor for light intensity.
int lightIntensity = analogRead(PHOTORESISTOR_PIN);
// Read temperature and humidity values from the DHT22 sensor.
float dhtTemperature = dht.readTemperature(); // Get the temperature.
float dhtHumidity = dht.readHumidity(); // Get the humidity.
// Read the potentiometer value and map it to simulate oxygen levels (0-100%).
int potValue = analogRead(POTENTIOMETER_PIN);
float oxygenLevel = map(potValue, 0, 1023, 0, 100);
// Measure the distance to an object using the ultrasonic sensor.
float distance = readUltrasonicDistance();
// Simulate wire pressures using random values for testing.
simulateWirePressures();
// Check for any warnings from the sensors and combine them into a single string.
String warnings = checkWarnings(dhtTemperature, dhtHumidity, oxygenLevel, wirePressures, distance);
// Display the sensor data and warnings on the TFT screen.
displayData(lightIntensity, dhtTemperature, dhtHumidity, oxygenLevel, distance, elapsedTime, warnings);
// Update the LEDs based on the current warnings.
handleLEDs(warnings);
// If there are any warnings, log them to the SD card with the system's uptime.
if (warnings != "") {
logWarningToSD(warnings, elapsedTime);
}
// Wait for 10 seconds before repeating the loop to refresh data.
delay(10000);
}
// Simulate random wire pressures for testing purposes.
void simulateWirePressures() {
for (int i = 0; i < 4; i++) {
// Generate a random pressure value between 0.00 and 5.00 bar.
wirePressures[i] = random(0, 501) / 100.0;
}
}
// Function to measure the distance using an ultrasonic sensor.
float readUltrasonicDistance() {
digitalWrite(TRIG_PIN, LOW); // Ensure the trigger pin is low initially.
delayMicroseconds(2); // Wait for 2 microseconds.
digitalWrite(TRIG_PIN, HIGH); // Set the trigger pin high to send a pulse.
delayMicroseconds(10); // Keep it high for 10 microseconds.
digitalWrite(TRIG_PIN, LOW); // Set it back to low.
// Measure the time taken for the echo signal to return.
long duration = pulseIn(ECHO_PIN, HIGH);
// If no echo is detected, return an error value.
if (duration == 0) {
Serial.println("Ultrasonic sensor timeout!"); // Print a timeout error.
return -1.0; // Return -1 to indicate an error.
}
// Convert the duration to distance in centimeters.
return (duration / 2.0) * 0.0343;
}
// Function to check for warnings based on sensor readings.
String checkWarnings(float temp, float humidity, float oxygen, float pressures[], float distance) {
String warnings = ""; // Initialize an empty string to hold warnings.
// Check for temperature warnings.
if (temp < 0 || temp > 50) { warnings += "Temp "; }
// Check for humidity warnings.
if (humidity < 20 || humidity > 90) { warnings += "Humidity "; }
// Check for oxygen level warnings.
if (oxygen < 10 || oxygen > 30) { warnings += "Oxygen "; }
// Check for wire pressure warnings for each wire.
for (int i = 0; i < 4; i++) {
if (pressures[i] < 1.0 || pressures[i] > 4.0) {
warnings += "WireP" + String(i + 1) + " ";
}
}
// Check for distance warnings.
if (distance < 5.0) { warnings += "Distance "; }
return warnings; // Return all warnings as a single string.
}
// Function to control LED states based on warnings.
void handleLEDs(String warnings) {
turnOffAllLEDs(); // Turn off all LEDs first.
// Turn on the appropriate LEDs based on the warnings string.
if (warnings.indexOf("Temp") != -1) { digitalWrite(LED_TEMP, HIGH); }
if (warnings.indexOf("Humidity") != -1) { digitalWrite(LED_HUMIDITY, HIGH); }
if (warnings.indexOf("Oxygen") != -1) { digitalWrite(LED_OXYGEN, HIGH); }
if (warnings.indexOf("WireP") != -1) { digitalWrite(LED_PRESSURE, HIGH); }
if (warnings.indexOf("Distance") != -1) { digitalWrite(LED_DISTANCE, HIGH); }
}
// Function to turn off all warning LEDs.
void turnOffAllLEDs() {
digitalWrite(LED_TEMP, LOW);
digitalWrite(LED_HUMIDITY, LOW);
digitalWrite(LED_OXYGEN, LOW);
digitalWrite(LED_PRESSURE, LOW);
digitalWrite(LED_DISTANCE, LOW);
}
// Function to display sensor data and warnings on the TFT screen.
void displayData(int light, float dhtTemp, float dhtHumidity, float oxygenLevel, float distance, unsigned long uptime, String warnings) {
tft.fillScreen(ILI9341_BLACK); // Clear the screen and fill it with black.
// Display various sensor data and system information on the screen.
tft.setCursor(10, 10); tft.println("OBD System");
tft.setCursor(10, 40); tft.print("Light: "); tft.print(light);
tft.setCursor(10, 60); tft.print("DHT Temp: "); tft.print(dhtTemp, 1); tft.println(" C");
tft.setCursor(10, 80); tft.print("Humidity: "); tft.print(dhtHumidity, 1); tft.println(" %");
tft.setCursor(10, 100); tft.print("Oxygen Level: "); tft.print(oxygenLevel, 1); tft.println(" %");
tft.setCursor(10, 120); tft.print("Distance: "); tft.print(distance, 1); tft.println(" cm");
// Display wire pressure readings for each wire.
for (int i = 0; i < 4; i++) {
tft.setCursor(10, 140 + i * 20);
tft.print("Wire P"); tft.print(i + 1); tft.print(": "); tft.print(wirePressures[i], 2); tft.println(" bar");
}
// Display system uptime.
tft.setCursor(10, 220); tft.print("Uptime: "); tft.print(uptime); tft.println(" sec");
// Display warnings if any exist.
if (warnings != "") {
tft.setCursor(10, 240);
tft.setTextColor(ILI9341_RED); // Set text color to red for warnings.
tft.print("Warnings: "); tft.println(warnings);
tft.setTextColor(ILI9341_WHITE); // Reset text color to white.
}
}
// Function to log warnings to the SD card.
void logWarningToSD(String warnings, unsigned long uptime) {
File warningFile = SD.open("obd_log.txt", FILE_WRITE); // Open the log file in write mode.
if (warningFile) {
// Write the warnings and system uptime to the file.
warningFile.print("Uptime: "); warningFile.print(uptime); warningFile.print(" sec, Warnings: "); warningFile.println(warnings);
warningFile.close(); // Close the file after writing.
Serial.println("Warnings logged to SD card successfully."); // Debugging message.
} else {
Serial.println("Failed to log warnings to SD card."); // Debugging error message.
}
}
// Function to read and display the contents of the SD card.
void readSDCardContents() {
File logFile = SD.open("obd_log.txt", FILE_READ); // Open the log file in read mode.
if (logFile) {
Serial.println("=== SD Card Contents ===");
while (logFile.available()) {
Serial.write(logFile.read()); // Print each character from the file to the serial monitor.
}
logFile.close(); // Close the file after reading.
Serial.println("\n=== End of File ===");
} else {
Serial.println("Failed to open obd_log.txt for reading."); // Debugging error message.
}
}