Skip to content

Instantly share code, notes, and snippets.

@conoro
Created December 20, 2023 09:32
Show Gist options
  • Save conoro/77058e27bf3d34567d13f21ac0462aad to your computer and use it in GitHub Desktop.
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.
#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