Since the beginning of the COVID-19 pandemic, cool face masks have shown up all over the internet. I started sewing face masks with my little machine, and saw a few light-up face masks show up across my social feed from time to time. I decided it was time to make my own.
I was excited to try out the Adafruit Feather with Bluefruit LE. It is lightweight and I thought it could tuck inside a face mask just perfectly. I purchased the Feather 32u4 with Bluefruit LE, an 8x8 Flexible NeoPixel matrix, some headers, a battery and an inline switch.
Here's a video of the face mask and the features:
The face mask is a design published by Craft Passion that has a pocket for some filter material, but I slid the electronics into the pocket. This basic design was inspired by Nerdforge on their Youtube Channel:
I wanted to do something similar, but using a pre-packaged matrix instead of soldering my own. I loved the idea in the video of making an application to design your pixel art and then uploading this art to the mask. I used a similar idea, making an app in Processing. In this little app, you can design your pixel art, and then export the art as Arduino code. I could then copy and paste the code into my mask code. I worked on the Processing app while I waited for my products to arrive.
I based the Color Matrix Picker off a color picker I found here: https://forum.processing.org/one/topic/processing-color-picker.html
My code is in this GitHub repository along with the Arduino code. https://github.com/dawndupriest/lightupfacemask
I decided to play with a silicon MEMS microphone, taping it to the back of the matrix - to see if I could maybe make a voice animation on the front of the mask. It works OK. I'm not sure this is the best use of that particular microphone.
I soldered the Feather to some female headers, and decided to use the male headers as removable connectors. The pin connections are:
NeoPixel Din to Feather Pin 6
NeoPixel 5v to Feather VBat
NeoPixel GND to Feather GND
Microphone Vin to 3V
Microphone GND to Feather GND
Microphone DC to Feather A1
One lesson I learned while making my second mask for my daughter: There is a second GND labeled on the Feather, but it's not actually Ground! Use the GND pin that's closest to the 3V pin... NOT the one closest to Tx. If you turn the Feather over, you'll see this one is actually labeled DFU and there's a silkscreening error on the board. This is explained in their hookup guide, but it's really important to know!! I hooked up the NeoPixel GND wire here at first, and when I plugged the Feather in, it let some smoke out and the charging light no longer turns on. It still seems to work, but I am not sure if it charges the battery anymore.
The soldering is all connected to male headers that can be removed from the Feather if I want to use it for a future project. Only the female headers are soldered onto the Feather. I used lots of electrical tape to tape the microphone to the back of the matrix, and then to cover any loose connections or poky ends that might catch on the fabric. I used the switch inline with the battery, so I don't have to remove the battery to turn it on and off. I used a 3D printed ear-saver I found on Thingiverse and added a little box that I can keep the battery in. This keeps the battery out of the moist environment of the mask and also gives me easy access to the on/off switch.
I also put a couple of small stitches in the mask to keep the matrix in place so it doesn't slide side to side. It's still removable, but you have to wiggle it around. The matrix just BARELY fits in the women's size mask, but might work better with the men's mask. I loved the way this gold fabric worked on top of the matrix, but just about any fabric will do.
Now it's time to code the project. Install Arduino if you haven't already, and you'll need to follow the instructions on the Adafruit hookup guide to get the board configuration files and libraries for the Feather, the Bluefruit capabilities, and the NeoPixel matrix. Use these two pages.
Feather hookup guide:
https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le
NeoMatrix libraries:
https://learn.adafruit.com/adafruit-neopixel-uberguide/neomatrix-library
After I got all of the libraries and configuration files, I opened the example called "matrixtest" and got that working first. I found I had to change the NeoPixel constructor to these settings:
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 8, PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
NEO_GRB + NEO_KHZ800);
Go to your example files, and you want to look in Examples --> Adafruit Bluefruit LE --> controller. Open that example. It uses the Bluefruit Connect app from your phone and gives you a skeleton you can work from to control the mask.
The first, most straightforward test is to see if you can use the color picker. You'll need to copy and paste some of the NeoPixel code into the "controller" example. Go into matrixtest and do some copying and pasting, or use this code here. In your declarations at the beginning of the "controller" example, paste these lines.
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#ifndef PSTR
#define PSTR // Make Arduino Due happy
#endif
#define PIN 6
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 8, PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
NEO_GRB + NEO_KHZ800);
Find your "void setup" function and paste these lines.
matrix.begin();
matrix.setBrightness(40);
matrix.setTextWrap(false);
matrix.setTextColor(textcolors[0]);
Then, look in "void loop" and notice the structure of parsing the Bluetooth commands. Each button in the Bluefruit Connect control pad is associated with a character code. The Color Picker is associated with the letter C. Look for this code:
// Color
if (packetbuffer[1] == 'C') {
uint8_t red = packetbuffer[2];
uint8_t green = packetbuffer[3];
uint8_t blue = packetbuffer[4];
Serial.print ("RGB #");
if (red < 0x10) Serial.print("0");
Serial.print(red, HEX);
if (green < 0x10) Serial.print("0");
Serial.print(green, HEX);
if (blue < 0x10) Serial.print("0");
Serial.println(blue, HEX);
}
And you'll just paste these two lines right after the "uint8_t blue=" line.
matrix.fillScreen(matrix.Color(red, green,blue));
matrix.show();
Upload the code, then open the Bluefruit Connect app, connect to the Feather, select "Controller" and then "Color Picker". If you choose a color and send it to the Feather, you should now see the entire matrix lights up that color. The colors are more vibrant and true if you use a battery instead of the USB cord for power.
Next you can use the control pad buttons to trigger animations and such. This is where the Processing app I used earlier came in handy. To make an animation, export a few different images that you want to display in order. For example, these two images show a coronavirus dancing.
void corona1(){
matrix.fillScreen(0);
matrix.drawPixel(2,1, matrix.Color(208,44,60));
matrix.drawPixel(5,1, matrix.Color(208,44,60));
matrix.drawPixel(3,2, matrix.Color(254,252,253));
matrix.drawPixel(4,2, matrix.Color(254,252,253));
matrix.drawPixel(1,3, matrix.Color(208,44,60));
matrix.drawPixel(2,3, matrix.Color(254,252,253));
matrix.drawPixel(3,3, matrix.Color(254,252,253));
matrix.drawPixel(4,3, matrix.Color(254,252,253));
matrix.drawPixel(5,3, matrix.Color(254,252,253));
matrix.drawPixel(2,4, matrix.Color(254,252,253));
matrix.drawPixel(3,4, matrix.Color(254,252,253));
matrix.drawPixel(4,4, matrix.Color(254,252,253));
matrix.drawPixel(5,4, matrix.Color(254,252,253));
matrix.drawPixel(6,4, matrix.Color(208,44,60));
matrix.drawPixel(3,5, matrix.Color(254,252,253));
matrix.drawPixel(4,5, matrix.Color(254,252,253));
matrix.drawPixel(2,6, matrix.Color(208,44,60));
matrix.drawPixel(5,6, matrix.Color(208,44,60));
matrix.show();
}
void corona3(){
matrix.fillScreen(0);
matrix.drawPixel(3,1, matrix.Color(208,44,60));
matrix.drawPixel(1,2, matrix.Color(208,44,60));
matrix.drawPixel(3,2, matrix.Color(254,252,253));
matrix.drawPixel(4,2, matrix.Color(254,252,253));
matrix.drawPixel(6,2, matrix.Color(208,44,60));
matrix.drawPixel(2,3, matrix.Color(254,252,253));
matrix.drawPixel(3,3, matrix.Color(254,252,253));
matrix.drawPixel(4,3, matrix.Color(254,252,253));
matrix.drawPixel(5,3, matrix.Color(254,252,253));
matrix.drawPixel(2,4, matrix.Color(254,252,253));
matrix.drawPixel(3,4, matrix.Color(254,252,253));
matrix.drawPixel(4,4, matrix.Color(254,252,253));
matrix.drawPixel(5,4, matrix.Color(254,252,253));
matrix.drawPixel(1,5, matrix.Color(208,44,60));
matrix.drawPixel(3,5, matrix.Color(254,252,253));
matrix.drawPixel(4,5, matrix.Color(254,252,253));
matrix.drawPixel(6,5, matrix.Color(208,44,60));
matrix.drawPixel(4,6, matrix.Color(208,44,60));
matrix.show();
}
Paste those two functions at the very very bottom of your Arduino code. Next, go back into void loop() and look for this section.
// Buttons
if (packetbuffer[1] == 'B') {
uint8_t buttnum = packetbuffer[2] - '0';
boolean pressed = packetbuffer[3] - '0';
Serial.print ("Button "); Serial.print(buttnum);
if (pressed) {
Serial.println(" pressed");
} else {
Serial.println(" released");
}
}
The control pad in the Bluefruit Connect app has four numbered buttons (1-4) and also four arrows(5-8), so you have eight possible animations with those buttons. To make the coronavirus animation activate when you push button 1, change the code to:
// Buttons
if (packetbuffer[1] == 'B') {
uint8_t buttnum = packetbuffer[2] - '0';
boolean pressed = packetbuffer[3] - '0';
Serial.print ("Button "); Serial.print(buttnum);
if (pressed) {
if(buttnum == 1)
{
for(int k = 0; k<5; k++)
{
corona1();
delay(400);
corona3();
delay(400);
}
}
Serial.println(" pressed");
} else {
Serial.println(" released");
}
}
If you want to add any other animations, just add more "if (buttnum== ) " conditionals and put as many animations as you want.
My example code also attempts to use the microphone to make a little "talking" animation. It looks for a threshold value on pin A1, and if that threshold is reached, an open-mouth image is shown. If the value is below the threshold, the closed-mouth image is shown. It works ok.
I also lifted some text-scrolling from the "matrixtest" example to make the "mask up" animation. The full video instructions are here if you'd like to make your own light-up face mask! I hope you modify and pay it forward - just please remember to give credit to previous creators!
Comments