# HG changeset patch # User Michiel Broek # Date 1540581826 -7200 # Node ID 49e2960d4642f17b96b022e1935d8cc8d33c9d2c # Parent 5d4a40fe9967e6fccdbdb235f3f0870a036d74d8 Implemented infusion mash. diff -r 5d4a40fe9967 -r 49e2960d4642 README.md --- a/README.md Fri Oct 26 13:29:14 2018 +0200 +++ b/README.md Fri Oct 26 21:23:46 2018 +0200 @@ -64,5 +64,4 @@ TODO: - Praktijktest. - Nosleep js code toevoegen. - - Bij infusie (en decoctie?) maisch stappen een prompt. diff -r 5d4a40fe9967 -r 49e2960d4642 main/automation.c --- a/main/automation.c Fri Oct 26 13:29:14 2018 +0200 +++ b/main/automation.c Fri Oct 26 21:23:46 2018 +0200 @@ -53,6 +53,8 @@ extern float Fake_HLT; #endif +extern const char *mashTypes[]; + static const char *TAG = "automation"; @@ -393,21 +395,26 @@ y += 16; _fg = TFT_WHITE; TFT_print("Maisch stap", 2, y); - TFT_print("Temp.", 200, y); - TFT_print("Rust", 260, y); + TFT_print("T", 200, y); + TFT_print("Temp.", 220, y); + TFT_print("Rust", 280, y); _fg = TFT_YELLOW; y += 16; for (int i = 1; i < 8; i++) { if (recipe.MashStep[i].Resttime) { TFT_print(recipe.MashStep[i].Name, 2, y); - sprintf(tmp, "%.2f", recipe.MashStep[i].Temperature); + strcpy(tmp, mashTypes[recipe.MashStep[i].Type]); + tmp[1] = '\0'; TFT_print(tmp, 200, y); - sprintf(tmp, "%2d min", recipe.MashStep[i].Resttime); - TFT_print(tmp, 260, y); + sprintf(tmp, "%.2f", recipe.MashStep[i].Temperature); + TFT_print(tmp, 220, y); + sprintf(tmp, "%2d m", recipe.MashStep[i].Resttime); + TFT_print(tmp, 280, y); y += 16; } } - ShowInteger(2, y, "Kooktijd", " miniuten", recipe.BoilTime); + ShowInteger(2, y, "Kooktijd", " min", recipe.BoilTime); + ShowFloat(162, y, "Koel tot", " C", recipe.CoolTemp, 2); y += 16; if (recipe.Additions) { _fg = TFT_YELLOW; @@ -427,7 +434,6 @@ TFT_print("Geen hop toevoegingen.", 2, y); } y += 16; - ShowFloat(2, y, "Koelen tot", " C", recipe.CoolTemp, 2); if (recipe.Whirlpool9) { ShowInteger(2, y, "Whirlpool 88..100 graden", " minuten", recipe.Whirlpool9); y += 16; @@ -593,8 +599,9 @@ xSemaphoreGive(xSemaphoreDriver); } MashState = MASH_WAITTEMP; - ESP_LOGI(TAG, "Mash step %d time: %d temp: %4.1f min: %4.1f max: %4.1f", - Main_Screen - MAIN_AUTO_MASH_IN, stageTime, stageTemp, MinMash, MaxMash); + ESP_LOGI(TAG, "Mash step %d type: %s time: %d temp: %4.1f min: %4.1f max: %4.1f", + Main_Screen - MAIN_AUTO_MASH_IN, mashTypes[recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Type], + stageTime, stageTemp, MinMash, MaxMash); if (Main_Screen > MAIN_AUTO_MASH_IN) { // Do not annotate before the log is open. @@ -612,9 +619,32 @@ sprintf(temp_buf, "Maisch stap #%d", Main_Screen - MAIN_AUTO_MASH_IN); TopMessage(temp_buf); } - Buttons_Add( 5, 30, 60, 40, "+sp", 0); - Buttons_Add(255, 30, 60, 40, "-sp", 1); - Buttons_Show(); + if ((Main_Screen > MAIN_AUTO_MASH_IN) && (Main_Screen < MAIN_AUTO_MASH_OUT) && + (recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Type == MASHTYPE_INFUSION)) { + Buttons_Add( 5,120, 60, 40, "Halt", 0); + Buttons[0].dark = true; + Buttons_Add(255,120, 60, 40, "Ok", 1); + Buttons_Show(); + _fg = TFT_WHITE; + _bg = TFT_BLACK; + TFT_setFont(DEJAVU18_FONT, NULL); + sprintf(temp_buf, "Infuse %.1f L/%.1f C", recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Infusion_amount, + recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Infusion_temp); + TFT_print(temp_buf, CENTER, 135); + SoundPlay(SOUND_Prompt); + MashState = MASH_INFUSE; + if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) { + // No heating during the infusion. + driver_state->mlt_sp = stageTemp; + driver_state->mlt_mode = MLT_MODE_OFF; + xSemaphoreGive(xSemaphoreDriver); + } + ESP_LOGI(TAG, "Mash infusion prompt"); + } else { + Buttons_Add( 5, 30, 60, 40, "+sp", 0); + Buttons_Add(255, 30, 60, 40, "-sp", 1); + Buttons_Show(); + } } else if (MashState == MASH_WAITTEMP) { pumpRest = false; @@ -817,6 +847,25 @@ break; default: break; } + } else if (MashState == MASH_INFUSE) { + switch (Buttons_Scan()) { + case 0: Main_Screen = MAIN_AUTO_ABORT; + break; + case 1: MashState = MASH_WAITTEMP; + if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) { + // Start PID again. + driver_state->mlt_sp = stageTemp; + driver_state->mlt_mode = MLT_MODE_PID; + xSemaphoreGive(xSemaphoreDriver); + } + Buttons_Clear(); + Buttons_Add( 5, 30, 60, 40, "+sp", 0); + Buttons_Add(255, 30, 60, 40, "-sp", 1); + Buttons_Show(); + TFT_fillRect(65, 120, 190, 40, TFT_BLACK); + break; + default: break; + } } /* MashState */ MLT_info(71, 26, true); if (_UseHLT) { diff -r 5d4a40fe9967 -r 49e2960d4642 main/buttons.c --- a/main/buttons.c Fri Oct 26 13:29:14 2018 +0200 +++ b/main/buttons.c Fri Oct 26 21:23:46 2018 +0200 @@ -13,6 +13,9 @@ extern uint16_t VNC_pointer_x; ///< Mouse coordinate X extern uint16_t VNC_pointer_y; ///< Mouse coordinate Y +const char *mashTypes[] = { "Infusion", "Temperature", "Decoction" }; +const char *SSR2Types[] = { "Uit", "HLT of MLT", "HLT en MLT", "Idle" }; + #define EDIT_TYPE_TEXT 0 ///< Editor type is text #define EDIT_TYPE_INT 1 ///< Editor type is integer @@ -55,7 +58,7 @@ Buttons[order].w = w; Buttons[order].h = h; strncpy(Buttons[order].text, txt, 11); - Buttons[order].dark = Buttons[order].small = false; + Buttons[order].dark = Buttons[order].small = Buttons[order].lock = false; } @@ -610,23 +613,9 @@ { _fg = TFT_LIGHTGREY; TFT_print("SSR2 ", x, y); - _fg = TFT_YELLOW; - TFT_clearStringRect(TFT_X, TFT_Y, "HLT en MLT"); - - switch (val) { - case SSR2_OFF: TFT_print("Uit", LASTX, LASTY); - break; - case SSR2_HLT_SHARE: TFT_print("HLT of MLT", LASTX, LASTY); - break; - - case SSR2_HLT_IND: TFT_print("HLT en MLT", LASTX, LASTY); - break; - - case SSR2_ON_IDLE: TFT_print("Idle", LASTX, LASTY); - break; - - default: TFT_print("N/A", LASTX, LASTY); - } + _fg = TFT_YELLOW; + TFT_clearStringRect(TFT_X, TFT_Y, "HLT en MLT"); + TFT_print((char *)SSR2Types[val], LASTX, LASTY); } @@ -945,24 +934,25 @@ TFT_fillScreen(_bg); TFT_resetclipwin(); TopMessage("Wijzigen"); - TFT_setFont(DEFAULT_FONT, NULL); - ShowSSR2(2, 28, value); Buttons_Clear(); - Buttons_Add( 20, 60,120, 40, "Uit", 0); - Buttons_Add(180, 60,120, 40, "HLT of MLT", 1); - Buttons_Add( 20, 130,120, 40, "HLT en MLT", 2); - Buttons_Add(180, 130,120, 40, "Idle", 3); + Buttons_Add( 20, 60,120, 40, (char *)SSR2Types[0], 0); + Buttons_Add(180, 60,120, 40, (char *)SSR2Types[1], 1); + Buttons_Add( 20, 130,120, 40, (char *)SSR2Types[2], 2); + Buttons_Add(180, 130,120, 40, (char *)SSR2Types[3], 3); Buttons_Add(120, 200, 80, 40, "Ok", 4); + Buttons[4].dark = true; + Buttons[value].lock = true; Buttons_Show(); while (loop) { key = Buttons_Scan(); if (key >= 0 && key <= 3) { + Buttons[value].lock = false; value = key; - TFT_setFont(DEFAULT_FONT, NULL); - ShowSSR2(2, 28, value); + Buttons[value].lock = true; + Buttons_Show(); } else if (key == 4) { loop = false; } @@ -973,6 +963,45 @@ +void EditMashType(uint8_t *val) +{ + bool loop = true; + int value = (int)*val; + int key; + + _bg = TFT_BLACK; + TFT_fillScreen(_bg); + TFT_resetclipwin(); + TopMessage("Wijzigen"); + + Buttons_Clear(); + Buttons_Add( 80, 40,160, 40, (char *)mashTypes[0], 0); + Buttons_Add( 80, 90,160, 40, (char *)mashTypes[1], 1); + Buttons_Add( 80, 140,160, 40, (char *)mashTypes[2], 2); + Buttons_Add(120, 200, 80, 40, "Ok", 3); + Buttons[3].dark = true; + Buttons[value].lock = true; + Buttons_Show(); + + while (loop) { + key = Buttons_Scan(); + + if (key >= 0 && key <= 2) { + Buttons[value].lock = false; + value = key; + Buttons[value].lock = true; + Buttons_Show(); + } else if (key == 3) { + loop = false; + } + vTaskDelay(20 / portTICK_PERIOD_MS); + } + Buttons[value].lock = false; + *val = (uint8_t)value; +} + + + int Confirm(char *top, char *ack, char *nak) { int rc = false; diff -r 5d4a40fe9967 -r 49e2960d4642 main/buttons.h --- a/main/buttons.h Fri Oct 26 13:29:14 2018 +0200 +++ b/main/buttons.h Fri Oct 26 21:23:46 2018 +0200 @@ -225,6 +225,12 @@ void EditSSR2(int *val); /** + * @brief Edit Mashtype value + * @param val The mash type + */ +void EditMashType(uint8_t *val); + +/** * @brief Confirm or not choice. Uses the whole screen. * @param top The top screen message. * @param ack The text for the ack button. diff -r 5d4a40fe9967 -r 49e2960d4642 main/config.c --- a/main/config.c Fri Oct 26 13:29:14 2018 +0200 +++ b/main/config.c Fri Oct 26 21:23:46 2018 +0200 @@ -431,13 +431,13 @@ recipe.MashStep[0].Infusion_amount = 15.0; recipe.MashStep[0].Resttime = 1; recipe.MashStep[0].Ramptime = 1; + for (int i = 1; i < 8; i++) + recipe.MashStep[i].Type = MASHTYPE_TEMPERATURE; sprintf(recipe.MashStep[1].Name, "Mash"); - recipe.MashStep[1].Type = MASHTYPE_TEMPERATURE; recipe.MashStep[1].Temperature = 67.0; recipe.MashStep[1].Resttime = 75; recipe.MashStep[1].Ramptime = 1; sprintf(recipe.MashStep[7].Name, "Mash-out"); - recipe.MashStep[7].Type = MASHTYPE_TEMPERATURE; recipe.MashStep[7].Temperature = 78.0; recipe.MashStep[7].Resttime = 5; recipe.MashStep[7].Ramptime = 11; diff -r 5d4a40fe9967 -r 49e2960d4642 main/config.h --- a/main/config.h Fri Oct 26 13:29:14 2018 +0200 +++ b/main/config.h Fri Oct 26 21:23:46 2018 +0200 @@ -83,6 +83,7 @@ #define VERSION "0.2.5" ///< Application version + /** * @brief Main mode different screens */ @@ -146,6 +147,7 @@ MASH_ADD, ///< Add mash wait MASH_IODINE, ///< Wait iodine test MASH_REMOVE, ///< Wait mash remove + MASH_INFUSE, ///< Wait infusion prompt } MASH_TYPE; /** diff -r 5d4a40fe9967 -r 49e2960d4642 main/files.h --- a/main/files.h Fri Oct 26 13:29:14 2018 +0200 +++ b/main/files.h Fri Oct 26 21:23:46 2018 +0200 @@ -6,13 +6,13 @@ #define _FILESS_H /** - * * @brief Files init fases. - * */ + * @brief Files init fases. + */ void Files_Init(void); /** - * * @brief Files loop screens. Bob-blocking. - * */ + * @brief Files loop screens. Bob-blocking. + */ void Files_Loop(void); #endif diff -r 5d4a40fe9967 -r 49e2960d4642 main/recipes.c --- a/main/recipes.c Fri Oct 26 13:29:14 2018 +0200 +++ b/main/recipes.c Fri Oct 26 21:23:46 2018 +0200 @@ -37,6 +37,8 @@ size_t offs; ///< Offset in buffer bool overflow; ///< Overflow in buffer +extern const char *mashTypes[]; + /** @@ -47,7 +49,6 @@ */ void Addition_Add(char *Name, uint8_t Type, uint16_t Time) { -// printf("Addition_Add(%s, %d, %d)\n", Name, Type, Time); if (! recipe.Additions) { // No entries yet, add the first one. sprintf(recipe.Addition[recipe.Additions].Name, "%s", Name); @@ -69,7 +70,6 @@ // A new entry and we already have some. Add it and keep the list sorted. for (int i = 0; i < recipe.Additions; i++) { if (Time > recipe.Addition[i].Time) { -// printf("Insert at %d\n", i); // Make room for (int j = i; j < recipe.Additions; j++) { sprintf(recipe.Addition[j+1].Name, "%s", recipe.Addition[j].Name); @@ -287,7 +287,6 @@ } } if ((_xml_depth == 5) && (strcmp("MASH_STEP", _xml_element[4]) == 0)) { -// printf("Flush End MASH_STEP %d %s\n", _xml_depth, _xml_add_name); _xml_mashsteps++; sprintf(recipe.MashStep[_xml_mashsteps].Name, "%s", _xml_add_name); recipe.MashStep[_xml_mashsteps].Type = _xml_add_type; @@ -350,7 +349,10 @@ } recipe.CoolTemp = 20.0; sprintf(recipe.MashStep[0].Name, "Mash-in"); - if (_xml_tun_temp > recipe.MashStep[1].Temperature) { + if ((recipe.MashStep[1].Type == MASHTYPE_INFUSION) && (recipe.MashStep[1].Infusion_temp > 0.0)) { + /* If next (first original) step is infusion, take that temperature. */ + recipe.MashStep[0].Temperature = recipe.MashStep[1].Infusion_temp; + } else if (_xml_tun_temp > recipe.MashStep[1].Temperature) { recipe.MashStep[0].Temperature = _xml_tun_temp; } else { recipe.MashStep[0].Temperature = recipe.MashStep[1].Temperature + 1.25; @@ -549,11 +551,9 @@ for (int i = 1; i < 8; i++) { if (recipe.MashStep[i].Resttime) { TFT_print(recipe.MashStep[i].Name, 2, y); - switch (recipe.MashStep[i].Type) { - case MASHTYPE_INFUSION: TFT_print("I", 200, y); break; - case MASHTYPE_TEMPERATURE: TFT_print("T", 200, y); break; - case MASHTYPE_DECOCTION: TFT_print("D", 200, y); break; - } + strcpy(tmp, mashTypes[recipe.MashStep[i].Type]); + tmp[1] = '\0'; + TFT_print(tmp, 200, y); sprintf(tmp, "%.2f", recipe.MashStep[i].Temperature); TFT_print(tmp, 220, y); sprintf(tmp, "%2d m", recipe.MashStep[i].Resttime); @@ -622,6 +622,8 @@ case 1: memset(&recipe, 0, sizeof(recipe)); recipe.Version = 1; + for (int i = 1; i < 8; i++) + recipe.MashStep[i].Type = MASHTYPE_TEMPERATURE; sprintf(recipe.Name, "Recipe %d", r_Records + 1); sprintf(recipe.Code, "00%d", r_Records + 1); sprintf(recipe.MashStep[0].Name, "Mash-in"); @@ -631,12 +633,10 @@ recipe.MashStep[0].Resttime = 1; recipe.MashStep[0].Ramptime = 1; sprintf(recipe.MashStep[1].Name, "Mash"); - recipe.MashStep[1].Type = MASHTYPE_TEMPERATURE; recipe.MashStep[1].Temperature = 67.0; recipe.MashStep[1].Resttime = 75; recipe.MashStep[1].Ramptime = 1; sprintf(recipe.MashStep[7].Name, "Mash-out"); - recipe.MashStep[7].Type = MASHTYPE_TEMPERATURE; recipe.MashStep[7].Temperature = 78.0; recipe.MashStep[7].Resttime = 5; recipe.MashStep[7].Ramptime = 11; @@ -715,6 +715,7 @@ for (int i = 1; i <= mashsteps; i++) { sprintf(tmp, "Maisch stap %d naam", i); EditText(tmp, recipe.MashStep[i].Name, 31); + EditMashType(&recipe.MashStep[i].Type); sprintf(tmp, "Maisch stap %d temperatuur", i); if (i == 1) mintemp = recipe.MashStep[0].Temperature - 5; @@ -729,6 +730,15 @@ } else { recipe.MashStep[i].Ramptime = (int)(recipe.MashStep[i].Temperature - recipe.MashStep[i - 1].Temperature); } + if (recipe.MashStep[i].Type == MASHTYPE_INFUSION) { + sprintf(tmp, "Stap %d infusie temperatuur", i); + mintemp = recipe.MashStep[i].Temperature; + EditFloat(tmp, &recipe.MashStep[i].Infusion_temp, mintemp, 100, 2); + sprintf(tmp, "Stap %d infusie volume", i); + EditFloat(tmp, &recipe.MashStep[i].Infusion_amount, 0.5, 1000.0, 2); + } else { + recipe.MashStep[i].Infusion_temp = recipe.MashStep[i].Infusion_amount = 0.0; + } } mintemp = recipe.MashStep[mashsteps].Temperature; EditFloat("Uitmaischen temperatuur", &recipe.MashStep[7].Temperature, mintemp, 80, 2);