Just to give a bit of a background: I'm a fairly new to Arduino, I've been playing around with my nano for a few weeks, I have a bit of programming background with Java and I tinker with electronics from time to time.
I've been trying to teach myself electronics theory for a while. I prefer learning by breaking things apart and blowing stuff up, but at some point you have to look at some equations.
Okay, so I've put together a simple circuit, some LED's, some shift registers (one in diagram for the sake of simplicity), a mic and a pot. Here are the component specs:
- Arduino: Nano
- Shift register: 74HC595
- Mic chip: VMA309
- Pot: 10K
What I'm trying to do is detect sound and send a pulse down the row of LED's, the sensitivity threshold is controlled by the pot while the sound detection is always sampling at the highest possible rate.
This works perfectly, HOWEVER, when any number of LED's are powered on, the analog output signal coming from the mic drops in sync with the voltage drop. I've measured the voltage drop as about 0.3V when all LED's are on, and the current draw is roughly 160mA. This causes the mic output to drop below the sensitivity threshold causing all LED's to light up permanently (until I lower the threshold with the pot and raise it back to where it was again)
I've been pulling my hair out trying to figure out an easy way around this, looked at countless post on here, videos on YouTube, random electronics blogs, etc.
So after a lot of frustration, I just added in an adaptive threshold using a circular buffer. It's not ideal, but it does work and more or less gives me the effect I'm looking for, even though the mic output is very erratic and not as accurate as it could otherwise be.
Another thing I did just as a troubleshooting step is to power the shift register and LED's off a separate 5V supply. This works perfectly, no drop in the mic output whatsoever, but also not ideal, I don't want to use up 2 USB ports. I also don't feel comfortable doing it this way, it just seems wrong.
Can someone please tell where I'm going wrong and how to fix the voltage/output drop?? You'd make my entire week.
Thanks!
P.S. I've modified the code to adapt to the mic output levels when it drops, so this isn't the exact sketch I was running when I had the problem of the whole thing going into always-on mode.
const int SND = 19;
const int POT = 14;
const int SER = 10;
const int LATCH = 11;
const int CLK = 12;
int updateInterval = 0;
boolean sndDetect = false;
unsigned long prevM = 0;
int s = 0;
int lowAvg = 0;
int hiAvg = 0;
int bufferAvg = 2;
void setup() {
pinMode(SND, INPUT);
pinMode(POT, INPUT);
pinMode(SER, OUTPUT);
pinMode(LATCH, OUTPUT);
pinMode(CLK, OUTPUT);
Serial.begin(9600);
}
void loop() {
unsigned long currM = millis();
updateInterval = map(analogRead(POT), 0, 1023, 0, 100);
s = analogRead(SND);
lowAvg = runningAvg(s);
hiAvg = lowAvg + bufferAvg * 2 + 1;
digitalWrite(LATCH, LOW);
if (s < lowAvg | s > hiAvg)
sndDetect = true;
if (currM - prevM > updateInterval)
{
prevM = currM;
if (sndDetect)
{
digitalWrite(SER, HIGH);
}
else
{
digitalWrite(SER, LOW);
}
digitalWrite(CLK, HIGH);
digitalWrite(CLK, LOW);
sndDetect = false;
}
digitalWrite(LATCH, HIGH);
Serial.print(s);
Serial.print("\t");
Serial.print(lowAvg);
Serial.print("\t");
Serial.println(hiAvg);
}
int runningAvg (int a)
{
#define block_size 10
static int block[block_size];
static byte index = 0;
static int sum = 0;
static byte count = 0;
sum -= block[index];
block[index] = a;
sum += block[index];
index++;
index = index % block_size;
if (count < block_size)
count++;
return (sum / count) - bufferAvg;
}