Created
April 25, 2021 17:44
-
-
Save OniDaito/aa1c5d52e7dc9c7083e7321cd1d7c622 to your computer and use it in GitHub Desktop.
Plague Doctor Mask Arduino Gist
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 <FastLED.h> | |
#include <SoftwareSerial.h> | |
SoftwareSerial MyBlue(11, 12); // RX | TX | |
#define PIN_LEFT_EYE 3 | |
#define PIN_RIGHT_EYE 4 | |
#define LEFT_OFFSET 2 | |
#define RIGHT_OFFSET -4 | |
#define STRIP_SIZE 16 | |
int CURRENT_STATUS = 0; // What state are the eyes in? | |
CRGB strip_left_eye[STRIP_SIZE]; | |
CRGB strip_right_eye[STRIP_SIZE]; | |
#define STATE_CLEAR 'a' | |
#define STATE_RAINBOW 'b' | |
#define STATE_TORCH 'c' | |
#define STATE_RAGE 'd' | |
#define STATE_HYPNO 'e' | |
#define STATE_IDLE 'f' | |
char STATE=STATE_CLEAR; | |
void setup() { | |
// LED strips | |
FastLED.addLeds<NEOPIXEL, PIN_LEFT_EYE>(strip_left_eye, STRIP_SIZE); | |
FastLED.addLeds<NEOPIXEL, PIN_RIGHT_EYE>(strip_right_eye, STRIP_SIZE); | |
// Serial and bluetooth | |
Serial.begin(9600); | |
MyBlue.begin(9600); | |
Serial.println("Ready to connect\nDefault password is 1234 or 0000"); | |
} | |
int idx(int i, int offset) { | |
int p = i + offset; | |
if (p < 0) { p = STRIP_SIZE + p;} | |
else if (p >= STRIP_SIZE) { p = p - STRIP_SIZE;} | |
return p; | |
} | |
int lidx(int i) { return idx(i, LEFT_OFFSET);} | |
int ridx(int i) { return idx(i, RIGHT_OFFSET);} | |
float cp(int i) { return float((i % STRIP_SIZE)) / STRIP_SIZE * PI * 2.0; } | |
int cdist(int i, int j) { | |
float a = degrees(cp(i)) - degrees(cp(j)); | |
if(a > 180) { a -= 360;} | |
else if (a < -180){ a += 360; } | |
return int(a / 360.0 * STRIP_SIZE); | |
} | |
void set_eyes_hsv(CHSV hsv) { | |
for (int i = 0; i < STRIP_SIZE; i++) { | |
strip_left_eye[i] = hsv; | |
strip_right_eye[i] = hsv; | |
} | |
} | |
void do_state(){ | |
switch(STATE) { | |
case STATE_CLEAR: { | |
set_eyes_hsv(CHSV(0,0,0)); | |
FastLED.show(); | |
break; | |
} | |
case STATE_TORCH: { | |
for (int i = 0; i < STRIP_SIZE; i++) { | |
strip_left_eye[lidx(i)] = CRGB::White; FastLED.show(); delay(10); | |
strip_right_eye[ridx(i)] = CRGB::White; FastLED.show(); delay(10); | |
} | |
break; | |
} | |
case STATE_RAINBOW: { | |
static int hue = 0; | |
hue += 1; | |
for (int i = 0; i < STRIP_SIZE; i++) { | |
strip_left_eye[lidx(i)] = CHSV(hue++, 255, 255); | |
strip_right_eye[ridx(i)] = CHSV(hue++, 255, 255); | |
} | |
FastLED.show(); | |
delay(100); | |
break; | |
} | |
case STATE_RAGE: { | |
static int var = 120; | |
static int dir = 1; | |
var += dir; | |
if (var > 250) { dir = -1;} | |
if (var < 120) { dir = 1;} | |
set_eyes_hsv(CHSV(0, 255, var)); | |
FastLED.show(); | |
delay(5); | |
break; | |
} | |
case STATE_HYPNO: { | |
static int pos = 0; | |
for (int i = 0; i < STRIP_SIZE; i++) { | |
int v = cdist(pos, i); | |
if (v < 0) { v = 0;} | |
else { | |
v = min(4, v); | |
v = int(float(4 - v) / 8 * 255.0); | |
} | |
int w = cdist((pos + 8) % STRIP_SIZE, i); | |
if (w < 0) { w = 0;} | |
else { | |
w = min(4, w); | |
w = int(float(4 - w) / 8 * 255.0); | |
} | |
v = max(v, w); | |
strip_left_eye[lidx(i)] = CHSV(255, 0, v); | |
strip_right_eye[ridx(i)] = CHSV(255, 0, v); | |
} | |
pos +=1; | |
if (pos >= 16) { pos = 0; } | |
FastLED.show(); | |
delay(50); | |
break; | |
} | |
case STATE_IDLE: { | |
int rx = random(1,100); | |
if (rx > 95) { | |
// blink | |
set_eyes_hsv( CHSV(0, 0, 0)); | |
FastLED.show(); | |
delay(random(50, 100)); | |
} else if (rx < 90) { | |
// Smile | |
} else { | |
set_eyes_hsv( CHSV(180, 200, 255)); | |
FastLED.show(); | |
} | |
delay(100); | |
break; | |
} | |
} | |
} | |
void loop() { | |
while (MyBlue.available() > 0) { | |
int data = MyBlue.read(); | |
Serial.print("Reading bluetooth data: "); | |
Serial.print(data); | |
Serial.println(""); | |
MyBlue.write(data); | |
// Basic parse of the input first | |
MyBlue.flush(); | |
// Set the state | |
switch(data) { | |
case STATE_CLEAR: { | |
STATE = STATE_CLEAR; | |
break; | |
} | |
case STATE_TORCH: { | |
STATE = STATE_TORCH; | |
break; | |
} | |
case STATE_RAINBOW: { | |
STATE = STATE_RAINBOW; | |
break; | |
} | |
case STATE_RAGE: { | |
STATE = STATE_RAGE; | |
break; | |
} | |
case STATE_HYPNO: { | |
STATE = STATE_HYPNO; | |
break; | |
} | |
case STATE_IDLE: { | |
STATE = STATE_IDLE; | |
break; | |
} | |
} | |
} | |
do_state(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment