|
|
@ -5,6 +5,7 @@ |
|
|
|
#include <AsyncElegantOTA.h>
|
|
|
|
#include <Wire.h>
|
|
|
|
#include <LiquidCrystal.h>
|
|
|
|
#include <EEPROM.h> // to store number of coffees made and pumped water
|
|
|
|
|
|
|
|
AsyncWebServer server(80); |
|
|
|
|
|
|
@ -14,13 +15,12 @@ unsigned long startTime; |
|
|
|
// WiFi settings
|
|
|
|
const char* ssid = "LILiK_WiFi"; //replace with your SSID
|
|
|
|
const char* password = "pippopippo"; //password
|
|
|
|
//const char* ssid = "AulaStud"; //replace with your SSID
|
|
|
|
//const char* password = "cinimerda"; //password
|
|
|
|
String hostname = "PyCoffee"; |
|
|
|
int wifiStatus = 0; // variable to store status (connected/disconnected, used by LCDprint)
|
|
|
|
|
|
|
|
// string to store coffee style from HTML
|
|
|
|
String input_field = "espr"; |
|
|
|
|
|
|
|
String input_field = ""; // string for coffee type
|
|
|
|
String input_field2 = ""; // string for serial commands
|
|
|
|
|
|
|
|
// HTML WEB interface
|
|
|
|
const char index_html[] PROGMEM = R"rawliteral( |
|
|
@ -46,7 +46,33 @@ const char index_html[] PROGMEM = R"rawliteral( |
|
|
|
</form> |
|
|
|
<br><br> |
|
|
|
|
|
|
|
<a>Clicca qui sotto per aggiornare il firmware:</a> <br> |
|
|
|
<a>Puoi mandare comandi a Arduino via seriale</a><br> |
|
|
|
<a>usa 'exit' per uscire dall'ultimo comando seriale</a><br><br> |
|
|
|
|
|
|
|
<form action="/serial"> |
|
|
|
<select name="serial_input"> |
|
|
|
<option value="exit">Exit Command</option> |
|
|
|
<option value="dryr">PerformDryRun</option> |
|
|
|
<option value="noco">NoCoffeeRun</option> |
|
|
|
<option value="clea">Self-Clean</option> |
|
|
|
<option value="make">Make Coffee</option> |
|
|
|
<option value="pump">pumpWater</option> |
|
|
|
<option value="pres">Press</option> |
|
|
|
<option value="unpr">un-Press</option> |
|
|
|
<option value="heat">Heat Boiler</option> |
|
|
|
<option value="grin">GrindPowder</option> |
|
|
|
<option value="drop">Drop Powder</option> |
|
|
|
<option value="rist">setRistretto</option> |
|
|
|
<option value="espr">setEspresso</option> |
|
|
|
<option value="long">setLungo</option> |
|
|
|
</select><br><br> |
|
|
|
<input type="submit" value="Invia Comando"> |
|
|
|
</form> |
|
|
|
<br><br> |
|
|
|
|
|
|
|
<a>Consulta la pagina Gitea per maggiori informazioni</a><br><br> |
|
|
|
|
|
|
|
<a>Aggiornamento firmware:</a> <br> |
|
|
|
<a href='/update'>⬆️ OTA Firmware_Update ⬆️</a><br><br> |
|
|
|
<a>Codice sorgente (su LILiK projects):</a> <br> |
|
|
|
<a href='https://projects.lilik.it/LILiK/PyCoffee_ESP8266'>☕Gitea☕</a><br><br>
|
|
|
@ -55,25 +81,36 @@ const char index_html[] PROGMEM = R"rawliteral( |
|
|
|
|
|
|
|
// input parameter for html server
|
|
|
|
const char* input_paramter1 = "coffee_input"; |
|
|
|
const char* input_paramter2 = "serial_input"; |
|
|
|
|
|
|
|
// enable http coffee making on server request
|
|
|
|
int httpCoffee = 0; |
|
|
|
int serialCommand = 0; |
|
|
|
|
|
|
|
// button pins
|
|
|
|
const int sel = 0, enter = 2; |
|
|
|
|
|
|
|
// Global string
|
|
|
|
// Global string, allows serial in
|
|
|
|
String readString; |
|
|
|
|
|
|
|
// coffee type variable
|
|
|
|
String type = "Espresso"; |
|
|
|
|
|
|
|
// number of coffees made and seconds of pumped water since last tray empty/water refill
|
|
|
|
// used by checkTrayWater() function
|
|
|
|
int coffeesDone = 0; |
|
|
|
int pumpedS = 0; |
|
|
|
const int MaxCoffees = 10; |
|
|
|
const int MaxPumped = 205; |
|
|
|
|
|
|
|
// Support string to store stuff to be sent over serial
|
|
|
|
String serialOUTbuffer = "none"; |
|
|
|
|
|
|
|
// Variables to store lines to be printed on LCD:
|
|
|
|
String line1 = ""; |
|
|
|
String line2 = ""; |
|
|
|
// only refresh LCD when needed
|
|
|
|
int printed = 0; |
|
|
|
|
|
|
|
// LCD pins <--> ESP8266 LOLIN D1 pins
|
|
|
|
const int e_RS = 4, e_EN = 5, e_D6 = 12, e_D7 = 13, e_D5 = 14, e_D8 = 15; |
|
|
@ -91,6 +128,9 @@ byte cupL1[8] = {0b00100,0b00100,0b00100,0b00010,0b01111,0b01000,0b00111,0b00000 |
|
|
|
byte cupC1[8] = {0b00000,0b00000,0b00000,0b00000,0b11111,0b00000,0b11111,0b00000}; |
|
|
|
// Custom character matrix (coffee cup right side line 2)
|
|
|
|
byte cupR1[8] = {0b01010,0b01010,0b01110,0b10000,0b11100,0b00100,0b11000,0b00000}; |
|
|
|
// Custom character matrix (WiFi connected/disconnected)
|
|
|
|
byte wifiok[8] = {0b00000,0b01110,0b10001,0b00100,0b01010,0b00000,0b00000,0b00100}; |
|
|
|
byte wifino[8] = {0b00000,0b10001,0b01010,0b00100,0b01010,0b10001,0b00000,0b00100}; |
|
|
|
|
|
|
|
void notFound(AsyncWebServerRequest *request) { |
|
|
|
request->send(404, "text/plain", "Not found"); |
|
|
@ -101,6 +141,10 @@ void notFound(AsyncWebServerRequest *request) { |
|
|
|
// the setup function runs once when you press reset or power the board
|
|
|
|
void setup(void) { |
|
|
|
|
|
|
|
// check how many coffees were done and seconds of pumped water from EEPROM
|
|
|
|
coffeesDone = (EEPROM.read(0)); |
|
|
|
pumpedS = (EEPROM.read(1)); |
|
|
|
|
|
|
|
// Set buttons as inputs with internal pull-ups
|
|
|
|
pinMode(enter, INPUT_PULLUP); |
|
|
|
pinMode(sel, INPUT_PULLUP); |
|
|
@ -115,6 +159,8 @@ void setup(void) { |
|
|
|
lcd.createChar(3, cupL1); |
|
|
|
lcd.createChar(4, cupC1); |
|
|
|
lcd.createChar(5, cupR1); |
|
|
|
lcd.createChar(6, wifiok); |
|
|
|
lcd.createChar(7, wifino); |
|
|
|
lcd.begin(16, 2); // set up number of columns and rows
|
|
|
|
lcd.clear(); // Clear LCD
|
|
|
|
|
|
|
@ -134,6 +180,7 @@ void setup(void) { |
|
|
|
}); |
|
|
|
|
|
|
|
// Get data from menu
|
|
|
|
// coffee
|
|
|
|
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) { |
|
|
|
if (request->hasParam(input_paramter1)) { |
|
|
|
type = request->getParam(input_paramter1)->value(); |
|
|
@ -141,6 +188,17 @@ void setup(void) { |
|
|
|
} |
|
|
|
request->send_P(200, "text/html", index_html); // Re-send main page, with data!
|
|
|
|
}); |
|
|
|
// serial commands
|
|
|
|
server.on("/serial", HTTP_GET, [] (AsyncWebServerRequest *request) { |
|
|
|
if (request->hasParam(input_paramter2)) { |
|
|
|
if (serialOUTbuffer != "") { |
|
|
|
serialOUTbuffer = request->getParam(input_paramter2)->value(); |
|
|
|
serialCommand = 1; |
|
|
|
httpCoffee = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
request->send_P(200, "text/html", index_html); // Re-send main page, with data!
|
|
|
|
}); |
|
|
|
|
|
|
|
// in case of error:
|
|
|
|
server.onNotFound(notFound); |
|
|
@ -149,9 +207,8 @@ void setup(void) { |
|
|
|
Serial.println("HTTP server started"); |
|
|
|
|
|
|
|
// Print selection screen
|
|
|
|
line1 = "Selection"; |
|
|
|
line2 = type; |
|
|
|
LCDprint(); |
|
|
|
printed = 1; |
|
|
|
|
|
|
|
// tell the Arduino we're ready
|
|
|
|
serialOUTbuffer = "read"; |
|
|
|
delay(100); |
|
|
@ -162,7 +219,9 @@ void setup(void) { |
|
|
|
|
|
|
|
void loop() { |
|
|
|
// the loop function runs over and over again forever
|
|
|
|
delay(10); |
|
|
|
checkTrayWater(); |
|
|
|
delay(10); |
|
|
|
serialFromHTTP(); |
|
|
|
|
|
|
|
// select type of brew by pressing the sel button
|
|
|
|
if (digitalRead(sel) == LOW && type == "Espresso") { |
|
|
@ -186,6 +245,32 @@ void loop() { |
|
|
|
LCDprint(); |
|
|
|
delay(500); |
|
|
|
} |
|
|
|
else if (Serial.available() > 0) { |
|
|
|
// read the incoming data: (we only care about the first few characters, I've chosen 4)
|
|
|
|
readString = ""; |
|
|
|
serialRead(); |
|
|
|
String incomingData = readString.substring(0,4); |
|
|
|
// are we heating the boiler to vapor temperature?
|
|
|
|
if (incomingData == "Vapo") { |
|
|
|
line1 = "Heating"; |
|
|
|
line2 = "Vapor"; |
|
|
|
LCDprint(); |
|
|
|
delay(1000); |
|
|
|
} |
|
|
|
if (incomingData == "reac") { |
|
|
|
line1 = "Vapor"; |
|
|
|
line2 = "ok"; |
|
|
|
LCDprint(); |
|
|
|
delay(1000); |
|
|
|
printed = 1; |
|
|
|
delay(10000); |
|
|
|
serialOUTbuffer = "unpr"; |
|
|
|
writeSerial(); |
|
|
|
delay(100); |
|
|
|
} |
|
|
|
} |
|
|
|
refreshMenu(); |
|
|
|
delay(100); |
|
|
|
|
|
|
|
// check if data has been sent on serial from Arduino,
|
|
|
|
// send commands to arduino and display corresponding messages on LCD
|
|
|
@ -212,16 +297,21 @@ void bootAnimation() { |
|
|
|
|
|
|
|
delay(1000); |
|
|
|
line1 = "ESP_Coffee"; |
|
|
|
line2 = "Beta 1"; |
|
|
|
line2 = "Release 1"; |
|
|
|
LCDprint(); |
|
|
|
delay(1000); |
|
|
|
lcd.setCursor(12,0); //print coffee cup top using uint8 method
|
|
|
|
lcd.setCursor(11,0); //print coffee cup top using uint8 method
|
|
|
|
lcd.write((uint8_t)0); |
|
|
|
delay(10); |
|
|
|
lcd.write((uint8_t)1); |
|
|
|
delay(10); |
|
|
|
lcd.write((uint8_t)2); |
|
|
|
lcd.setCursor(12,1); //print coffee cup bottom using uint8 method
|
|
|
|
delay(10); |
|
|
|
lcd.setCursor(11,1); //print coffee cup bottom using uint8 method
|
|
|
|
lcd.write((uint8_t)3); |
|
|
|
delay(10); |
|
|
|
lcd.write((uint8_t)4); |
|
|
|
delay(10); |
|
|
|
lcd.write((uint8_t)5); |
|
|
|
delay(2000); |
|
|
|
} |
|
|
@ -239,9 +329,12 @@ void connectedTo() { |
|
|
|
line1 = "Timeout at SSID"; |
|
|
|
line2 = ssid; |
|
|
|
LCDprint(); |
|
|
|
delay(10000); |
|
|
|
break; |
|
|
|
} |
|
|
|
delay(10000); |
|
|
|
else { |
|
|
|
wifiStatus = 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Serial.println(""); |
|
|
@ -257,19 +350,59 @@ void connectedTo() { |
|
|
|
line1 = "Connected to IP:"; |
|
|
|
line2 = ""; |
|
|
|
LCDprint(); |
|
|
|
lcd.setCursor(0, 1); // move cursor to (0, 0)
|
|
|
|
delay(10); |
|
|
|
lcd.setCursor(0, 1); // move cursor to (0, 1)
|
|
|
|
lcd.print(WiFi.localIP()); // re-print line2 or IP won't print
|
|
|
|
delay(2000); |
|
|
|
} |
|
|
|
|
|
|
|
//_____________________________________________________________________________
|
|
|
|
|
|
|
|
void refreshMenu() { |
|
|
|
if (line1 == "Selection" && printed == 1) { |
|
|
|
lcd.clear(); |
|
|
|
lcd.setCursor(0, 0); // move cursor to (0, 0)
|
|
|
|
lcd.print(line1); // print line1
|
|
|
|
delay(10); |
|
|
|
lcd.setCursor(15, 0); // move cursor to (14, 0)
|
|
|
|
// print wifi logo depending on connection starus
|
|
|
|
if (wifiStatus == 1) { |
|
|
|
lcd.write((uint8_t)6); |
|
|
|
delay(10); |
|
|
|
} |
|
|
|
else if (wifiStatus == 0) { |
|
|
|
lcd.write((uint8_t)7); |
|
|
|
delay(10); |
|
|
|
} |
|
|
|
|
|
|
|
lcd.setCursor(0, 1); // move cursor to (0, 1)
|
|
|
|
lcd.print(line2); // print line2
|
|
|
|
delay(10); |
|
|
|
printed = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//_____________________________________________________________________________
|
|
|
|
|
|
|
|
void LCDprint() { |
|
|
|
lcd.clear(); |
|
|
|
lcd.setCursor(0, 0); // move cursor to (0, 0)
|
|
|
|
lcd.print(line1); // print line1
|
|
|
|
lcd.setCursor(0, 1); // move cursor to (0, 0)
|
|
|
|
delay(10); |
|
|
|
lcd.setCursor(15, 0); // move cursor to (14, 0)
|
|
|
|
// print wifi logo depending on connection starus
|
|
|
|
if (wifiStatus == 1) { |
|
|
|
lcd.write((uint8_t)6); |
|
|
|
delay(10); |
|
|
|
} |
|
|
|
else if (wifiStatus == 0) { |
|
|
|
lcd.write((uint8_t)7); |
|
|
|
delay(10); |
|
|
|
} |
|
|
|
|
|
|
|
lcd.setCursor(0, 1); // move cursor to (0, 1)
|
|
|
|
lcd.print(line2); // print line2
|
|
|
|
delay(10); |
|
|
|
} |
|
|
|
|
|
|
|
//_____________________________________________________________________________
|
|
|
@ -280,17 +413,119 @@ void writeSerial() { |
|
|
|
|
|
|
|
//_____________________________________________________________________________
|
|
|
|
|
|
|
|
void serialFromHTTP() { |
|
|
|
if (serialCommand == 1){ |
|
|
|
serialCommand = 0; |
|
|
|
line1 = "serialCom"; |
|
|
|
line2 = serialOUTbuffer; |
|
|
|
LCDprint(); |
|
|
|
delay(1000); |
|
|
|
writeSerial(); |
|
|
|
while (serialOUTbuffer != "exit" && digitalRead(sel) == HIGH ) { |
|
|
|
|
|
|
|
if (Serial.available() > 0) { |
|
|
|
// read the incoming data: (we only care about the first few characters, I've chosen 4)
|
|
|
|
readString = ""; |
|
|
|
serialRead(); |
|
|
|
String incomingData = readString.substring(0,16); |
|
|
|
Serial.print("serial put from Arduino:\n"); |
|
|
|
Serial.print(incomingData); |
|
|
|
Serial.print("\n"); |
|
|
|
if (serialOUTbuffer != "none") { |
|
|
|
line1 = serialOUTbuffer; |
|
|
|
} |
|
|
|
line2 = incomingData; |
|
|
|
LCDprint(); |
|
|
|
delay(100); |
|
|
|
serialOUTbuffer = "none"; |
|
|
|
writeSerial(); |
|
|
|
} |
|
|
|
} |
|
|
|
line1 = "Selection"; |
|
|
|
line2 = type; |
|
|
|
LCDprint(); |
|
|
|
delay(500); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//_____________________________________________________________________________
|
|
|
|
|
|
|
|
void checkTrayWater() { |
|
|
|
// section dedicated to empty tray and refill water messages
|
|
|
|
if ((EEPROM.read(0)) < 0 or (EEPROM.read(0)) > MaxCoffees + 1) { |
|
|
|
EEPROM.write(0, 0); |
|
|
|
EEPROM.commit(); |
|
|
|
} |
|
|
|
else if ((EEPROM.read(0)) < coffeesDone) { |
|
|
|
EEPROM.write(0, coffeesDone); |
|
|
|
EEPROM.commit(); |
|
|
|
} |
|
|
|
|
|
|
|
if ((EEPROM.read(1)) < 0 or (EEPROM.read(1)) > MaxPumped + 1) { |
|
|
|
EEPROM.write(1, 0); |
|
|
|
EEPROM.commit(); |
|
|
|
} |
|
|
|
else if ((EEPROM.read(1)) < pumpedS) { |
|
|
|
EEPROM.write(1, pumpedS); |
|
|
|
EEPROM.commit(); |
|
|
|
} |
|
|
|
|
|
|
|
if (coffeesDone > (MaxCoffees - 1)) { |
|
|
|
lcd.clear(); |
|
|
|
while (digitalRead(enter) == HIGH) { |
|
|
|
lcd.setCursor(0, 0); // move cursor to (0, 0)
|
|
|
|
lcd.print("Empty Tray"); // print line1
|
|
|
|
delay(10); |
|
|
|
lcd.setCursor(0, 1); // move cursor to (0, 1)
|
|
|
|
lcd.print("Then hold Make"); // print line2
|
|
|
|
delay(10); |
|
|
|
} |
|
|
|
coffeesDone = 0; |
|
|
|
EEPROM.write(0, coffeesDone); |
|
|
|
EEPROM.commit(); |
|
|
|
delay(500); |
|
|
|
LCDprint(); |
|
|
|
delay(500); |
|
|
|
printed = 1; |
|
|
|
} |
|
|
|
if (pumpedS > (MaxPumped + 1)) { |
|
|
|
lcd.clear(); |
|
|
|
while (digitalRead(enter) == HIGH) { |
|
|
|
lcd.setCursor(0, 0); // move cursor to (0, 0)
|
|
|
|
lcd.print("Refill Water"); // print line1
|
|
|
|
delay(10); |
|
|
|
lcd.setCursor(0, 1); // move cursor to (0, 1)
|
|
|
|
lcd.print("Then hold Make"); // print line2
|
|
|
|
delay(10); |
|
|
|
} |
|
|
|
pumpedS = 0; |
|
|
|
EEPROM.write(1, pumpedS); |
|
|
|
EEPROM.commit(); |
|
|
|
delay(500); |
|
|
|
LCDprint(); |
|
|
|
delay(500); |
|
|
|
printed = 1; |
|
|
|
} |
|
|
|
line1 = "Selection"; |
|
|
|
line2 = type; |
|
|
|
} |
|
|
|
|
|
|
|
//_____________________________________________________________________________
|
|
|
|
|
|
|
|
void serialCoffeeCommandLCDInterface() { |
|
|
|
if (digitalRead(enter) == LOW or httpCoffee == 1) { |
|
|
|
httpCoffee = 0; |
|
|
|
if (type == "Espresso") { |
|
|
|
serialOUTbuffer = "espr"; |
|
|
|
pumpedS = pumpedS + 15; |
|
|
|
} |
|
|
|
else if (type == "Lungo") { |
|
|
|
serialOUTbuffer = "long"; |
|
|
|
pumpedS = pumpedS + 18; |
|
|
|
} |
|
|
|
else if (type == "Ristretto") { |
|
|
|
serialOUTbuffer = "rist"; |
|
|
|
pumpedS = pumpedS + 12; |
|
|
|
} |
|
|
|
writeSerial(); |
|
|
|
delay(500); |
|
|
@ -310,15 +545,23 @@ void serialCoffeeCommandLCDInterface() { |
|
|
|
line1 = "Making"; |
|
|
|
line2 = type; |
|
|
|
LCDprint(); |
|
|
|
|
|
|
|
delay(10); |
|
|
|
|
|
|
|
lcd.setCursor(12,0); //print coffee cup top using uint8 method
|
|
|
|
lcd.setCursor(11,0); //print coffee cup top using uint8 method
|
|
|
|
lcd.write((uint8_t)0); |
|
|
|
delay(10); |
|
|
|
lcd.write((uint8_t)1); |
|
|
|
delay(10); |
|
|
|
lcd.write((uint8_t)2); |
|
|
|
lcd.setCursor(12,1); //print coffee cup bottom using uint8 method
|
|
|
|
delay(10); |
|
|
|
lcd.setCursor(11,1); //print coffee cup bottom using uint8 method
|
|
|
|
lcd.write((uint8_t)3); |
|
|
|
delay(10); |
|
|
|
lcd.write((uint8_t)4); |
|
|
|
delay(10); |
|
|
|
lcd.write((uint8_t)5); |
|
|
|
delay(10); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
@ -406,14 +649,13 @@ void serialCoffeeCommandLCDInterface() { |
|
|
|
} |
|
|
|
} |
|
|
|
if (incomingData == "Comp") { |
|
|
|
coffeesDone++; |
|
|
|
Serial.print("Made coffee\n"); |
|
|
|
line1 = "Coffee Done :)"; |
|
|
|
line2 = "Enjoy!"; |
|
|
|
LCDprint(); |
|
|
|
delay(5000); |
|
|
|
line1 = "Selection"; |
|
|
|
line2 = type; |
|
|
|
LCDprint(); |
|
|
|
delay(500); |
|
|
|
} |
|
|
|
} |
|
|
|