/**
* @file main.cpp
* @brief Ember Mug 3 Prototype Firmware
* @details This firmware manages temperature control and water level detection for the Ember Mug 3 prototype.
* Developed using ESP32 with OneWire, DallasTemperature, and HC-SR04 sensors.
*
* @author Leonardo Patrocinio Escalante
* @version 1.0
* @date 2024-11-26
*/
#include <Wire.h>
#include <WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// --- Pin Definitions ---
#define TEMP_SENSOR_PIN 4
#define BUTTON_PLUS_PIN 16
#define BUTTON_MINUS_PIN 17
#define PROXIMITY_SENSOR_TRIGGER_PIN 25
#define PROXIMITY_SENSOR_ECHO_PIN 26
#define RELAY_PIN 27
#define LED_BAR_PIN 32
#define LED_STATUS_PIN 33
// --- Constants ---
const float TEMP_MIN = 45.0; // Minimum allowable temperature
const float TEMP_MAX = 63.5; // Maximum allowable temperature
const float TEMP_STEP = 0.5; // Temperature adjustment step
const float PROXIMITY_THRESHOLD = 18.0; // Threshold distance in cm
// --- Global Variables ---
float idealTemperature = 50.0; // Default ideal temperature
float currentTemperature = 0.0; // Current temperature measured
bool relayState = false; // Relay status (heater control)
bool ledStatus = false; // Status LED
bool proximityDetected = false; // Proximity detection flag
// --- Sensor Setup ---
OneWire oneWire(TEMP_SENSOR_PIN);
DallasTemperature tempSensor(&oneWire);
/**
* @brief Initializes all components and prints a welcome message.
*/
void setup() {
Serial.begin(115200); // Set up serial communication
while (!Serial) {
// Wait for Serial to initialize
}
Serial.println("Welcome to Ember Mug 3 Prototype!");
Serial.println("Developer: Leonardo Patrocinio Escalante");
// Initialize pins
pinMode(BUTTON_PLUS_PIN, INPUT_PULLUP);
pinMode(BUTTON_MINUS_PIN, INPUT_PULLUP);
pinMode(PROXIMITY_SENSOR_TRIGGER_PIN, OUTPUT);
pinMode(PROXIMITY_SENSOR_ECHO_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_BAR_PIN, OUTPUT);
pinMode(LED_STATUS_PIN, OUTPUT);
// Initialize sensors
tempSensor.begin();
}
/**
* @brief Main program loop to manage temperature, proximity, and device status.
*/
void loop() {
handleTemperature(); // Manage temperature control
handleProximity(); // Monitor proximity detection
updateDeviceStatus(); // Output current status to serial monitor
delay(5000); // Update status every 5 seconds
}
/**
* @brief Handles temperature monitoring and heater control.
*/
void handleTemperature() {
tempSensor.requestTemperatures();
currentTemperature = tempSensor.getTempCByIndex(0);
if (currentTemperature < idealTemperature) {
digitalWrite(RELAY_PIN, HIGH); // Turn on heater
relayState = true;
ledStatus = false;
} else if (currentTemperature > idealTemperature) {
digitalWrite(RELAY_PIN, LOW); // Turn off heater
relayState = false;
ledStatus = false;
} else {
relayState = false;
ledStatus = true; // Indicate ideal temperature reached
}
digitalWrite(LED_STATUS_PIN, ledStatus);
}
/**
* @brief Monitors proximity using the HC-SR04 ultrasonic sensor.
*/
void handleProximity() {
digitalWrite(PROXIMITY_SENSOR_TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(PROXIMITY_SENSOR_TRIGGER_PIN, LOW);
long duration = pulseIn(PROXIMITY_SENSOR_ECHO_PIN, HIGH);
float distance = (duration / 2) * 0.0343;
if (distance >= PROXIMITY_THRESHOLD) {
proximityDetected = false; // Stand-by mode
digitalWrite(RELAY_PIN, LOW);
} else {
proximityDetected = true; // Active mode
}
}
/**
* @brief Updates the device's operational status and outputs it to the serial monitor.
*/
void updateDeviceStatus() {
String macAddress = WiFi.macAddress();
String mode = proximityDetected ? "ACTIVE" : "STAND_BY";
Serial.print("{");
Serial.print("\"deviceMacAddress\": \"" + macAddress + "\", ");
Serial.print("\"operationMode\": \"" + mode + "\", ");
Serial.print("\"idealTemperature\": " + String(idealTemperature) + ", ");
Serial.print("\"currentTemperature\": " + String(currentTemperature) + ", ");
Serial.print("\"waterLevelDistance\": " + String(proximityDetected ? "In Range" : "Out of Range") + ", ");
Serial.print("\"createdAt\": \"" + String(millis()) + "\"");
Serial.println("}");
}