In this part, the Pro-Trinket 5v is supposed to run a constant animation loop on some 8x8 LED packs, while at the same time monitor a microphone and use its level to drive a NeoPixel Strip as a VU meter.
I've had to move the wires around a bit from how my drawing has them due to some concerns with interference, but this is the basic jist of it:
http://tinyurl.com/kwb4xwn
I have it all wired up and the code pieces work separately, but when combined I'm getting a weird effect....
the strip of LEDs used for the VU meter is refreshing veeeeeeery slowly and seems to be based entirely on the cycle of the animation for the 8x8 LED packs.
As such, the VU meter hardly responds at all.
http://tinyurl.com/qcqfhwq
- Code: Select all | TOGGLE FULL SIZE
/* LED "Color Organ" for Adafruit Trinket and NeoPixel LEDs.
Hardware requirements:
- Adafruit Trinket or Gemma mini microcontroller (ATTiny85).
- Adafruit Electret Microphone Amplifier (ID: 1063)
- Several Neopixels, you can mix and match
o Adafruit Flora RGB Smart Pixels (ID: 1260)
o Adafruit NeoPixel Digital LED strip (ID: 1138)
o Adafruit Neopixel Ring (ID: 1463)
Software requirements:
- Adafruit NeoPixel library
Connections:
- 5 V to mic amp +
- GND to mic amp -
- Analog pinto microphone output (configurable below)
- Digital pin to LED data input (configurable below)
Written by Adafruit Industries. Distributed under the BSD license.
This paragraph must be included in any redistribution.
*/
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
//define for LED pack info
Adafruit_8x8matrix matrixleft = Adafruit_8x8matrix();
Adafruit_8x8matrix matrixright = Adafruit_8x8matrix();
//define for headfin
#define N_PIXELS 10 // Number of pixels you are using
#define MIC_PIN A0 // Microphone is attached to Trinket GPIO #2/Gemma D2 (A1)
#define LED_PIN 4 // NeoPixel LED strand is connected to GPIO #0 / D0
#define DC_OFFSET 0 // DC offset in mic signal - if unusure, leave 0
#define NOISE 200 // Noise/hum/interference in mic signal
#define SAMPLES 70 // Length of buffer for dynamic level adjustment
#define TOP (N_PIXELS +1) // Allow dot to go slightly off scale
// Comment out the next line if you do not want brightness control or have a Gemma
//#define POT_PIN 3 // if defined, a potentiometer is on GPIO #3 (A3, Trinket only)
byte
peak = 0, // Used for falling dot
dotCount = 0, // Frame counter for delaying dot-falling speed
volCount = 0; // Frame counter for storing past volume data
int
vol[SAMPLES], // Collection of prior volume samples
lvl = 30, // Current "dampened" audio level
minLvlAvg = 0, // For dynamic adjustment of graph low & high
maxLvlAvg = 512;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
memset(vol, 0, sizeof(vol));
strip.begin();
Serial.begin(9600);
Serial.println("8x8 LED Matrix Test");
matrixleft.begin(0x70); // pass in the address
matrixright.begin(0x71);
}
static const uint8_t PROGMEM
lefteye_img[] =
{ B00000011,
B00000111,
B00011111,
B01011111,
B11011111,
B11011111,
B11111100,
B11100000 },
leftblink1[] =
{ B00000000,
B00000001,
B00000111,
B00011111,
B11011111,
B11011111,
B11111100,
B11100000 },
leftblink2[] =
{ B00000000,
B00000000,
B00000000,
B00000000,
B00000011,
B11011111,
B11111100,
B11100000 },
leftblink3[] =
{ B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000001,
B00111100,
B11100000 },
leftblink4[] =
{ B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000 },
righteye_img[] =
{ B11000000,
B11100000,
B11111000,
B11111010,
B11111011,
B11111011,
B00111111,
B00000111 },
rightblink1[] =
{ B00000000,
B10000000,
B11100000,
B11111000,
B11111011,
B11111011,
B00111111,
B00000111 },
rightblink2[] =
{ B00000000,
B00000000,
B00000000,
B00000000,
B11000000,
B11111011,
B00111111,
B00000111 },
rightblink3[] =
{ B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B10000000,
B00111100,
B00000111 },
rightblink4[] =
{ B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000 };
void loop() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = analogRead(MIC_PIN); // Raw reading from mic
n = abs(n - 512 - DC_OFFSET); // Center on zero
n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum
lvl = ((lvl * 7) + n) >> 3; // "Dampened" reading (else looks twitchy)
// Calculate bar height based on dynamic min/max levels (fixed point):
height = 1.0 * TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if(height < 0L) height = 0; // Clip output
else if(height > TOP) height = TOP;
if(height > peak) peak = height; // Keep 'peak' dot at top
// if POT_PIN is defined, we have a potentiometer on GPIO #3 on a Trinket
// (Gemma doesn't have this pin)
uint8_t bright = 100;
//#ifdef POT_PIN
// bright = analogRead(POT_PIN); // Read pin (0-255) (adjust potentiometer
// to give 0 to Vcc volts
//#endif
// strip.setBrightness(bright); // Set LED brightness (if POT_PIN at top
// define commented out, will be full)
// Color pixels based on rainbow gradient
for(i=0; i<N_PIXELS; i++) {
if(i >= height)
strip.setPixelColor(i, 0, 0, 0);
else
//strip.setPixelColor(i,Wheel(map(i,0,strip.numPixels()-1,30,150)));
strip.setPixelColor(i, 5, 250, 200); // sets the color to a nice sharp blue rather than rainbow.
}
strip.show(); // Update strip
vol[volCount] = n; // Save sample for dynamic leveling
if(++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter
// Get volume range of prior frames
minLvl = maxLvl = vol[0];
for(i=1; i<SAMPLES; i++) {
if(vol[i] < minLvl) minLvl = vol[i];
else if(vol[i] > maxLvl) maxLvl = vol[i];
}
// minLvl and maxLvl indicate the volume range over prior frames, used
// for vertically scaling the output graph (so it looks interesting
// regardless of volume level). If they're too close together though
// (e.g. at very low volume levels) the graph becomes super coarse
// and 'jumpy'...so keep some minimum distance between them (this
// also lets the graph go to zero when no sound is playing):
if((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
//eyes test start
//Eyes Open
matrixleft.clear();
matrixleft.setRotation(3);
matrixleft.drawBitmap(0, 0, lefteye_img, 8, 8, LED_ON);
matrixleft.writeDisplay();
matrixright.clear();
matrixright.setRotation(3);
matrixright.drawBitmap(0, 0, righteye_img, 8, 8, LED_ON);
matrixright.writeDisplay();
delay(5000);
//Eyes Blink
matrixleft.clear();
matrixleft.setRotation(3);
matrixleft.drawBitmap(0, 0, leftblink1, 8, 8, LED_ON);
matrixleft.writeDisplay();
matrixright.clear();
matrixright.setRotation(3);
matrixright.drawBitmap(0, 0, rightblink1, 8, 8, LED_ON);
matrixright.writeDisplay();
delay(25);
matrixleft.clear();
matrixleft.setRotation(3);
matrixleft.drawBitmap(0, 0, leftblink2, 8, 8, LED_ON);
matrixleft.writeDisplay();
matrixright.clear();
matrixright.setRotation(3);
matrixright.drawBitmap(0, 0, rightblink2, 8, 8, LED_ON);
matrixright.writeDisplay();
delay(25);
matrixleft.clear();
matrixleft.setRotation(3);
matrixleft.drawBitmap(0, 0, leftblink3, 8, 8, LED_ON);
matrixleft.writeDisplay();
matrixright.clear();
matrixright.setRotation(3);
matrixright.drawBitmap(0, 0, rightblink3, 8, 8, LED_ON);
matrixright.writeDisplay();
delay(25);
matrixleft.clear();
matrixleft.setRotation(3);
matrixleft.drawBitmap(0, 0, leftblink4, 8, 8, LED_ON);
matrixleft.writeDisplay();
matrixright.clear();
matrixright.setRotation(3);
matrixright.drawBitmap(0, 0, rightblink4, 8, 8, LED_ON);
matrixright.writeDisplay();
delay(25);
matrixleft.clear();
matrixleft.setRotation(3);
matrixleft.drawBitmap(0, 0, leftblink3, 8, 8, LED_ON);
matrixleft.writeDisplay();
matrixright.clear();
matrixright.setRotation(3);
matrixright.drawBitmap(0, 0, rightblink3, 8, 8, LED_ON);
matrixright.writeDisplay();
delay(25);
matrixleft.clear();
matrixleft.setRotation(3);
matrixleft.drawBitmap(0, 0, leftblink2, 8, 8, LED_ON);
matrixleft.writeDisplay();
matrixright.clear();
matrixright.setRotation(3);
matrixright.drawBitmap(0, 0, rightblink2, 8, 8, LED_ON);
matrixright.writeDisplay();
delay(25);
matrixleft.clear();
matrixleft.setRotation(3);
matrixleft.drawBitmap(0, 0, leftblink1, 8, 8, LED_ON);
matrixleft.writeDisplay();
matrixright.clear();
matrixright.setRotation(3);
matrixright.drawBitmap(0, 0, rightblink1, 8, 8, LED_ON);
matrixright.writeDisplay();
delay(25);
// eyes test end
matrixleft.setRotation(0);
matrixright.setRotation(0);
}
// 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);
}
}
AND on a slightly separate note, the VU meter goes nuts with noise when it's just hooked up on its own with the mic, I was following this guide here:
https://learn.adafruit.com/trinket-soun ... n?view=all
which didn't make use of 3.3v for the Microphone, but I'm thinking I might need to, and if that's the case, how do I get a 3.3v reference that'll satisfy this little snippet of code right there:
- Code: Select all | TOGGLE FULL SIZE
// This is only needed on 5V Arduinos (Uno, Leonardo, etc.).
// Connect 3.3V to mic AND TO AREF ON ARDUINO and enable this
// line. Audio samples are 'cleaner' at 3.3V.
// COMMENT OUT THIS LINE FOR 3.3V ARDUINOS (FLORA, ETC.):
// analogReference(EXTERNAL);
would really love some help on these, please. :)