Как подключить два 1306 OLED дисплея по шине I2C к Arduino Mega?

Daminski

✩✩✩✩✩✩✩
26 Май 2021
23
1
Доброго времени суток. Использую для управления дисплеями библиотеку Adafruit, подключаю их по шине I2C. Столкнулся с проблемой подключения двух 1306 OLED дисплеев с разным разрешением (один 128х32 и второй 128х64). Они оба виделись микроконтроллером под одинаковым адресом 0х3С и при выводе текста на экран они просто дублировали друг друга.

Я перепаял адресный резистор на одном из дисплеев и он получил адрес 0х3D. Но возникла вторая проблема: я не знаю как теперь инициализировать второй дисплей в этой библиотеке, задать ему другое разрешение, а также совсем непонятно как выводить на два разных дисплея разную информацию?

Возможно кто-то сталкивался с такой задачей, и как вы её решили? Может нужно использовать другую библиотеку? Но хотелось бы конечно остаться на Adafruit чтобы не переписывать с нуля код для первого дисплея.
 

xof

★✩✩✩✩✩✩
24 Окт 2020
123
44
Но возникла вторая проблема: я не знаю как теперь инициализировать второй дисплей в этой библиотеке, задать ему другое разрешение, а также совсем непонятно как выводить на два разных дисплея разную информацию?
C++:
#include <Wire.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Default OLED address, usually
  display2.begin(SSD1306_SWITCHCAPVCC, 0x3D); // Second OLED address, via onboard jumper
 
 
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print("Display A");
  display.display();
 
  display2.clearDisplay();
  display2.setTextSize(1);
  display2.setTextColor(WHITE);
  display2.setCursor(0,0);
  display2.print("Display B");
  display2.display();
}

void loop() {
  }
Источник - https://forums.adafruit.com/viewtopic.php?t=150341
 
  • Лойс +1
Реакции: Daminski

rGlory

★✩✩✩✩✩✩
11 Май 2021
200
20
Я перепаял адресный резистор на одном из дисплеев и он получил адрес 0х3D. Но возникла вторая проблема: я не знаю как теперь инициализировать второй дисплей в этой библиотеке, задать ему другое разрешение, а также совсем непонятно как выводить на два разных дисплея разную информацию?
Адрес на шине I2C можно задать в begin()
C++:
bool begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC, uint8_t i2caddr = 0,
             bool reset = true, bool periphBegin = true);
второй параметр, это адрес. Для другого разрешения просто задаете другие макро, например
C++:
#define SCREEN1_WIDTH 128 // First OLED display width, in pixels
#define SCREEN1_HEIGHT 32 // First OLED display height, in pixels

#define SCREEN2_WIDTH 256 // Second OLED display width, in pixels
#define SCREEN2_HEIGHT 64 // Second OLED display height, in pixels


// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN1_WIDTH, SCREEN1_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display2(SCREEN2_WIDTH, SCREEN2_HEIGHT, &Wire, OLED_RESET);
 
  • Лойс +1
Реакции: Daminski

Daminski

✩✩✩✩✩✩✩
26 Май 2021
23
1
Адрес на шине I2C можно задать в begin()
C++:
bool begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC, uint8_t i2caddr = 0,
bool reset = true, bool periphBegin = true);
второй параметр, это адрес. Для другого разрешения просто задаете другие макро, например
Ого, а так тоже можно было? Выходит зря резистор перепаивал :)

#define SCREEN1_WIDTH 128 // First OLED display width, in pixels #define SCREEN1_HEIGHT 32 // First OLED display height, in pixels #define SCREEN2_WIDTH 256 // Second OLED display width, in pixels #define SCREEN2_HEIGHT 64 // Second OLED display height, in pixels
Вот это как раз то, что мне было нужно, благодарю!
 

rGlory

★✩✩✩✩✩✩
11 Май 2021
200
20
Ого, а так тоже можно было? Выходит зря резистор перепаивал
Да нет не зря, у вас два дисплея, если они сидят на одной шине I2C, то должны иметь разные адреса. Просто если вы не задаете адрес в begin(), то он будет использовать по умолчанию и будет работать только с тем устройством, в котором адрес не менялся. На этот счет в принципе проще использовать SPI - там просто нужно задавать разные пины для выбора устройства, да и самих шин SPI в Atmega2560 аж 5 штук.
 

Daminski

✩✩✩✩✩✩✩
26 Май 2021
23
1
На этот счет в принципе проще использовать SP
А разве этот тип дисплея поддерживает подключение по SPI? Вроде бы только I2C


Да нет не зря, у вас два дисплея, если они сидят на одной шине I2C, то должны иметь разные адреса.
Фух, ну тогда я рад, что не зря :)
 

rGlory

★✩✩✩✩✩✩
11 Май 2021
200
20
А разве этот тип дисплея поддерживает подключение по SPI? Вроде бы только I2C
Это зависит от того, что вы понимаете под "тип дисплея". Зависит от управляющей мискросхемы, есть такие дисплеи с I2C есть и SPI (есть ли такие, которые поддерживают оба не знаю, наврядли наверное). В самой библиотеке Adafruit_SSD1306 есть конструктор для пинов с I2C и есть для SPI.