6

I'm trying to do something I think would be simple. I'd like to read the input of a electret microphone board and update the Adafruit 24-segment LED Bar Graph. I got each individual item working perfectly: I can read the input of the microphone on the analog pin and I can update the LED bar graph using I2C.

The issue occurs when I tried to combine the two concepts. When the bard graph gets updated, the analog input reads HIGH (1023) and never changes. I used my standard debug method and commented out code until the problem went away, so I've narrowed down the issue to a single line of code (right at the end). When the bar.writeDisplay is called the analog input perpetually reads 1023.

If I comment out that one line of code and re-upload my sketch the readings (in the Serial Monitor) are as expected (lower when its quiet and higher when its loud).

Under the hood Adafruit is using the Wire library.

I'm no good at wiring diagrams, but here's what I have:

RoboDyn Mega 2560 Pro (Embed) 5V, Gnd, SDA (20), SCL (21) to the LED Backpack 5V, Gnd, Out (A15/69)

That said, I'm relatively confident this is not a wiring problem as everything works until the software gets ahold of it.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

Adafruit_24bargraph bar = Adafruit_24bargraph();

int pin = 69; unsigned int sampleWindow = 50; // millis unsigned int maxScale = 24;

void setup() { Serial.begin(9600); bar.begin(0x70); // pass in the address }

void loop() { unsigned long startMillis = millis(); // Start of sample window unsigned int peakToPeak = 0; // peak-to-peak level unsigned int sample; unsigned int signalMax = 0; unsigned int signalMin = 1024; while (millis() - startMillis < sampleWindow) { sample = analogRead(pin); if (sample < 1024) { // toss out spurious readings if (sample > signalMax) { signalMax = sample; // save just the max levels } else if (sample < signalMin) { signalMin = sample; // save just the min levels } } } peakToPeak = signalMax - signalMin;
int displayPeak = map(peakToPeak, 0, 1023, 0, maxScale); // map 1v p-p level to the max scale of the display Serial.print("mic: "); Serial.print(peakToPeak); Serial.print(" "); Serial.println(displayPeak); for (uint8_t b = 0; b < 24; b++) { if (b <= displayPeak) { int c = LED_GREEN; if (b >= 20) { c = LED_RED; } else if (b >= 16) { c = LED_YELLOW; } bar.setBar(23 - b, c); } else { bar.setBar(23 - b, LED_OFF); } //bar.writeDisplay(); // <------- THIS LINE } }

The Breadboard

UPDATE: It appears to be something with the way Adafruit uses the Wire library. I have a similar problem when I use the Adafruit 7-segment library, when I use their MCP23017 library.

But it is wiring related too. If I uncomment the commented out line above but disconnect the I2C device the analog input starts working again.

One more thing I've discovered: it depends on how many lights are lit on the I2C board. Once all the lights are lit, the analog pin reads full. When only a couple of lights are lit, the values are lower. It is like the voltage going into the mic is higher when the lights are brighter.

For curiosity sake, I tried the same thing on a different Arduino (Adafruit Feather 32u4) with the same result (so it isn't my Arduino).

  • step one: comment out everything to do with the LED backback and see if it still gives 1023. – Majenko Oct 27 '20 at 19:24
  • As I said, that's what I've already done. If I comment out just that one line, I get normal readings. If I leave that one line in, I get 1023. – OneCleverMonkey Oct 27 '20 at 19:50
  • I may have been too quick to say it wasn't a wiring problem. I also don't get the issue if I leave that line in the code and remove the led backpack from the breadboard. Perhaps the LED backpack is the issue. Maybe I messed up the soldering or maybe I got a bad board. – OneCleverMonkey Oct 27 '20 at 19:51
  • Ah, I missed that bit. My bad. – Majenko Oct 27 '20 at 19:51
  • 1
    Can you post a photo of your breadboard setup? – Majenko Oct 27 '20 at 19:51
  • 1
    Do I maybe need a resistor somewhere? – OneCleverMonkey Oct 27 '20 at 20:07
  • No, that all looks fine to me. – Majenko Oct 27 '20 at 20:19
  • Does the supply voltage to the microphone and/or the microcontroller drop when the LEDs are on? – ocrdu Oct 29 '20 at 20:55
  • I found something similar https://esp32.com/viewtopic.php?t=2794 – xbox gamer Oct 30 '20 at 04:27
  • Does bending the micophone signal wire well away from the I2C wires make any difference? – ocrdu Oct 30 '20 at 10:06
  • You get 1023, what? The value of analogRead? The value of Peak-to-peak? I'd try using a different analog pin for the microphone. Also add a small delay after bar.writeDisplay();. Lastly; I'd try providing the microphone board with it's own power wires, instead of getting it from the bar-graph module. – Gerben Nov 04 '20 at 15:56
  • 2
    Add up all the current needed to run your project. Double the number. That's the amperage you should use as a minimum for your power supply. Guessing, say there are 24 LEDs at 3mA each. That's about 100mA? Add another 50mA for the Arduino Uno and another 50mA for the microphone? Totaled that's about 200mA? So you're power supply should be rated for at least 1/2 Amp. And you should double that if going through the analog Arduino regulator. BTW, USB power sources are only supposed to hand out 500mA. Beyond that they are allowed to drop voltage. That's a lot of guess work. Just try a big PS. – st2000 Nov 05 '20 at 14:54

1 Answers1

0

Since you cannot post a schematic I will take a SWAG and say you have two different hardware devices using the same pin for different reasons. I2C is a bus only and its associated pins cannot be used for anything else. Be sure the I2C bus is only connected to I2C terminals. Also be sure it is terminated properly.

Gil
  • 1,833
  • 8
  • 17