This is a rewrite of Duke of Dummies' Black Mage Eyes, whose tutorials heavily helped me create my own mask. Thank you!
Warning: Code is NOT a drop-in replacement, however it is easy:tm: for you to configure for your own setup.
-
Selecting emotions: Using a 4+2 button controller, you can select up to 16 emotions (+1 for the idle/nothing pressed state). The TOP and/or BOT buttons serve as a bank switch, giving you 4 banks of 4 possible emotions (TOP + 4 directions, BOT + 4 directions, TOP+BOT + 4 directions and nothing + 4 directions)
-
Brightness control: Press the UP and DOWN buttons simultaneously, and change the brightness between 5 levels using the TOP and BOT buttons.
Everything you will need to configure is at the start of the file: The LED strip's data pin as well as the pins for your controller.
// Number of pixels in LED chain
#define PIXEL_SUM 62
// Digital pin that's sending data to the eyes (Din on the strip)
#define DATA_PIN 12
// Controller pins
#define PIN_UP 9
#define PIN_DOWN 7
#define PIN_LEFT 11
#define PIN_RIGHT 10
#define PIN_TOP 6
#define PIN_BOTTOM 4
If you do not have a controller yet, set the value of TEST_MODE
to 1
. This will cycle through all the emotions for testing.
#define TEST_MODE 0
Keybinds are set in a switch statement situated at around line 300. Just replace the name of the emotion inside DrawEyes()
to the desired key combination.
switch(selectedEmot){
case 0: // Nothing
DrawEyes(EM_NORMAL);
break;
case 1: // Up
DrawEyes(EM_SKEPTICAL);
break;
case 2: // Up + Top
DrawEyes(EM_SUSPICIOUS);
break;
case 3: // Up + Bottom
DrawEyes(EM_ANGRY);
break;
case 4: // Up + Top + Bottom
DrawEyes(EM_VERYANGRY);
break;
case 5: // Left
DrawEyes(EM_SAD);
break;
case 6: // Left + Top
DrawEyes(EM_CRY);
break;
case 7: // Left + Bottom
DrawEyes(EM_BLINK);
break;
case 8: // Left + Top + Bottom
DrawEyes(EM_DISAPPOINTED);
break;
case 9: // Down
DrawEyes(EM_SURPRISE);
break;
case 10: // Down + Top
DrawEyes(EM_KAWAII);
break;
case 11: // Down + Bottom
DrawEyes(EM_UU);
break;
case 12: // Down + Top + Bottom
DrawEyes(EM_DEAD);
break;
case 13: // Right
DrawEyes(EM_HAPPIER);
break;
case 14: // Right + Top
DrawEyes(EM_WINK);
break;
case 15: // Right + Bottom
DrawEyes(EM_HAPPY);
break;
case 16: // Right + Top + Bottom
DrawEyes(EM_HEARTS);
break;
}
Emotions are stored as 2-dimensional arrays, corresponding to what the LEDs will display when viewed from the front (values in the "corners" are ignored).
Each number corresponds to a color defined in COL_PALETTE
(starting at 0, of course).
const uint32_t COL_PALETTE[6] = {COL_BLACK, COL_YELLOW, COL_RED, COL_BLUE, COL_PINK, COL_WHITE};
Here's an emotion and it's result:
const byte EM_CRY[7][10] PROGMEM = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, => ⚫⚫⚫⚫⚫ ⚫⚫⚫⚫⚫
{0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, => ⚫⚫⚫⚫🟡 🟡⚫⚫⚫⚫
{0, 0, 1, 1, 1, 1, 1, 1, 0, 0}, => ⚫⚫🟡🟡🟡 🟡🟡🟡⚫⚫
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, => 🟡🟡🟡🟡🟡 🟡🟡🟡🟡🟡
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, => 🟡🟡🟡🟡🟡 🟡🟡🟡🟡🟡
{3, 3, 1, 3, 3, 3, 3, 1, 3, 3}, => 🔵🔵🟡🔵🔵 🔵🔵🟡🔵🔵
{0, 3, 3, 3, 0, 0, 3, 3, 3, 0} => ⚫🔵🔵🔵⚫ ⚫🔵🔵🔵⚫
};
If you wish to add colors, create a new color using eyesArray.Color()
, specifying 3 values ranging from 0-255 (However, try to make the sum of the 3 numbers close to 3 or 4), then add it to the COL_PALETTE
, changing it's size to the number of colors in it.
const uint32_t COL_TURQUOISE = eyesArray.Color(0, 2, 2);
- const uint32_t COL_PALETTE[6] = {COL_BLACK, COL_YELLOW, COL_RED, COL_BLUE, COL_PINK, COL_WHITE};
+ const uint32_t COL_PALETTE[7] = {COL_BLACK, COL_YELLOW, COL_RED, COL_BLUE, COL_PINK, COL_WHITE, COL_TURQUOISE};
If your headset's LEDs are not laid out like mine, you will need to edit the DrawEyes()
method at the bottom of the file.
/*
* For reference, this is the index of each LED (viewed from the front) :
*
* 50 43 36 25 18 11
* 57 51 44 37 31 30 24 17 10 4
* 58 52 45 38 32 29 23 16 9 3
* 59 53 46 39 33 28 22 15 8 2
* 60 54 47 40 34 27 21 14 7 1
* 61 55 48 41 35 26 20 13 6 0
* 56 49 42 19 12 5
*/
I'm afraid to explain this and confuse you more than anything, just keep in mind that this method reads the 2-dimentionnal Emotion array according to the schema above:
- First cell read is the one anotated 0, which would be
EM_EMOTION[6][8]
- Second one would be 1 =>
EM_EMOTION[5][8]
... - Cell 6 would be
EM_EMOTION[6][7]
etc...