#include <SevSeg.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <math.h>
// --- PIN DEFINITIONS ---
#define ONE_WIRE_BUS 2 // DS18B20 Data
#define NTC_PIN A7 // NTC Analog Input
#define BTN_UP A1 // Button to increase temp
#define BTN_DOWN A2 // Button to decrease temp
#define COMPRESSOR_PIN A3 // Output to Relay/MOSFET
// --- CONFIGURATION CONSTANTS ---
#define RESISTOR_ROOM_TEMP 4700
#define SERIES_RESISTOR 4700
#define BETA_COEFFICIENT 3950
#define TEMPERATURE_NOMINAL 25
// Hysteresis prevents the compressor from turning on/off rapidly at the threshold
// Example: If Set=25.0, On at 25.5, Off at 24.5
float hysteresis = 0.5;
// --- OBJECTS ---
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
SevSeg sevSeg;
// --- VARIABLES ---
// Timing
unsigned long timerSensors = 0;
unsigned long timerButtons = 0; // For debouncing
unsigned long timerInactivity = 0; // For returning to main menu
const int sensorInterval = 3000; // Read sensors every 3s
const int buttonDebounce = 300; // Min time between button presses (ms)
const int editTimeout = 3000; // Time before returning to sensor view
// State
bool showDS18B20 = true; // Toggle between sensors
bool isEditing = false; // Are we currently changing the setpoint?
// Data
float currentDsTemp = 0.0;
float currentNtcTemp = 0.0;
float setPoint = 25.0; // Default target temperature
void setup() {
// Hardware Setup
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(COMPRESSOR_PIN, OUTPUT);
// Initial States
digitalWrite(COMPRESSOR_PIN, LOW);
Serial.begin(9600);
sensors.begin();
// Display Setup (Same as before)
byte numDigits = 4;
byte digitPins[] = {11, 12, 13, A0};
byte segmentPins[] = {3, 4, 5, 6, 7, 8, 9, 10};
bool resistorsOnSegments = false;
byte hardwareConfig = COMMON_CATHODE;
sevSeg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
false, false, false);
sevSeg.setBrightness(90);
}
void loop() {
// 1. ALWAYS REFRESH DISPLAY (High Priority)
sevSeg.refreshDisplay();
unsigned long currentMillis = millis();
// 2. CHECK BUTTONS
// Logic: If button pressed, enter "Editing" mode and reset inactivity timer
if (currentMillis - timerButtons > buttonDebounce) {
if (digitalRead(BTN_UP) == LOW) {
setPoint += 0.5; // Increase by 0.5 degrees
isEditing = true;
timerInactivity = currentMillis;
timerButtons = currentMillis;
}
if (digitalRead(BTN_DOWN) == LOW) {
setPoint -= 0.5; // Decrease by 0.5 degrees
isEditing = true;
timerInactivity = currentMillis;
timerButtons = currentMillis;
}
}
// 3. CHECK TIMEOUT
// If we are editing but haven't pressed a button in 3 seconds, stop editing
if (isEditing && (currentMillis - timerInactivity > editTimeout)) {
isEditing = false;
}
// 4. READ SENSORS (Every 3 seconds, unless we are furiously pressing buttons)
if (currentMillis - timerSensors >= sensorInterval) {
timerSensors = currentMillis;
// Read DS18B20
sensors.requestTemperatures();
float t = sensors.getTempCByIndex(0);
// Filter out errors (-127)
if (t > -100) currentDsTemp = t;
// Read NTC
currentNtcTemp = readNTC();
// Toggle view for next cycle (only affects display if NOT editing)
showDS18B20 = !showDS18B20;
// --- COMPRESSOR LOGIC ---
// We only control compressor based on DS18B20 as requested
controlCompressor();
}
// 5. UPDATE DISPLAY CONTENT
// Decide what number goes onto the screen buffer
if (isEditing) {
// Show the Set Point (blinking or static)
sevSeg.setNumber(setPoint*10, 1);
} else {
// Normal Mode: Cycle sensors
if (showDS18B20) {
// Optional: You could modify the library to show "d 25.0"
// but for now we just show the temp
sevSeg.setNumber(currentDsTemp*10, 1);
} else {
sevSeg.setNumber(currentNtcTemp, 1);
}
}
}
// --- LOGIC: Compressor Control ---
void controlCompressor() {
// Basic Thermostat: If Temp > Setpoint -> ON
// With Hysteresis:
// ON if Temp > Setpoint + Hysteresis
// OFF if Temp < Setpoint - Hysteresis
if (currentDsTemp > (setPoint + hysteresis)) {
digitalWrite(COMPRESSOR_PIN, HIGH);
}
else if (currentDsTemp < (setPoint - hysteresis)) {
digitalWrite(COMPRESSOR_PIN, LOW);
}
}
// --- HELPER: Calculate NTC Temperature ---
float readNTC() {
int analogValue = analogRead(NTC_PIN);
if (analogValue == 0) return -999;
float resistance = SERIES_RESISTOR / (1023.0 / analogValue - 1);
float steinhart;
steinhart = resistance / RESISTOR_ROOM_TEMP;
steinhart = log(steinhart);
steinhart /= BETA_COEFFICIENT;
steinhart += 1.0 / (TEMPERATURE_NOMINAL + 273.15);
steinhart = 1.0 / steinhart;
steinhart -= 273.15;
return steinhart;
}Loading
ds18b20
ds18b20