Lo primero de todo, GRACIAS a tod@s, ya que gracias a vuestras respuestas lo tengo todo funcionando!!
finalmente compré un VMA309 , Y ya lo tengo conectado junto a un potenciometro, unos botones y con este codigo:
//Libraries
#include <Adafruit_NeoPixel.h> //Library to simplify interacting with the LED strand
#ifdef __AVR__
#include <avr/power.h> //Includes the library for power reduction registers if your chip supports them.
#endif //More info: http://www.nongnu.org/avr-libc/user-manual/group__avr__power.htlm
//Constants (change these as necessary)
#define LED_PIN A5 //Pin for the pixel strand. Can be analog or digital.
#define LED_TOTAL 144 //Change this to the number of LEDs in your strand.
#define LED_HALF LED_TOTAL/2
#define VISUALS 6 //Change this accordingly if you add/remove a visual in the switch-case in Visualize()
#define AUDIO_PIN A0 //Pin for the envelope of the sound detector
#define KNOB_PIN A1 //Pin for the trimpot 10K
#define BUTTON_1 6 //Button 1 cycles color palettes
#define BUTTON_2 5 //Button 2 cycles visualization modes
#define BUTTON_3 4 //Button 3 toggles shuffle mode (automated changing of color and visual)
//////////<Globals>
// These values either need to be remembered from the last pass of loop() or
// need to be accessed by several functions in one pass, so they need to be global.
Adafruit_NeoPixel strand = Adafruit_NeoPixel(LED_TOTAL, LED_PIN, NEO_GRB + NEO_KHZ800); //LED strand objetcs
uint16_t gradient = 0; //Used to iterate and loop through each color palette gradually
//IMPORTANT:
// This array holds the "threshold" of each color function (i.e. the largest number they take before repeating).
// The values are in the same order as in ColorPalette()'s switch case (Rainbow() is first, etc). This is simply to
// keep "gradient" from overflowing, the color functions themselves can take any positive value. For example, the
// largest value Rainbow() takes before looping is 1529, so "gradient" should reset after 1529, as listed.
// Make sure you add/remove values accordingly if you add/remove a color function in the switch-case in ColorPalette().
uint16_t thresholds[] = {1529, 1019, 764, 764, 764, 1274};
uint8_t palette = 0; //Holds the current color palette.
uint8_t visual = 0; //Holds the current visual being displayed.
uint8_t volume = 0; //Holds the volume level read from the sound detector.
uint8_t last = 0; //Holds the value of volume from the previous loop() pass.
float maxVol = 15; //Holds the largest volume recorded thus far to proportionally adjust the visual's responsiveness.
float knob = 1023.0; //Holds the percentage of how twisted the trimpot is. Used for adjusting the max brightness.
float avgBump = 0; //Holds the "average" volume-change to trigger a "bump."
float avgVol = 0; //Holds the "average" volume-level to proportionally adjust the visual experience.
float shuffleTime = 0; //Holds how many seconds of runtime ago the last shuffle was (if shuffle mode is on).
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//NOTE: The reason "average" is quoted is because it is not a true mathematical average. This is because I have
// found what I call a "sequenced average" is more successful in execution than a real average. The difference
// is that the sequenced average doesn't use the pool of all values recorded thus far, but rather averages the
// last average and the current value received (in sequence). Concretely:
//
// True average: (1 + 2 + 3) / 3 = 2
// Sequenced: (1 + 2) / 2 = 1.5 --> (1.5 + 3) / 2 = 2.25 (if 1, 2, 3 was the order the values were received)
//
// All "averages" in the program operate this way. The difference is subtle, but the reason is that sequenced
// averages are more adaptive to changes in the overall volume. In other words, if you went from loud to quiet,
// the sequenced average is more likely to show an accurate and proportional adjustment more fluently.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool shuffle = false; //Toggles shuffle mode.
bool bump = false; //Used to pass if there was a "bump" in volume
//For Traffic() visual
int8_t pos[LED_TOTAL] = { -2}; //Stores a population of color "dots" to iterate across the LED strand.
uint8_t rgb[LED_TOTAL][3] = {0}; //Stores each dot's specific RGB values.
//For Snake() visual
bool left = false; //Determines the direction of iteration. Recycled in PaletteDance()
int8_t dotPos = 0; //Holds which LED in the strand the dot is positioned at. Recycled in most other visuals.
float timeBump = 0; //Holds the time (in runtime seconds) the last "bump" occurred.
float avgTime = 0; //Holds the "average" amount of time between each "bump" (used for pacing the dot's movement).
//////////</Globals>
//////////<Standard Functions>
void setup() { //Like it's named, this gets ran before any other function.
Serial.begin(9600); //Sets data rate for serial data transmission.
//Defines the buttons pins to be input.
pinMode(BUTTON_1, INPUT); pinMode(BUTTON_2, INPUT); pinMode(BUTTON_3, INPUT);
//Write a "HIGH" value to the button pins.
digitalWrite(BUTTON_1, HIGH); digitalWrite(BUTTON_2, HIGH); digitalWrite(BUTTON_3, HIGH);
strand.begin(); //Initialize the LED strand object.
strand.show(); //Show a blank strand, just to get the LED's ready for use.
}
void loop() { //This is where the magic happens. This loop produces each frame of the visual.
volume = analogRead(AUDIO_PIN); //Record the volume level from the sound detector
knob = analogRead(KNOB_PIN) / 1023.0; //Record how far the trimpot is twisted
//Sets a threshold for volume.
// In practice I've found noise can get up to 15, so if it's lower, the visual thinks it's silent.
// Also if the volume is less than average volume / 2 (essentially an average with 0), it's considered silent.
if (volume < avgVol / 2.0 || volume < 15) volume = 0;
else avgVol = (avgVol + volume) / 2.0; //If non-zeo, take an "average" of volumes.
//If the current volume is larger than the loudest value recorded, overwrite
if (volume > maxVol) maxVol = volume;
//Check the Cycle* functions for specific instructions if you didn't include buttons in your design.
////////////////////////////////////////////////////////////////////////////////////////////////////
CyclePalette(); //Changes palette for shuffle mode or button press.
CycleVisual(); //Changes visualization for shuffle mode or button press.
ToggleShuffle(); //Toggles shuffle mode. Delete this if you didn't use buttons.
////////////////////////////////////////////////////////////////////////////////////////////////////
//This is where "gradient" is modulated to prevent overflow.
if (gradient > thresholds[palette]) {
gradient %= thresholds[palette] + 1;
//Everytime a palette gets completed is a good time to readjust "maxVol," just in case
// the song gets quieter; we also don't want to lose brightness intensity permanently
// because of one stray loud sound.
maxVol = (maxVol + volume) / 2.0;
}
//If there is a decent change in volume since the last pass, average it into "avgBump"
if (volume - last > 10) avgBump = (avgBump + (volume - last)) / 2.0;
//If there is a notable change in volume, trigger a "bump"
// avgbump is lowered just a little for comparing to make the visual slightly more sensitive to a beat.
bump = (volume - last > avgBump * .9);
//If a "bump" is triggered, average the time between bumps
if (bump) {
avgTime = (((millis() / 1000.0) - timeBump) + avgTime) / 2.0;
timeBump = millis() / 1000.0;
}
Visualize(); //Calls the appropriate visualization to be displayed with the globals as they are.
gradient++; //Increments gradient
last = volume; //Records current volume for next pass
delay(30); //Paces visuals so they aren't too fast to be enjoyable
}
//////////</Standard Functions>
//////////<Visual Functions>
//This function calls the appropriate visualization based on the value of "visual"
void Visualize() {
switch (visual) {
case 0: return Pulse();
case 1: return PalettePulse();
case 2: return Traffic();
case 3: return Snake();
case 4: return PaletteDance();
case 5: return Glitter();
case 6: return Paintball();
default: return Pulse();
}
}
lo tengo todo funcionando bien, y me queda una duda, y es ¿como ajustar la sensibilidad del microfono, para hacerla más baja y asi reaccione más a lo que yo quiera y no al ambiente ruidoso?
Gracias!!