Skip to content

Instantly share code, notes, and snippets.

@ovidb
Created April 20, 2021 08:05
Show Gist options
  • Save ovidb/37f5836720cc29c2a3d075c2feeceb8f to your computer and use it in GitHub Desktop.
Save ovidb/37f5836720cc29c2a3d075c2feeceb8f to your computer and use it in GitHub Desktop.
Pomodoro Particle Internet Button
#include "InternetButton/InternetButton.h"
#include "math.h"
/* Here's a nice combination of features that I like to use.
Note the use of the allButtons function. */
InternetButton b = InternetButton();
int NO_LEDS = 12;
int focusDuration = 60 * 40;
int breakDuration = 60 * 5;
int maxChecks = 10;
float focusIncreaseRatio = 1.5;
int focusFitnessIncrease = 1;
int focusFitnessDecrease = 2;
int focusIncreaseRangeMultiplier = 2;
int defaultFocusFitness = 1;
int defaultCheckWindow = 20;
// mutable variables
int checkWindow = defaultCheckWindow;
int focusFitness = 1;
int checksDone = 0;
int startFocusTime = 0;
int startBreakTime = 0;
int startRedAlertTime = 0;
int startCheckingTime = 0;
int focusSessions = 0;
int breakSessions = 0;
bool focusSessionStarted = false;
bool breakSessionStarted = false;
bool redAlertStarted = false;
bool focusCheckingStarted = false;
bool allowFocusInput = false;
void setup() {
// Tell b to get everything ready to go
// Use b.begin(1); if you have the original SparkButton, which does not have a buzzer or a plastic enclosure
// to use, just add a '1' between the parentheses in the code above.
b.begin();
}
void loop(){
if (b.buttonOn(1)) {
startFocus();
}
if (b.buttonOn(2)) {
startBreak();
}
if (b.buttonOn(3)) {
focused();
}
if (b.buttonOn(4)) {
stop();
}
// focus
playAnimation(focusSessionStarted, startFocusTime, focusDuration, 0, 100, 0);
// break
playAnimation(breakSessionStarted, startBreakTime, breakDuration, 0, 0, 100);
checkkFocus();
playRedAlert();
}
void startFocus() {
focusCheckingStarted = true;
focusSessionStarted = true;
breakSessionStarted = false;
redAlertStarted = false;
focusSessions++;
checkWindow = defaultCheckWindow;
checksDone = 0;
startFocusTime = Time.now();
startCheckingTime = Time.now();
b.playSong("E5,8,G5,8,E6,8,C6,8,D6,8,G6,8");
blinkAllLeds(1, 300, 0, 100, 0);
publish("Start Focus: ", focusSessions);
}
void startBreak() {
focusCheckingStarted = false;
focusSessionStarted = false;
breakSessionStarted = true;
redAlertStarted = false;
breakSessions++;
startBreakTime = Time.now();
b.playSong("E5,8,G5,8,E6,8,C6,8,D6,8,G6,8,E5,8,G5,8,E6,8,C6,8");
blinkAllLeds(1, 300, 0, 0, 100);
publish("Start Break: ", breakSessions);
}
void stop() {
focusCheckingStarted = false;
focusSessionStarted = false;
breakSessionStarted = false;
redAlertStarted = false;
checkWindow = defaultCheckWindow;
b.playSong("F5,8,E5,8,D4,8,C4,8");
blinkAllLeds(2, 300, 100, 50, 50);
focusSessions = 0;
breakSessions = 0;
focusFitness = defaultFocusFitness;
}
void startRedAlert() {
if (redAlertStarted) {
return;
}
focusSessionStarted = false;
breakSessionStarted = false;
focusCheckingStarted = false;
redAlertStarted = true;
}
void playRedAlert() {
if (!redAlertStarted) {
return;
}
b.playSong("C4,4,D4,4,E4,4");
blinkAllLeds(3, 300, 255, 20, 20);
blinkAllLeds(3, 300, 20, 20, 255);
focusFitness -= focusFitnessDecrease;
publish("focusFitness: ", focusFitness);
if (focusFitness <= defaultFocusFitness) {
publish("focusFitness <= defaultFocusFitness", focusFitness);
focusFitness = defaultFocusFitness;
}
}
void focused() {
if (!allowFocusInput) {
return;
}
focusCheckingStarted = true;
focusSessionStarted = true;
breakSessionStarted = false;
redAlertStarted = false;
focusFitness += focusFitnessIncrease;
int currentCheckWindow = defaultCheckWindow * pow(focusIncreaseRatio, focusFitness);
publish("Focused. currentCheckWindow", currentCheckWindow);
checkWindow = random(currentCheckWindow, currentCheckWindow * focusIncreaseRangeMultiplier);
startCheckingTime = Time.now();
checksDone = 0;
allowFocusInput = false;
}
void checkkFocus() {
if (!focusCheckingStarted) {
return;
}
int ellapsed = Time.now() - startCheckingTime;
if (ellapsed > checkWindow) {
publish("checksDone: ", checksDone);
allowFocusInput = true;
checksDone++;
// b.playSong("C2,2,D2,2");
blinkAllLeds(checksDone, 2000 / checksDone, 100 + (15* checksDone), 100, 100);
if (checksDone > maxChecks) {
startRedAlert();
}
}
}
/** utility functions */
void playAnimation(bool shouldRun, int sinceStart, int duration, int r, int g, int b) {
if (!shouldRun) {
return;
}
int ellapsed = Time.now() - sinceStart;
if (ellapsed > duration) {
if (focusSessionStarted) {
startBreak();
return;
}
if (breakSessionStarted) {
startFocus();
return;
}
}
showDuration(duration, ellapsed, 75, r, g, b);
}
void publish(char* message, int value) {
if (Particle.connected()) {
Particle.publish(message, String(value));
}
}
void blinkAllLeds(int times, int millis, int red, int green, int blue) {
for (int i = 0; i < times; i++) {
b.allLedsOn(red, green, blue);
delay(millis/2);
b.allLedsOff();
delay(millis/2);
}
}
void showDuration(int duration, int ellapsed, int delayMs, int red, int green, int blue) {
int ratio = duration / NO_LEDS;
for(int i = 0; i < NO_LEDS; i++) {
if ((ellapsed / ratio) >= i - 1) {
b.ledOn(i, red, green, blue);
}
delay(delayMs);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment