#include <EEPROM.h>
// Pinos
const int sensorPin = A0;
const int relayPin = 8;
const int setButton = 2;
const int upButton = 3;
const int downButton = 4;
const int segmentPins[7] = {5, 6, 7, 9, 10, 11, 12};
const int digitPins[3] = {A1, A2, A3};
// Variáveis principais
float currentTemp = 0.0;
float setTemp = 30.0;
float hysteresis = 1.0;
float tempOffset = 0.0;
float minSet = 0.0;
float maxSet = 110.0;
float overTemp = 120.0;
int mode = 1; // 0=resfriar, 1=aquecer
int relayDelay = 0;
unsigned long lastRelayChange = 0;
bool relayState = false;
bool menuMode = false;
int menuIndex = 0;
unsigned long lastButtonTime = 0;
// Segmentos 0-9
const byte digits[10] = {
B00111111, B00000110, B01011011, B01001111, B01100110,
B01101101, B01111101, B00000111, B01111111, B01101111
};
// --- EEPROM positions
#define ADDR_SETTEMP 0
#define ADDR_MODE 4
#define ADDR_HYST 8
#define ADDR_MINTEMP 12
#define ADDR_OFFSET 16
#define ADDR_DELAY 20
#define ADDR_OVERTEMP 24
void saveSettings() {
EEPROM.put(ADDR_SETTEMP, setTemp);
EEPROM.put(ADDR_MODE, mode);
EEPROM.put(ADDR_HYST, hysteresis);
EEPROM.put(ADDR_MINTEMP, minSet);
EEPROM.put(ADDR_OFFSET, tempOffset);
EEPROM.put(ADDR_DELAY, relayDelay);
EEPROM.put(ADDR_OVERTEMP, overTemp);
}
void loadSettings() {
EEPROM.get(ADDR_SETTEMP, setTemp);
EEPROM.get(ADDR_MODE, mode);
EEPROM.get(ADDR_HYST, hysteresis);
EEPROM.get(ADDR_MINTEMP, minSet);
EEPROM.get(ADDR_OFFSET, tempOffset);
EEPROM.get(ADDR_DELAY, relayDelay);
EEPROM.get(ADDR_OVERTEMP, overTemp);
// fallback
if (isnan(setTemp)) setTemp = 30.0;
}
// Leitura do sensor (simples)
float readTemp() {
int raw = analogRead(sensorPin);
float voltage = raw * (5.0 / 1023.0);
float temp = (5.0 - voltage) * 100.0 + tempOffset;
return temp;
}
void setup() {
Serial.begin(115200);
for (int i = 0; i < 7; i++) pinMode(segmentPins[i], OUTPUT);
for (int i = 0; i < 3; i++) {
pinMode(digitPins[i], OUTPUT);
digitalWrite(digitPins[i], HIGH);
}
pinMode(relayPin, OUTPUT);
pinMode(setButton, INPUT_PULLUP);
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
loadSettings();
}
void displayDigits(int val) {
Serial.println(val);
int d[3] = {val / 100, (val / 10) % 10, val % 10};
for (int i = 0; i < 3; i++) {
digitalWrite(digitPins[i], LOW);
for (int s = 0; s < 7; s++)
digitalWrite(segmentPins[s], bitRead(digits[d[i]], s));
delay(2);
for (int s = 0; s < 7; s++) digitalWrite(segmentPins[s], LOW);
digitalWrite(digitPins[i], HIGH);
}
}
// Exibe “P0”, “P1” etc.
void displayParamCode(int idx) {
Serial.print("P");
Serial.println(idx);
byte p = B01110011; // 'P'
byte n = digits[idx];
byte empty = 0;
byte codes[3] = {p, n, empty};
for (int i = 0; i < 3; i++) {
digitalWrite(digitPins[i], LOW);
for (int s = 0; s < 7; s++) digitalWrite(segmentPins[s], bitRead(codes[i], s));
delay(2);
for (int s = 0; s < 7; s++) digitalWrite(segmentPins[s], LOW);
digitalWrite(digitPins[i], HIGH);
}
}
// Leitura botões
bool btnPressed(int pin) {
return digitalRead(pin) == LOW;
}
// Loop principal
void loop() {
currentTemp = readTemp();
// Entra em menu
if (btnPressed(setButton) && millis() - lastButtonTime > 3000) {
menuMode = true;
menuIndex = 0;
lastButtonTime = millis();
}
// Menu ativo
if (menuMode) {
displayParamCode(menuIndex);
delay(500);
if (btnPressed(setButton)) {
menuIndex++;
if (menuIndex > 6) {
menuMode = false;
saveSettings();
}
delay(300);
} else if (btnPressed(upButton) || btnPressed(downButton)) {
// Modifica valor do parâmetro
switch (menuIndex) {
case 0: mode = !mode; break;
case 1: hysteresis += btnPressed(upButton) ? 0.5 : -0.5; break;
case 2: minSet += btnPressed(upButton) ? 1 : -1; break;
case 3: maxSet += btnPressed(upButton) ? 1 : -1; break;
case 4: tempOffset += btnPressed(upButton) ? 0.1 : -0.1; break;
case 5: relayDelay += btnPressed(upButton) ? 1 : -1; break;
case 6: overTemp += btnPressed(upButton) ? 1 : -1; break;
}
delay(200);
}
return;
}
// Controle relé
if (millis() - lastRelayChange > relayDelay * 60000UL) {
if (mode == 1) { // aquecer
if (!relayState && currentTemp < setTemp - hysteresis) {
relayState = true;
digitalWrite(relayPin, HIGH);
lastRelayChange = millis();
} else if (relayState && currentTemp > setTemp + hysteresis) {
relayState = false;
digitalWrite(relayPin, LOW);
lastRelayChange = millis();
}
} else { // resfriar
if (!relayState && currentTemp > setTemp + hysteresis) {
relayState = true;
digitalWrite(relayPin, HIGH);
lastRelayChange = millis();
} else if (relayState && currentTemp < setTemp - hysteresis) {
relayState = false;
digitalWrite(relayPin, LOW);
lastRelayChange = millis();
}
}
}
// Alarme de temperatura
if (currentTemp > overTemp) {
digitalWrite(relayPin, LOW);
relayState = false;
}
// Exibe temperatura
displayDigits((int)(currentTemp * 10));
delay(5);
}