// ***** INCLUDES ***** //
#include <SSD1306Ascii.h>
#include <SSD1306AsciiAvrI2c.h>
// SSD1306 oled definitions - START
const uint8_t i2c_address = 0x3C;
const int8_t rst_pin = -1;
SSD1306AsciiAvrI2c oled;
// SSD1306 oled definitions - STOP
// Menu system definitions - START
const uint8_t buttonScroll = 5;
const uint8_t buttonEnter = 4;
const uint8_t buttonMenu = 3;
volatile bool menuButtonPressed = false;
typedef enum OVEN_STATUS {
STATUS_OFF,
STATUS_ON
} ovenStatus_t;
ovenStatus_t ovenStatus;
typedef enum BUTTON {
BUTTON_NONE,
BUTTON_SCROLL,
BUTTON_ENTR
} button_t;
button_t button;
const char *menuItems[] = {
"Set PID parameters",
"Info",
"Exit menu",
};
typedef enum MENU_STATUS {
START_MENU,
SET_PID_PARAMS,
INFO,
END_MENU
} menuStatus_t;
int8_t row = -1;
const uint8_t maxRows = 4;
// Menu system definitions - STOP
// PID system definitions - START
double Kc = 0.;
double Ti = 0.;
double Td = 0.;
// PID system definitions - STOP
void setup() {
// Initialize the oled
#if rst_pin >= 0
oled.begin(&Adafruit128x64, i2c_address, rst_pin);
#else
oled.begin(&Adafruit128x64, i2c_address);
#endif
oled.setFont(Adafruit5x7);
// pinMode definitions
pinMode(buttonScroll, INPUT);
pinMode(buttonEnter, INPUT);
pinMode(buttonMenu, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonMenu), openMenu, LOW);
oled.setFont(Adafruit5x7);
oled.set2X();
oled.setCursor(30, 1);
oled.print(F("Reflow"));
oled.setCursor(5, 3);
oled.print(F("Controller"));
oled.setCursor(40, 5);
oled.print(F("2024"));
oled.set1X();
delay(2000);
oled.clear();
oled.set2X();
oled.setCursor(0, 0);
oled.print(F("OVEN:OFF"));
oled.setCursor(0, 3);
oled.print(F("TEMP:213.75"));
oled.set1X();
}
void loop() {
if (menuButtonPressed) {
mainMenu();
}
readButton();
switch (button) {
case BUTTON_NONE:
break;
case BUTTON_SCROLL:
break;
case BUTTON_ENTR:
if (ovenStatus == STATUS_ON) {
oled.set2X();
oled.clear(60, 127, 0, 1);
oled.setCursor(60, 0);
oled.print(F("OFF"));
oled.set1X();
ovenStatus = STATUS_OFF;
break;
}
ovenStatus = STATUS_ON;
oled.set2X();
oled.clear(60, 127, 0, 1);
oled.setCursor(60, 0);
oled.print(F("ON"));
oled.set1X();
break;
}
}
// ISR functions - START
void openMenu() {
menuButtonPressed = true;
}
void count() {
}
// ISR functions - STOP
// Button functions - START
void readButton() {
button_t buttonValue = BUTTON_NONE;
unsigned long lastDebounceTime;
if (!digitalRead(buttonScroll)) buttonValue = BUTTON_SCROLL;
if (!digitalRead(buttonEnter)) buttonValue = BUTTON_ENTR;
if (buttonValue != BUTTON_NONE) {
lastDebounceTime = millis();
}
while ((millis() - lastDebounceTime) < 200) {}
if (buttonValue != button) {
button = buttonValue;
}
}
// Button functions - STOP
// Menu functions - START
void initMenu() {
oled.clear();
oled.set2X();
oled.setCursor(50, 1);
oled.print(F("SET"));
oled.setCursor(30, 3);
oled.print(F("PARAMS"));
}
void mainMenu() {
initMenu();
float valueChange[8] = {-100, -10, -1, -0.1, 0.1, 1, 10, 100};
int8_t valueChangeCounter = 0;
while(menuButtonPressed == true) {
readButton();
switch(button) {
case BUTTON_SCROLL:
oled.clear();
if (++row > maxRows) {
row = 0;
}
if (row == 0) {
oled.setCursor(55, 1);
oled.print(F("KP"));
oled.setCursor(40, 4);
oled.print(Kc);
}
else if (row == 1) {
oled.setCursor(55, 1);
oled.print(F("Ti"));
oled.setCursor(40, 4);
oled.print(Ti);
}
else if (row == 2) {
oled.setCursor(55, 1);
oled.print(F("Td"));
oled.setCursor(40, 4);
oled.print(Td);
}
else if (row == 3) {
oled.setCursor(10, 1);
oled.print(F("INCREMENT"));
oled.setCursor(30, 4);
oled.print(valueChange[valueChangeCounter]);
}
else {
oled.setCursor(35, 1);
oled.print(F("DONE?"));
}
break;
case BUTTON_ENTR:
if (row == 0) {
oled.clear(0, 127, 3, 7);
oled.setCursor(30, 4);
Kc += valueChange[valueChangeCounter];
if (Kc < 0) {
Kc = 0;
}
if (Kc > 1000) {
Kc = 1000;
}
oled.print(Kc);
}
else if (row == 1) {
oled.clear(0, 127, 3, 7);
oled.setCursor(30, 4);
Ti += valueChange[valueChangeCounter];
if (Ti < 0) {
Ti = 0;
}
if (Ti > 10000) {
Kc = 10000;
}
oled.print(Ti);
}
else if (row == 2) {
oled.clear(0, 127, 3, 7);
oled.setCursor(30, 4);
Td += valueChange[valueChangeCounter];
if (Td < 0) {
Td = 0;
}
if (Td > 1000) {
Td = 1000;
}
oled.print(Td);
}
else if (row == 3) {
oled.clear(0, 127, 3, 7);
oled.setCursor(30, 4);
if (++valueChangeCounter > 7) {
valueChangeCounter = 0;
}
oled.print(valueChange[valueChangeCounter]);
}
else {
row = -1;
menuButtonPressed = false;
break;
}
/*
// Set the PID parameters
if (row == 0) {
int8_t pidRow = 0;
uint8_t maxPidRow = 4;
float valueChange[8] = {-100, -10, -1, -0.1, 0.1, 1, 10, 100};
int8_t valueChangeCounter = 0;
bool setParams = true;
oled.clear();
oled.set2X();
oled.setCursor(30, 0);
oled.print(F("PID"));
oled.set1X();
oled.setCursor(10, 3);
oled.print(F("Kc: "));
oled.setCursor(30, 3);
oled.print(Kc);
oled.setCursor(10, 4);
oled.print(F("Ti: "));
oled.setCursor(30, 4);
oled.print(Ti);
oled.setCursor(10, 5);
oled.print(F("Td: "));
oled.setCursor(30, 5);
oled.print(Td);
oled.setCursor(10, 6);
oled.print(F("Value: "));
oled.setCursor(50, 6);
oled.print(valueChange[valueChangeCounter]);
oled.setCursor(10, 7);
oled.print(F("Back"));
oled.clear(0, 9, 3, 7);
oled.setCursor(0, pidRow + 3);
oled.print(F(">"));
while(setParams) {
readButton();
switch(button) {
case BUTTON_SCROLL:
if (++pidRow > maxPidRow) {
pidRow = 0;
}
oled.clear(0, 9, 3, 7);
oled.setCursor(0, pidRow + 3);
oled.print(F(">"));
break;
case BUTTON_ENTR:
if (pidRow == 0) {
oled.clear(30, 127, 3, 3);
oled.setCursor(30, 3);
Kc = Kc + valueChange[valueChangeCounter];
if (Kc <= 0) {
Kc = 0;
}
if (Kc >= 1000) {
Kc = 1000;
}
oled.print(Kc);
}
if (pidRow == 1) {
oled.clear(30, 127, 4, 4);
oled.setCursor(30, 4);
Ti = Ti + valueChange[valueChangeCounter];
if (Ti <= 0) {
Ti = 0.001;
}
if (Ti >= 1000) {
Ti = 1000;
}
oled.print(Ti);
}
if (pidRow == 2) {
oled.clear(30, 127, 5, 5);
oled.setCursor(30, 5);
Td = Td + valueChange[valueChangeCounter];
if (Td <= 0) {
Td = 0;
}
if (Td >= 1000) {
Td = 1000;
}
oled.print(Td);
}
if (pidRow == 3) {
oled.clear(50, 127, 6, 6);
if (++valueChangeCounter > 7) {
valueChangeCounter = 0;
}
oled.setCursor(50, 6);
oled.print(valueChange[valueChangeCounter]);
}
if (pidRow == 4) {
setParams = false;
}
break;
case BUTTON_NONE:
break;
}
}
initMenu();
}
// Print out the current information
if (row == 1) {
oled.clear();
oled.setCursor(0, 0);
oled.print(F("Info"));
oled.setCursor(10, 1);
oled.print(F("kp: "));
oled.print(Kc);
oled.setCursor(10, 2);
oled.print(F("ki: "));
oled.print(Kc/Ti);
oled.setCursor(10, 3);
oled.print(F("kd: "));
oled.print(Kc*Td);
while(true) {
readButton();
if (button == BUTTON_ENTR) {
break;
}
}
initMenu();
}
// Exit the menu
if (row == 2) {
menuButtonPressed = false;
}
break;
*/
case BUTTON_NONE:
break;
}
}
oled.clear();
}
// Menu functions - STOP