Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /* Copyright (c) 2017 Philippe Kalaf, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 // Espresso Machine Mods 00020 // --------------------- 00021 // Hardware 00022 // -------- 00023 // Boiler temperature sensor (x2) 00024 // Brewing pressure sensor 00025 // Flowmeter 00026 // Solenoid control 00027 00028 // Software 00029 // -------- 00030 // PID temperature control (back-flush for temperature reduction) 00031 // pressure control (phase control) 00032 // auto-shot clock 00033 // auto-shot volume 00034 // auto-flowrate on fixed shot clock and shot volume 00035 // manual mode 00036 // brew soft-stop 00037 // pre-infusion 00038 00039 #include "mbed.h" 00040 #include "rtos.h" 00041 #include "Small_6.h" 00042 #include "Small_7.h" 00043 #include "Arial_9.h" 00044 #include "Arial12x12.h" 00045 #include "Arial24x23.h" 00046 #include "stdio.h" 00047 #include "C12832_lcd.h" 00048 #include "string" 00049 #include "brewcontrol.h" 00050 00051 #if MBED_HEAP_STATS_ENABLED || MBED_STACK_STATS_ENABLED 00052 #include "platform/mbed_stats.h" 00053 #endif 00054 00055 // This is for debugging and control without a LCD/joystick 00056 Serial pc(USBTX, USBRX); // tx, rx 00057 00058 // LCD object 00059 C12832_LCD LCD; 00060 00061 // Menu display thread 00062 Thread menu_thread(osPriorityNormal, 1024); 00063 00064 // mutex for heap between main and menu_handler threads 00065 Mutex heap_mutex; 00066 00067 // Joystick for menu control 00068 InterruptIn Fire(p9); // JS_PUSH 00069 InterruptIn Up(p30); // JS_UP 00070 InterruptIn Down(p29); // JS_DOWN 00071 InterruptIn Left(p28); // JS_LEFT 00072 InterruptIn Right(p27); // JS_RIGHT 00073 00074 // This is used to ignore double clicks 00075 Timer js_timer; 00076 00077 // Timer for power saving mode 00078 Timer power_save_timer; 00079 bool power_save; 00080 #define POWER_SAVE_TIMEOUT_S 600 00081 00082 // Main Brew Control class holding all brewing features and logic 00083 // parameters are (in order): 00084 // valve/zcd/pump power control (VALVE_CTRL) 00085 // flow sensor input pin (FLOW_IN) 00086 // ZDC detector input (ZCD_IN) 00087 // pump phasecontrol signal (PUMP_CTRL) 00088 // pressure sensor (PRESSURE_IN) 00089 // side temperature sensor (TEMP_IN) 00090 // top temperature sensor (TEMP2_IN) 00091 // boiler control ssr (BOILER_CTRL) 00092 BrewControl brew_control(p10, p15, p12, p13, p20, p25, p14, p26); 00093 00094 // Menu structures 00095 // 00096 // TODO portafilter size 00097 // TODO powersaving 00098 #define PRE_INFUSE_TIME 0 00099 #define PRESSURE 1 00100 #define YIELD 2 00101 #define SHOT_TIME 3 00102 #define TEMPERATURE 4 00103 #define FLOW_RATE 5 00104 #define EMPTY 6 00105 00106 #define L_STANDBY 0 00107 #define L_MENU 1 00108 #define L_MENU_SUB 2 00109 #define L_BREW 3 00110 00111 #define M_BREW_SETTINGS 0 00112 #define M_BREW_TIME MODE_TIME 00113 #define M_BREW_YIELD MODE_YIELD 00114 #define M_BREW_TIME_YIELD MODE_TIME_YIELD 00115 #define M_BREW_MANUAL MODE_MANUAL 00116 #define M_BREW_STEAM MODE_STEAM 00117 00118 #define NUM_BREW_MENUS 6 00119 00120 const char* MENU_TITLES[NUM_BREW_MENUS]= { 00121 "Brew Settings", 00122 "Brew Set Time", 00123 "Brew Set Yield", 00124 "Brew Set Time/Yield", 00125 "Manual Brew", 00126 "Steam" 00127 }; 00128 00129 const uint8_t MENU_ITEMS[NUM_BREW_MENUS][5]= { 00130 {1, 3, TEMPERATURE, PRE_INFUSE_TIME, PRESSURE}, 00131 {1, 1, SHOT_TIME, EMPTY, EMPTY}, 00132 {1, 1, YIELD, EMPTY, EMPTY}, 00133 {1, 2, YIELD, SHOT_TIME, EMPTY}, 00134 {1, 0, EMPTY, EMPTY, EMPTY}, // stub for manual brew (no sub menu) 00135 {1, 0, EMPTY, EMPTY, EMPTY} // stub for steam (no sub menu) 00136 }; 00137 00138 const char* ITEM_STRINGS[7]= { 00139 "Pre-Infuse Time (s): ", 00140 "Pressure (bar): ", 00141 "Yield (ml): ", 00142 "Shot Time (s): ", 00143 "Temperature (C): ", 00144 "Flow rate (dl/s): ", 00145 "" 00146 }; 00147 00148 uint8_t brew_params[NUM_BREW_MENUS][3][3]= { 00149 { {92, 1, 9}, {0, 0, 0}, {0, 0, 0} }, 00150 { {28, 0, 0}, {0, 0, 0}, {0, 0, 0} }, 00151 { {55, 0, 0}, {0, 0, 0}, {0, 0, 0} }, 00152 { {55, 28, 0}, {55, 28, 0}, {55, 28, 0} }, 00153 { {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }, // stub for manual brew (no sub menu) 00154 { {0, 0, 0}, {0, 0, 0}, {0, 0, 0} } // stub for steam (no sub menu) 00155 }; 00156 00157 #define LEFT static_cast<int>(1 << 0) 00158 #define UP static_cast<int>(1 << 1) 00159 #define RIGHT static_cast<int>(1 << 2) 00160 #define DOWN static_cast<int>(1 << 3) 00161 #define FIRE static_cast<int>(1 << 4) 00162 00163 uint8_t active_menu = 0; 00164 uint8_t menu_level = L_STANDBY; 00165 00166 // 0 means not in edit mode - 1 to 9 are positions on a 3x3 square 00167 uint8_t edit_mode = 0; 00168 const uint8_t conversion_table[9][2] = { 00169 {0, 0}, {1, 0}, {2, 0}, 00170 {0, 1}, {1, 1}, {2, 1}, 00171 {0, 2}, {1, 2}, {2, 2} 00172 }; 00173 00174 #define MAIN_LOOP_PERIOD_MS 500 00175 00176 // takes the params from given menu and give thems to brew control 00177 void set_params(uint8_t menu_id) 00178 { 00179 if (menu_id == M_BREW_MANUAL) 00180 { 00181 brew_control.set_shot_volume(0); 00182 brew_control.set_shot_time(0); 00183 brew_control.set_preinfuse_time(0); 00184 return; 00185 } 00186 uint8_t i; 00187 for(i = 0; i < MENU_ITEMS[menu_id][1]; i++) { 00188 switch (MENU_ITEMS[menu_id][i+2]) 00189 { 00190 case PRE_INFUSE_TIME: 00191 brew_control.set_preinfuse_time( 00192 brew_params[menu_id][0][i]); 00193 break; 00194 case YIELD: brew_control.set_shot_volume( 00195 brew_params[menu_id][0][i]); 00196 break; 00197 case SHOT_TIME: brew_control.set_shot_time( 00198 brew_params[menu_id][0][i]); 00199 break; 00200 case TEMPERATURE: brew_control.set_shot_temperature( 00201 brew_params[menu_id][0][i]); 00202 break; 00203 case FLOW_RATE: brew_control.set_shot_flow_rate( 00204 float(brew_params[menu_id][0][i]/10)); 00205 break; 00206 case PRESSURE: brew_control.set_shot_pressure( 00207 brew_params[menu_id][0][i]); 00208 break; 00209 } 00210 } 00211 } 00212 00213 // Draw menu 00214 void draw_menu() 00215 { 00216 uint8_t i, j; 00217 uint8_t state; 00218 string out_s; 00219 // clear screen if required & set 00220 LCD.cls(); 00221 LCD.invert(0); 00222 00223 // Draw standby and brew specific info 00224 if (menu_level == L_STANDBY || menu_level == L_BREW) { 00225 state = brew_control.get_state(); 00226 00227 // Draw brew screen 00228 LCD.set_font((unsigned char*) Small_6); 00229 if (menu_level == L_BREW) 00230 { 00231 // Invert screen while brewing or steaming 00232 if (state != STOPPED) 00233 LCD.invert(1); 00234 if (active_menu == M_BREW_MANUAL) 00235 { 00236 LCD.locate(5,16); 00237 LCD.printf("MANUAL"); 00238 LCD.locate(9,23); 00239 LCD.printf("BREW"); 00240 } 00241 else if (active_menu == M_BREW_TIME) 00242 { 00243 LCD.locate(5,16); 00244 LCD.printf("TIME"); 00245 } 00246 else if (active_menu == M_BREW_YIELD) 00247 { 00248 LCD.locate(4,16); 00249 LCD.printf("YIELD"); 00250 } 00251 else if (active_menu == M_BREW_TIME_YIELD) 00252 { 00253 LCD.locate(2,16); 00254 LCD.printf("FLOWRATE"); 00255 } 00256 else if (active_menu == M_BREW_STEAM) 00257 { 00258 LCD.locate(4,16); 00259 LCD.printf("STEAM"); 00260 } 00261 if (state == BREWING) 00262 { 00263 LCD.locate(5,23); 00264 if (active_menu == M_BREW_STEAM) 00265 LCD.printf("HOT"); 00266 else 00267 LCD.printf("BREW"); 00268 } 00269 else if (state == PRE_INFUSING) 00270 { 00271 LCD.locate(2,23); 00272 LCD.printf("PRE-INFUSE"); 00273 } 00274 else if (state == SOFT_STOPPING) 00275 { 00276 LCD.locate(2,23); 00277 LCD.printf("SOFT-STOP"); 00278 } 00279 } 00280 // Draw standby screen 00281 else 00282 { 00283 if (power_save) 00284 { 00285 LCD.locate(5,17); 00286 LCD.printf("POWER"); 00287 LCD.locate(5,24); 00288 LCD.printf("STANDBY"); 00289 } 00290 else 00291 { 00292 LCD.locate(5,19); 00293 LCD.printf("STANDBY"); 00294 } 00295 } 00296 00297 // Draw common area (metrics) 00298 LCD.locate(4,4); 00299 LCD.set_font((unsigned char*) Arial12x12); 00300 if (state == SOFT_STOPPING) 00301 LCD.printf("Av, pressure: %.1f bar", 00302 brew_control.get_average_pressure()); 00303 else 00304 LCD.printf("%.1fC %.1fbar %.1fml/s", 00305 brew_control.get_current_temperature(), 00306 brew_control.get_current_pressure(), 00307 brew_control.get_current_flow_rate()); 00308 LCD.locate(55,17); 00309 LCD.printf("%.0f ml %.0f s", 00310 brew_control.get_current_volume(), 00311 brew_control.get_current_time()); 00312 } 00313 00314 // Draw first level menu (brew modes) 00315 else if (menu_level == L_MENU) { 00316 LCD.locate(0,12); 00317 LCD.set_font((unsigned char*) Arial12x12); 00318 LCD.printf("%s ", MENU_TITLES[active_menu]); 00319 } 00320 00321 // Draw second level menu (brew parameters) 00322 else if (menu_level == L_MENU_SUB) { 00323 out_s.clear(); 00324 // Display all menu items 00325 for(i = 2; i < sizeof(MENU_ITEMS[active_menu])/sizeof(*MENU_ITEMS[active_menu]); i++) { 00326 // Get the type of current menu item (T, P, Y or ST) 00327 int idx = MENU_ITEMS[active_menu][i]; 00328 char default_n[8]; 00329 // break out if we have an empty element 00330 if (idx == EMPTY) 00331 break; 00332 out_s += ITEM_STRINGS[idx]; 00333 // For each menu item, get all the parameters (either 1 or 3) 00334 for (j = 0; j < MENU_ITEMS[active_menu][0]; j++) { 00335 // Add brackets if edit selection is over current parameter 00336 if (edit_mode == (i-2)*3+(j+1)) 00337 sprintf(default_n, "[%d]", brew_params[active_menu][j][i-2]); 00338 else 00339 sprintf(default_n, "%d", brew_params[active_menu][j][i-2]); 00340 out_s += default_n; 00341 out_s += " "; 00342 } 00343 out_s += '\n'; 00344 } 00345 // Set position and font size based on number of parameters 00346 if (MENU_ITEMS[active_menu][1] == 1) 00347 { 00348 LCD.set_font((unsigned char*) Arial12x12); 00349 LCD.locate(0,12); 00350 } 00351 else if (MENU_ITEMS[active_menu][1] == 2) 00352 { 00353 LCD.set_font((unsigned char*) Arial12x12); 00354 LCD.locate(0,6); 00355 } 00356 else 00357 { 00358 LCD.set_font((unsigned char*) Small_7); 00359 LCD.locate(0,2); 00360 } 00361 LCD.printf("%s", out_s.c_str()); 00362 } 00363 } 00364 00365 void enter_power_save() 00366 { 00367 // let's disable PID temperature control 00368 brew_control.disable_boiler(); 00369 // turn on LCD power saving 00370 //LCD.power_save(1); 00371 00372 power_save = 1; 00373 menu_level = L_STANDBY; 00374 } 00375 00376 void exit_power_save() 00377 { 00378 power_save = 0; 00379 power_save_timer.reset(); 00380 // enabled PID temperature control 00381 brew_control.enable_boiler(); 00382 // turn off LCD power saving 00383 //LCD.power_save(0); 00384 } 00385 00386 // should get called everytime a power saving reset event happens 00387 void check_power_save() 00388 { 00389 if(power_save) 00390 exit_power_save(); 00391 else 00392 power_save_timer.reset(); 00393 } 00394 00395 // This thread waits for joystick commands, then sets parameters and then draws the menu 00396 void menu_handler() 00397 { 00398 while(true) { 00399 // wait on joystick action 00400 uint32_t flags = ThisThread::flags_wait_any_for(LEFT | UP | RIGHT | DOWN | FIRE, 500); 00401 00402 heap_mutex.lock(); 00403 // Flags should return osFlagsErrorTimeout but it's returning 0... 00404 if (!flags) 00405 { 00406 draw_menu(); 00407 heap_mutex.unlock(); 00408 continue; 00409 } 00410 else 00411 { 00412 check_power_save(); 00413 } 00414 00415 // fire 00416 if (flags == FIRE) { 00417 switch (menu_level) 00418 { 00419 case L_STANDBY: break; 00420 case L_MENU: break; 00421 case L_MENU_SUB: if(!edit_mode) 00422 // enter edit mode 00423 edit_mode = 1; 00424 else 00425 // exit edit mode 00426 edit_mode = 0; 00427 break; 00428 case L_BREW: // send params to brew control b4 brewing 00429 if(brew_control.get_state() == STOPPED) 00430 { 00431 // set general settings 00432 set_params(M_BREW_SETTINGS); 00433 // set brew mode settings 00434 set_params(active_menu); 00435 } 00436 brew_control.toggle(active_menu); 00437 break; 00438 } 00439 } 00440 // left 00441 else if (flags == LEFT) { 00442 switch (menu_level) 00443 { 00444 case L_STANDBY: break; 00445 case L_MENU: menu_level = L_STANDBY; break; 00446 case L_MENU_SUB: if(!edit_mode) 00447 { 00448 menu_level = L_MENU; 00449 // if we exiting settings, let's set them 00450 if(active_menu == M_BREW_SETTINGS) 00451 set_params(active_menu); 00452 } 00453 else 00454 brew_params[active_menu] 00455 [conversion_table[edit_mode-1][0]] 00456 [conversion_table[edit_mode-1][1]]--; 00457 break; 00458 case L_BREW: // skip sub-menu for manual or steam mode 00459 if(active_menu == M_BREW_MANUAL || active_menu == M_BREW_STEAM) 00460 menu_level = L_MENU; 00461 // only exit brew menu if not in brewing mode 00462 else if(brew_control.get_state() == STOPPED) 00463 menu_level = L_MENU_SUB; 00464 break; 00465 } 00466 } 00467 // up 00468 else if (flags == UP) { 00469 switch (menu_level) 00470 { 00471 case L_STANDBY: menu_level = L_MENU; break; 00472 case L_MENU: active_menu = (!active_menu)?active_menu:active_menu-1; 00473 break; 00474 case L_MENU_SUB: if(edit_mode > 1) 00475 // sub 1 or 3 based on number of phases 00476 edit_mode -= (MENU_ITEMS[active_menu][0] == 1)?3:1; 00477 break; 00478 case L_BREW: if(active_menu == M_BREW_MANUAL) 00479 brew_control.pressure_up(5); 00480 break; 00481 } 00482 } 00483 // right 00484 else if (flags == RIGHT) { 00485 switch (menu_level) 00486 { 00487 case L_STANDBY: menu_level = L_MENU; break; 00488 case L_MENU: if(active_menu == M_BREW_MANUAL 00489 || active_menu == M_BREW_STEAM) 00490 // skip sub-menu for manual mode 00491 menu_level = L_BREW; 00492 else 00493 menu_level = L_MENU_SUB; 00494 break; 00495 case L_MENU_SUB: if(!edit_mode && active_menu != M_BREW_SETTINGS) 00496 { 00497 menu_level = L_BREW; 00498 } 00499 else 00500 brew_params[active_menu] 00501 [conversion_table[edit_mode-1][0]] 00502 [conversion_table[edit_mode-1][1]]++; 00503 break; 00504 case L_BREW: if(brew_control.get_state() == PRE_INFUSING) 00505 brew_control.stop_preinfuse_now(); 00506 break; 00507 } 00508 } 00509 // down 00510 else if (flags == DOWN) { 00511 switch (menu_level) 00512 { 00513 case L_STANDBY: menu_level = L_MENU; break; 00514 case L_MENU: active_menu = (active_menu < NUM_BREW_MENUS-1)?active_menu+1:active_menu; 00515 break; 00516 case L_MENU_SUB: if(edit_mode < (MENU_ITEMS[active_menu][1]-1)*3 00517 && edit_mode > 0) 00518 // move fwd by 1 or 3 based on number of phases 00519 edit_mode += (MENU_ITEMS[active_menu][0] == 1)?3:1; 00520 break; 00521 case L_BREW: if(active_menu == M_BREW_MANUAL) 00522 brew_control.pressure_down(5); 00523 break; 00524 } 00525 } 00526 00527 // draw next menu 00528 draw_menu(); 00529 heap_mutex.unlock(); 00530 } 00531 } 00532 00533 // timer to ignore double clicks 00534 bool check_js_timer() 00535 { 00536 if(js_timer.read_ms() < 250) 00537 { 00538 js_timer.reset(); 00539 return 0; 00540 } 00541 else 00542 { 00543 js_timer.reset(); 00544 return 1; 00545 } 00546 } 00547 00548 // Joystick ISRs just send signals to unblock menu thread 00549 void cycle_up() 00550 { 00551 if(check_js_timer()) 00552 menu_thread.flags_set(UP); 00553 } 00554 void cycle_down() 00555 { 00556 if(check_js_timer()) 00557 menu_thread.flags_set(DOWN); 00558 } 00559 void cycle_left() 00560 { 00561 if(check_js_timer()) 00562 menu_thread.flags_set(LEFT); 00563 } 00564 void cycle_right() 00565 { 00566 if(check_js_timer()) 00567 menu_thread.flags_set(RIGHT); 00568 } 00569 void fire_away() 00570 { 00571 if(check_js_timer()) 00572 menu_thread.flags_set(FIRE); 00573 } 00574 00575 00576 #if MBED_HEAP_STATS_ENABLED 00577 void print_heap_stats() 00578 { 00579 mbed_stats_heap_t heap_info; 00580 pc.printf("\nMemoryStats:"); 00581 mbed_stats_heap_get( &heap_info ); 00582 pc.printf("\n\tBytes allocated currently: %d", heap_info.current_size); 00583 pc.printf("\n\tMax bytes allocated at a given time: %d", heap_info.max_size); 00584 pc.printf("\n\tCumulative sum of bytes ever allocated: %d", heap_info.total_size); 00585 pc.printf("\n\tCurrent number of bytes allocated for the heap: %d", heap_info.reserved_size); 00586 pc.printf("\n\tCurrent number of allocations: %d", heap_info.alloc_cnt); 00587 pc.printf("\n\tNumber of failed allocations: %d", heap_info.alloc_fail_cnt); 00588 } 00589 #endif 00590 00591 #if MBED_STACK_STATS_ENABLED 00592 void print_stack_stats() 00593 { 00594 mbed_stats_stack_t stack_info[ 10 ]; 00595 mbed_stats_stack_get( &stack_info[0] ); 00596 pc.printf("\nCumulative Stack Info:"); 00597 pc.printf("\n\tMaximum number of bytes used on the stack: %d", stack_info[0].max_size); 00598 pc.printf("\n\tCurrent number of bytes allocated for the stack: %d", stack_info[0].reserved_size); 00599 pc.printf("\n\tNumber of stacks stats accumulated in the structure: %d", stack_info[0].stack_cnt); 00600 00601 mbed_stats_stack_get_each( stack_info, 10 ); 00602 pc.printf("\nThread Stack Info:"); 00603 for(int i=0;i < 10; i++) { 00604 if(stack_info[i].thread_id != 0) { 00605 pc.printf("\n\tThread: %d", i); 00606 pc.printf("\n\t\tThread Id: 0x%08X", stack_info[i].thread_id); 00607 pc.printf("\n\t\tMaximum number of bytes used on the stack: %d", stack_info[i].max_size); 00608 pc.printf("\n\t\tCurrent number of bytes allocated for the stack: %d", stack_info[i].reserved_size); 00609 pc.printf("\n\t\tNumber of stacks stats accumulated in the structure: %d", stack_info[i].stack_cnt); 00610 } 00611 } 00612 } 00613 #endif 00614 00615 // print the actual contrast 00616 int main() 00617 { 00618 pc.baud(115200); 00619 00620 // Initialize default mode - 60ml shots 00621 int target_volume = 60; 00622 brew_control.set_shot_volume(target_volume); 00623 js_timer.start(); 00624 00625 power_save_timer.start(); 00626 power_save = 0; 00627 00628 // We want to call the menu_handler in another thread 00629 menu_thread.start(callback(menu_handler)); 00630 00631 // Attach joystick ISR callbacks 00632 Up.rise(&cycle_up); 00633 Down.rise(&cycle_down); 00634 Left.rise(&cycle_left); 00635 Right.rise(&cycle_right); 00636 Fire.rise(&fire_away); 00637 00638 // This loop will use the main thread to get commands from ttyUSB 00639 // it will also display debug/status info on ttyUSB 00640 while(true) { 00641 #if 1 00642 if (pc.readable()) { 00643 char c = pc.getc(); 00644 heap_mutex.lock(); 00645 00646 // Menu navigation from ttyUSB 00647 if(c == 'i') 00648 cycle_up(); 00649 else if(c == 'j') 00650 cycle_left(); 00651 else if(c == 'k') 00652 cycle_down(); 00653 else if(c == 'l') 00654 cycle_right(); 00655 else if(c == 'm') 00656 fire_away(); 00657 00658 // b for Manual Brew Toggle 00659 else if(c == 'b') 00660 { 00661 brew_control.set_shot_volume(0); 00662 brew_control.set_shot_time(0); 00663 brew_control.toggle(MODE_MANUAL); 00664 pc.printf("brew to %d\n", brew_control.get_state()); 00665 } 00666 00667 // q and a to control target pressure 00668 else if(c == 'q') 00669 { 00670 brew_control.pressure_up(); 00671 } 00672 else if(c == 'a') 00673 { 00674 brew_control.pressure_down(); 00675 } 00676 00677 // z for Automatic Volume Brew 00678 else if(c == 'z') 00679 { 00680 brew_control.set_shot_volume(target_volume); 00681 brew_control.start(MODE_YIELD); 00682 } 00683 00684 // w and s to set target temperature 00685 else if (c == 'w') 00686 { 00687 brew_control.set_shot_temperature(brew_control.get_shot_temperature() + 0.5); 00688 pc.printf("Temp set to %.1f\n", brew_control.get_shot_temperature()); 00689 } 00690 else if (c == 's') 00691 { 00692 brew_control.set_shot_temperature(brew_control.get_shot_temperature() - 0.5); 00693 pc.printf("Temp set to %.1f\n", brew_control.get_shot_temperature()); 00694 } 00695 00696 // e and d to set pre-infuse time 00697 else if (c == 'e') 00698 { 00699 brew_control.set_preinfuse_time(brew_control.get_preinfuse_time() + 1); 00700 pc.printf("Pre-Infuse set to %d seconds\n", brew_control.get_preinfuse_time()); 00701 } 00702 else if (c == 'd') 00703 { 00704 brew_control.set_preinfuse_time(brew_control.get_preinfuse_time() - 1); 00705 pc.printf("Pre-Infuse set to %d seconds\n", brew_control.get_preinfuse_time()); 00706 } 00707 00708 // r and f to set target shot volume 00709 else if (c == 'r') 00710 { 00711 target_volume = brew_control.get_shot_volume() + 5; 00712 brew_control.set_shot_volume(target_volume); 00713 pc.printf("Target Volume set to %d\n", target_volume); 00714 } 00715 else if (c == 'f') 00716 { 00717 target_volume = brew_control.get_shot_volume() - 5; 00718 brew_control.set_shot_volume(target_volume); 00719 pc.printf("Target Volume set to %d\n", target_volume); 00720 } 00721 00722 // p to toggle PID control (if off there will be no heating at all) 00723 else if (c == 'p') 00724 { 00725 if (brew_control.toggle_boiler()) 00726 pc.printf("Enabling PID\n"); 00727 else 00728 pc.printf("Disabling PID\n"); 00729 } 00730 else if (c == '=') 00731 brew_control.toggle_solenoid(); 00732 00733 heap_mutex.unlock(); 00734 } 00735 /* 00736 pc.printf("%d %.3f ml %.2f bar %.1f C %.1f C %.1f s %.2f ml/s\n", 00737 brew_control.get_pump_level(), 00738 brew_control.get_current_volume(), 00739 brew_control.get_current_pressure(), 00740 brew_control.get_current_temperature_side(), 00741 brew_control.get_current_temperature_top(), 00742 brew_control.get_current_time(), 00743 brew_control.get_current_flow_rate()); 00744 */ 00745 00746 pc.printf("%.1f, %.1f, %.1f, %d, %.2f, %.2f, %.2f, %d\n", 00747 brew_control.get_current_time(), 00748 brew_control.get_current_temperature_side(), 00749 brew_control.get_current_temperature_top(), 00750 brew_control.get_pump_level(), 00751 brew_control.get_current_pressure(), 00752 brew_control.get_current_volume(), 00753 brew_control.get_current_flow_rate(), 00754 brew_control.get_state()); 00755 00756 #if MBED_HEAP_STATS_ENABLED 00757 print_heap_stats(); 00758 #endif 00759 00760 #if MBED_STACK_STATS_ENABLED 00761 print_stack_stats(); 00762 #endif 00763 00764 #endif 00765 00766 heap_mutex.lock(); 00767 // If there has been no keypress for POWER_SAVE_TIMEOUT_S, go to powersaving mode 00768 if (power_save_timer.read() > POWER_SAVE_TIMEOUT_S) 00769 enter_power_save(); 00770 heap_mutex.unlock(); 00771 00772 ThisThread::sleep_for(MAIN_LOOP_PERIOD_MS); // wait 0.1s 00773 } 00774 00775 }
Generated on Thu Jul 14 2022 00:36:34 by
1.7.2