I'm in the final stages of coding a project I've been struggling with (as I'm only a beginner when it comes to Arduino) - it uses Neopixels that react to sound (coming through an Adafruit sound sensor - A0), they work well on their own. What I'm trying my best to add is a "lightning mode" (as the Neopixels will sit inside lanterns that are designed to look like a cloud).
When a user places their hand over an LDR/photocell sat atop of the cloud, the sound reactive mode will cease and the Neopixels will begin flashing rapidly, much like lightning. I have the lightning code separately (see attached if you want to see it - it works well) but I'm struggling to combine the LDR reactive, sound reactive and lightning code. I want the sound reactive code to run constantly from the point the cloud is plugged into the mains - until the LDR is triggered, that is.
I hope that makes sense! My edition of the code is below. The error I'm currently getting is that "ledsOff" isn't declared - prior to adding "else", it was also telling me that "lightning" hadn't been declared either - even though void lightning() is further down the code.
Go easy on me, I've researched quite heavily - I hope it's just something minor tripping me up!
// Sound activated LEDs with Sound Sensor and NeoPixels
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define MIC_PIN A0 // Adafruit Amplifier/Mic
#define LED_PIN 6 // NeoPixel LED strand
#define N_PIXELS 60 // number of pixels in LED strand
#define N 25 // Number of samples to take each time readSamples is called
#define fadeDelay 30 // delay time for each fade amount
#define noiseLevel 6 // slope level of average mic noise without sound
#define SECTION_LEN (10) // number of LEDs to be grouped as one
#define NUM_SECTIONS (1) // number of LED groups
#define HEARTBEAT_PIN (13) // output pin for heartbeat LED <--- (these 3 lines ADDED)
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;
int sensorPin = A2; // select the input pin for the ldr
unsigned int sensorValue = 0; // variable to store the value coming from the ldr (2 lines ADDED)
int loop_count = 0;
bool heartbeat = false; // <- 2 added lines
// Arduino setup Method
void setup() {
pinMode(HEARTBEAT_PIN, OUTPUT);
strip.begin();
ledsOff();
delay(500);
displayColor(Wheel(100));
strip.show();
delay(500);
}
// Arduino loop Method
void loop() {
//Check to see if hand is above LDR
sensorValue = analogRead(sensorPin);
if(600 < sensorValue) {
lightning(); //DO LIGHTING STUFF
int delay_long = random(100, 200);
delay(delay_long);
}
else {
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(0.5);
}
}
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 * 255, 0 - 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);
}
const int sec_count = 9; // the maximum "width" of each lightning sequence
const int seq_count = 9; // the maximum "duration" of each lightning sequence
// run lightning flash sequence once (call from main loop to repeat)
void lightning()
{
// randomly select the color of the current lightning sequence
int r = random(200, 255);
int g = random(150, 255) - 100;
int b = random(200, 255);
// randomly select the order in which the LED sections will flash
// for the current lightning sequence
int seq_order[seq_count];
int seq_max = 0;
for (int i = 0; i < seq_count; i++)
{
seq_order[i] = random(0, sec_count);
seq_max = max(seq_max, seq_order[i]);
}
// randomly select the "duration" of the current lightning sequence
int sections = random(5, seq_count);
// randomly select the starting location of the current lightning sequence
int seq_start = random(0, NUM_SECTIONS - seq_max);
// loop through each of the chosen sections
for (int j = 0; j < sections; j++)
{
// loop through each LED of the current section
for (int k = 0; k < SECTION_LEN; k++)
{
// turn on the current LED
int pix_cur = ((seq_start + seq_order[j]) * SECTION_LEN) + k;
pixels.setPixelColor(pix_cur, pixels.Color(r, g, b));
// turn off the LEDs of the previous section
if (j > 0)
{
int pix_prv = ((seq_start + seq_order[j - 1]) * SECTION_LEN) + k;
pixels.setPixelColor(pix_prv, pixels.Color(0, 0, 0));
}
}
// very short (random) delay so we actually see the lightning
int delay_quick = random(15, 40);
delay(delay_quick);
pixels.show();
}
all_off();
}
}
LIGHTNING.ino (2.6 KB)