final version of the code:
imputs:
size selection button
reset button
level switch
flow switch
high tray switch
low tray switch
full ice detection photoresistor
outputs:
water pump drive
compressor drive
tray motor drive
reverse solenoid drive to release ice
UV LED drive for photobarrier
execution times are adjusted and correct for real operation.
refueling 15 seconds
small ice 12 min
medium ice 14 min
big ice 16 min
hot gas 8 seconds.
The only thing that remains to be adjusted is the photobarrier value yet to be analyzed
I will make changes to the schematic (I will try to make the background white) and completely redo the layout of the board to post here and declare the project complete
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Endereço e dimensões do LCD (16x2)
// Definições dos pinos
enum Pins {
pinButton = 2,
pinReset = 3,
pinWaterLevel = 4,
pinTrayHigh = 6,
pinTrayLow = 7,
pinWaterFlow = 5,
pinWaterPump = 8,
pinIceSolenoid = 11,
pinCompressor = 9,
pinTrayMotor = 10,
pinPhotoresistor = A0, // Novo pino analógico para o fotoresistor
pinSourceLED = 12 // LED da fonte de luz
};
#define stopTrayMotor digitalWrite(pinTrayMotor, LOW)
const char getIceSizeName[3][7] = { "PEQUENO ", "MEDIO", "GRANDE "};
const byte Time[3] = {720, 840, 960};
enum State {
SETUP,
SELECT_TIME,
COMPRESSOR_ON,
CHECK_WATER_LEVEL,
INITIAL_TRAY_POSITION,
FILLING,
MAKING_ICE,
LOWER_TRAY,
RELEASE_ICE,
ERROR_WATER,
ERROR_FLOW,
ERROR_TRAY,
CUBA_CHEIA // Novo estado para cuba cheia
};
unsigned long stateStartTime;
unsigned long iceMakingTime = 0; // Tempo padrão de 10 segundos
State currentState;
int buttonPressCount = 0; // Variável de seleção
bool CountedDown = false; // Variável de contagem inicializada fora do switch
void setup() {
// Configuração de entrada/saída dos pinos
pinMode(pinButton, INPUT_PULLUP);
pinMode(pinReset, INPUT_PULLUP);
pinMode(pinWaterLevel, INPUT_PULLUP);
pinMode(pinTrayHigh, INPUT_PULLUP);
pinMode(pinTrayLow, INPUT_PULLUP);
pinMode(pinWaterFlow, INPUT_PULLUP);
pinMode(pinPhotoresistor, INPUT); // Pino do fotoresistor como entrada analógica
pinMode(pinSourceLED, OUTPUT); // Pino do LED da fonte de luz como saída
pinMode(pinWaterPump, OUTPUT);
pinMode(pinIceSolenoid, OUTPUT);
pinMode(pinCompressor, OUTPUT);
pinMode(pinTrayMotor, OUTPUT);
// Inicialização do LCD
lcd.init();
lcd.backlight();
// Iniciar a máquina de estados no estado SELECT_TIME
currentState = SELECT_TIME;
}
void loop() {
static unsigned long waterFlowHighStartTime = 0;
static bool waterFlowHigh = false;
switch (currentState) {
case SELECT_TIME:
lcd.clear();
lcd.print("SELECIONE:");
stateStartTime = millis();
while (millis() - stateStartTime < 15000) {
if (digitalRead(pinButton) == LOW) {
buttonPressCount++;
if (buttonPressCount > 3) buttonPressCount = 1; // Ciclo fechado
lcd.setCursor(0, 1);
lcd.print(getIceSizeName[buttonPressCount - 1]);
}
delay(50); // Atraso de debounce
}
iceMakingTime = Time[buttonPressCount - 1];
lcd.clear();
lcd.print("TAMANHO DO CUBO: ");
lcd.print(getIceSizeName[buttonPressCount - 1]);
lcd.setCursor(0, 1);
lcd.print(iceMakingTime);
lcd.print(" TEMPO");
delay(2000);
iceMakingTime *= 1000;
currentState = CHECK_WATER_LEVEL;
break;
case CHECK_WATER_LEVEL:
if (digitalRead(pinWaterLevel) == HIGH) {
lcd.clear();
lcd.print("POUCA AGUA");
digitalWrite(pinWaterPump, LOW);
digitalWrite(pinIceSolenoid, LOW);
digitalWrite(pinCompressor, LOW);
stopTrayMotor;
while (digitalRead(pinReset));
} else currentState = INITIAL_TRAY_POSITION;
lcd.clear();
lcd.print("COMPRESSOR ON");
digitalWrite(pinCompressor, HIGH);
delay(2000);
break;
case INITIAL_TRAY_POSITION:
lcd.clear();
lcd.print("SUBINDO");
runTrayMotor(); // Subir bandeja
digitalWrite(pinSourceLED, HIGH); // Acionar LED da fonte de luz
stateStartTime = millis();
CountedDown = false;
// Espera o pinTrayHigh ficar LOW
while (digitalRead(pinTrayHigh) == HIGH) {
if (millis() - stateStartTime > 10000) {
currentState = ERROR_TRAY;
return;
}
delay(100);
displayCountdown(stateStartTime, 10000);
// Verificar o fotoresistor (A0) para cuba cheia (lógica invertida)
int photoresistorValue = analogRead(pinPhotoresistor);
if (photoresistorValue > 800) { // Exemplo de valor limite a ser ajustado conforme necessário
currentState = CUBA_CHEIA;
return;
}
}
stopTrayMotor;
digitalWrite(pinSourceLED, LOW); // Desligar LED da fonte de luz ao terminar
currentState = FILLING;
break;
case FILLING:
lcd.clear();
lcd.print("ABASTECENDO");
stateStartTime = millis();
waterFlowHighStartTime = 0;
waterFlowHigh = false;
digitalWrite(pinWaterPump, HIGH);
while (millis() - stateStartTime < 15000) {
displayCountdown(stateStartTime, 15000);
if (digitalRead(pinWaterFlow) == HIGH) {
if (!waterFlowHigh) {
waterFlowHigh = true;
waterFlowHighStartTime = millis();
} else if (millis() - waterFlowHighStartTime > 3000) {
digitalWrite(pinWaterPump, LOW);
currentState = ERROR_FLOW;
return;
}
} else {
waterFlowHigh = false;
}
}
digitalWrite(pinWaterPump, LOW);
currentState = MAKING_ICE;
break;
case MAKING_ICE:
stateStartTime = millis();
lcd.clear();
lcd.print("PRODUZINDO");
while (millis() - stateStartTime < iceMakingTime) {
displayCountdown(stateStartTime, iceMakingTime);
}
currentState = LOWER_TRAY;
break;
case LOWER_TRAY:
lcd.clear();
lcd.print("ABAIXANDO");
runTrayMotor(); // Descer bandeja
stateStartTime = millis();
CountedDown = false;
// Espera o pinTrayLow ficar LOW
while (digitalRead(pinTrayLow) == HIGH) {
if (millis() - stateStartTime > 10000) {
currentState = ERROR_TRAY;
return;
}
delay(100);
displayCountdown(stateStartTime, 10000);
}
stopTrayMotor;
currentState = RELEASE_ICE;
break;
case RELEASE_ICE:
stateStartTime = millis();
lcd.clear();
lcd.print("SOLTANDO CUBOS");
digitalWrite(pinIceSolenoid, HIGH);
while (millis() - stateStartTime < 8000) {
displayCountdown(stateStartTime, 8000);
}
digitalWrite(pinIceSolenoid, LOW);
currentState = CHECK_WATER_LEVEL;
break;
case ERROR_WATER:
lcd.clear();
lcd.print("FALTA DE AGUA");
digitalWrite(pinWaterPump, LOW);
digitalWrite(pinIceSolenoid, LOW);
digitalWrite(pinCompressor, LOW);
stopTrayMotor;
while (digitalRead(pinReset));
currentState = CHECK_WATER_LEVEL;
break;
case ERROR_FLOW:
lcd.clear();
lcd.print("SEM FLUXO");
digitalWrite(pinWaterPump, LOW);
digitalWrite(pinIceSolenoid, LOW);
digitalWrite(pinCompressor, LOW);
stopTrayMotor;
while (digitalRead(pinReset));
currentState = CHECK_WATER_LEVEL;
break;
case ERROR_TRAY:
lcd.clear();
lcd.print("BANDEJA TRAVADA");
digitalWrite(pinWaterPump, LOW);
digitalWrite(pinIceSolenoid, LOW);
digitalWrite(pinCompressor, LOW);
stopTrayMotor;
while (digitalRead(pinReset));
currentState = CHECK_WATER_LEVEL;
break;
case CUBA_CHEIA:
lcd.clear();
lcd.print("MUITO GELO");
digitalWrite(pinWaterPump, LOW);
digitalWrite(pinIceSolenoid, LOW);
digitalWrite(pinCompressor, LOW);
stopTrayMotor;
digitalWrite(pinSourceLED, LOW); // Desligar LED da fonte de luz
while (digitalRead(pinReset));
currentState = CHECK_WATER_LEVEL;
break;
default:
currentState = CHECK_WATER_LEVEL;
break;
}
}
void displayCountdown(unsigned long startTime, unsigned long duration) {
unsigned long remainingTime = (duration - (millis() - startTime)) / 1000;
lcd.setCursor(0, 1);
lcd.print("FALTAM: ");
lcd.print(remainingTime);
lcd.print(" sec");
}
void runTrayMotor() {
digitalWrite(pinTrayMotor, HIGH);
}