This project is interactive and explores how physical gestures and breath can be translated into emotional states using light and sound. Different movements trigger different emotional responses, allowing the user to perform and observe different moods. Using the Circuit Playground’s built-in accelerometer, speaker, microphone, buttons, and NeoPixel LEDs, the device will be able to respond to the user’s movements/orientations. Different motions will trigger different pitches, rhythms, and colors to represent different moods such as calmness, excitement/happiness, or anxiety/anger. For example, rapid movement or shaking the Circuit Playground for anxiety/anger will produce flashing red lights along with a high tone. On the other hand, stillness for calmness will create low tones and a cooler blue color. By tilting the board right, the lights will show yellow to represent excitement/happiness while following a circular path and lighting up to go around clockwise. When tilting the board left, the lights will go around counter-clockwise. The sounds produced will be in between/regular tones. In addition, when the user blows on the device, it activates a breathing mode where the light slowly pulses and the pitch lowers/descends, symbolizing calming down or regulating emotion. By pressing the right button once on the Circuit Playground, you can skip forward through the emotions. Also, by pressing the left button once, you can go back through the emotions. Additionally, the device is connected to the Adafruit NeoPixel LED Strip with Alligator Clips that mimics the light patterns from the device. The red clip from the LED strip connects to VOUT on the device, black clip to GND, and white clip to A1. The project, once the sketch is uploaded to the Circuit Playground using the USB and laptop, will work smoothly with just the 3x AAA Battery Pack (with JST connector) and the led strip connected to it as well. The goal of the project is to explore how technology can translate physical movement and emotional expression into an audiovisual experience that the user can both perform and observe.
Materials:
*Circuit Playground Express
*Micro USB cable/power
*Laptop with Arduino IDE
*Adafruit NeoPixel LED Strip with Alligator Clips
*3x AAA Battery Pack (with JST connector)
Features:
*Accelerometer (movement detection)
*NeoPixel LED ring
*Speaker
*Microphone
*Buttons A & B
*Adafruit NeoPixel Strip library
*Battery (can run without being connected to laptop/USB)
Audience:
*Students/Peers
*Family/Friends
*Everyday people that can use it for everyday/regular use and for their own interest
Resources:
Accelerometer:
*https://learn.adafruit.com/how-tall-is-it/hello-accelerometer
*https://learn.adafruit.com/make-it-shake-rattle-and-roll/uses-for-accelerometers
*https://learn.adafruit.com/make-it-shake-rattle-and-roll
*https://learn.adafruit.com/circuit-playground-lesson-number-0/accelerometer
Sound Sensor/Microphone:
*https://learn.adafruit.com/circuit-playground-lesson-number-0/sound-sensor
*https://learn.adafruit.com/make-it-sense/use-the-sound-sensor
Speaker:
*https://learn.adafruit.com/circuit-playground-lesson-number-0/mini-speaker
NeoPixel:
*https://learn.adafruit.com/circuit-playground-bike-light/basic-neopixel-animation
*https://learn.adafruit.com/circuit-playground-lesson-number-0/neopixels
*https://learn.adafruit.com/circuit-playground-bike-light/the-flasher
*https://learn.adafruit.com/circuit-playground-bike-light/the-all-of-them
Projects/Works Examples:
*https://learn.adafruit.com/circuit-playground-slouch-detector
*https://www.youtube.com/watch?v=hqGEoQycUnM
*https://vimeo.com/205586508
*https://learn.adafruit.com/sparkle-skirt/overview
*https://learn.adafruit.com/circuit-playground-music/motion-to-sound
*https://learn.adafruit.com/circuit-playground-music/using-the-circuit-playground-speaker
Code (for Sounds):
*https://makecode.adafruit.com/
*https://learn.adafruit.com/make-it-sound/music-and-sound-in-makecode *https://learn.adafruit.com/make-it-sound/music-and-sound-in-makecode-2
Sketch 1 (Laptop & USB):
#include <Adafruit_CircuitPlayground.h>
int pixelPos = 0;
int emotionMode = 0;
int totalModes = 5;
bool manualMode = false; // ← ADD THIS LINE
#define STRIP_PIN A1
#define NUM_STRIP_PIXELS 30 // change if your strip has a different length
Adafruit_CPlay_NeoPixel strip(NUM_STRIP_PIXELS, STRIP_PIN);
void setup() {
// put your setup code here, to run once:
CircuitPlayground.begin();
strip.begin();
strip.show();
}
void loop() {
// Read sensors
float x = CircuitPlayground.motionX();
float y = CircuitPlayground.motionY();
float z = CircuitPlayground.motionZ();
int soundLevel = CircuitPlayground.mic.soundPressureLevel(10);
// -------- BUTTON CONTROLS --------
// Button B → next emotion
if(CircuitPlayground.rightButton()){
manualMode = true;
emotionMode++;
if(emotionMode >= totalModes){
emotionMode = 0;
}
delay(350);
}
// Button A → previous emotion
if(CircuitPlayground.leftButton()){
manualMode = true;
emotionMode--;
if(emotionMode < 0){
emotionMode = totalModes - 1;
}
delay(350);
}
// -------- SENSOR DETECTION --------
if(!manualMode){
if(soundLevel > 70){
emotionMode = 4;
}
else if(abs(x) + abs(y) + abs(z) > 30){
emotionMode = 1;
}
else if(x > 5){
emotionMode = 2;
}
else if(x < -5){
emotionMode = 3;
}
else{
emotionMode = 0;
}
}
// -------- RUN CURRENT EMOTION --------
switch(emotionMode){
case 0:
calmEffect();
break;
case 1:
angryEffect();
break;
case 2:
circleClockwise();
break;
case 3:
circleCounter();
break;
case 4:
breathingEffect();
break;
}
}
// -------- EFFECT FUNCTIONS --------
// Calm blue
void calmEffect(){
setAllPixels(0,0,255);
CircuitPlayground.playTone(200,40);
delay(200);
}
// Angry red
void angryEffect(){
setAllPixels(255,0,0);
CircuitPlayground.playTone(800,60);
delay(80);
setAllPixels(0,0,0);
delay(80);
}
// Breathing calm
void breathingEffect(){
// inhale (fade in)
for(int b = 0; b <= 255; b += 5){
setAllPixels(b,b,b);
delay(20);
}
CircuitPlayground.playTone(900,80);
// exhale (fade out)
for(int b = 255; b >= 0; b -= 5){
setAllPixels(b,b,b);
delay(20);
}
CircuitPlayground.playTone(600,80);
CircuitPlayground.playTone(400,80);
}
// Clockwise circle
void circleClockwise(){
// CPX ring animation
CircuitPlayground.clearPixels();
CircuitPlayground.setPixelColor(pixelPos,255,255,0);
// Strip animation
strip.clear();
int stripPos = map(pixelPos,0,9,0,NUM_STRIP_PIXELS-1);
strip.setPixelColor(stripPos, strip.Color(255,255,0));
strip.show();
pixelPos++;
if(pixelPos > 9){
pixelPos = 0;
}
CircuitPlayground.playTone(400,40);
delay(100);
}
// Counter-clockwise circle
void circleCounter(){
// CPX ring animation
CircuitPlayground.clearPixels();
CircuitPlayground.setPixelColor(pixelPos,255,255,0);
// Strip animation
strip.clear();
int stripPos = map(pixelPos,0,9,0,NUM_STRIP_PIXELS-1);
strip.setPixelColor(stripPos, strip.Color(255,255,0));
strip.show();
pixelPos--;
if(pixelPos < 0){
pixelPos = 9;
}
CircuitPlayground.playTone(400,40);
delay(100);
}
// -------- MIRROR CPX RING TO STRIP --------
void setAllPixels(uint8_t r, uint8_t g, uint8_t b){
// CPX LEDs
for(int i = 0; i < 10; i++){
CircuitPlayground.setPixelColor(i, r, g, b);
}
// Strip LEDs
for(int i = 0; i < NUM_STRIP_PIXELS; i++){
strip.setPixelColor(i, strip.Color(r,g,b));
}
strip.show();
}
Sketch 2 (Battery):
#include <Adafruit_CircuitPlayground.h>
int pixelPos = 0;
int emotionMode = 0;
int totalModes = 5;
bool manualMode = false; // ← ADD THIS LINE
#define STRIP_PIN A1
#define NUM_STRIP_PIXELS 30 // change if your strip has a different length
Adafruit_CPlay_NeoPixel strip(NUM_STRIP_PIXELS, STRIP_PIN);
void setup() {
// put your setup code here, to run once:
CircuitPlayground.begin();
strip.begin();
strip.setBrightness(60); // try 40–80 range
strip.show();
}
void loop() {
// put your main code here, to run repeatedly:
// Read sensors
float x = CircuitPlayground.motionX();
float y = CircuitPlayground.motionY();
float z = CircuitPlayground.motionZ();
int soundLevel = CircuitPlayground.mic.soundPressureLevel(10);
// -------- BUTTON CONTROLS --------
// Button B → next emotion
if(CircuitPlayground.rightButton()){
manualMode = true;
emotionMode++;
if(emotionMode >= totalModes){
emotionMode = 0;
}
delay(350);
}
// Button A → previous emotion
if(CircuitPlayground.leftButton()){
manualMode = true;
emotionMode--;
if(emotionMode < 0){
emotionMode = totalModes - 1;
}
delay(350);
}
// -------- SENSOR DETECTION --------
if(!manualMode){
if(soundLevel > 70){
emotionMode = 4;
}
else if(abs(x) + abs(y) + abs(z) > 30){
emotionMode = 1;
}
else if(x > 5){
emotionMode = 2;
}
else if(x < -5){
emotionMode = 3;
}
else{
emotionMode = 0;
}
}
// -------- RUN CURRENT EMOTION --------
switch(emotionMode){
case 0:
calmEffect();
break;
case 1:
angryEffect();
break;
case 2:
circleClockwise();
break;
case 3:
circleCounter();
break;
case 4:
breathingEffect();
break;
}
}
// -------- EFFECT FUNCTIONS --------
// Calm blue
void calmEffect(){
setAllPixels(0,0,255);
CircuitPlayground.playTone(200,40);
delay(200);
}
// Angry red
void angryEffect(){
setAllPixels(255,0,0);
CircuitPlayground.playTone(800,60);
delay(80);
setAllPixels(0,0,0);
delay(80);
}
// Breathing calm
void breathingEffect(){
// inhale (fade in)
for(int b = 0; b <= 255; b += 10){
setAllPixels(b/2, b/2, b/2); // reduced brightness
delay(20);
}
CircuitPlayground.playTone(900,80);
// exhale (fade out)
for(int b = 255; b >= 0; b -= 10){
setAllPixels(b/2, b/2, b/2); // reduced brightness for battery
delay(20);
}
CircuitPlayground.playTone(600,80);
CircuitPlayground.playTone(400,80);
}
// Clockwise circle
void circleClockwise(){
// CPX ring animation
CircuitPlayground.clearPixels();
CircuitPlayground.setPixelColor(pixelPos,255,255,0);
// Strip animation
strip.clear();
int stripPos = map(pixelPos,0,9,0,NUM_STRIP_PIXELS-1);
strip.setPixelColor(stripPos, strip.Color(255,255,0));
strip.show();
pixelPos++;
if(pixelPos > 9){
pixelPos = 0;
}
CircuitPlayground.playTone(400,40);
delay(100);
}
// Counter-clockwise circle
void circleCounter(){
// CPX ring animation
CircuitPlayground.clearPixels();
CircuitPlayground.setPixelColor(pixelPos,255,255,0);
// Strip animation
strip.clear();
int stripPos = map(pixelPos,0,9,0,NUM_STRIP_PIXELS-1);
strip.setPixelColor(stripPos, strip.Color(255,255,0));
strip.show();
pixelPos--;
if(pixelPos < 0){
pixelPos = 9;
}
CircuitPlayground.playTone(400,40);
delay(100);
}
// -------- MIRROR CPX RING TO STRIP --------
void setAllPixels(uint8_t r, uint8_t g, uint8_t b){
// CPX LEDs
for(int i = 0; i < 10; i++){
CircuitPlayground.setPixelColor(i, r, g, b);
}
// Strip LEDs
for(int i = 0; i < NUM_STRIP_PIXELS; i++){
strip.setPixelColor(i, strip.Color(r,g,b));
}
strip.show();
}