#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
#define UP_BTN 18
#define DOWN_BTN 19
#define ENTER_BTN 5
#define BACK_BTN 17
#define ECHO_PIN 2
#define TRIGGER_PIN 4
#define led1 27
#define led2 14
#define led3 12
#define led4 13
#define led5 3
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
// Variables
int progress = 0;
int setHeight = 0;
int start = 1;
int selected = 0;
int entered = -1;
bool enterClicked = false;
void setup() {
pinMode(UP_BTN, INPUT);
pinMode(DOWN_BTN, INPUT);
pinMode(ENTER_BTN, INPUT);
pinMode(BACK_BTN, INPUT);
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
Serial.begin(9600);
}
void loop() {
if (start == 0) {
drawProgressBar();
} else {
menu();
}
display.display();
}
void heightCalculator() {
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
float duration = pulseIn(ECHO_PIN, HIGH);
int distance = (duration * 0.034 / 2) + 1;
float convert_inch = distance * 0.3937;
float convert_ft = distance / 30.48;
float convert_m = distance * 0.01;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
display.setCursor(45, 0);
display.print("Length");
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 15);
display.print("Unit");
display.setCursor(80, 15);
display.print("Value");
// Sample data
display.setCursor(0, 25);
display.print("Centimeter");
display.setCursor(80, 25);
display.print(distance);
display.setCursor(0, 35);
display.print("Inch/es");
display.setCursor(80, 35);
display.print(convert_inch);
display.setCursor(0, 45);
display.print("Feet");
display.setCursor(80, 45);
display.print(convert_ft);
display.setCursor(0, 55);
display.print("Meter");
display.setCursor(80, 55);
display.print(convert_m);
Serial.print("Duration: ");
Serial.print(duration);
Serial.print(" Distance: ");
Serial.print(distance);
Serial.println(" cm");
delay(50);
}
void waterLevelCalculator() {
// Read button inputs
int addHeight = digitalRead(UP_BTN);
int subHeight = digitalRead(DOWN_BTN);
// Check for button presses
if (addHeight == HIGH) {
// Check upper limit
if (setHeight < 400) {
setHeight += 1;
delay(50);
}
}
if (subHeight == HIGH) {
// Check lower limit
if (setHeight > 0) {
setHeight -= 1;
delay(50);
}
}
// Ultrasonic sensor measurements
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
float duration = pulseIn(ECHO_PIN, HIGH);
int distance = (duration * 0.034 / 2) + 1;
// Calculate water level and conversions
int waterLevel = setHeight - distance;
float convertInch = waterLevel * 0.3937;
int convertCm = waterLevel;
int convertPercent = map(waterLevel, 0, setHeight, 0, 100);
convertPercent = constrain(convertPercent, 0, 100); // Ensure it's within 0-100
// Control LEDs based on the water level percentage
digitalWrite(led1, convertPercent >= 20);
digitalWrite(led2, convertPercent >= 40);
digitalWrite(led3, convertPercent >= 60);
digitalWrite(led4, convertPercent >= 80);
digitalWrite(led5, convertPercent >= 95);
// Display information on OLED
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
display.setCursor(38, 0);
display.print("Water Level");
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 15);
display.print("Height: ");
display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
display.print(" ");
display.print(setHeight);
display.print(" ");
// Display water level data
display.setCursor(0, 30);
display.print(" Centi: ");
display.print(convertCm);
display.print("cm");
display.setCursor(0, 40);
display.print(" Inch: ");
display.print(convertInch);
display.print("''");
display.setCursor(0, 50);
display.print(" Percent: ");
display.print(convertPercent);
display.print("%");
delay(50);
}
void objectDetector() {
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
float duration = pulseIn(ECHO_PIN, HIGH);
int distance = (duration * 0.034 / 2) + 1;
display.clearDisplay();
display.setTextSize(1.5);
display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
display.setCursor(0, 0);
display.print(" Object Detector");
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 30);
// Fixing grammar: "Object detected within {distance} cm reach."
display.print(" Object detected within ");
display.print(distance);
display.print(" cm reach.");
}
void menu() {
const char *options[3] = {
" Water Level ",
" Height ",
" Object Detector"
};
int UP_VALUE = digitalRead(UP_BTN);
int DOWN_VALUE = digitalRead(DOWN_BTN);
int ENTER_VALUE = digitalRead(ENTER_BTN);
int BACK_VALUE = digitalRead(BACK_BTN);
if(enterClicked == false){
if (UP_VALUE == HIGH && DOWN_VALUE == HIGH) {
}
if (UP_VALUE == HIGH) {
if(selected == 0){
selected = 3;
}
selected = selected - 1;
delay(100);
}
if (DOWN_VALUE == HIGH) {
if(selected == 2){
selected = -1;
}
selected = selected + 1;
delay(100);
}
Serial.print("Up Value: ");
Serial.print(UP_VALUE);
Serial.print(" DOWN Value: ");
Serial.print(DOWN_VALUE);
Serial.print(" BACK Value: ");
Serial.print(BACK_VALUE);
Serial.print(" Enter Value: ");
Serial.print(ENTER_VALUE);
Serial.print(" Selected: ");
Serial.println(selected);
}
if (ENTER_VALUE == HIGH) {
entered = selected;
enterClicked = true;
delay(100);
}
if(BACK_VALUE == HIGH){
entered = -1;
enterClicked = false;
delay(100);
}
if (entered == -1) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(F(" Menu "));
display.println("");
for (int i = 0; i < 3; i++) {
if (i == selected) {
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.print("--> |");
display.println(options[i]);
display.println("");
} else if (i != selected) {
display.setTextColor(SSD1306_WHITE);
display.print(" |");
display.println(options[i]);
display.println("");
}
}
}else if(entered == 0){
waterLevelCalculator();
}else if(entered == 1){
heightCalculator();
}else if(entered == 2){
objectDetector();
}
}
void drawProgressBar() {
int x = 10;
int y = 40;
int width = 110;
int height = 13;
display.clearDisplay();
display.setCursor(2, 0);
display.setTextSize(2);
display.setTextColor(WHITE);
display.print(" Project 2");
display.setCursor(2, 20);
display.setTextSize(1);
display.setTextColor(WHITE);
display.print(" Digital MultiMeter");
float bar = ((float)(width - 4) / 100) * progress;
display.drawRect(x, y, width, height, WHITE);
display.fillRect(x + 2, y + 2, bar, height - 4, WHITE);
display.setCursor((width / 2) + 2, y + 3);
display.setTextSize(1);
display.setTextColor(WHITE);
if (progress >= 50) {
display.setTextColor(BLACK, WHITE); // 'inverted' text
}
if (progress >= 100) {
progress = 0;
start = 1;
}
display.print(progress);
display.print("%");
progress++;
delay(50);
}
// void displayTable() {
// // Clear the display
// display.clearDisplay();
// // Table headers
// display.setTextSize(1);
// display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
// display.setCursor(60, 0);
// display.print("Distance");
// display.setTextSize(1);
// display.setTextColor(SSD1306_WHITE);
// display.setCursor(0, 15);
// display.print("Unit");
// display.setCursor(80, 15);
// display.print("Value");
// // Sample data
// display.setCursor(0, 25);
// display.print("Centimeter");
// display.setCursor(80, 25);
// display.print(convert_cm);
// display.print("cm");
// display.setCursor(0, 35);
// display.print("Inches");
// display.setCursor(80, 35);
// display.print(convert_inch);
// display.print("inch/es");
// display.setCursor(0, 45);
// display.print("Millimeter");
// display.setCursor(80, 45);
// display.print(convert_mm);
// display.print("mm");
// }