-
-
Save SimonMerrett/9b855fcd34bd837698b692378b8d4a5b to your computer and use it in GitHub Desktop.
putting helper functions into headers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Actions library for thermometer | |
@created: 2020-05-16 | |
@author: Simon Merrett | |
@version: 0.2 | |
Source code link: #TODO: complete link when published | |
For changelog see actions.h | |
*/ | |
#include "actions.h" // associated header file for this cpp file | |
// #include "numbersIn.h" // actions::alarmLowLimit() and two others need access to e.g. NumberInputSystem::render() and others | |
//#include "thermDisplay.h" // actions::coolDownState() needs access to member Display::showOnOff(bool) | |
void Actions::digits() | |
{ | |
Serial.print(F("DISPLAY Current Temp = ")); | |
disp.printTemperatureDiv10(currentTempx10); | |
char u = temperature.getUnitSymbol(unit); | |
Serial.println(u); | |
if (button1Pressed) | |
{ | |
menuState = Option::graph; | |
} | |
if (button2Pressed) | |
{ | |
menuState = Option::units; | |
} | |
} | |
void Actions::graph() | |
{ | |
Serial.println(F("DISPLAY Graph")); | |
if (button1Pressed) | |
{ | |
menuState = (coolDownState) ? Option::countdown : Option::digits; | |
} | |
if (button2Pressed) | |
{ | |
menuState = Option::units; | |
} | |
} | |
void Actions::countdown() | |
{ | |
Serial.print(F("DISPLAY Count down remaining = ")); | |
Serial.println(countDownRemaining); | |
if (button1Pressed) | |
{ | |
menuState = Option::digits; | |
} | |
if (button2Pressed) | |
{ | |
menuState = Option::units; | |
} | |
} | |
void Actions::units() | |
{ | |
// show the current setting | |
Serial.print(F("MENU Units: ")); | |
Serial.println(printout = (static_cast<bool>(unit)) ? "Celsius" : "Farenheit"); | |
if (button2Pressed) | |
{ //TODO: deal with toggling bool | |
unit = static_cast<TempUnit>(1 - static_cast<bool>(unit));//!temperatureUnits; // toggle the variable | |
} | |
if (button1Pressed) | |
{ | |
menuState = Option::alarmOnOff; | |
} | |
} | |
void Actions::alarmOnOff() | |
{ | |
// show the current setting | |
Serial.print(F("MENU Alarm: ")); | |
disp.showOnOff(alarmState); | |
if (button2Pressed) | |
{ | |
alarmState = !alarmState; // toggle the setting | |
} | |
if (button1Pressed) | |
{ | |
menuState = (alarmState) ? Option::alarmLowLimit : Option::coolDownOnOff; | |
} | |
} | |
void Actions::alarmLowLimit() | |
{ | |
lowerLimitAlarmInput.render(); | |
if (button2Pressed) | |
lowerLimitAlarmInput.incrementDigit(); | |
if (button1Pressed) | |
{ | |
auto previous = lowerLimitAlarmInput.getDigit(); | |
lowerLimitAlarmInput.cycleDigit(); | |
auto current = lowerLimitAlarmInput.getDigit(); | |
if((previous == Digit::Tenths) && (current == Digit::Tens)) | |
menuState = Option::alarmHighLimit; | |
} | |
} | |
void Actions::alarmHighLimit() | |
{ | |
higherLimitAlarmInput.render(); | |
if (button2Pressed) | |
higherLimitAlarmInput.incrementDigit(); | |
if (button1Pressed) | |
{ | |
auto previous = higherLimitAlarmInput.getDigit(); | |
higherLimitAlarmInput.cycleDigit(); | |
auto current = higherLimitAlarmInput.getDigit(); | |
if((previous == Digit::Tenths) && (current == Digit::Tens)) | |
menuState = Option::coolDownOnOff; | |
} | |
} | |
void Actions::coolDownOnOff() | |
{ | |
Serial.print(F("MENU Cooldown counter: ")); // show the current setting | |
disp.showOnOff(coolDownState); | |
if (button2Pressed) | |
{ | |
coolDownState = !coolDownState; // toggle the setting | |
} | |
if (button1Pressed) | |
{ | |
menuState = (coolDownState) ? Option::coolDownTarget : Option::digits ; | |
} | |
} | |
void Actions::coolDownTarget() | |
{ | |
coolDownTargetInput.render(); | |
if (button2Pressed) | |
coolDownTargetInput.incrementDigit(); | |
if (button1Pressed) | |
{ | |
auto previous = coolDownTargetInput.getDigit(); | |
coolDownTargetInput.cycleDigit(); | |
auto current = coolDownTargetInput.getDigit(); | |
if((previous == Digit::Tenths) && (current == Digit::Tens)) | |
menuState = Option::digits; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Actions library for thermometer | |
@created: 2020-05-16 | |
@author: Simon Merrett | |
@version: 0.2 | |
Credits: thanks to @Pharap who provided many of the elements of this code and coached Simon Merrett hugely | |
Source code link: #TODO: complete link when published | |
Changelog: | |
- V0.2 works with thermDisplay.h and tempHelper.h to move some functions out of main.cpp | |
- capitalises class names for consistent C++ style | |
- V0.1 initial drafting, after moving to platformio | |
*/ | |
#ifndef ACTIONS_H | |
#define ACTIONS_H | |
#include <Arduino.h> // required for uint8_t to be recognised as a type | |
#include "numbersIn.h" // Actions::alarmLowLimit() and two others need access to e.g. NumberInputSystem::render() and others | |
#include "tempHelper.h" // Actions::digits() needs access to tempHelper::getUnitsSymbol(bool) | |
#include "thermDisplay.h" // Actions::digits() needs access to Display::printTemperatureDiv10(uint16_t) | |
// declare classes initialised elsewhere | |
class NumberInputSystem; // numbersIn.h | |
class Display; // thermDisplay.h | |
class TempHelper; // tempHelper.h | |
enum class Option : uint8_t | |
{ | |
digits, | |
graph, | |
countdown, | |
units, | |
alarmOnOff, | |
alarmLowLimit, | |
alarmHighLimit, | |
coolDownOnOff, | |
coolDownTarget, | |
}; | |
extern uint16_t currentTempx10; // dummy number for displaying digits | |
extern Option menuState; | |
extern TempUnit unit; | |
extern bool button1Pressed; | |
extern bool button2Pressed; | |
extern bool alarmState; // initialises that the alarm is off | |
extern bool coolDownState; // initialises to not showing or activating the countdown | |
extern uint8_t countDownRemaining; // dummy countdown variable | |
extern uint16_t alarmLowLimit; // equivalent to 10 * temperature, so 200 = 20.0 degrees Centigrade | |
extern uint16_t alarmHighLimit; // equivalent to 10 * temperature, so 200 = 20.0 degrees Centigrade | |
extern uint16_t coolingTarget; // equivalent to 10 * temperature, so 200 = 20.0 degrees Centigrade | |
extern const char* printout; // declare to hold values for printing later | |
extern NumberInputSystem lowerLimitAlarmInput; // declare instances that we want to use of the NumberInputSystem class | |
extern NumberInputSystem higherLimitAlarmInput;// declare instances that we want to use of the NumberInputSystem class | |
extern NumberInputSystem coolDownTargetInput; // declare instances that we want to use of the NumberInputSystem class | |
extern Display disp; // declare instances we want to use | |
extern TempHelper temperature; // declare instances we want to use | |
class Actions | |
{ | |
public: | |
void digits(); | |
void graph(); | |
void countdown(); | |
void units(); | |
void alarmOnOff(); | |
void alarmLowLimit(); | |
void alarmHighLimit(); | |
void coolDownOnOff(); | |
void coolDownTarget(); | |
} ; | |
#endif // ACTIONS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Menu Test for memory-limited microcontrollers | |
This aims to see how much memory is required to implement different techniques of providing a menu system | |
Credits: thanks to @Pharap who provided many of the elements of this code and coached Simon Merrett hugely | |
Changelog: | |
- V07 makes some changes to put things in more logical file locations, outside main.cpp | |
- V06 moves more of the main file into header files for readability (and one day, maintainability) | |
- V05 is purely a transition to platformio (change to .cpp etc) | |
- V04 fixes some issues that Pharap pointed out (assignment inside an expression) and moves towards separate files | |
- V03 moves from one single enum class to two enum classes, moves functions out of cases, uses the ternary operator, removes the floats (saving 1700B!) | |
- V02 adds some simulated behaviour, such as a (constant) current temperature value and adds menu state change functionality | |
- V01 changes some names for better readability and removes conditional compilation | |
*/ | |
#include <Arduino.h> | |
#include "actions.h" | |
#include "numbersIn.h" | |
#include "thermDisplay.h" | |
bool button1Pressed = false; // button state | |
bool button2Pressed = false; // button state | |
uint16_t currentTempx10 = 443; // dummy number for displaying digits | |
bool alarmState = false; // default that the alarm is off | |
bool coolDownState = false; // default to not showing or activating the countdown | |
uint8_t countDownRemaining = 255; // dummy countdown variable | |
uint16_t alarmLowLimit = 200; // equivalent to 10 * temperature, so 200 = 20.0 degrees Centigrade | |
uint16_t alarmHighLimit = 210; // equivalent to 10 * temperature, so 200 = 20.0 degrees Centigrade | |
uint16_t coolingTarget = 200; // equivalent to 10 * temperature, so 200 = 20.0 degrees Centigrade | |
const char* printout; // declare to hold values for printing later | |
// Initialise Arduino pin numbers | |
constexpr uint8_t button1 = 2; | |
constexpr uint8_t button2 = 3; | |
constexpr uint8_t led1 = 4; | |
constexpr uint8_t led2 = 5; | |
// Function prototypes | |
void buttonCheck(); | |
void Blink(uint8_t led); | |
Option menuState = Option::digits; // initialise the first state | |
TempUnit unit = TempUnit::celsius; // initialise the first unit | |
Actions act; // initialise an instance of the class `actions`, called `act` | |
NumberInputSystem lowerLimitAlarmInput { /*F("MENU Alarm lower limit: "), */ alarmLowLimit/*, Digit::Tens*/ }; // initialise an instance of the class `NumberInputSystem`, called `lowerLimitAlarmInput` | |
NumberInputSystem higherLimitAlarmInput {/* F("MENU Alarm upper limit: "),*/ alarmHighLimit/*, Digit::Tens*/ }; | |
NumberInputSystem coolDownTargetInput { /*F("MENU Cooldown target: "),*/ coolingTarget/*, Digit::Tens */}; | |
Display disp; // initialise instance of class 'display' | |
TempHelper temperature; // initialise instance of class 'tempHelper' | |
void setup() { | |
// set up serial monitor for output and user input | |
Serial.begin(115200); | |
// set up real buttons and state LEDs | |
pinMode(2, INPUT_PULLUP); | |
pinMode(3, INPUT_PULLUP); | |
pinMode(4, OUTPUT); | |
pinMode(5, OUTPUT); | |
// set the messages for the input prompts | |
lowerLimitAlarmInput.setMessage(F("MENU Alarm lower limit: ")); | |
higherLimitAlarmInput.setMessage(F("MENU Alarm upper limit: ")); | |
coolDownTargetInput.setMessage(F("MENU Cooldown target: ")); | |
} | |
void loop() { | |
switch (menuState) | |
{ | |
// display current reading in digits | |
case Option::digits: | |
act.digits(); | |
break; | |
// display graph of current and past readings | |
case Option::graph: | |
act.graph(); | |
break; | |
// display countdown estimate to target temperature | |
case Option::countdown: | |
act.countdown(); | |
break; | |
// let the user toggle between Centigrade and Farenheit | |
case Option::units: | |
act.units(); | |
break; | |
// let the user toggle between on and off | |
case Option::alarmOnOff: | |
act.alarmOnOff(); | |
break; | |
// set the value of the lower limit for the alarm | |
case Option::alarmLowLimit: | |
act.alarmLowLimit(); | |
break; | |
// set the value of the upper limit for the alarm | |
case Option::alarmHighLimit: | |
act.alarmHighLimit(); | |
break; | |
// let the user toggle between on and off | |
case Option::coolDownOnOff: | |
act.coolDownOnOff(); | |
break; | |
// let the user increment and select the cooling target temperature | |
case Option::coolDownTarget: | |
act.coolDownTarget(); | |
break; | |
} | |
buttonCheck(); | |
delay(100); | |
} | |
void buttonCheck() | |
{ | |
button1Pressed = 0; // reset so serial input can be used | |
button2Pressed = 0; // reset so serial input can be used | |
if ( Serial.available() ) | |
{ | |
char c = Serial.read(); | |
if ( c == '1') | |
{ | |
button1Pressed = 1; | |
Serial.println(F("Button 1 pressed")); | |
} | |
else if (c == '2') | |
{ | |
button2Pressed = 2; | |
Serial.println(F("Button 2 pressed")); | |
} | |
} | |
else // read hardware buttons | |
{ | |
button1Pressed = digitalRead(button1) == 0; | |
button2Pressed = digitalRead(button2) == 0; | |
} | |
if (button1Pressed) | |
{ | |
Blink(led1); | |
Serial.println(F("Button 1 pressed")); | |
} | |
if (button2Pressed) | |
{ | |
Blink(led2); | |
Serial.println(F("Button 2 pressed")); | |
} | |
} | |
void Blink(uint8_t led) | |
{ | |
digitalWrite(led, HIGH); | |
delay(100); | |
digitalWrite(led, LOW); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Value editing library for the thermometer. Handles the incrementing of digits in variables by using the buttons | |
@created: 2020-05-18 | |
@author: Simon Merrett | |
@version: 0.2 | |
Credits: thanks to @Pharap who provided many of the elements of this code and coached Simon Merrett hugely | |
Source code link: #TODO: complete link when published | |
Changelog: | |
- V0.2 refinement of header and cpp file structures and moving some functions into header files | |
- V0.1 initial drafting, after moving to platformio | |
*/ | |
#ifndef NUMBERSIN_H | |
#define NUMBERSIN_H | |
#include <Arduino.h> // required for uint8_t to be recognised as a type | |
#include "thermDisplay.h" | |
#include "tempHelper.h" | |
enum class Digit : uint8_t { | |
Tens, | |
Ones, | |
Tenths, | |
}; | |
class Display; | |
extern Display disp; // declare instances we want to use | |
class TempHelper; | |
extern TempHelper temperature; // declare instances we want to use | |
class NumberInputSystem | |
{ | |
private: | |
const __FlashStringHelper * message; | |
uint16_t & value; | |
Digit digit; | |
public: | |
NumberInputSystem(/*const __FlashStringHelper * message,*/ uint16_t & value) : /*message(message),*/ value(value), digit(Digit::Tens) {} | |
void setMessage(const __FlashStringHelper * m) | |
{ | |
message = m; | |
} | |
Digit getDigit() | |
{ | |
return this->digit; | |
} | |
void render() | |
{ | |
Serial.print(message); | |
disp.printTemperatureDiv10(this->value); | |
Serial.println(); | |
} | |
void incrementDigit() | |
{ | |
switch(this->digit) | |
{ | |
case Digit::Tens: | |
this->value = temperature.incrementTens(this->value); | |
break; | |
case Digit::Ones: | |
this->value = temperature.incrementOnes(this->value); | |
break; | |
case Digit::Tenths: | |
this->value = temperature.incrementTenths(this->value); | |
break; | |
} | |
} | |
void cycleDigit() | |
{ | |
switch(this->digit) | |
{ | |
case Digit::Tens: | |
this->digit = Digit::Ones; | |
break; | |
case Digit::Ones: | |
this->digit = Digit::Tenths; | |
break; | |
case Digit::Tenths: | |
this->digit = Digit::Tens; | |
break; | |
} | |
} | |
}; | |
#endif // NUMBERSIN_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* TempHelper class to provide temperature units and increment temperatures by digit (base 10). | |
@created: 2020-05-20 | |
@author: Simon Merrett | |
@version: 0.1 | |
Credits: thanks to @Pharap who provided many of the elements of this code and coached Simon Merrett hugely | |
Changelog: | |
- V0.1 initial creation to move enum class and functions out of main.cpp | |
*/ | |
#ifndef TEMPHELPER_H | |
#define TEMPHELPER_H | |
#include <Arduino.h> // required for uint8_t to be recognised as a type | |
enum class TempUnit : uint8_t | |
{ | |
farenheit, | |
celsius | |
}; | |
class TempHelper | |
{ | |
public: | |
char getUnitSymbol(TempUnit Unit) | |
{ | |
switch(Unit) | |
{ | |
case TempUnit::farenheit: | |
return 'F'; | |
case TempUnit::celsius: | |
return 'C'; | |
default: | |
return '?'; | |
} | |
}; | |
uint16_t incrementTens(uint16_t tensToIncrease) | |
{ | |
tensToIncrease = (tensToIncrease + 100) % 1000; // remember that 100 represents 10 degrees. Modulo keeps tensToIncrease in range | |
return tensToIncrease; | |
}; | |
uint16_t incrementOnes(uint16_t onesToIncrease) | |
{ | |
uint16_t strippedLimit = (onesToIncrease / 100) * 100 + onesToIncrease % 10; // take the 10's out of onesToIncrease, e.g 258 -> 208 | |
onesToIncrease = strippedLimit + 10 * ((1 + (onesToIncrease / 10) ) % 10); | |
return onesToIncrease; | |
}; | |
uint16_t incrementTenths(uint16_t tenthsToIncrease) | |
{ | |
uint16_t strippedLimit = (tenthsToIncrease / 10) * 10; // take the 1's out of alarmLowLimit, e.g 258 -> 250 | |
tenthsToIncrease = strippedLimit + ((1 + tenthsToIncrease ) % 10); | |
return tenthsToIncrease; | |
}; | |
}; | |
#endif //TEMPHELPER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* The Display class contains functions to print the temperature out. | |
@created: 2020-05-20 | |
@author: Simon Merrett | |
@version: 0.1 | |
Credits: thanks to @Pharap who provided many of the elements of this code and coached Simon Merrett hugely | |
*/ | |
#ifndef THERMDISPLAY_H | |
#define THERMDISPLAY_H | |
class Display | |
{ | |
public : | |
void showOnOff(bool var) | |
{ | |
String p = (var) ? F("ON") : F("OFF"); | |
Serial.println(p); | |
}; | |
void printTemperatureDiv10(uint16_t Tempx10) | |
{ | |
Serial.print(Tempx10 / 10); | |
Serial.print(F(".")); | |
Serial.print(Tempx10 % 10); | |
}; | |
void displayUpdate() | |
{ | |
// TODO: insert code to see if the screen needs to be changed | |
}; | |
}; | |
#endif // THERMDISPLAY_H | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment