Skip to content

Commit

Permalink
Merge pull request rancilio-pid#275 from kjyv/various-fixes
Browse files Browse the repository at this point in the history
Various fixes: favicon, logging, use proper PID library
  • Loading branch information
murmeltier08 authored Nov 15, 2022
2 parents 23e40df + ba20ec3 commit 1703704
Show file tree
Hide file tree
Showing 17 changed files with 251 additions and 244 deletions.
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Clevercoffee
# CleverCoffee
(formerly Rancilio PID)

<div align="center">
<img src="https://img.shields.io/github/workflow/status/rancilio-pid/ranciliopid/Build/master">
Expand All @@ -8,15 +9,23 @@

# About

This project implements a PID for stable and accurate temperature control, originally for Rancilio Silvia espresso machines but also includes support for Gaggia and Quickmill machines. Others can easily be added or are already compatible.
This project implements a PID controller for stable and accurate temperature control, originally for Rancilio Silvia espresso machines but also includes support for Gaggia and Quickmill machines. Others can easily be added or are already compatible.

Additional features include:

* brew timer
* pre-infusion (reduced initial pressure using a dimmer for the pump)
* brew by weight (using weight cells, no support for external scales yet)
* pressure monitoring
* water level monitoring

The hardware has a small footprint and can easily fit also into most smaller espresso machines. The original wiring of the machine (mostly) remains and is only extended. The machine can be easily reversed to the orignal state after the conversion.

The project has been in active development and supported for 4 years with continuous improvements. Hundreds of machines have been converted to PID control already.

You can find our project website here: [Clever Coffee Website](https://clevercoffee.de).

The PID software is Open Source: free of charge for you and customizable to your personal needs.
This software is Open Source: free of charge for you and customizable to your personal needs.

We recommend you to have a look at the manual before starting a build, you can find the german one [here](https://rancilio-pid.github.io/ranciliopid-handbook/). It is currently being reworked to include all the latest features. The english one is sadly still very outdated but will also be updated soon.

Expand All @@ -26,7 +35,7 @@ Video tutorial on how to flash the firmware (a little outdated but mostly still
https://youtu.be/KZPjisOEcQ4

## Version
The next version is going to be 3.1.0 (03.11.2022)
The next version is going to be 3.1.x (last release was on 03.11.2022)

## What is possible after installation into your espresso machine?
* Control of the brewing temperature with an accuracy of up to +/- 0,1°.
Expand Down
1 change: 1 addition & 0 deletions data/html_fragments/header.htm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Clever Coffee PID</title>
<link rel="icon" href="data:image/svg+xml,%%3Csvg%%20xmlns='http://www.w3.org/2000/svg'%%20viewBox='0%%200%%2016%%2016'%%3E%%3Ctext%%20x='0'%%20y='14'%%3E☕%%3C/text%%3E%%3C/svg%%3E" type="image/svg+xml" />

%VAR_HEADER_FONTAWESOME%
%VAR_HEADER_BOOTSTRAP%
Expand Down
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ lib_deps =
adafruit/Adafruit_VL53L0X @ ^1.2.0
olkal/HX711_ADC @ ^1.2.12
olikraus/U8g2 @ ^2.34.3
git+https://github.com/kjyv/Arduino-PID-Library
git+https://github.com/rancilio-pid/Arduino-PID-Library
knolleary/PubSubClient @ ^2.8
me-no-dev/AsyncTCP @ ^1.1.1
bblanchon/ArduinoJson @ ^6.19
Expand Down
10 changes: 5 additions & 5 deletions src/Displaytemplateminimal.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* @brief Send data to display
*/
void printScreen() {
if ((machinestate == kSetPointNegative || machinestate == kPidNormal || machinestate == kBrewDetectionTrailing) ||
((machinestate == kBrew || machinestate == kShotTimerAfterBrew) && SHOTTIMER == 0) || // shottimer == 0, auch Bezug anzeigen
machinestate == kCoolDown || ((machinestate == kColdStart) && HEATINGLOGO == 0) || ((machinestate == kPidOffline) && OFFLINEGLOGO == 0))
if ((machineState == kBelowSetPoint || machineState == kPidNormal || machineState == kBrewDetectionTrailing) ||
((machineState == kBrew || machineState == kShotTimerAfterBrew) && SHOTTIMER == 0) || // shottimer == 0, auch Bezug anzeigen
machineState == kCoolDown || ((machineState == kColdStart) && HEATINGLOGO == 0) || ((machineState == kPidOffline) && OFFLINEGLOGO == 0))
{
if (!sensorError) {
u8g2.clearBuffer();
Expand Down Expand Up @@ -86,7 +86,7 @@ void printScreen() {
u8g2.print("/");

if (ONLYPID == 1) {
u8g2.print(brewtimersoftware, 0); // deaktivieren wenn Preinfusion ( // voransetzen )
u8g2.print(brewtimesoftware, 0); // deaktivieren wenn Preinfusion ( // voransetzen )
} else {
u8g2.print(totalBrewTime / 1000, 0); // aktivieren wenn Preinfusion
}
Expand All @@ -99,7 +99,7 @@ void printScreen() {
u8g2.print("BD: ");
u8g2.print((millis() - timeBrewDetection) / 1000, 1);
u8g2.print("/");
u8g2.print(brewtimersoftware, 0);
u8g2.print(brewtimesoftware, 0);
}

// Für Statusinfos
Expand Down
10 changes: 5 additions & 5 deletions src/Displaytemplatescale.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
* @brief Send data to display
*/
void printScreen() {
if ((machinestate == kSetPointNegative || machinestate == kPidNormal || machinestate == kBrewDetectionTrailing) ||
((machinestate == kBrew || machinestate == kShotTimerAfterBrew) && SHOTTIMER == 0) || // shottimer == 0, auch Bezug anzeigen
machinestate == kCoolDown || ((machinestate == kInit || machinestate == kColdStart) &&
HEATINGLOGO == 0) || ((machinestate == kPidOffline) && OFFLINEGLOGO == 0))
if ((machineState == kBelowSetPoint || machineState == kPidNormal || machineState == kBrewDetectionTrailing) ||
((machineState == kBrew || machineState == kShotTimerAfterBrew) && SHOTTIMER == 0) || // shottimer == 0, auch Bezug anzeigen
machineState == kCoolDown || ((machineState == kInit || machineState == kColdStart) &&
HEATINGLOGO == 0) || ((machineState == kPidOffline) && OFFLINEGLOGO == 0))
{
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_profont11_tf);
Expand Down Expand Up @@ -65,7 +65,7 @@ void printScreen() {
u8g2.print("/");

if (ONLYPID == 1) {
u8g2.print(brewtimersoftware, 0); // deaktivieren wenn Preinfusion ( // voransetzen )
u8g2.print(brewtimesoftware, 0); // deaktivieren wenn Preinfusion ( // voransetzen )
} else {
u8g2.print(totalBrewTime / 1000, 1); // aktivieren wenn Preinfusion und eine Nachkommastelle
// oder alternativ keine
Expand Down
16 changes: 8 additions & 8 deletions src/Displaytemplatestandard.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
*/
void printScreen()
{
if ((machinestate == kSetPointNegative || machinestate == kPidNormal || machinestate == kBrewDetectionTrailing) ||
((machinestate == kBrew || machinestate == kShotTimerAfterBrew) && SHOTTIMER == 0) || // shottimer == 0, also show brew
machinestate == kCoolDown || ((machinestate == kInit || machinestate == kColdStart ) && HEATINGLOGO == 0) ||
((machinestate == kPidOffline) && OFFLINEGLOGO == 0))
if ((machineState == kBelowSetPoint || machineState == kPidNormal || machineState == kBrewDetectionTrailing) ||
((machineState == kBrew || machineState == kShotTimerAfterBrew) && SHOTTIMER == 0) || // shottimer == 0, also show brew
machineState == kCoolDown || ((machineState == kInit || machineState == kColdStart ) && HEATINGLOGO == 0) ||
((machineState == kPidOffline) && OFFLINEGLOGO == 0))
{
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_profont11_tf); // set font
Expand Down Expand Up @@ -106,7 +106,7 @@ void printScreen()
u8g2.print("/");

if (ONLYPID == 1) {
u8g2.print(brewtimersoftware, 0); // deactivate if only pid without preinfusion
u8g2.print(brewtimesoftware, 0); // deactivate if only pid without preinfusion
}
else {
u8g2.print(totalBrewTime / 1000, 1); // activate if pre-infusion and one decimal place or alternatively none
Expand Down Expand Up @@ -141,7 +141,7 @@ void printScreen()
}
} else {
u8g2.drawXBMP(40, 2, 8, 8, antenna_NOK_u8g2);
u8g2.setCursor(88, 2);
u8g2.setCursor(88, 1);
u8g2.print("RC: ");
u8g2.print(wifiReconnects);
}
Expand All @@ -157,8 +157,8 @@ void printScreen()
}
}
} else {
u8g2.setCursor(40, 2);
u8g2.print(langstring_offlinemod);
u8g2.setCursor(40, 1);
u8g2.print(langstring_offlinemode);
}

#if TOF == 1
Expand Down
8 changes: 4 additions & 4 deletions src/Displaytemplatetemponly.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ float blinkingtempoffset = 0.3; // offset for blinking
* @brief Send data to display
*/
void printScreen() {
if ((machinestate == kSetPointNegative || machinestate == kPidNormal || machinestate == kBrewDetectionTrailing) ||
((machinestate == kBrew || machinestate == kShotTimerAfterBrew) && SHOTTIMER == 0) || // shottimer == 0, auch Bezug anzeigen
machinestate == kCoolDown || ((machinestate == kInit || machinestate == kColdStart) && HEATINGLOGO == 0) ||
((machinestate == kPidOffline) && OFFLINEGLOGO == 0)) {
if ((machineState == kBelowSetPoint || machineState == kPidNormal || machineState == kBrewDetectionTrailing) ||
((machineState == kBrew || machineState == kShotTimerAfterBrew) && SHOTTIMER == 0) || // shottimer == 0, auch Bezug anzeigen
machineState == kCoolDown || ((machineState == kInit || machineState == kColdStart) && HEATINGLOGO == 0) ||
((machineState == kPidOffline) && OFFLINEGLOGO == 0)) {

if (!sensorError) {
u8g2.clearBuffer();
Expand Down
12 changes: 6 additions & 6 deletions src/Displaytemplateupright.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
* @brief Send data to display
*/
void printScreen() {
if ((machinestate == kSetPointNegative || machinestate == kPidNormal || machinestate == kBrewDetectionTrailing) ||
((machinestate == kBrew || machinestate == kShotTimerAfterBrew) && SHOTTIMER == 0) ||// shottimer == 0, auch Bezug anzeigen
machinestate == kCoolDown || ((machinestate == kInit || machinestate == kColdStart ) && HEATINGLOGO == 0) ||
((machinestate == kPidOffline) && OFFLINEGLOGO == 0))
if ((machineState == kBelowSetPoint || machineState == kPidNormal || machineState == kBrewDetectionTrailing) ||
((machineState == kBrew || machineState == kShotTimerAfterBrew) && SHOTTIMER == 0) ||// shottimer == 0, auch Bezug anzeigen
machineState == kCoolDown || ((machineState == kInit || machineState == kColdStart ) && HEATINGLOGO == 0) ||
((machineState == kPidOffline) && OFFLINEGLOGO == 0))
{
if (!sensorError) {
u8g2.clearBuffer();
Expand Down Expand Up @@ -56,7 +56,7 @@ void printScreen() {
u8g2.print("BD ");
u8g2.print((millis() - timeBrewDetection) / 1000, 1);
u8g2.print("/");
u8g2.print(brewtimersoftware, 0);
u8g2.print(brewtimesoftware, 0);
}

// PID Werte ueber heatbar
Expand Down Expand Up @@ -95,7 +95,7 @@ void printScreen() {
u8g2.print("/");

if (ONLYPID == 1) {
u8g2.print(brewtimersoftware, 0);// deaktivieren wenn Preinfusion ( // voransetzen )
u8g2.print(brewtimesoftware, 0);// deaktivieren wenn Preinfusion ( // voransetzen )
}
else {
u8g2.print(totalBrewTime / 1000, 0); // aktivieren wenn Preinfusion
Expand Down
18 changes: 12 additions & 6 deletions src/RancilioServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ constexpr unsigned int str2int(const char* str, int h = 0) {
}

String getHeader(String varName) {
//TODO: actually put the references libs on local file system again (only when using ESP32 which has more flash mem, but also make sure web server can handle this many concurrent requests (might crash)
//TODO: actually put the references libs on local file system again (only when using ESP32 which has more flash mem,
//but also make sure web server can handle this many concurrent requests (might crash)
switch (str2int(varName.c_str())) {
case (str2int("FONTAWESOME")):
#if defined(WEB_USE_LOCAL_LIBS) && WEB_USE_LOCAL_LIBS == 1
Expand Down Expand Up @@ -278,16 +279,21 @@ String staticProcessor(const String& var) {

File file = LittleFS.open("/html_fragments/" + varLower + ".htm", "r");

if (file && file.size()*2 < ESP.getFreeHeap()) {
String ret = file.readString();
file.close();
return ret;
if (file) {
if (file.size()*2 < ESP.getFreeHeap()) {
String ret = file.readString();
file.close();
return ret;
} else {
debugPrintf("Can't open file %s, not enough memory available\n", file.name());
}
} else {
debugPrintf("Can't open file %s, not enough memory available\n", file ? file.name() : "");
debugPrintf("Fragment %s not found\n", varLower.c_str());
}

skipHeaterISR = false;

//didn't find a value for the var, replace var with empty string
return String();
}

Expand Down
10 changes: 5 additions & 5 deletions src/Storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ typedef struct __attribute__((packed)) {
uint8_t freeToUse8[2];
double pidTvBd;
uint8_t freeToUse9[2];
double brewSwTimerSec;
double brewSwTimeSec;
uint8_t freeToUse10[2];
double brewDetectionThreshold;
uint8_t freeToUse11;
Expand Down Expand Up @@ -88,7 +88,7 @@ static const sto_data_t itemDefaults PROGMEM = {
{0xFF, 0xFF}, // free to use
AGGBTV, // STO_ITEM_PID_TV_BD
{0xFF, 0xFF}, // free to use
BREW_SW_TIMER, // STO_ITEM_BREW_SW_TIMER
BREW_SW_TIME, // STO_ITEM_BREW_SW_TIME
{0xFF, 0xFF}, // free to use
BREWSENSITIVITY, // STO_ITEM_BD_THRESHOLD
0xFF, // free to use
Expand Down Expand Up @@ -185,9 +185,9 @@ static inline int32_t getItemAddr(sto_item_id_t itemId, uint16_t* maxItemSize =
size = STRUCT_MEMBER_SIZE(sto_data_t, pidTvBd);
break;

case STO_ITEM_BREW_SW_TIMER:
addr = offsetof(sto_data_t, brewSwTimerSec);
size = STRUCT_MEMBER_SIZE(sto_data_t, brewSwTimerSec);
case STO_ITEM_BREW_SW_TIME:
addr = offsetof(sto_data_t, brewSwTimeSec);
size = STRUCT_MEMBER_SIZE(sto_data_t, brewSwTimeSec);
break;

case STO_ITEM_BD_THRESHOLD:
Expand Down
2 changes: 1 addition & 1 deletion src/Storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ typedef enum
STO_ITEM_PID_KP_BD, // PID P part at brew detection phase
STO_ITEM_PID_TN_BD, // PID I part at brew detection phase
STO_ITEM_PID_TV_BD, // PID D part at brew detection phase
STO_ITEM_BREW_SW_TIMER, // brew software timer
STO_ITEM_BREW_SW_TIME, // brew software time
STO_ITEM_BD_THRESHOLD, // brew detection limit
STO_ITEM_PID_KP_START, // PID P part at cold start phase
STO_ITEM_PID_TN_START, // PID I part at cold start phase
Expand Down
2 changes: 1 addition & 1 deletion src/brewvoid.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void checkbrewswitch() {
break;
case 30:
// Stop Brew trigger (one push) brewswitch == HIGH
if ((brewswitchTrigger == HIGH && brewswitch == HIGH) || (machinestate == kShotTimerAfterBrew) ) {
if ((brewswitchTrigger == HIGH && brewswitch == HIGH) || (machineState == kShotTimerAfterBrew) ) {
brewswitch = LOW;
brewswitchTriggerCase = 40;
brewswitchTriggermillis = millis();
Expand Down
Loading

0 comments on commit 1703704

Please sign in to comment.