The shield buttons are used to navigate between the different screens. After a period of inactivity, a timeout returns the system to the "Run" screen to display the current set-point (the temperature we desire) and current temperature of the bath. The states are as shown in the diagram below:
If you're working on a project that has a lot of stuff going on, drawing a state machine can be really useful to keep your head straight!
// ************************************************ // Main Control Loop // // All state changes pass through here // ************************************************ void loop() { // wait for button release before changing state while(ReadButtons() != 0) {} lcd.clear(); Serial.println(opState); switch (opState) { case OFF: Off(); break; case SETP: Tune_Sp(); break; case RUN: Run(); break; case TUNE_P: TuneP(); break; case TUNE_I: TuneI(); break; case TUNE_D: TuneD(); break; } }
The 5th button on the shield is used as a 'shift' key. When pressed simultaneously with the UP or DOWN keys, it increments or decrements by 10 instead of just 1. The other tuning screens work the same way.
// ************************************************ // Setpoint Entry State // UP/DOWN to change setpoint // RIGHT for tuning parameters // LEFT for OFF // SHIFT for 10x tuning // ************************************************ void Tune_Sp() { lcd.setBacklight(TEAL); lcd.print(F("Set Temperature:")); uint8_t buttons = 0; while(true) { buttons = ReadButtons(); float increment = 0.1; if (buttons & BUTTON_SHIFT) { increment *= 10; } if (buttons & BUTTON_LEFT) { opState = RUN; return; } if (buttons & BUTTON_RIGHT) { opState = TUNE_P; return; } if (buttons & BUTTON_UP) { Setpoint += increment; delay(200); } if (buttons & BUTTON_DOWN) { Setpoint -= increment; delay(200); } if ((millis() - lastInput) > 3000) // return to RUN after 3 seconds idle { opState = RUN; return; } lcd.setCursor(0,1); lcd.print(Setpoint); DoControl(); } }