From af5bee76f653704cb7fee29b630da74931d92abf Mon Sep 17 00:00:00 2001 From: Alastair Young Date: Sat, 11 Feb 2017 22:54:56 -0800 Subject: [PATCH] Add lcdPrintLIne_P() Move static lcd strings to PROGMEM to save about 550 bytes of SRAM Also clear a couple of minor compiler warnings. --- ControLeo2/examples/ReflowWizard/Bake.ino | 18 +++---- ControLeo2/examples/ReflowWizard/Config.ino | 37 ++++++------- ControLeo2/examples/ReflowWizard/Reflow.ino | 52 +++++++++---------- .../examples/ReflowWizard/ReflowWizard.ino | 18 +++++-- ControLeo2/examples/ReflowWizard/Testing.ino | 4 +- 5 files changed, 70 insertions(+), 59 deletions(-) diff --git a/ControLeo2/examples/ReflowWizard/Bake.ino b/ControLeo2/examples/ReflowWizard/Bake.ino index 7e8f6f8..127dd8b 100644 --- a/ControLeo2/examples/ReflowWizard/Bake.ino +++ b/ControLeo2/examples/ReflowWizard/Bake.ino @@ -30,19 +30,19 @@ boolean Bake() { // Read the temperature currentTemperature = getCurrentTemperature(); if (THERMOCOUPLE_FAULT(currentTemperature)) { - lcdPrintLine(0, "Thermocouple err"); + lcdPrintLine_P(0, PSTR("Thermocouple err")); Serial.print(F("Thermocouple Error: ")); switch ((int) currentTemperature) { case FAULT_OPEN: - lcdPrintLine(1, "Fault open"); + lcdPrintLine_P(1, PSTR("Fault open")); Serial.println(F("Fault open")); break; case FAULT_SHORT_GND: - lcdPrintLine(1, "Short to GND"); + lcdPrintLine_P(1, PSTR("Short to GND")); Serial.println(F("Short to ground")); break; case FAULT_SHORT_VCC: - lcdPrintLine(1, "Short to VCC"); + lcdPrintLine_P(1, PSTR("Short to VCC")); break; } @@ -55,8 +55,8 @@ boolean Bake() { // Abort the bake if a button is pressed if (getButton() != CONTROLEO_BUTTON_NONE) { bakePhase = BAKING_PHASE_ABORT; - lcdPrintLine(0, "Aborting bake"); - lcdPrintLine(1, "Button pressed"); + lcdPrintLine_P(0, PSTR("Aborting bake")); + lcdPrintLine_P(1, PSTR("Button pressed")); Serial.println(F("Button pressed. Aborting bake ...")); delay(2000); } @@ -81,8 +81,8 @@ boolean Bake() { if (isHeatingElement(outputType[i])) break; if (i == 4) { - lcdPrintLine(0, "Please configure"); - lcdPrintLine(1, " outputs first! "); + lcdPrintLine_P(0, PSTR("Please configure")); + lcdPrintLine_P(1, PSTR(" outputs first! ")); Serial.println(F("Outputs must be configured before baking")); // Abort the baking @@ -100,7 +100,7 @@ boolean Bake() { // Move to the next phase bakePhase = BAKING_PHASE_HEATUP; lcdPrintLine(0, bakingPhaseDescription[bakePhase]); - lcdPrintLine(1, ""); + lcdPrintLine_P(1, PSTR("")); // Start with a duty cycle proportional to the desired temperature bakeDutyCycle = map(bakeTemperature, 0, 250, 0, 100); diff --git a/ControLeo2/examples/ReflowWizard/Config.ino b/ControLeo2/examples/ReflowWizard/Config.ino index 1d62beb..62f0107 100644 --- a/ControLeo2/examples/ReflowWizard/Config.ino +++ b/ControLeo2/examples/ReflowWizard/Config.ino @@ -21,7 +21,7 @@ boolean Config() { case 0: // Set up the output types if (drawMenu) { drawMenu = false; - lcdPrintLine(0, "Dx is"); + lcdPrintLine_P(0, PSTR("Dx is")); lcd.setCursor(1, 0); lcd.print(output); type = getSetting(SETTING_D4_TYPE - 4 + output); @@ -58,8 +58,8 @@ boolean Config() { case 1: // Get the maximum temperature if (drawMenu) { drawMenu = false; - lcdPrintLine(0, "Max temperature"); - lcdPrintLine(1, "xxx\1C"); + lcdPrintLine_P(0, PSTR("Max temperature")); + lcdPrintLine_P(1, PSTR("xxx\1C")); maxTemperature = getSetting(SETTING_MAX_TEMPERATURE); displayMaxTemperature(maxTemperature); } @@ -84,8 +84,8 @@ boolean Config() { case 2: // Get the servo open and closed settings if (drawMenu) { drawMenu = false; - lcdPrintLine(0, "Door servo"); - lcdPrintLine(1, selectedServo == SETTING_SERVO_OPEN_DEGREES? "open:" : "closed:"); + lcdPrintLine_P(0, PSTR("Door servo")); + lcdPrintLine_P(1, selectedServo == SETTING_SERVO_OPEN_DEGREES? PSTR("open:") : PSTR("closed:")); servoDegrees = getSetting(selectedServo); displayServoDegrees(servoDegrees); // Move the servo to the saved position @@ -125,8 +125,8 @@ boolean Config() { case 3: // Get bake temperature if (drawMenu) { drawMenu = false; - lcdPrintLine(0, "Bake temperature"); - lcdPrintLine(1, ""); + lcdPrintLine_P(0, PSTR("Bake temperature")); + lcdPrintLine_P(1, PSTR("")); bakeTemperature = getSetting(SETTING_BAKE_TEMPERATURE); lcd.setCursor(0, 1); lcd.print(bakeTemperature); @@ -155,8 +155,8 @@ boolean Config() { case 4: // Get bake duration if (drawMenu) { drawMenu = false; - lcdPrintLine(0, "Bake duration"); - lcdPrintLine(1, ""); + lcdPrintLine_P(0, PSTR("Bake duration")); + lcdPrintLine_P(1, PSTR("")); bakeDuration = getSetting(SETTING_BAKE_DURATION); displayDuration(0, getBakeSeconds(bakeDuration)); } @@ -165,7 +165,8 @@ boolean Config() { switch (getButton()) { case CONTROLEO_BUTTON_TOP: // Increase the duration - bakeDuration = ++bakeDuration % BAKE_MAX_DURATION; + bakeDuration++; + bakeDuration %= BAKE_MAX_DURATION; displayDuration(0, getBakeSeconds(bakeDuration)); break; case CONTROLEO_BUTTON_BOTTOM: @@ -180,13 +181,13 @@ boolean Config() { if (drawMenu) { drawMenu = false; if (getSetting(SETTING_LEARNING_MODE) == false) { - lcdPrintLine(0, "Restart learning"); - lcdPrintLine(1, "mode? No ->"); + lcdPrintLine_P(0, PSTR("Restart learning")); + lcdPrintLine_P(1, PSTR("mode? No ->")); } else { - lcdPrintLine(0, "Oven is in"); - lcdPrintLine(1, "learning mode"); + lcdPrintLine_P(0, PSTR("Oven is in")); + lcdPrintLine_P(1, PSTR("learning mode")); } } @@ -206,16 +207,16 @@ boolean Config() { case 6: // Restore to factory settings if (drawMenu) { drawMenu = false; - lcdPrintLine(0, "Restore factory"); - lcdPrintLine(1, "settings? No ->"); + lcdPrintLine_P(0, PSTR("Restore factory")); + lcdPrintLine_P(1, PSTR("settings? No ->")); } // Was a button pressed? switch (getButton()) { case CONTROLEO_BUTTON_TOP: // Reset EEPROM to factory - lcdPrintLine(0, "Please wait ..."); - lcdPrintLine(1, ""); + lcdPrintLine_P(0, PSTR("Please wait ...")); + lcdPrintLine_P(1, PSTR("")); setSetting(SETTING_EEPROM_NEEDS_INIT, true); InitializeSettingsIfNeccessary(); diff --git a/ControLeo2/examples/ReflowWizard/Reflow.ino b/ControLeo2/examples/ReflowWizard/Reflow.ino index bf45449..908a2e4 100644 --- a/ControLeo2/examples/ReflowWizard/Reflow.ino +++ b/ControLeo2/examples/ReflowWizard/Reflow.ino @@ -37,19 +37,19 @@ boolean Reflow() { // Read the temperature currentTemperature = getCurrentTemperature(); if (THERMOCOUPLE_FAULT(currentTemperature)) { - lcdPrintLine(0, "Thermocouple err"); + lcdPrintLine_P(0, PSTR("Thermocouple err")); Serial.print(F("Thermocouple Error: ")); switch ((int) currentTemperature) { case FAULT_OPEN: - lcdPrintLine(1, "Fault open"); + lcdPrintLine_P(1, PSTR("Fault open")); Serial.println(F("Fault open")); break; case FAULT_SHORT_GND: - lcdPrintLine(1, "Short to GND"); + lcdPrintLine_P(1, PSTR("Short to GND")); Serial.println(F("Short to ground")); break; case FAULT_SHORT_VCC: - lcdPrintLine(1, "Short to VCC"); + lcdPrintLine_P(1, PSTR("Short to VCC")); break; } @@ -61,8 +61,8 @@ boolean Reflow() { // Abort the reflow if a button is pressed if (getButton() != CONTROLEO_BUTTON_NONE) { reflowPhase = PHASE_ABORT_REFLOW; - lcdPrintLine(0, "Aborting reflow"); - lcdPrintLine(1, "Button pressed"); + lcdPrintLine_P(0, PSTR("Aborting reflow")); + lcdPrintLine_P(1, PSTR("Button pressed")); Serial.println(F("Button pressed. Aborting reflow ...")); } @@ -72,8 +72,8 @@ boolean Reflow() { // Make sure the oven is cool. This makes for more predictable/reliable reflows and // gives the SSR's time to cool down a bit. if (currentTemperature > 50.0) { - lcdPrintLine(0, "Temp > 50\1C"); - lcdPrintLine(1, "Please wait..."); + lcdPrintLine_P(0, PSTR("Temp > 50\1C")); + lcdPrintLine_P(1, PSTR("Please wait...")); Serial.println(F("Oven too hot to start reflow. Please wait ...")); // Abort the reflow @@ -92,8 +92,8 @@ boolean Reflow() { if (isHeatingElement(outputType[i])) break; if (i == 4) { - lcdPrintLine(0, "Please configure"); - lcdPrintLine(1, " outputs first! "); + lcdPrintLine_P(0, PSTR("Please configure")); + lcdPrintLine_P(1, PSTR(" outputs first! ")); Serial.println(F("Outputs must be configured before reflow")); // Abort the reflow @@ -105,8 +105,8 @@ boolean Reflow() { if (getSetting(SETTING_SETTINGS_CHANGED) == true) { setSetting(SETTING_SETTINGS_CHANGED, false); // Tell the user that learning mode is being enabled - lcdPrintLine(0, "Settings changed"); - lcdPrintLine(1, "Initializing..."); + lcdPrintLine_P(0, PSTR("Settings changed")); + lcdPrintLine_P(1, PSTR("Initializing...")); Serial.println(F("Settings changed by user. Reinitializing element duty cycles and enabling learning mode ...")); // Turn learning mode on @@ -184,8 +184,8 @@ boolean Reflow() { } // Let the user know if learning mode is on if (learningMode) { - lcdPrintLine(0, "Learning Mode"); - lcdPrintLine(1, "is enabled"); + lcdPrintLine_P(0, PSTR("Learning Mode")); + lcdPrintLine_P(1, PSTR("is enabled")); Serial.println(F("Learning mode is enabled. Duty cycles may be adjusted automatically if necessary")); delay(3000); } @@ -193,7 +193,7 @@ boolean Reflow() { // Move to the next phase reflowPhase = PHASE_PRESOAK; lcdPrintLine(0, phaseDescription[reflowPhase]); - lcdPrintLine(1, ""); + lcdPrintLine_P(1, PSTR("")); // Display information about this phase serialDisplayPhaseData(reflowPhase, &phase[reflowPhase], outputType); @@ -236,7 +236,7 @@ boolean Reflow() { // Abort this run lcdPrintPhaseMessage(reflowPhase, "Too fast"); - lcdPrintLine(1, "Aborting ..."); + lcdPrintLine_P(1, PSTR("Aborting ...")); reflowPhase = PHASE_ABORT_REFLOW; displayAdjustmentsMadeContinue(false); @@ -294,7 +294,7 @@ boolean Reflow() { // Abort this run lcdPrintPhaseMessage(reflowPhase, "Too slow"); - lcdPrintLine(1, "Aborting ..."); + lcdPrintLine_P(1, PSTR("Aborting ...")); reflowPhase = PHASE_ABORT_REFLOW; displayAdjustmentsMadeContinue(false); } @@ -328,7 +328,7 @@ boolean Reflow() { phase[reflowPhase].phaseMaxDuration += 10; else { lcdPrintPhaseMessage(reflowPhase, "Too slow"); - lcdPrintLine(1, "Aborting ..."); + lcdPrintLine_P(1, PSTR("Aborting ...")); reflowPhase = PHASE_ABORT_REFLOW; Serial.println(F("Aborting reflow. Oven cannot reach required temperature!")); } @@ -367,8 +367,8 @@ boolean Reflow() { if (firstTimeInPhase) { firstTimeInPhase = false; // Update the display - lcdPrintLine(0, "Reflow"); - lcdPrintLine(1, " "); + lcdPrintLine_P(0, PSTR("Reflow")); + lcdPrintLine_P(1, PSTR(" ")); Serial.println(F("******* Phase: Waiting *******")); Serial.println(F("Turning all heating elements off ...")); // Make sure all the elements are off (keep convection fans on) @@ -400,7 +400,7 @@ boolean Reflow() { if (firstTimeInPhase) { firstTimeInPhase = false; // Update the display - lcdPrintLine(0, "Cool - open door"); + lcdPrintLine_P(0, PSTR("Cool - open door")); Serial.println(F("******* Phase: Cooling *******")); Serial.println(F("Open the oven door ...")); // If a servo is attached, use it to open the door over 10 seconds @@ -429,8 +429,8 @@ boolean Reflow() { if (firstTimeInPhase) { firstTimeInPhase = false; // Update the display - lcdPrintLine(0, "Okay to remove "); - lcdPrintLine(1, " boards"); + lcdPrintLine_P(0, PSTR("Okay to remove ")); + lcdPrintLine_P(1, PSTR(" boards")); // Play a tune to let the user know the boards can be removed playTones(TUNE_REMOVE_BOARDS); } @@ -441,8 +441,8 @@ boolean Reflow() { // Once the temperature drops below 50C a new reflow can be started if (currentTemperature < 50.0) { reflowPhase = PHASE_ABORT_REFLOW; - lcdPrintLine(0, "Reflow complete!"); - lcdPrintLine(1, " "); + lcdPrintLine_P(0, PSTR("Reflow complete!")); + lcdPrintLine_P(1, PSTR(" ")); } break; @@ -580,7 +580,7 @@ void displayAdjustmentsMadeContinue(boolean willContinue) { counterTemp += dir; return counterTemp; -/* if (diff[phase] > 0 && counterTemp > tempChange[phase]) + if (diff[phase] > 0 && counterTemp > tempChange[phase]) phase++; else if (diff[phase] < 0 && counterTemp < tempChange[phase]) phase++; diff --git a/ControLeo2/examples/ReflowWizard/ReflowWizard.ino b/ControLeo2/examples/ReflowWizard/ReflowWizard.ino index eb8095d..89f990e 100644 --- a/ControLeo2/examples/ReflowWizard/ReflowWizard.ino +++ b/ControLeo2/examples/ReflowWizard/ReflowWizard.ino @@ -146,8 +146,8 @@ void setup() { initializeTimer(); // Write the initial message on the LCD screen - lcdPrintLine(0, " ControLeo2"); - lcdPrintLine(1, "Reflow Oven v2.0"); + lcdPrintLine_P(0, PSTR(" ControLeo2")); + lcdPrintLine_P(1, PSTR("Reflow Oven v2.0")); delay(100); playTones(TUNE_STARTUP); delay(3000); @@ -185,7 +185,7 @@ void loop() if (drawMenu) { drawMenu = false; lcdPrintLine(0, modes[mode]); - lcdPrintLine(1, " Yes ->"); + lcdPrintLine_P(1, PSTR(" Yes ->")); } // Update the temperature roughtly once per second @@ -271,7 +271,17 @@ void lcdPrintLine(int line, const char* str) { strncpy(buffer, str, strlen(str)); lcd.print(buffer); } - +// Same as above using PROGMEM to save SRAM +// works with constant strings only +void lcdPrintLine_P(int line, const char* str) { + char buffer[17] = " "; + // Sanity check on the parameters + if (line < 0 || line > 1 || !str || strlen_P(str) > 16) + return; + lcd.setCursor(0, line); + strncpy_P(buffer, str, strlen_P(str)); + lcd.print(buffer); +} // Displays the temperature in the bottom left corner of the LCD display void displayTemperature(double temperature) { diff --git a/ControLeo2/examples/ReflowWizard/Testing.ino b/ControLeo2/examples/ReflowWizard/Testing.ino index 66defb2..8b24234 100644 --- a/ControLeo2/examples/ReflowWizard/Testing.ino +++ b/ControLeo2/examples/ReflowWizard/Testing.ino @@ -14,8 +14,8 @@ boolean Testing() { // Is this the first time "Testing" has been run? if (firstRun) { firstRun = false; - lcdPrintLine(0, "Test Outputs"); - lcdPrintLine(1, "Output 4"); + lcdPrintLine_P(0, PSTR("Test Outputs")); + lcdPrintLine_P(1, PSTR("Output 4")); displayOnState(channelIsOn); }