Most, if not all, input pins on AVR controllers are internally protected by clamping diodes. These diodes prevent that an input voltage can be higher than the supply voltage.
Why these internal diodes are there:
It is important to realize that when an input pin does rise above the supply voltage and these diodes weren't there, the chip might act as an SCR, latch, short the battery, and the chip itself would probably get damaged by overcurrent/overheating.
Why your Arduino runs from the battery
Take a look at the circuit diagram below. When Vcc is detached from the normal power source, there is a path from the battery, via D1, to Vcc. The battery voltage is just high enough for the controller to operate.
simulate this circuit – Schematic created using CircuitLab
How to solve it
The solution is simple, add a high value resistor in series between the battery and the controller's input. Most AVR's have a maximum input leakage current specified (IIL) of 1μA, so you want to make sure the voltage drop is acceptable with that current, say 100kΩ.
But beware!
You do have to realize that the input may draw this current from your button cell and shorten its life time.
Observations from the data:
- First row of data appears to be a statistical outlier and can be rejected: All readings are lower than the profile for subsequent rows, probably due to start-up behavior.
- The last band is not saturating, it varies from 1002 to 1022, so it is capturing valid data
- Bands 4, 5 and 6 are nearly saturated, but are not "stuck to the rail", they do show some variation, so they aren't in a failed, stuck-to-Vcc state
This indicates that the signal generated by the preamplified electret microphone is very high at the frequency bands represented by output 4, 5 and 6. This can be verified using a reverse biased avalanche diode or a zener diode (Vzener > 7 Volts) as a white noise source replacing the electret microphone in the BoB's preamplifier, and checking the output using an oscilloscope in spectrum analysis mode.
This is not surprising at all, as electret microphones are not very linear, and the preamplifier in the break-out board does not have any equalization built in, as per SparkFun's schematic. Hence net result is expected to be a rather non-linear output profile.
The MSGEQ7 frequency response, on the other hand, is pretty linear across bands:
If the problem just involves getting the signal levels for all bands into usable range, a simple resistor voltage divider to attenuate the incoming signal to perhaps 50 or 75% should do the trick, across all bands. 50% will leave plenty of headroom to capture signal spikes on any band, as will invariably occur with normal audio.
simulate this circuit – Schematic created using CircuitLab
If it is also necessary to equalize the signal such that the mid-range and tweeter bands are attenuated while the relatively weak woofer bands are not affected, then a circuit such as a bandstop filter can be used, with a very low Q, and the pole frequency between the band-5 (~ 2200 Hz) and band-6 (~ 6000 Hz) frequencies. In effect, this will be more of a "band attenuate" filter, for the problematic bands, with some effect on the lower and higher bands as well:
(source)
Such a filter is non-trivial, and perhaps deserves a separate question if required.
Best Answer
I was running into the same issue, I tried reading voltage input on A0 and A1 (just to see if A0 was bad) and I was getting values higher than expected.
3.6 instead of 3.4
so the line
wasn't outputting the correct value
My Arduino mega 2560 was being powered by rasberry pi via USB
Solution:
Supply your arduino board with regulated dc input and don't rely on USB power for your 5v or 3.3v boards.