Arduino Art Installation for special needs children: cLOUD
cLOUD is an art project that Eleanor (one of our members) designed as part of their university training.
Eleanor is going to university for a design degree. Strangely enough, she’s been assigned a project heavily centered around Arduino.
Luckily the Arduino platform shines in projects and prototypes for people from experienced makers to first time tinkerers; a lot can be accomplished even when just getting started.
This project was submitted by one of our members. You can see more of our member's projects here.
Not a member yet? Sign up here.
The cLOUD
She has made a sound-responsive ‘cLOUD’ lamp. It looks like an indoor cloud bringing a light show but no rain. It responds to sound, which can be music or voice, and typically the Arduino senses noise levels to generate corresponding light and colors. However, the cLOUD lights up with lightning like an incoming thunder storm when you cover the LDR sensor.
Not just a light show
Eleanor designed this as a visual stimulus providing enjoyment, entertainment, and development for the disabled. Light and sound together in a sensory room can be a therapeutic environment for special needs children, dealing with autism, deafness, blindness, and/or other developmental disabilities.
Here is a video of Eleanor experimenting around with neopixels as she tried to figure out how to control them like she wanted…
This cLOUD is wired for sound
An Arduino Uno does the controlling, a NeoPixel strip for lighting (including ability for individual control of each LED for brightness and color), a microphone and light dependent resistor for inputs, lamp bases, fishing line, poly-fill cloud material. This all comes together in a great looking cloud that lights up very nicely.
Your lessons have been great, and I’ve found my feet.
Eleanor Osada
Eleanor had a great experience building this project. She overcame what might seem a daunting task with her learning, an inviting platform, and a little guidance. After trying different coding techniques and debugging the code and hardware, she developed a cool and very helpful device for kids, and was able to build in some great functionality.
As a design student not focused on electronics, Eleanor was able to get this great project together using the Arduino platform and Programming Electronics tutorials. Her experience here will hopefully inspire her and others to jump in and do the project they are dreaming of without thinking that it will be too hard or technical to achieve.
It’s gonna be a bright, bright sunshiny future:
Arduino Code:
// Sound activated LEDs with the Trinket and NeoPixels // Sound activated LEDs with the Trinket and NeoPixels #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif #define MIC_PIN A0 // Microphone #define LED_PIN 6 // NeoPixel LED strand #define N_PIXELS 60 // number of pixels in LED strand #define N 110 // Number of samples to take each time readSamples is called #define fadeDelay 35 // delay time for each fade amount #define noiseLevel 10 // slope level of average mic noise without sound Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800); int samples[N]; // storage for a sample collection set int periodFactor = 0; // keep track of number of ms for period calculation int t1 = -1; // times of slope > 100 detected. int T; // period between times scaled to milliseconds int slope; // the slope of two collected data sample points byte periodChanged = 0; // Arduino setup Method void setup() { strip.begin(); ledsOff(); delay(500); displayColor(Wheel(100)); strip.show(); delay(500); } // Arduino loop Method void loop() { readSamples(); } // Read and Process Sample Data from Mic void readSamples() { for (int i = 0; i < N; i++) { samples[i] = analogRead(0); if (i > 0) { slope = samples[i] - samples[i - 1]; } else { slope = samples[i] - samples[N - 1]; } // Check if Slope greater than noiseLevel - sound that is not at noise level detected if (abs(slope) > noiseLevel) { if (slope < 0) { calculatePeriod(i); if (periodChanged == 1) { displayColor(getColor(T)); } } } else { ledsOff(); } periodFactor += 1; delay(1); } } void calculatePeriod(int i) { if (t1 == -1) { // t1 has not been set t1 = i; } else { // t1 was set so calc period int period = periodFactor * (i - t1); periodChanged = T == period ? 0 : 1; T = period; //Serial.println(T); // reset t1 to new i value t1 = i; periodFactor = 0; } } uint32_t getColor(int period) { if (period == -1) return Wheel(0); else if (period > 400) return Wheel(5); else return Wheel(map(-1 * period, -400, -1, 50, 255)); } void fadeOut() { for (int i = 0; i < 5; i++) { strip.setBrightness(110 - i * 20); strip.show(); // Update strip delay(fadeDelay); periodFactor += fadeDelay; } } void fadeIn() { strip.setBrightness(100); strip.show(); // Update strip // fade color in for (int i = 0; i < 5; i++) { //strip.setBrightness(20*i + 30); //strip.show(); // Update strip delay(fadeDelay); periodFactor += fadeDelay; } } void ledsOff() { fadeOut(); for (int i = 0; i < N_PIXELS; i++) { strip.setPixelColor(i, 0, 0, 0); } } void displayColor(uint32_t color) { for (int i = 0; i < N_PIXELS; i++) { strip.setPixelColor(i, color); } fadeIn(); } // Input a value 0 to 255 to get a color value. // The colors are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { if (WheelPos < 85) { return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } else if (WheelPos < 170) { WheelPos -= 85; return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } else { WheelPos -= 170; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } }