The Making Process
Step 1:Code and Wiring
This project required quite a few components:
- Arduino Nano
- Accelerometer
- Speaker
- Amp
- SD data storage
- Two power sources
I needed to build a script that would detect the accelerometer being flipped over which would trigger oceanic lighting effects shining from inside the shell, pull a random sound file from an SD card, and play it on a tiny speaker. Everything had to fit into the shell. The whole thing required two power sources because without this, the power being drawn by the light interfered with the sound coming through the speaker.
Project Arduino Code
#include "FastLED.h"
#define NUM_LEDS 7
CRGB leds[NUM_LEDS];
#define LED_PIN 6
uint8_t gBrightness = 255;
#include "SD.h"
#define SD_ChipSelectPin 4
#include "SPI.h"
#include "TMRpcm.h"
TMRpcm audio;
File root;
char toPlay[20];
int indexToWrite = 0;
#define SPEAKER_PIN 9
#define DISABLE_SPEAKER2
// ACCELEROMETER
int Zval;
int accPin = A1;
void setup() {
audio.speakerPin = 9;
FastLED.addLeds
(leds, NUM_LEDS) .setCorrection(TypicalLEDStrip);
Serial.begin(9600);
pinMode(accPin, INPUT);
pinMode(SPEAKER_PIN, OUTPUT);
digitalWrite(SPEAKER_PIN, LOW);
pinMode(LED_PIN, OUTPUT);
Zval = analogRead(accPin);
if (!SD.begin(SD_ChipSelectPin)) {
Serial.println("SD fail");
return;
}
Serial.println("OK!");
root = SD.open("/"); // open SD card main root
audio.setVolume(0);
}
void loop() {
Zval = analogRead(accPin);
Serial.print(analogRead(accPin));
Serial.println();
// only the z-axis is needed to detect it's been flipped over
if (Zval > 460) {
digitalWrite(SPEAKER_PIN, LOW);
audio.pause();
audio.setVolume(0);
fill_solid(leds, NUM_LEDS, CRGB::Black);
FastLED[1].showLeds(gBrightness);
}
else if (Zval < 460) {
// SOUNDS
digitalWrite(SPEAKER_PIN, HIGH);
randomSeed(analogRead(0));
int randNumber = random(20); // random number between 0 and 18
makeName(randNumber, 0); // generate file name
audio.play(toPlay);
audio.quality(10);
audio.setVolume(4); // Volume below 5 causes lights to whine
while (audio.isPlaying()) {
delay(500);
// LIGHTS
TwinkleRandom(5, 200, false);
}
};
}
void TwinkleRandom(int Count, int SpeedDelay, boolean OnlyOne) {
setAll(0, 0, 0);
for (int i = 0; i < Count; i++) {
setPixel(random(NUM_LEDS), random(0, 55), random(0, 0), random(0, 255));
showStrip();
delay(SpeedDelay);
if (OnlyOne) {
setAll(0, 0, 0);
}
}
delay(SpeedDelay);
}
// ******* sd card and sound ******* //
void makeName(int number, int depth) { // generates a file name 0.WAV to
// 9999.WAV suppressing leading zeros
if (number > 9) {
makeName(number / 10, ++depth); // recursion
depth--;
number =
number %
10; // only have to deal with the next significant digit of the number
}
toPlay[indexToWrite] = (number & 0xf) | 0x30;
indexToWrite++;
if (depth > 0)
return; // return if we have more levels of recursion to go
else { // finish off the string with the wave extesion
toPlay[indexToWrite] = '.';
toPlay[1 + indexToWrite] = 'W';
toPlay[2 + indexToWrite] = 'A';
toPlay[3 + indexToWrite] = 'V';
toPlay[4 + indexToWrite] = '\0'; // terminator
indexToWrite = 0; // reset pointer for next time we enter
}
}
// LIGHTS LIGHTS LIGHTS *************************************
void Twinkle(byte red, byte green, byte blue, int Count, int SpeedDelay,
boolean OnlyOne) {
setAll(0, 0, 0);
for (int i = 0; i < Count; i++) {
setPixel(random(NUM_LEDS), red, green, blue);
showStrip();
delay(SpeedDelay);
if (OnlyOne) {
setAll(0, 0, 0);
}
}
delay(SpeedDelay);
}
// *** REPLACE TO HERE ***
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
FastLED.show();
#endif
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
#endif
}
void setAll(byte red, byte green, byte blue) {
for (int i = 0; i < NUM_LEDS; i++) {
setPixel(i, red, green, blue);
}
showStrip();
}
Step 2:Soldering
Soldering keeps the wires secure and gives me a chance to start trimming them shorter so that all the components can fit inside the shell.
Step 3:Assemblage
I made sure the electronics fit inside this beautiful natural conch shell. I placed velcro inside the shell to hold the accelerometer in the correct position. I glued small magnets around the inside and placed magnets inside of the fabric covering. The resulting cover holds everything inside of the shell and diffuses the lighting.
The Finished Seashell
The finished product! The fabric diffuses the LEDs beautifully and the speaker echos into the shell's chamber, creating a wonderful otherworldly effect.