Created
December 20, 2023 09:32
-
-
Save conoro/77058e27bf3d34567d13f21ac0462aad to your computer and use it in GitHub Desktop.
Arduino Franken-Timer for George Foreman Grill. ESP32-S2 with Hardware SPI to OLED screen. Tune on simple speaker.
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
#include "pitches.h" | |
#include "CountDown.h" | |
#include <Adafruit_GFX.h> // Core graphics library | |
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789 | |
#include <Fonts/FreeSans24pt7b.h> | |
#include <SPI.h> | |
#define TFT_CS 10 | |
#define TFT_RST 7 | |
#define TFT_DC 5 | |
#define TFT_MOSI 35 // Data out | |
#define TFT_SCLK 36 // Clock out | |
Adafruit_ST7789 *_tft = NULL; | |
CountDown CD; | |
// Use interrupts for Button input | |
volatile unsigned long Debounce1Timer; | |
volatile int Button1Pressed=0; | |
volatile unsigned long Debounce2Timer; | |
volatile int Button2Pressed=0; | |
volatile unsigned int delayTime = 500; | |
// Pins | |
// Button 1 is Start/Stop/Reset | |
// Button 2 in increment counter | |
int button1Pin = 6; | |
int button2Pin = 2; | |
int speakerPin = 39; | |
int relayPin = 3; | |
void debouncer1(){ | |
if (Button1Pressed+= (millis() - Debounce1Timer) >= (delayTime )) Debounce1Timer = millis(); | |
} | |
void debouncer2(){ | |
if (Button2Pressed+= (millis() - Debounce2Timer) >= (delayTime )) Debounce2Timer = millis(); | |
} | |
int prev_minute = 0; | |
int prev_second = 0; | |
int countdown_running = 0; | |
// notes in the melody: | |
int melody[] = { | |
NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 | |
}; | |
// note durations: 4 = quarter note, 8 = eighth note, etc.: | |
int noteDurations[] = { | |
4, 8, 8, 4, 4, 4, 4, 4 | |
}; | |
char countdownDisplay[6]; | |
void setup() { | |
Serial.begin(115200); | |
// Button Pins. Implemented as Interrupt so it should never miss a trigger. | |
pinMode(button1Pin, INPUT_PULLUP); | |
pinMode(button2Pin, INPUT_PULLUP); | |
attachInterrupt(digitalPinToInterrupt(button1Pin), debouncer1, RISING); | |
Button1Pressed=0; | |
attachInterrupt(digitalPinToInterrupt(button2Pin), debouncer2, RISING); | |
Button2Pressed=0; | |
pinMode(speakerPin, OUTPUT); | |
// Setup the relay to OFF | |
digitalWrite(relayPin, 0); | |
pinMode(relayPin, OUTPUT); | |
// Hardware SPI - Many times faster than software | |
SPIClass *spi = new SPIClass(HSPI); | |
spi->begin(TFT_SCLK, -1, TFT_MOSI, TFT_CS); | |
_tft = new Adafruit_ST7789(spi, TFT_CS, TFT_DC, TFT_RST); | |
// 80MHz should work, but you may need lower speeds | |
_tft->setSPISpeed(80000000); | |
// this will vary depending on your display | |
_tft->init(240, 280, SPI_MODE0); | |
_tft->setFont(&FreeSans24pt7b); | |
_tft->setTextSize(2); | |
_tft->setRotation(3); | |
_tft->fillScreen(ST77XX_BLACK); | |
_tft->setTextColor(ST77XX_WHITE, ST77XX_BLACK); | |
// large block of text | |
int16_t x1, y1; | |
int x, y; | |
uint16_t w, h; | |
_tft->getTextBounds(countdownDisplay, x, y, &x1, &y1, &w, &h); //calc width of new string | |
//_tft->setCursor(x - w / 2, y); | |
_tft->fillRect(35, 35, 230, 110, ST77XX_BLACK); | |
_tft->setCursor(35,140); | |
strncpy(countdownDisplay, (char *)"00:00", 5); | |
_tft->print(countdownDisplay); | |
} | |
void loop() { | |
uint32_t t; | |
// Button 1 is Start/Stop/Reset | |
if (Button1Pressed > 0){ | |
Serial.println("Button 1 Pressed"); | |
Button1Pressed = 0; | |
// If already running - Stop and Reset | |
if (countdown_running == 1){ | |
// Active HIGH so write 0 to deactivate relay | |
digitalWrite(relayPin, 0); | |
countdown_running = 0; | |
prev_minute = 0; | |
prev_second = 0; | |
CD.stop(); | |
strncpy(countdownDisplay, (char *)"00:00", 5); | |
_tft->fillRect(35, 35, 230, 110, ST77XX_BLACK); | |
_tft->setCursor(35,140); | |
_tft->print(countdownDisplay); | |
for (int thisNote = 0; thisNote < 8; thisNote++) { | |
int noteDuration = 1000 / noteDurations[thisNote]; | |
tone(speakerPin, melody[thisNote], noteDuration); | |
int pauseBetweenNotes = noteDuration * 1.30; | |
delay(pauseBetweenNotes); | |
noTone(8); | |
} | |
// If not running and there's a duration set - start running | |
} else if ((countdown_running == 0) && (prev_minute != 0)) { | |
// Active HIGH so write 1 to activate relay | |
digitalWrite(relayPin, 1); | |
CD.start(0, 0, prev_minute, prev_second); | |
countdown_running = 1; | |
sprintf(countdownDisplay, "%02d:%02d", prev_minute,prev_second); | |
_tft->fillRect(35, 35, 230, 110, ST77XX_BLACK); | |
_tft->setCursor(35,140); | |
_tft->print(countdownDisplay); | |
} | |
} | |
// Button 2 is Incremement Counter | |
if (Button2Pressed > 0){ | |
Serial.println("Button 2 Pressed"); | |
Button2Pressed = 0; | |
// Is already running - add 1 to the minute timer | |
if (countdown_running == 1){ | |
prev_minute = (prev_minute + 1) % 30; | |
sprintf(countdownDisplay, "%02d:%02d", prev_minute,prev_second); | |
_tft->fillRect(35, 35, 230, 110, ST77XX_BLACK); | |
_tft->setCursor(35,140); | |
_tft->print(countdownDisplay); | |
CD.stop(); | |
CD.start(0, 0, prev_minute, prev_second); | |
} else { | |
prev_minute = (prev_minute + 1) % 30; | |
prev_second = 0; | |
sprintf(countdownDisplay, "%02d:%02d", prev_minute,prev_second); | |
_tft->fillRect(35, 35, 230, 110, ST77XX_BLACK); | |
_tft->setCursor(35,140); | |
_tft->print(countdownDisplay); | |
} | |
} | |
if (countdown_running == 1){ | |
t = CD.remaining(); | |
int s = t % 60; | |
int trem = (t - s)/60; | |
int m = trem % 60; | |
if (s != prev_second){ | |
Serial.print("Remaining: "); | |
Serial.print(m); | |
Serial.print("m "); | |
Serial.print(s); | |
Serial.println("s"); | |
sprintf(countdownDisplay, "%02d:%02d", m,s); | |
_tft->fillRect(35, 35, 230, 110, ST77XX_BLACK); | |
_tft->setCursor(35,140); | |
_tft->print(countdownDisplay); | |
} | |
prev_minute = m; | |
prev_second = s; | |
if (t == 0){ | |
// Active HIGH so write 0 to deactivate relay | |
digitalWrite(relayPin, 0); | |
CD.stop(); | |
countdown_running = 0; | |
prev_minute = 0; | |
prev_second = 0; | |
sprintf(countdownDisplay, "%02d:%02d", m,s); | |
_tft->fillRect(35, 35, 230, 110, ST77XX_BLACK); | |
_tft->setCursor(35,140); | |
_tft->print(countdownDisplay); | |
for (int thisNote = 0; thisNote < 8; thisNote++) { | |
int noteDuration = 1000 / noteDurations[thisNote]; | |
tone(speakerPin, melody[thisNote], noteDuration); | |
int pauseBetweenNotes = noteDuration * 1.30; | |
delay(pauseBetweenNotes); | |
noTone(8); | |
} | |
} | |
} | |
delay(100); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment