mirror of
https://github.com/arwidcool/Solder-Plate.git
synced 2025-02-19 20:12:25 +01:00
menu first work
This commit is contained in:
parent
84c246d3d7
commit
721113ddcb
@ -12,7 +12,7 @@
|
||||
platform = atmelmegaavr
|
||||
board = ATmega4809
|
||||
framework = arduino
|
||||
|
||||
monitor_speed = 38400
|
||||
upload_speed = 115200
|
||||
board_hardware.uart = uart0
|
||||
upload_protocol = arduino
|
||||
|
@ -50,6 +50,7 @@ template <typename First, typename Second>
|
||||
class Pair
|
||||
{
|
||||
public:
|
||||
Pair(){};
|
||||
Pair(First first, Second second) : first(first), second(second) {}
|
||||
First first;
|
||||
Second second;
|
||||
|
128
src/displays/menustatemachine.h
Normal file
128
src/displays/menustatemachine.h
Normal file
@ -0,0 +1,128 @@
|
||||
#ifndef __OLEDSTATEMACHINE_H_
|
||||
#define __OLEDSTATEMACHINE_H_
|
||||
#include "../buttons/base.h"
|
||||
#include "../common.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
class OledMenuItem {
|
||||
public:
|
||||
OledMenuItem(){};
|
||||
OledMenuItem(char *title): title(title), identifier(0) {};
|
||||
OledMenuItem(char *title, uint8_t identifier): title(title), identifier(identifier) {};
|
||||
|
||||
char const * title;
|
||||
// Identifier c
|
||||
uint8_t identifier;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
class OledMenu {
|
||||
public:
|
||||
OledMenu(){};
|
||||
OledMenu(uint8_t identifier): identifier(identifier), elementsLength(0), childrenLength(0) {};
|
||||
~OledMenu() {
|
||||
delete elements;
|
||||
delete children;
|
||||
delete childrenMatrix;
|
||||
};
|
||||
uint8_t identifier;
|
||||
|
||||
void setChildren(OledMenu **children, int length) {
|
||||
this->children = children;
|
||||
this->childrenLength = length;
|
||||
for (int i=0; i<length; i++) {
|
||||
children[i]->parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
void setElements(OledMenuItem *elements, int length) {
|
||||
this->elements = new OledMenuItem[length];
|
||||
|
||||
for (int i=0; i<length; i++) {
|
||||
this->elements[i].title = malloc(strlen(elements[i].title) + 1);
|
||||
memcpy(this->elements[i].title, elements[i].title, strlen(elements[i].title) + 1);
|
||||
this->elements[i].identifier = elements[i].identifier;
|
||||
|
||||
Serial.println(String(this->elements[i].title) + " " + String(elements[i].title));
|
||||
}
|
||||
this->elementsLength = length;
|
||||
}
|
||||
|
||||
void setChildrenMatrix(int length, uint8_t (*matrix)[2]) {
|
||||
this->childrenMatrix = matrix;
|
||||
this->childrenMatrixLength = length;
|
||||
}
|
||||
|
||||
// To be invoked when the user presses the SELECT btn
|
||||
// If null is returned then the menu should not be changed
|
||||
OledMenu *getNextMenu() {
|
||||
for (int i=0; i<childrenMatrixLength; i++) {
|
||||
if (childrenMatrix[i][0] == curItem) {
|
||||
return children[childrenMatrix[i][1]];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// To be invoked when the user presses the UP btn
|
||||
OledMenuItem goNextItem() {
|
||||
curItem++;
|
||||
curItem = curItem % elementsLength;
|
||||
Serial.println(String(elements[curItem].title) + " - " + String(curItem));
|
||||
return elements[curItem];
|
||||
}
|
||||
|
||||
// To be invoked when the user presses the DOWN btn
|
||||
OledMenuItem goPrevItem() {
|
||||
curItem--;
|
||||
if (curItem < 0) {
|
||||
curItem = elementsLength - 1;
|
||||
}
|
||||
Serial.println(String(elements[curItem].title) + " - " + String(curItem));
|
||||
|
||||
return elements[curItem];
|
||||
}
|
||||
|
||||
OledMenuItem getCurItem() {
|
||||
return elements[curItem];
|
||||
}
|
||||
|
||||
OledMenu *parent;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
int curItem = 0;
|
||||
OledMenuItem *elements;
|
||||
int elementsLength;
|
||||
OledMenu **children;
|
||||
int childrenLength;
|
||||
/**
|
||||
* Matrix of pairs of (element index, children index)
|
||||
* ex if element at index 0 should go to children at index 1 when user hits SELECT
|
||||
* then the matrix would be:
|
||||
* { ..., {0, 1}, ...}
|
||||
*/
|
||||
uint8_t (*childrenMatrix)[2]; // First is element index, second is children index,
|
||||
int childrenMatrixLength;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#define SETMATRIX(menuItem, CODE) { Pair<ButtonKind,int> matrix[] = { CODE }; menuItem.setMatrix( sizeof(matrix)/sizeof(matrix[0]), matrix); }
|
||||
#define UPBUTTON(index) Pair<ButtonKind, int>(ButtonKind::UP, index),
|
||||
#define DOWNBUTTON(index) Pair<ButtonKind, int>(ButtonKind::DOWN, index),
|
||||
#define SELECTBUTTON(index) Pair<ButtonKind, int>(ButtonKind::SELECT, index),
|
||||
#define BACKBUTTON(index) Pair<ButtonKind, int>(ButtonKind::BACK, index),
|
||||
// #define SETOLED_HANDLER(handler, CODE) { handler.buttonPressed = [](ButtonKind kind) -> OledInterfaceHandler* { CODE }; }
|
||||
// #define BTNGOTOHANDLER(_kind, gotoHandler) if (kind == _kind) { return gotoHandler; }
|
||||
// #define HANDLER_ONUP(gotoHandler) BTNGOTOHANDLER(ButtonKind::UP, gotoHandler)
|
||||
// #define HANDLER_ONDOWN(gotoHandler) BTNGOTOHANDLER(ButtonKind::DOWN, gotoHandler)
|
||||
// #define HANDLER_ONBACK(gotoHandler) BTNGOTOHANDLER(ButtonKind::BACK, gotoHandler)
|
||||
// #define HANDLER_ONSELECT(gotoHandler) BTNGOTOHANDLER(ButtonKind::SELECT, gotoHandler)
|
||||
// #define HANDLER_NULL return nullptr;
|
||||
|
||||
#endif
|
@ -1,9 +1,11 @@
|
||||
#include "./oled.h"
|
||||
#include <Arduino.h>
|
||||
#include "../globals.h"
|
||||
#include "./menustatemachine.h"
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 64
|
||||
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
||||
#define MENUID_PLATERES 2
|
||||
|
||||
unsigned long lastProcessedReflowState = 0;
|
||||
OledDisplay::OledDisplay()
|
||||
@ -12,8 +14,70 @@ OledDisplay::OledDisplay()
|
||||
display = Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
void OledDisplay::handleButtonStateChange(Pair<ButtonKind, StateChangeEvent<ButtonState>> change)
|
||||
{
|
||||
if (change.second.to == ButtonState::PRESSED)
|
||||
{
|
||||
if (change.first == ButtonKind::SELECT)
|
||||
{
|
||||
OledMenu *selectedMenu = curMenu->getNextMenu();
|
||||
if (selectedMenu != NULL)
|
||||
{
|
||||
curMenu = selectedMenu;
|
||||
}
|
||||
} else if (change.first == ButtonKind::BACK) {
|
||||
OledMenu *selectedMenu = curMenu->parent;
|
||||
if (selectedMenu != NULL)
|
||||
{
|
||||
curMenu = selectedMenu;
|
||||
}
|
||||
} else if (change.first == ButtonKind::UP) {
|
||||
curMenu->goNextItem();
|
||||
} else if (change.first == ButtonKind::DOWN){
|
||||
curMenu->goPrevItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
void OledDisplay::setup()
|
||||
{
|
||||
curMenu = new OledMenu();
|
||||
curMenu->setElements(new OledMenuItem[3]{
|
||||
OledMenuItem("Reflow\0"),
|
||||
OledMenuItem("PlateR\0"),
|
||||
OledMenuItem("Temps\0"),
|
||||
}, 3);
|
||||
|
||||
OledMenu *pickProfilesMenu = new OledMenu(1);
|
||||
OledMenuItem *pickProfilesMenuItems = new OledMenuItem[nReflowProfiles];
|
||||
for (int i=0; i<nReflowProfiles; i++) {
|
||||
pickProfilesMenuItems[i] = OledMenuItem(reflowProfiles[i].name, 100+1);
|
||||
}
|
||||
pickProfilesMenu->setElements(pickProfilesMenuItems, nReflowProfiles);
|
||||
|
||||
OledMenu *plateRMenu = new OledMenu(MENUID_PLATERES);
|
||||
OledMenu *tempsMenu = new OledMenu(3);
|
||||
tempsMenu->setElements(new OledMenuItem[6]{
|
||||
OledMenuItem("T1\0", 150),
|
||||
OledMenuItem("T2\0", 151),
|
||||
OledMenuItem("T3\0", 152),
|
||||
OledMenuItem("T4\0", 153),
|
||||
OledMenuItem("T5\0", 154),
|
||||
OledMenuItem("T6\0", 155),
|
||||
}, 6);
|
||||
|
||||
curMenu->setChildren(new OledMenu*[3]{
|
||||
pickProfilesMenu,
|
||||
plateRMenu,
|
||||
tempsMenu,
|
||||
}, 3);
|
||||
curMenu->setChildrenMatrix(3, new uint8_t[3][2]{
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
});
|
||||
|
||||
// curItem = 0; // ROOT
|
||||
|
||||
// Setup implementation
|
||||
bool initialized = display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
|
||||
if (!initialized)
|
||||
@ -25,51 +89,37 @@ void OledDisplay::setup()
|
||||
Serial.println("OLED Display initialized");
|
||||
}
|
||||
display.setRotation(0);
|
||||
display.setCursor(0, 0);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(SSD1306_WHITE); // Defaults to white
|
||||
|
||||
}
|
||||
|
||||
void OledDisplay::loop()
|
||||
{
|
||||
|
||||
StateChangeEvent<ReflowProcessState> *evt = reflowProcessState.getSince(lastProcessedReflowState);
|
||||
// REdraw only on reflow state change
|
||||
if (evt != NULL)
|
||||
ReflowProcessState state = reflowProcessState.get();
|
||||
if (state == USER_INPUT)
|
||||
{
|
||||
lastProcessedReflowState = millis();
|
||||
ReflowProcessState reflowState = reflowProcessState.get();
|
||||
if (reflowState == USER_INPUT)
|
||||
{
|
||||
handleUserInputState();
|
||||
return;
|
||||
}
|
||||
else if (reflowState == SOAK)
|
||||
{
|
||||
handleSoakState();
|
||||
return;
|
||||
}
|
||||
else if (reflowState == REFLOW)
|
||||
{
|
||||
handleReflowState();
|
||||
return;
|
||||
}
|
||||
else if (reflowState == ReflowProcessState::COOL)
|
||||
{
|
||||
handleCoolingState();
|
||||
return;
|
||||
}
|
||||
else if (reflowState == ReflowProcessState::DONE)
|
||||
{
|
||||
handleFinishedState();
|
||||
return;
|
||||
}
|
||||
}
|
||||
display.clearDisplay();
|
||||
display.setTextSize(2);
|
||||
|
||||
if (reflowProcessState.get() == PREHEAT)
|
||||
{
|
||||
drawDebug();
|
||||
OledMenuItem menuItem = curMenu->getCurItem();
|
||||
display.setTextSize(2);
|
||||
if (curMenu->identifier == MENUID_PLATERES) {
|
||||
|
||||
} else {
|
||||
|
||||
// draw menu item with selectors.
|
||||
|
||||
display.setRotation(0);
|
||||
centerText(menuItem.title);
|
||||
display.setRotation(1);
|
||||
display.setCursor(0,SCREEN_WIDTH/2-5);
|
||||
display.print("<");
|
||||
display.setCursor(SCREEN_HEIGHT-14,SCREEN_WIDTH/2-5);
|
||||
display.print(">");
|
||||
|
||||
}
|
||||
|
||||
display.display();
|
||||
}
|
||||
// Loop implementation
|
||||
}
|
||||
@ -96,35 +146,24 @@ void OledDisplay::drawDebug()
|
||||
display.display();
|
||||
}
|
||||
|
||||
void OledDisplay::centerText(const char *txt)
|
||||
{
|
||||
int16_t x1, y1;
|
||||
uint16_t w, h;
|
||||
display.getTextBounds(txt, 0, 0, &x1, &y1, &w, &h);
|
||||
display.setCursor(display.width() / 2 - w / 2, display.height() / 2 -h/2);
|
||||
|
||||
display.println(txt);
|
||||
}
|
||||
|
||||
void OledDisplay::handleUserInputState()
|
||||
{
|
||||
Serial.println("USER_INPUT_STATE");
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
display.setCursor(0, SCREEN_HEIGHT / 2 + 10);
|
||||
display.setTextSize(2);
|
||||
|
||||
display.println("INPUT_STATE");
|
||||
display.display();
|
||||
}
|
||||
|
||||
void OledDisplay::handlePreheatState()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
|
||||
display.println("PREHEATING");
|
||||
display.display();
|
||||
}
|
||||
|
||||
void OledDisplay::handleSoakState()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
|
||||
display.println("SOAKING");
|
||||
display.display();
|
||||
}
|
||||
|
||||
void OledDisplay::handleReflowState()
|
||||
{
|
||||
display.clearDisplay();
|
||||
@ -133,21 +172,3 @@ void OledDisplay::handleReflowState()
|
||||
display.println("REFLOW");
|
||||
display.display();
|
||||
}
|
||||
|
||||
void OledDisplay::handleCoolingState()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
|
||||
display.println("COOLING");
|
||||
display.display();
|
||||
}
|
||||
|
||||
void OledDisplay::handleFinishedState()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
|
||||
display.println("Done :)");
|
||||
display.display();
|
||||
}
|
@ -2,22 +2,24 @@
|
||||
#define __oled_h
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include "../reflow.h"
|
||||
#include "menustatemachine.h"
|
||||
|
||||
class OledDisplay {
|
||||
public:
|
||||
OledDisplay();
|
||||
void setup();
|
||||
void loop();
|
||||
void teardown();
|
||||
void handleButtonStateChange(Pair<ButtonKind, StateChangeEvent<ButtonState>> change);
|
||||
|
||||
private:
|
||||
OledMenu *curMenu;
|
||||
Adafruit_SSD1306 display;
|
||||
void drawDebug();
|
||||
void handleUserInputState();
|
||||
void handlePreheatState();
|
||||
void handleSoakState();
|
||||
void handleReflowState();
|
||||
void handleCoolingState();
|
||||
void handleFinishedState();
|
||||
|
||||
void centerText(const char * text);
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,4 +12,6 @@ extern Thermistor thermistor3;
|
||||
extern Thermistor thermistor4;
|
||||
extern Thermistor thermistor5;
|
||||
extern Thermistor thermistor6;
|
||||
extern ReflowProfile reflowProfiles[];
|
||||
extern int nReflowProfiles;
|
||||
#endif
|
@ -19,6 +19,7 @@ void LEDS::handleButtonStateChange(Pair<ButtonKind, StateChangeEvent<ButtonState
|
||||
{
|
||||
switch (change.first) {
|
||||
case ButtonKind::UP:
|
||||
Serial.println("MEOW");
|
||||
if (change.second.to == ButtonState::PRESSED) {
|
||||
digitalWrite(yellowLED, HIGH);
|
||||
} else if (!yellowLEDSeleOn) {
|
||||
|
77
src/main.cpp
77
src/main.cpp
@ -43,17 +43,28 @@ LEDS leds = LEDS();
|
||||
// Declare the PID
|
||||
ArduPID PID;
|
||||
OledDisplay oled = OledDisplay();
|
||||
ReflowProfile profile = ReflowProfile(new ReflowStep[5] {
|
||||
ReflowProfile reflowProfiles[] = {
|
||||
ReflowProfile(new ReflowStep[5] {
|
||||
ReflowStep(ReflowProcessState::PREHEAT, 2, 150),
|
||||
ReflowStep(ReflowProcessState::SOAK, 3, 180),
|
||||
ReflowStep(ReflowProcessState::REFLOW, 3, 220, EASE_IN_OUT),
|
||||
ReflowStep(ReflowProcessState::COOL, 3, 100),
|
||||
ReflowStep(ReflowProcessState::DONE, 0, 0)
|
||||
}, "meow\0");
|
||||
}, "Test\0"),
|
||||
ReflowProfile(new ReflowStep[5] {
|
||||
ReflowStep(ReflowProcessState::PREHEAT, 2, 150),
|
||||
ReflowStep(ReflowProcessState::SOAK, 3, 180),
|
||||
ReflowStep(ReflowProcessState::REFLOW, 3, 220, EASE_IN_OUT),
|
||||
ReflowStep(ReflowProcessState::COOL, 3, 100),
|
||||
ReflowStep(ReflowProcessState::DONE, 0, 0)
|
||||
}, "Test2\0"),
|
||||
};
|
||||
int nReflowProfiles = 2;
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.begin(38400);
|
||||
|
||||
Serial.println("Starting OLED");
|
||||
// Set PWM frequency to 64 kHz
|
||||
@ -61,27 +72,8 @@ void setup()
|
||||
buttons.setup();
|
||||
leds.setup();
|
||||
oled.setup();
|
||||
|
||||
char name[20] = "meow\0";
|
||||
// ReflowProfile profile = ReflowProfile::fromEEPROM(0);
|
||||
|
||||
// ReflowProfile profile = ReflowProfile(new ReflowStep[5] {
|
||||
// ReflowStep(ReflowProcessState::PREHEAT, 30, 150),
|
||||
// ReflowStep(ReflowProcessState::SOAK, 30, 180),
|
||||
// ReflowStep(ReflowProcessState::REFLOW, 30, 220),
|
||||
// ReflowStep(ReflowProcessState::COOL, 30, 100),
|
||||
// ReflowStep(ReflowProcessState::DONE, 0, 0)
|
||||
// }, name);
|
||||
// profile.toEEPROM(0);
|
||||
|
||||
Serial.println(profile.name);
|
||||
for (int i=0; i<5; i++) {
|
||||
Serial.print(profile.steps[i].duration);
|
||||
Serial.print(" ");
|
||||
Serial.println(profile.steps[i].targetTempAtEnd);
|
||||
}
|
||||
reflowProcessState = USER_INPUT;
|
||||
profile.start();
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
@ -92,29 +84,30 @@ void loop()
|
||||
|
||||
if (k != NULL) {
|
||||
leds.handleButtonStateChange(*k);
|
||||
oled.handleButtonStateChange(*k);
|
||||
|
||||
if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::SELECT, ButtonState::PRESSED)) {
|
||||
reflowProcessState.set(ReflowProcessState::PREHEAT);
|
||||
} else if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::BACK, ButtonState::PRESSED)) {
|
||||
reflowProcessState.set(ReflowProcessState::USER_INPUT);
|
||||
} else if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::UP, ButtonState::PRESSED)) {
|
||||
reflowProcessState.set(ReflowProcessState::COOL);
|
||||
} else if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::DOWN, ButtonState::PRESSED)) {
|
||||
reflowProcessState.set(ReflowProcessState::REFLOW);
|
||||
}
|
||||
// if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::SELECT, ButtonState::PRESSED)) {
|
||||
// reflowProcessState.set(ReflowProcessState::PREHEAT);
|
||||
// } else if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::BACK, ButtonState::PRESSED)) {
|
||||
// reflowProcessState.set(ReflowProcessState::USER_INPUT);
|
||||
// } else if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::UP, ButtonState::PRESSED)) {
|
||||
// reflowProcessState.set(ReflowProcessState::COOL);
|
||||
// } else if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::DOWN, ButtonState::PRESSED)) {
|
||||
// reflowProcessState.set(ReflowProcessState::REFLOW);
|
||||
// }
|
||||
}
|
||||
|
||||
ReflowStep step = profile.curReflowStep();
|
||||
if (step.state != reflowProcessState.get()) {
|
||||
reflowProcessState.set(step.state);
|
||||
}
|
||||
// ReflowStep step = profile.curReflowStep();
|
||||
// if (step.state != reflowProcessState.get()) {
|
||||
// reflowProcessState.set(step.state);
|
||||
// }
|
||||
|
||||
oled.loop();
|
||||
if (step.state == ReflowProcessState::DONE) {
|
||||
profile.start();
|
||||
return;
|
||||
}
|
||||
Serial.print(String(STATE_STR(step.state)) + " " + String(step.duration) + " " + String(step.targetTempAtEnd) + " " + String(profile.getTargetTemp())+"\r");
|
||||
oled.loop();
|
||||
// if (step.state == ReflowProcessState::DONE) {
|
||||
// profile.start();
|
||||
// return;
|
||||
// }
|
||||
// Serial.print(String(STATE_STR(step.state)) + " " + String(step.duration) + " " + String(step.targetTempAtEnd) + " " + String(profile.getTargetTemp())+"\r");
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user