#include <OneWire.h>
#include <DallasTemperature.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
// Pin where the DS18B20 is connected
#define ONE_WIRE_BUS 4
// Pin where the beeper is connected
#define BEEPER_PIN 6
// Pin where the LEDs are connected
#define LED_PIN_HOT 2
#define LED_PIN_COLD 8
// Define the screen width and height for your SSD1306 display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// Declaration for SSD1306 display connected using I2C (SDA, SCL pins)
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Create instances of the required classes
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// Variables to track temperature readings
int aboveFreezingCount = 0;
bool hasDroppedBelowFreezing = false;
float temperatureF = 0.0;
float maxTemperature = -1000.0; // Initialize to a very low value
float minTemperature = 1000.0; // Initialize to a very high value
unsigned long startTime = 0; // Variable to store the start time
void setup() {
// Start serial communication for debugging (optional)
Serial.begin(9600);
// Initialize the DS18B20 sensor
sensors.begin();
// Set the beeper and LED pins as output
pinMode(BEEPER_PIN, OUTPUT);
pinMode(LED_PIN_HOT, OUTPUT);
pinMode(LED_PIN_COLD, OUTPUT);
// Ensure beeper is off
digitalWrite(BEEPER_PIN, LOW);
// Screen setup
setupScreen();
// Initialize the start time
startTime = millis();
// Initialization is done
for (int i = 1; i < 20; i++) {
bool toggle = (i % 2 == 1); // true for odd, false for even
toggleLED(toggle);
delay(100);
}
}
void loop() {
// Check if 24 hours have passed
unsigned long currentTime = millis();
if (currentTime - startTime >= 86400000) { // 86400000 milliseconds = 24 hours
startTime = currentTime;
minTemperature = temperatureF;
maxTemperature = temperatureF;
}
updateDisplay(false, 0);
if (temperatureF > 34.0) {
if (hasDroppedBelowFreezing) { // Only count if the temp has dropped below freezing at least once
aboveFreezingCount++;
toggleLED(false);
// If the temperature has been above 32F for 4 consecutive readings
if (aboveFreezingCount >= 4) {
while (temperatureF > 34.0) {
updateDisplay(false, 0);
// Fire the alarm
beep(1000, 1);
// Wait for 30 seconds before recheck
for (int i = 1; i < 31; i++) {
updateDisplay(true, i);
delay(1000);
}
}
}
} else {
// Not Yet Dropped Below 40F"
toggleLED(false);
}
} else {
// If temperature drops below 32F
if (hasDroppedBelowFreezing == false){
hasDroppedBelowFreezing = true; // Set flag to true
beep(3,200);
}
aboveFreezingCount = 0; // Reset the count
toggleLED(true);
}
updateDisplay(false, 0);
Serial.println("Before:");
Serial.print(F("Temp: "));
Serial.println(temperatureF);
Serial.print(F("Max:"));
Serial.println(maxTemperature);
Serial.print(F("Min:"));
Serial.println(minTemperature);
// Update max and min temperatures
if (temperatureF > maxTemperature) {
maxTemperature = temperatureF;
}
if (temperatureF < minTemperature) {
minTemperature = temperatureF;
}
delay(1000);
}
void updateDisplay(bool isRechecking, int recheckCount) {
sensors.requestTemperatures(); // Request temperature readings
temperatureF = sensors.getTempFByIndex(0);
display.clearDisplay();
display.setTextSize(1); // Medium text
display.setCursor(0, 0); // Set cursor to the top-left corner
display.print("Temp: ");
display.setTextSize(2); // Large text
display.print(temperatureF);
if(aboveFreezingCount > 0 || isRechecking){
if (aboveFreezingCount > 0) {
display.setTextSize(1); // Medium text
display.setCursor(0, 30); // Move cursor down to write "Over Temp"
display.print("Over Temp: ");
display.setTextSize(2); // Large text
display.print(aboveFreezingCount);
display.print("/4");
}
if (isRechecking) {
display.setTextSize(1); // Medium text
display.setCursor(0, 48); // Move cursor down
display.print("Recheck: ");
display.setTextSize(2); // Large text
display.print(recheckCount);
display.print("/30");
}
}else{
display.setTextSize(1); // Medium text
display.setCursor(0, 30); // Move cursor down
display.print("Max: ");
display.print(maxTemperature);
display.setCursor(0, 48); // Move cursor down
display.print("Min: ");
display.print(minTemperature);
}
display.display(); // Update the display with the data
}
void beep(int beepDuration, int beepCount) {
for (int i = 0; i < beepCount; i++) {
digitalWrite(BEEPER_PIN, HIGH);
delay(beepDuration);
digitalWrite(BEEPER_PIN, LOW);
delay(beepDuration);
}
}
void setupScreen() {
// Initialize the SSD1306 display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.setTextColor(SSD1306_WHITE); // White text
}
void toggleLED(bool isCold) {
if(isCold) {
digitalWrite(LED_PIN_HOT, LOW);
digitalWrite(LED_PIN_COLD, HIGH);
} else {
digitalWrite(LED_PIN_HOT, HIGH);
digitalWrite(LED_PIN_COLD, LOW);
}
}