Одинаковый вывод на дисплеях с разными I2C-адресами (библиотека AdaFruit, ESP32)
У меня есть два дисплея, подключенных к ESP32 через I2C, и я использую библиотеку AdaFruit. Вся обработка вывода дисплея упакована в собственную библиотеку. Во время тестирования у меня был настроен только один дисплей, и все выглядело нормально. Теперь, в моей фактической настройке с двумя дисплеями, я получаю вывод только первого дисплея на обоих экранах. Дисплеи работают на одной I2C-шине, заданы разные адреса. Я также запустил сканер адресов/портов, который подтвердил разные адреса (0x3C и 0x3D).
Раньше я использовал в такой настройке отдельные дисплеи с библиотекой AdaFruit, но только на Arduino Uno и без перемещения кода в собственные библиотеки. Поэтому я не могу сказать, что-то портит ESP32 или наличие нескольких файлов, или я что-то упускаю.
Вот части кода в cpp-файле, который я использовал для инициализации дисплеев, и некоторых функций, которые я вызываю:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <gfxfont.h>
#include <SPI.h>
#include "DisplayOut.h"
#include "Game.h"
/* -------------esp32 Pin setup --------------------- */
const byte displayData = 21; // I2C SDA
const byte displayClock = 23; // I2C СКЛ
/* --------------------------------------------------- */
// Определить OLED
#define OLED_RESET displayData
Adafruit_SSD1306 display1(OLED_RESET);
Adafruit_SSD1306 display2(OLED_RESET);
/* some variables */
void DisplayOutClass::init()
{
// Инициализируем каждый дисплей с помощью i2c-адреса
display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);
display1.setTextWrap(false);
display2.setTextWrap(false);
}
void DisplayOutClass::scorePlayer1(int score1)
{
display1.clearDisplay();
if (gameMode == 2)
{
display1.clearDisplay();
display1.setCursor(0, 0);
display1.setTextSize(2);
display1.setTextColor(WHITE);
display1.print(playerName[player1]);
}
display1.setTextSize(4);
display1.setTextColor(WHITE);
display1.setCursor(getCenteredPosX(3, String(score1)), 24);
display1.print(score1);
}
void DisplayOutClass::scorePlayer2(int score2)
{
display2.clearDisplay();
if (gameMode == 2)
{
display2.clearDisplay();
display2.setCursor(0, 0);
display2.setTextSize(2);
display2.setTextColor(WHITE);
display2.print(playerName[player2]);
}
display2.setTextSize(4);
display2.setTextColor(WHITE);
display2.setCursor(getCenteredPosX(3, String(score2)), 24);
display2.print(score2);
}
/* some more Functions */
DisplayOutClass DisplayOut;
Я не публиковал полный код или заголовочный файл, поскольку он превышает несколько сотен строк. Но это должно показать, как используются I2C-адреса. При необходимости я, конечно, могу выложить остальной код.
Мой следующий подход — либо попробовать библиотеку U8g2, либо попытаться запустить вторую шину I2C. Поскольку у меня уже есть готовая печатная плата, это будет для меня наименее предпочтительным вариантом.
@cfu479, 👍0
Обсуждение1 ответ
Лучший ответ:
Попробуйте новые конструкторы (старые устарели):
Wire.begin(21, 23); // SDA, SCL
Adafruit_SSD1306 display1(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT);
Adafruit_SSD1306 display2(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT);
display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);
Использование этого с «#define SSD1306_LCDWIDTH 128» и «#define SSD1306_LCDHEIGHT 64» просто дает мне ошибки и не компилируется, хотя я перезаписал библиотеку библиотекой из ссылки, чтобы быть уверенным, что у меня правильная версия., @cfu479
Нашел проблему, все еще неправильно использовал конструктор. В чем заключался трюк:
#define OLED_RESET -1
#define SCREEN_WIDTH 128 // Ширина OLED-дисплея в пикселях
#define SCREEN_HEIGHT 64 // Высота OLED-дисплея в пикселях
Adafruit_SSD1306 display1 (SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
, @cfu479
- Как выбрать альтернативные контакты I2C на ESP32?
- I2C связь между Arduino Uno и Nodemcu32-s (ESP32)
- Не могу отключить внутренний интерфейс I2C подтягиваний на ESP32
- Адрес TTGO TS I2C
- Отправка и получение различных типов данных через I2C в Arduino
- Альтернативы библиотеке Wire для I2C
- Библиотека Wire.h работает на Uno, но не компилируется для ATtiny85
- Вызов I2C во время Wire.requestFrom
Ваши контакты сброса установлены на номер адреса i2c, и вы используете один и тот же контакт сброса для обоих дисплеев? Вы читали, что вы можете сделать вывод сброса -1, чтобы не использовать его или поделиться им с сбросом Arduino., @Jot
Я согласен с @Jot, контакты сброса должны быть разделены: вы используете один и тот же контакт (то же определение OLED_RESET), что приводит к сбросу первого дисплея после инициализации..., @caligari
Каждый дисплей имеет только четыре контакта: VCC, GND, SCL, SDA. Таким образом, контакта сброса нет. Установка OLED_RESET на -1 не сработала, как и установка OLED_RESET на неиспользуемые контакты., @cfu479
Добавление false к методам начала display1.begin(SSD1306_SWITCHCAPVCC, 0x3C, false) и display2.begin(SSD1306_SWITCHCAPVCC, 0x3D, false) для отключения сброса также не принесло никакого прогресса., @cfu479
Кстати, мне пришлось использовать вторую строку i2c, чтобы esp32 работал нормально. сработало хорошо и положило конец моему разочарованию, но если есть лучший способ, мне тоже любопытно., @dandavis