Библиотека Adafruit_LEDBackpack мешает чтению аналогового ввода
Я пытаюсь сделать что-то простое. Я хотел бы прочитать вход платы электретного микрофона и обновить 24-сегментную светодиодную гистограмму Adafruit. У меня отлично работает каждый отдельный элемент: я могу считывать вход микрофона на аналоговом выводе и обновлять светодиодную гистограмму с помощью I2C.
Проблема возникает, когда я пытаюсь объединить эти две концепции. Когда гистограмма обновляется, на аналоговом входе отображается ВЫСОКИЙ уровень (1023) и он никогда не меняется. Я использовал свой стандартный метод отладки и комментировал код до тех пор, пока проблема не исчезла, поэтому я сузил проблему до одной строки кода (в самом конце). При вызове bar.writeDisplay аналоговый ввод постоянно считывает 1023.
Если я закомментирую эту строку кода и повторно загружу свой скетч, показания (в последовательном мониторе) будут такими, как ожидалось (ниже, когда тихо, и выше, когда громко).
Под капотом Adafruit используется библиотека Wire.
Я плохо разбираюсь в электрических схемах, но вот что у меня есть:
RoboDyn Mega 2560 Pro (встроить) 5V, Gnd, SDA (20), SCL (21) к светодиодному рюкзаку 5 В, земля, выход (A15/69)
Тем не менее, я относительно уверен, что это не проблема с проводкой, так как все работает до тех пор, пока программное обеспечение не обработает это.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_24bargraph bar = Adafruit_24bargraph();
int pin = 69;
unsigned int sampleWindow = 50; // миллисекунды
unsigned int maxScale = 24;
void setup() {
Serial.begin(9600);
bar.begin(0x70); // передаем адрес
}
void loop() {
unsigned long startMillis = millis(); // Начало окна примера
unsigned int peakToPeak = 0; // размах уровня
unsigned int sample;
unsigned int signalMax = 0;
unsigned int signalMin = 1024;
while (millis() - startMillis < sampleWindow) {
sample = analogRead(pin);
if (sample < 1024) { // отбросить ложные показания
if (sample > signalMax) {
signalMax = sample; // сохранить только максимальные уровни
}
else if (sample < signalMin) {
signalMin = sample; // сохраняем только минимальные уровни
}
}
}
peakToPeak = signalMax - signalMin;
int displayPeak = map(peakToPeak, 0, 1023, 0, maxScale); // сопоставляем уровень 1v pp с максимальным масштабом дисплея
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);
}
//бар.writeDisplay(); // <------- ЭТА СТРОКА
}
}
ОБНОВЛЕНИЕ: похоже, что-то связано с тем, как Adafruit использует библиотеку Wire. У меня похожая проблема, когда я использую 7-сегментную библиотеку Adafruit, когда я использую их библиотеку MCP23017.
Но это тоже связано с проводкой. Если я раскомментирую закомментированную выше строку, но отключу устройство I2C, аналоговый ввод снова начнет работать.
Еще одна вещь, которую я обнаружил: это зависит от того, сколько индикаторов горит на плате I2C. Как только все индикаторы загорятся, аналоговый вывод будет заполнен. Когда горит только пара лампочек, значения ниже. Это похоже на то, что напряжение, подаваемое на микрофон, выше, когда свет ярче.
Ради любопытства я попробовал то же самое на другом Arduino (Adafruit Feather 32u4) с тем же результатом (значит, это не мой Arduino).
@OneCleverMonkey, 👍6
Обсуждение1 ответ
Поскольку вы не можете опубликовать схему, я возьму SWAG и скажу, что у вас есть два разных аппаратных устройства, использующих один и тот же контакт по разным причинам. I2C — это только шина, и связанные с ней контакты не могут использоваться ни для чего другого. Убедитесь, что шина I2C подключена только к клеммам I2C. Также убедитесь, что он правильно завершен.
- Почему на моем ЖК-дисплее 16x2 отображаются странные буквы и не удается вставить клавишу с клавиатуры?
- Adafruit Micro-SD breakout не инициализируется на MEGA 2560
- Одинаковый вывод на дисплеях с разными I2C-адресами (библиотека AdaFruit, ESP32)
- Как изменить i2c-адрес Lidar Lite v3 с помощью библиотеки LidarLite (Решено)
- Совместима ли плата atmega 2560 с решеткой Adafruit Trellis?
- Отправка и получение различных типов данных через I2C в Arduino
- Как выбрать альтернативные контакты I2C на ESP32?
- Wire.h не найден!
Шаг первый: закомментируйте все, что связано с обратной светодиодной подсветкой, и посмотрите, выдает ли она по-прежнему 1023., @Majenko
Как я уже сказал, это то, что я уже сделал. Если я закомментирую только эту строку, я получу нормальные показания. Если я оставлю эту строку, я получу 1023., @OneCleverMonkey
Возможно, я поторопился сказать, что проблема не в проводке. У меня также не возникает проблемы, если я оставлю эту строку в коде и удалю светодиодный рюкзак с макетной платы. Возможно, проблема в светодиодном рюкзаке. Может я пайку накосячил или плата плохая попалась., @OneCleverMonkey
Ах, я пропустил этот момент. Виноват., @Majenko
Можете выложить фото макетной платы?, @Majenko
Может где резистор нужен?, @OneCleverMonkey
Нет, мне кажется, все в порядке., @Majenko
Падает ли напряжение питания микрофона и/или микроконтроллера, когда горят светодиоды?, @ocrdu
Я нашел что-то похожее https://esp32.com/viewtopic.php?t=2794, @xbox gamer
Имеет ли значение изгиб сигнального провода микрофона вдали от проводов I2C?, @ocrdu
Вы получаете 1023, что? Значение AnalogRead? Значение размаха? Я бы попробовал использовать другой аналоговый контакт для микрофона. Также добавьте небольшую задержку после
bar.writeDisplay();
. Наконец; Я бы попробовал снабдить плату микрофона собственными проводами питания, а не получать его от модуля гистограммы., @GerbenСложите все текущие, необходимые для запуска вашего проекта. Удвойте число. Это сила тока, которую вы должны использовать как минимум для вашего источника питания. Предположим, там 24 светодиода по 3 мА каждый. Это около 100 мА? Добавить еще 50 мА для Arduino Uno и еще 50 мА для микрофона? В сумме это около 200 мА? Таким образом, ваш блок питания должен быть рассчитан как минимум на 1/2 ампера. И вы должны удвоить это, если используете аналоговый регулятор Arduino. Кстати, источники питания USB должны выдавать только 500 мА. Кроме того, им разрешено падение напряжения. Это много догадок. Просто попробуйте большой PS., @st2000