-
-
Save SimonMerrett/bdc6985e4abe5b38a7c09fd95926f557 to your computer and use it in GitHub Desktop.
move NumberInputSystem from main.cpp to Actions class
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.3 | |
Source code link: #TODO: complete link when published | |
For changelog see actions.h | |
*/ | |
#include "actions.h" // associated header file for this cpp file | |
// Class constructor with parameter-filled initialisations of the other classes we want made | |
Actions::Actions() : lowerLimitAlarmInput ( lowerLimitAlarmText, alarmLowSetting), | |
higherLimitAlarmInput ( higherLimitAlarmText, alarmHighSetting), | |
coolDownTargetInput ( coolDownTargetText, coolingTarget) | |
{} | |
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.3 moves the NumberInputSystem instances to the Actions constructor (Phew!) | |
- 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 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 uint8_t countDownRemaining; // dummy countdown variable | |
const char lowerLimitAlarmText[] = "MENU Alarm lower limit: "; | |
const char higherLimitAlarmText[] = "MENU Alarm upper limit: "; | |
const char coolDownTargetText[] = "MENU Cooling target: "; | |
extern Display disp; // declare instances we want to use | |
extern TempHelper temperature; // declare instances we want to use | |
class Actions | |
{ | |
bool alarmState = false; // default that the alarm is off | |
bool coolDownState = false; // default to not showing or activating the countdown | |
uint16_t alarmLowSetting = 200; // equivalent to 10 * temperature, so 200 = 20.0 degrees Centigrade | |
uint16_t alarmHighSetting = 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 | |
public: | |
NumberInputSystem lowerLimitAlarmInput; | |
NumberInputSystem higherLimitAlarmInput; | |
NumberInputSystem coolDownTargetInput; | |
Actions(); // declare constructor | |
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: | |
- V08 tried using @Pharap's FlashStringHelper (but removed in the end) and moves all NumberInputSystem initialisation to Actions class | |
- 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 | |
uint8_t countDownRemaining = 255; // dummy countdown variable | |
// 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); | |
// Class and enum class initialisations | |
Option menuState = Option::digits; // initialise the first state | |
TempUnit unit = TempUnit::celsius; // initialise the first unit | |
Display disp; // initialise instance of class 'display' | |
TempHelper temperature; // initialise instance of class 'tempHelper' | |
Actions act; // initialise an instance of the class `actions`, called `act` | |
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); | |
} | |
void loop() { | |
//Serial.println(alarmLowSetting); | |
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(300); | |
} | |
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.3 remove FlashStringHelper because ATtiny 0/1 series don't use progmem. | |
- remove void setMessage() as no longer needed | |
- 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 char * message; | |
uint16_t & value; | |
Digit digit; | |
public: | |
NumberInputSystem(const char * message, uint16_t & value) : message(message), value(value), digit(Digit::Tens) {} | |
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment