foranushtup — Esp32 Devkit C V4 simulation

A birthday present

An interactive Esp32 Devkit C V4 circuit simulation you can run free in your browser on Velxio, by baskeyritu.

Components

Sketch code

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_NeoPixel.h>

#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define BUTTON_PIN 14
#define LED_R_PIN  16
#define LED_G_PIN  17
#define LED_B_PIN  18
#define POT_PIN    34
#define NEO_PIN    4
#define NUM_PIXELS 64
Adafruit_NeoPixel ring(NUM_PIXELS, NEO_PIN, NEO_GRB + NEO_KHZ800);

#define MW 8
#define MH 8

int xy(int x, int y) {
  if (y & 1) return y * MW + (MW - 1 - x);
  return y * MW + x;
}

const char* NAME = "Anushtup";


struct Page { const char* lines[5]; uint8_t count; };
const Page PAGES[] = {
  {{"That heart you saw", "wasn't drawn.", "It was built", "from circles."}, 4},
  {{"Dozens of tiny", "spins, each plain", "alone together", "they trace us."}, 4},
  {{"And that weaving", "curve? Two waves,", "two frequencies:", "you and me."}, 4},
  {{"Different rhythms,", "never quite same,", "yet they close", "into one shape."}, 4},
  {{"That's the math", "I believe in:", "small loops that", "turn into a heart."}, 4},
  {{"Happy Birthday,", "my favourite", "frequency.", "I love you so so so"}, 4},
};
const int PAGE_COUNT = sizeof(PAGES) / sizeof(PAGES[0]);

enum Mode { BOOT, LOVE, CAKE, FOURIER, LISSAJOUS, LETTER, MODE_COUNT };
Mode mode = BOOT;
unsigned long modeStart = 0;


volatile bool btnFlag = false;
volatile unsigned long btnLastISR = 0;
void IRAM_ATTR onButtonPress() {
  unsigned long now = millis();
  if (now - btnLastISR > 200) { btnFlag = true; btnLastISR = now; }
}

void pollButton();
void runBoot();  void runLove();  void runCake();
void runFourier(); void runLissajous(); void runLetter();
void drawChrome(unsigned long t);
void centerText(const char* s, int y, int size);
void setLED(int r, int g, int b);
float easeOutElastic(float x);
float easeInOutSine(float x);


void ringSolid(uint8_t r, uint8_t g, uint8_t b) {
  for (int i = 0; i < NUM_PIXELS; i++) ring.setPixelColor(i, ring.Color(r, g, b));
  ring.show();
}
void ringPulse(uint8_t r, uint8_t g, uint8_t b, float k) {
  for (int i = 0; i < NUM_PIXELS; i++)
    ring.setPixelColor(i, ring.Color((uint8_t)(r*k), (uint8_t)(g*k), (uint8_t)(b*k)));
  ring.show();
}
void ringSpinRainbow(float t) {
  for (int y = 0; y < MH; y++)
    for (int x = 0; x < MW; x++) {
      float d = sqrt((x - 3.5) * (x - 3.5) + (y - 3.5) * (y - 3.5));
      uint16_t hue = (uint16_t)((long)(t * 9000) + (long)(d * 8000));
      ring.setPixelColor(xy(x, y), ring.gamma32(ring.ColorHSV(hue, 255, 255)));
    }
  ring.show();
}
void ringComet(uint8_t r, uint8_t g, uint8_t b, float t) {
  float head = fmod(t * 6.0, (MW + MH));
  for (int y = 0; y < MH; y++)
    for (int x = 0; x < MW; x++) {
      float d = head - (x + y);
      float f = (d >= 0 && d < 4) ? (1.0 - d / 4.0) : 0;
      ring.setPixelColor(xy(x, y), ring.Color((uint8_t)(r*f), (uint8_t)(g*f), (uint8_t)(b*f)));
    }
  ring.show();
}


float easeOutElastic(floa