Skip to content

Instantly share code, notes, and snippets.

@OniDaito
Created April 25, 2021 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OniDaito/aa1c5d52e7dc9c7083e7321cd1d7c622 to your computer and use it in GitHub Desktop.
Save OniDaito/aa1c5d52e7dc9c7083e7321cd1d7c622 to your computer and use it in GitHub Desktop.
Plague Doctor Mask Arduino Gist
#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