Руководство по I2C OLED-дисплею с Arduino

В этой статье показано, как использовать I2C OLED-дисплей SSD1306 размером 0.96 дюйма с Arduino. Мы покажем некоторые функции OLED-дисплея, как подключить его к плате Arduino и как выводить текст, рисовать фигуры и отображать bitmap-изображения. В конце мы создадим проект-пример, который отображает показания температуры и влажности.

Руководство по I2C OLED-дисплею с Arduino

Знакомство с OLED-дисплеем 0.96 дюйма

Органический светоизлучающий диодный (OLED) дисплей, который мы будем использовать в этом руководстве — модель SSD1306: монохромный дисплей размером 0.96 дюйма с разрешением 128x64 пикселя, как показано на следующем рисунке.

I2C OLED-дисплей SSD1306

OLED-дисплей не требует подсветки, что обеспечивает очень хорошую контрастность в темных условиях. Кроме того, его пиксели потребляют энергию только когда они включены, поэтому OLED-дисплей потребляет меньше энергии по сравнению с другими дисплеями.

Модель, которую мы здесь используем, имеет только четыре вывода и взаимодействует с Arduino по протоколу I2C. Существуют модели с дополнительным выводом RESET. Также есть другие OLED-дисплеи, которые взаимодействуют по SPI.

Подключение выводов

Поскольку OLED-дисплей использует протокол связи I2C, подключение очень простое. Вам нужно только подключить его к выводам I2C Arduino Uno, как показано в таблице ниже.

Вывод

Подключение к Arduino Uno

Vin

5V

GND

GND

SCL

A5

SDA

A4

Если вы используете другую плату Arduino, убедитесь, что вы проверили правильные выводы I2C:

  • Nano: SDA (A4); SCL (A5);

  • MEGA: SDA (20); SCL (21);

  • Leonardo: SDA (20); SCL (21);

Схема подключения Arduino с OLED-дисплеем

Библиотеки

Для управления OLED-дисплеем вам нужны библиотеки adafruit_SSD1306.h и adafruit_GFX.h. Следуйте приведенным ниже инструкциям для установки этих библиотек.

  1. Откройте Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Должен открыться менеджер библиотек.

  2. Введите «SSD1306» в поле поиска и установите библиотеку SSD1306 от Adafruit.

Установка библиотеки SSD1306 OLED от Adafruit
  1. После установки библиотеки SSD1306 от Adafruit введите «GFX» в поле поиска и установите библиотеку.

Установка библиотеки GFX от Adafruit
  1. После установки библиотек перезапустите Arduino IDE.

Советы по написанию текста с использованием этих библиотек

Вот некоторые функции, которые помогут вам работать с библиотекой OLED-дисплея для вывода текста или рисования простой графики.

  • display.clearDisplay() – все пиксели выключены

  • display.drawPixel(x,y, color) – рисует пиксель по координатам x,y

  • display.setTextSize(n) – устанавливает размер шрифта, поддерживаются размеры от 1 до 8

  • display.setCursor(x,y) – устанавливает координаты для начала вывода текста

  • display.print("message") – выводит символы в позиции x,y

  • display.display() – вызовите этот метод, чтобы изменения вступили в силу

Тестирование OLED-дисплея

После подключения OLED-дисплея к Arduino и установки всех необходимых библиотек вы можете использовать один из примеров библиотеки, чтобы проверить, что всё работает правильно.

В Arduino IDE перейдите в File > Examples > Adafruit SSD1306 и выберите пример для вашего дисплея.

Тестирование примера библиотеки Adafruit SSD1306

Должен загрузиться следующий код:

/*********
  Complete project details at https://randomnerdtutorials.com

  This is an example for our Monochrome OLEDs based on SSD1306 drivers. Pick one up today in the adafruit shop! ------> http://www.adafruit.com/category/63_98
  This example is for a 128x32 pixel display using I2C to communicate 3 pins are required to interface (two I2C and one reset).
  Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
  Written by Limor Fried/Ladyada for Adafruit Industries, with contributions from the open source community. BSD license, check license.txt for more information All text above, and the splash screen below must be included in any redistribution.
*********/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // 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);

#define NUMFLAKES     10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

void setup() {
  Serial.begin(115200);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Draw a single pixel in white
  display.drawPixel(10, 10, WHITE);

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);
  // display.display() is NOT necessary after every single drawing command,
  // unless that's what you want...rather, you can batch up a bunch of
  // drawing operations and then update the screen all at once by calling
  // display.display(). These examples demonstrate both approaches...

  testdrawline();      // Draw many lines

  testdrawrect();      // Draw rectangles (outlines)

  testfillrect();      // Draw rectangles (filled)

  testdrawcircle();    // Draw circles (outlines)

  testfillcircle();    // Draw circles (filled)

  testdrawroundrect(); // Draw rounded rectangles (outlines)

  testfillroundrect(); // Draw rounded rectangles (filled)

  testdrawtriangle();  // Draw triangles (outlines)

  testfilltriangle();  // Draw triangles (filled)

  testdrawchar();      // Draw characters of the default font

  testdrawstyles();    // Draw 'stylized' characters

  testscrolltext();    // Draw scrolling text

  testdrawbitmap();    // Draw a small bitmap image

  // Invert and restore display, pausing in-between
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);

  testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
}

void loop() {
}

void testdrawline() {
  int16_t i;

  display.clearDisplay(); // Clear display buffer

  for(i=0; i<display.width(); i+=4) {
    display.drawLine(0, 0, i, display.height()-1, WHITE);
    display.display(); // Update screen with each newly-drawn line
    delay(1);
  }
  for(i=0; i<display.height(); i+=4) {
    display.drawLine(0, 0, display.width()-1, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=0; i<display.width(); i+=4) {
    display.drawLine(0, display.height()-1, i, 0, WHITE);
    display.display();
    delay(1);
  }
  for(i=display.height()-1; i>=0; i-=4) {
    display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=display.width()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
    display.display();
    delay(1);
  }
  for(i=display.height()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();

  for(i=0; i<display.height(); i+=4) {
    display.drawLine(display.width()-1, 0, 0, i, WHITE);
    display.display();
    delay(1);
  }
  for(i=0; i<display.width(); i+=4) {
    display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);
    display.display();
    delay(1);
  }

  delay(2000); // Pause for 2 seconds
}

void testdrawrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2; i+=2) {
    display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
    display.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testfillrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2; i+=3) {
    // The INVERSE color is used so rectangles alternate white/black
    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, INVERSE);
    display.display(); // Update screen with each newly-drawn rectangle
    delay(1);
  }

  delay(2000);
}

void testdrawcircle(void) {
  display.clearDisplay();

  for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) {
    display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfillcircle(void) {
  display.clearDisplay();

  for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) {
    // The INVERSE color is used so circles alternate white/black
    display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE);
    display.display(); // Update screen with each newly-drawn circle
    delay(1);
  }

  delay(2000);
}

void testdrawroundrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2-2; i+=2) {
    display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,
      display.height()/4, WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfillroundrect(void) {
  display.clearDisplay();

  for(int16_t i=0; i<display.height()/2-2; i+=2) {
    // The INVERSE color is used so round-rects alternate white/black
    display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,
      display.height()/4, INVERSE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testdrawtriangle(void) {
  display.clearDisplay();

  for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) {
    display.drawTriangle(
      display.width()/2  , display.height()/2-i,
      display.width()/2-i, display.height()/2+i,
      display.width()/2+i, display.height()/2+i, WHITE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testfilltriangle(void) {
  display.clearDisplay();

  for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) {
    // The INVERSE color is used so triangles alternate white/black
    display.fillTriangle(
      display.width()/2  , display.height()/2-i,
      display.width()/2-i, display.height()/2+i,
      display.width()/2+i, display.height()/2+i, INVERSE);
    display.display();
    delay(1);
  }

  delay(2000);
}

void testdrawchar(void) {
  display.clearDisplay();

  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  for(int16_t i=0; i<256; i++) {
    if(i == '\n') display.write(' ');
    else          display.write(i);
  }

  display.display();
  delay(2000);
}

void testdrawstyles(void) {
  display.clearDisplay();

  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner
  display.println(F("Hello, world!"));

  display.setTextColor(BLACK, WHITE); // Draw 'inverse' text
  display.println(3.141592);

  display.setTextSize(2);             // Draw 2X-scale text
  display.setTextColor(WHITE);
  display.print(F("0x")); display.println(0xDEADBEEF, HEX);

  display.display();
  delay(2000);
}

void testscrolltext(void) {
  display.clearDisplay();

  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(WHITE);
  display.setCursor(10, 0);
  display.println(F("scroll"));
  display.display();      // Show initial text
  delay(100);

  // Scroll in various directions, pausing in-between:
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
  delay(1000);
}

void testdrawbitmap(void) {
  display.clearDisplay();

  display.drawBitmap(
    (display.width()  - LOGO_WIDTH ) / 2,
    (display.height() - LOGO_HEIGHT) / 2,
    logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1000);
}

#define XPOS   0 // Indexes into the 'icons' array in function below
#define YPOS   1
#define DELTAY 2

void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  int8_t f, icons[NUMFLAKES][3];

  // Initialize 'snowflake' positions
  for(f=0; f< NUMFLAKES; f++) {
    icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
    icons[f][YPOS]   = -LOGO_HEIGHT;
    icons[f][DELTAY] = random(1, 6);
    Serial.print(F("x: "));
    Serial.print(icons[f][XPOS], DEC);
    Serial.print(F(" y: "));
    Serial.print(icons[f][YPOS], DEC);
    Serial.print(F(" dy: "));
    Serial.println(icons[f][DELTAY], DEC);
  }

  for(;;) { // Loop forever...
    display.clearDisplay(); // Clear the display buffer

    // Draw each snowflake:
    for(f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
    }

    display.display(); // Show the display buffer on the screen
    delay(200);        // Pause for 1/10 second

    // Then update coordinates of each flake...
    for(f=0; f< NUMFLAKES; f++) {
      icons[f][YPOS] += icons[f][DELTAY];
      // If snowflake is off the bottom of the screen...
      if (icons[f][YPOS] >= display.height()) {
        // Reinitialize to a random position, just off the top
        icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
        icons[f][YPOS]   = -LOGO_HEIGHT;
        icons[f][DELTAY] = random(1, 6);
      }
    }
  }
}

Посмотреть исходный код

Если у вашего OLED нет вывода RESET, вы должны установить переменную OLED_RESET в -1, как показано ниже:

#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Установка вывода RESET в Arduino IDE для OLED-дисплея

Загрузите код на плату Arduino. Не забудьте выбрать правильную плату и COM-порт в меню Tools.

Вы должны увидеть серию различных анимаций на OLED, как показано в следующем коротком видео.

Если ваш OLED-дисплей ничего не показывает:

  • Проверьте, что OLED-дисплей правильно подключен к Arduino

  • Перепроверьте I2C-адрес OLED-дисплея: при подключенном к Arduino OLED-дисплее загрузите этот код и проверьте I2C-адрес в Serial Monitor

При необходимости вам следует изменить адрес OLED в следующей строке. В нашем случае адрес – 0x3C.

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {

Вывод текста – OLED-дисплей

Библиотека Adafruit для OLED-дисплея содержит несколько функций для вывода текста. В этом разделе вы узнаете, как выводить и прокручивать текст с помощью функций библиотеки.

«Hello, world!» на OLED-дисплее

Следующий скетч выводит сообщение Hello, world! на OLED-дисплее.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

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

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 10);
  // Display static text
  display.println("Hello, world!");
  display.display();
}

void loop() {

}

Посмотреть исходный код

После загрузки кода вот что вы получите на OLED:

Arduino OLED-дисплей Hello World

Давайте кратко рассмотрим, как работает код.

Импорт библиотек

Сначала вам нужно импортировать необходимые библиотеки. Библиотека Wire для использования I2C и библиотеки Adafruit для записи на дисплей: Adafruit_GFX и Adafruit_SSD1306.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Инициализация OLED-дисплея

Затем вы определяете ширину и высоту OLED. В этом примере мы используем OLED-дисплей 128x64. Если вы используете другие размеры, вы можете изменить это в переменных SCREEN_WIDTH и SCREEN_HEIGHT.

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

Затем инициализируйте объект дисплея с шириной и высотой, определенными ранее, с протоколом связи I2C (&Wire).

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

Параметр (-1) означает, что ваш OLED-дисплей не имеет вывода RESET. Если ваш OLED-дисплей имеет вывод RESET, он должен быть подключен к GPIO. В этом случае вы должны передать номер GPIO в качестве параметра.

В setup() инициализируйте Serial Monitor на скорости 115200 бод для отладки.

Serial.begin(115200);

Инициализируйте OLED-дисплей с помощью метода begin() следующим образом:

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  Serial.println("SSD1306 allocation failed");
  for(;;); // Don't proceed, loop forever
}

Этот фрагмент также выводит сообщение в Serial Monitor, если мы не можем подключиться к дисплею.

Serial.println("SSD1306 allocation failed");

Если вы используете другой OLED-дисплей, вам может потребоваться изменить адрес OLED. В нашем случае адрес – 0x3C.

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {

Если этот адрес не работает, вы можете запустить скетч I2C-сканера, чтобы найти адрес вашего OLED. Вы можете найти скетч I2C-сканера здесь.

После инициализации дисплея добавьте двухсекундную задержку, чтобы OLED успел инициализироваться перед выводом текста:

delay(2000);

Очистка дисплея, установка размера шрифта, цвета и вывод текста

После инициализации дисплея очистите буфер дисплея с помощью метода clearDisplay():

display.clearDisplay();

Перед выводом текста вам нужно установить размер текста, цвет и место, где текст будет отображаться на OLED.

Установите размер шрифта с помощью метода setTextSize():

display.setTextSize(1);

Установите цвет шрифта с помощью метода setTextColor():

display.setTextColor(WHITE);

WHITE устанавливает белый шрифт и черный фон.

Определите позицию, с которой начинается текст, с помощью метода setCursor(x,y). В данном случае мы устанавливаем начало текста в координатах (0,10).

display.setCursor(0,10);

Наконец, вы можете отправить текст на дисплей с помощью метода println() следующим образом:

display.println("Hello, world!");

Затем вам нужно вызвать метод display(), чтобы фактически отобразить текст на экране.

display.display();

Прокрутка текста

Библиотека Adafruit OLED предоставляет полезные методы для легкой прокрутки текста.

  • startscrollright(0x00, 0x0F): прокрутка текста слева направо

  • startscrollleft(0x00, 0x0F): прокрутка текста справа налево

  • startscrolldiagright(0x00, 0x07): прокрутка текста из левого нижнего угла в правый верхний

  • startscrolldiagleft(0x00, 0x07): прокрутка текста из правого нижнего угла в левый верхний

Следующий скетч реализует эти методы.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

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

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  // Display static text
  display.println("Scrolling Hello");
  display.display();
  delay(100);

}

void loop() {
  // Scroll in various directions, pausing in-between:
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
  delay(1000);
}

Посмотреть исходный код

Текст прокручивается, как показано в следующем коротком видео.

Использование других шрифтов – OLED-дисплей

Библиотека Adafruit GFX позволяет использовать альтернативные шрифты помимо встроенных. Она позволяет выбирать между Serif, Sans и Mono. Каждый шрифт доступен в жирном, курсивном начертании и в различных размерах.

Размеры задаются самим шрифтом. Поэтому метод setTextSize() не работает с этими шрифтами. Шрифты доступны в размерах 9, 12, 18 и 24 пункта и также содержат 7-битные символы (коды ASCII) (обозначены как 7b в названии шрифта).

Вы можете выбрать из следующего набора шрифтов:

FreeMono12pt7b.h             FreeSansBoldOblique12pt7b.h
FreeMono18pt7b.h             FreeSansBoldOblique18pt7b.h
FreeMono24pt7b.h             FreeSansBoldOblique24pt7b.h
FreeMono9pt7b.h                      FreeSansBoldOblique9pt7b.h
FreeMonoBold12pt7b.h         FreeSansOblique12pt7b.h
FreeMonoBold18pt7b.h         FreeSansOblique18pt7b.h
FreeMonoBold24pt7b.h         FreeSansOblique24pt7b.h
FreeMonoBold9pt7b.h          FreeSansOblique9pt7b.h
FreeMonoBoldOblique12pt7b.h  FreeSerif12pt7b.h
FreeMonoBoldOblique18pt7b.h  FreeSerif18pt7b.h
FreeMonoBoldOblique24pt7b.h  FreeSerif24pt7b.h
FreeMonoBoldOblique9pt7b.h   FreeSerif9pt7b.h
FreeMonoOblique12pt7b.h              FreeSerifBold12pt7b.h
FreeMonoOblique18pt7b.h              FreeSerifBold18pt7b.h
FreeMonoOblique24pt7b.h              FreeSerifBold24pt7b.h
FreeMonoOblique9pt7b.h               FreeSerifBold9pt7b.h
FreeSans12pt7b.h             FreeSerifBoldItalic12pt7b.h
FreeSans18pt7b.h             FreeSerifBoldItalic18pt7b.h
FreeSans24pt7b.h             FreeSerifBoldItalic24pt7b.h
FreeSans9pt7b.h                      FreeSerifBoldItalic9pt7b.h
FreeSansBold12pt7b.h         FreeSerifItalic12pt7b.h
FreeSansBold18pt7b.h         FreeSerifItalic18pt7b.h
FreeSansBold24pt7b.h         FreeSerifItalic24pt7b.h
FreeSansBold9pt7b.h          FreeSerifItalic9pt7b.h

Шрифты, которые лучше всего работают с OLED-дисплеем – размеры 9 и 12 пунктов.

Чтобы использовать один из этих шрифтов, сначала вам нужно включить его в свой скетч, например:

#include <Fonts/FreeSerif12pt7b.h>

Затем вам нужно использовать метод setFont() и передать в качестве аргумента указанный шрифт:

display.setFont(&FreeSerif12pt7b);

После указания шрифта все методы для вывода текста будут использовать этот шрифт. Чтобы вернуться к использованию оригинального шрифта, просто вызовите метод setFont() без аргументов:

display.setFont();

Загрузите следующий скетч на вашу плату:

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerif9pt7b.h>

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

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 allocation failed");
    for(;;);
  }
  delay(2000);

  display.setFont(&FreeSerif9pt7b);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,20);
  display.println("Hello, world!");
  display.display();
  delay(2000);
}
void loop() {

}

Посмотреть исходный код

Теперь ваш дисплей выводит сообщение «Hello, world!» шрифтом FreeSerif.

Arduino OLED-дисплей тип шрифта

Рисование фигур на OLED-дисплее

Библиотека Adafruit OLED предоставляет полезные методы для рисования пикселей, линий и фигур. Давайте кратко рассмотрим эти методы.

Рисование пикселя

Arduino OLED-дисплей пиксель точка

Чтобы нарисовать пиксель на OLED-дисплее, вы можете использовать метод drawPixel(x, y, color), который принимает в качестве аргументов координаты x и y, где появляется пиксель, и цвет. Например:

display.drawPixel(64, 32, WHITE);

Рисование линии

Arduino OLED-дисплей линия

Используйте метод drawLine(x1, y1, x2, y2, color) для создания линии. Координаты (x1, y1) указывают начало линии, а координаты (x2, y2) указывают, где линия заканчивается. Например:

display.drawLine(0, 0, 127, 20, WHITE);

Рисование прямоугольника

Arduino OLED-дисплей прямоугольник

Метод drawRect(x, y, width, height, color) предоставляет простой способ нарисовать прямоугольник. Координаты (x, y) указывают верхний левый угол прямоугольника. Затем вам нужно указать ширину, высоту и цвет:

display.drawRect(10, 10, 50, 30, WHITE);

Вы можете использовать fillRect(x, y, width, height, color) для рисования залитого прямоугольника. Этот метод принимает те же аргументы, что и drawRect().

Arduino OLED-дисплей залитый прямоугольник

Библиотека также предоставляет методы для отображения прямоугольников со скругленными углами: drawRoundRect() и fillRoundRect(). Эти методы принимают те же аргументы, что и предыдущие методы, плюс радиус скругления углов. Например:

display.drawRoundRect(10, 10, 30, 50, 2, WHITE);
Arduino OLED-дисплей скругленный прямоугольник

Или залитый скругленный прямоугольник:

display.fillRoundRect(10, 10, 30, 50, 2, WHITE);
Arduino OLED-дисплей залитый скругленный прямоугольник

Рисование окружности

Arduino OLED-дисплей окружность

Чтобы нарисовать окружность, используйте метод drawCircle(x, y, radius, color). Координаты (x,y) указывают центр окружности. Вы также должны передать радиус в качестве аргумента. Например:

display.drawCircle(64, 32, 10, WHITE);

Аналогично, для создания залитой окружности используйте метод fillCircle() с теми же аргументами:

display.fillCircle(64, 32, 10, WHITE);
Arduino OLED-дисплей залитая окружность

Рисование треугольника

Arduino OLED-дисплей треугольник

Используйте метод drawTriangle(x1, y1, x2, y2, x3, y3, color) для построения треугольника. Этот метод принимает в качестве аргументов координаты каждого угла и цвет.

display.drawTriangle(10, 10, 55, 20, 5, 40, WHITE);

Используйте метод fillTriangle() для рисования залитого треугольника.

display.fillTriangle(10, 10, 55, 20, 5, 40, WHITE);
Arduino OLED-дисплей залитый треугольник

Инверсия

Библиотека предоставляет дополнительный метод, который можно использовать с фигурами или текстом: метод invertDisplay(). Передайте true в качестве аргумента для инверсии цветов экрана или false для возврата к исходным цветам.

Если вы вызовете следующую команду после определения треугольника:

display.invertDisplay(true);

Вы получите инвертированный треугольник следующим образом:

Arduino OLED-дисплей инвертированный треугольник

Код – Рисование фигур

Загрузите следующий скетч, который реализует каждый фрагмент кода, рассмотренный ранее, и последовательно отображает все фигуры.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Draw a single pixel in white
  display.drawPixel(64, 32, WHITE);
  display.display();
  delay(3000);

  // Draw line
  display.clearDisplay();
  display.drawLine(0, 0, 127, 20, WHITE);
  display.display();
  delay(3000);

  // Draw rectangle
  display.clearDisplay();
  display.drawRect(30, 10, 50, 30, WHITE);
  display.display();
  delay(3000);
  // Fill rectangle
  display.fillRect(30, 10, 50, 30, WHITE);
  display.display();
  delay(3000);

  // Draw round rectangle
  display.clearDisplay();
  display.drawRoundRect(10, 10, 30, 50, 2, WHITE);
  display.display();
  delay(3000);
  // Fill round rectangle
  display.clearDisplay();
  display.fillRoundRect(10, 10, 30, 50, 2, WHITE);
  display.display();
  delay(3000);

  // Draw circle
  display.clearDisplay();
  display.drawCircle(64, 32, 10, WHITE);
  display.display();
  delay(3000);
  // Fill circle
  display.fillCircle(64, 32, 10, WHITE);
  display.display();
  delay(3000);

  // Draw triangle
  display.clearDisplay();
  display.drawTriangle(10, 10, 55, 20, 5, 40, WHITE);
  display.display();
  delay(3000);
  // Fill triangle
  display.fillTriangle(10, 10, 55, 20, 5, 40, WHITE);
  display.display();
  delay(3000);

  // Invert and restore display, pausing in-between
  display.invertDisplay(true);
  delay(3000);
  display.invertDisplay(false);
  delay(3000);
}

void loop() {

}

Посмотреть исходный код

Отображение bitmap-изображений на OLED

Вы можете отображать монохромные bitmap-изображения размером 128x64 на OLED-дисплее.

Сначала используйте графический редактор, чтобы изменить размер фотографии или изображения и сохранить его как монохромный bitmap. Если вы работаете на Windows PC, вы можете использовать Paint.

Отображение bitmap-изображений OLED конвертация изображения

Затем используйте конвертер изображения в C-массив для преобразования изображения в массив. Мы использовали LCD Image Converter.

Запустите программу и начните с нового изображения. Перейдите в Image > Import и выберите bitmap-изображение, которое вы создали ранее.

Отображение bitmap-изображений OLED

Перейдите в Options > Conversion и на вкладке Prepare выберите следующие параметры:

  • Type: Monochrome, Threshold Dither

  • Main Scan Direction: Top to Bottom

  • Line Scan Direction: Forward

Отображение bitmap-изображений OLED конвертация изображения параметры

Перейдите на вкладку Image и выберите следующие параметры:

  • Split to rows

  • Block size: 8 bit

  • Byte order: Little-Endian

Отображение bitmap-изображений OLED конвертация экспорт

Затем нажмите OK. Наконец, в главном меню перейдите в File > Convert. Должен быть сохранен новый файл с расширением .c. Этот файл содержит C-массив для изображения. Откройте этот файл в текстовом редакторе и скопируйте массив.

В нашем случае вот массив, который мы получили:

static const uint8_t image_data_Saraarray[1024] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x14, 0x9e, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x36, 0x3f, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x6d, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xfb, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xd7, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xef, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xdf, 0xff, 0x90, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xbf, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1d, 0x7f, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x01, 0x1b, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x02, 0xa7, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0x80, 0x00, 0x0b, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x07, 0xff, 0xf8, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0e, 0x01, 0xff, 0xc0, 0x38, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0x46, 0xff, 0xb1, 0x18, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0x97, 0xff, 0xc0, 0x7a, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xbf, 0xff, 0xff, 0xff, 0xfe, 0x81, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xfc, 0x81, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0x83, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xbf, 0xff, 0xfe, 0xff, 0xfd, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfb, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xdc, 0xff, 0xfa, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xd8, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xd0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x90, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x02, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xf5, 0xff, 0xd7, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x5f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xa0, 0x00, 0x0f, 0xfb, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x0f, 0xfd, 0xff, 0xdf, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xbf, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x87, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x43, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x73, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfe, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7b, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00, 0x33, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x27, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x67, 0xff, 0xe0, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfd, 0x40, 0x00, 0x00, 0xf3, 0xff, 0xc4, 0x00, 0x00, 0x0b, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfe, 0x80, 0x00, 0x00, 0xfc, 0xff, 0x8c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0x3c, 0x3c, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x7c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff
};

Посмотреть исходный код

Скопируйте ваш массив в скетч. Затем для отображения массива используйте метод drawBitmap(), который принимает следующие аргументы (x, y, массив изображения, ширина изображения, высота изображения, поворот). Координаты (x, y) определяют, где начинается отображение изображения.

Скопируйте приведенный ниже код для отображения вашего bitmap-изображения на OLED.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

static const unsigned char PROGMEM image_data_Saraarray[] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x14, 0x9e, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x36, 0x3f, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x6d, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xfb, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xd7, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xef, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xdf, 0xff, 0x90, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xbf, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1d, 0x7f, 0xff, 0xd0, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x01, 0x1b, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x02, 0xa7, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0x80, 0x00, 0x0b, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x07, 0xff, 0xf8, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0e, 0x01, 0xff, 0xc0, 0x38, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0x46, 0xff, 0xb1, 0x18, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0x97, 0xff, 0xc0, 0x7a, 0x07, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xbf, 0xff, 0xff, 0xff, 0xfe, 0x81, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xfc, 0x81, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0x83, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xbf, 0xff, 0xfe, 0xff, 0xfd, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfb, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xdc, 0xff, 0xfa, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xd8, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xd0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x90, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x02, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xf5, 0xff, 0xd7, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x5f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xa0, 0x00, 0x0f, 0xfb, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x0f, 0xfd, 0xff, 0xdf, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xbf, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x87, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x43, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x73, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfe, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7b, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00, 0x33, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfd, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x27, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x00, 0x67, 0xff, 0xe0, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfd, 0x40, 0x00, 0x00, 0xf3, 0xff, 0xc4, 0x00, 0x00, 0x0b, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfe, 0x80, 0x00, 0x00, 0xfc, 0xff, 0x8c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0x3c, 0x3c, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x7c, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff
};

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000); // Pause for 2 seconds

  // Clear the buffer.
  display.clearDisplay();

  // Draw bitmap on the screen
  display.drawBitmap(0, 0, image_data_Saraarray, 128, 64, 1);
  display.display();
}

void loop() {

}

Посмотреть исходный код

После загрузки кода вот что мы получили на дисплее.

Arduino OLED-дисплей отображение изображения

Отображение температуры и влажности на OLED-дисплее с Arduino

В этом разделе мы создадим проект, который отображает показания температуры и влажности на OLED-дисплее. Мы получим температуру и влажность с помощью датчика температуры и влажности DHT11. Если вы не знакомы с датчиком DHT11, прочитайте следующую статью:

Необходимые компоненты

Для выполнения этого проекта вам понадобятся следующие компоненты:

Схема подключения

Соберите схему, следуя приведенной ниже схеме подключения.

Схема подключения Arduino с DHT11 DHT22 и OLED-дисплеем

Примечание: если вы используете модуль с датчиком DHT, он обычно имеет только три вывода. Выводы должны быть подписаны, чтобы вы знали, как их подключить. Кроме того, многие из этих модулей уже имеют встроенный подтягивающий резистор, поэтому вам не нужно добавлять его в схему.

Установка библиотек

Перед продолжением убедитесь, что вы установили библиотеки «adafruit_GFX.h» и «adafruit_SSD1306.h» для управления OLED-дисплеем.

Для этого проекта вам также понадобятся две дополнительные библиотеки для считывания данных с датчика DHT: библиотека DHT и библиотека Adafruit_Sensor. Следуйте приведенным ниже шагам для установки этих библиотек.

1. Откройте Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Должен открыться менеджер библиотек.

2. Введите «DHT» в поле поиска и установите библиотеку DHT от Adafruit.

Установка библиотеки DHT от Adafruit в Arduino IDE

3. После установки библиотеки DHT от Adafruit введите «Adafruit Unified Sensor» в поле поиска. Прокрутите вниз, чтобы найти библиотеку, и установите её.

Установка библиотеки Adafruit Unified Sensor в Arduino IDE

4. Перезапустите Arduino IDE.

Код

После установки всех необходимых библиотек вы можете загрузить следующий код.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>

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

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

#define DHTPIN 2     // Digital pin connected to the DHT sensor

// Uncomment the type of sensor in use:
#define DHTTYPE    DHT11     // DHT 11
//#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);

  dht.begin();

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);
}

void loop() {
  delay(5000);

  //read temperature and humidity
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
  }

  //clear display
  display.clearDisplay();

  // display temperature
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("Temperature: ");
  display.setTextSize(2);
  display.setCursor(0,10);
  display.print(t);
  display.print(" ");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");

  // display humidity
  display.setTextSize(1);
  display.setCursor(0, 35);
  display.print("Humidity: ");
  display.setTextSize(2);
  display.setCursor(0, 45);
  display.print(h);
  display.print(" %");

  display.display();
}

Посмотреть исходный код

Как работает код

Прочитайте этот раздел, если хотите узнать, как работает код. В противном случае вы можете перейти к разделу «Демонстрация».

Импорт библиотек

Код начинается с подключения необходимых библиотек. Wire, Adafruit_GFX и Adafruit_SSD1306 используются для работы с OLED-дисплеем. Adafruit_Sensor и DHT используются для работы с датчиками DHT22 или DHT11.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>

Создание объекта дисплея

Затем определите размеры вашего OLED-дисплея. В данном случае мы используем дисплей 128x64 пикселя.

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

Затем инициализируйте объект дисплея с шириной и высотой, определенными ранее, с протоколом связи I2C (&Wire).

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

Параметр (-1) означает, что ваш OLED-дисплей не имеет вывода RESET. Если ваш OLED-дисплей имеет вывод RESET, он должен быть подключен к GPIO. В этом случае вы должны передать номер GPIO в качестве параметра.

Создание объекта DHT

Затем определите тип используемого датчика DHT. Если вы используете DHT11, вам не нужно ничего менять в коде. Если вы используете другой датчик, просто раскомментируйте строку с вашим датчиком и закомментируйте остальные.

#define DHTTYPE    DHT11     // DHT 11
//#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)

Инициализируйте объект датчика DHT с выводом и типом, определенными ранее.

DHT dht(DHTPIN, DHTTYPE);

setup()

В setup() инициализируйте Serial Monitor для отладки.

Serial.begin(115200);

Инициализируйте датчик DHT:

dht.begin();

Затем инициализируйте OLED-дисплей.

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
  Serial.println(F("SSD1306 allocation failed"));
  for(;;);
}

В данном случае адрес OLED-дисплея, который мы используем – 0x3C. Если этот адрес не работает, вы можете запустить скетч I2C-сканера, чтобы найти адрес вашего OLED. Вы можете найти скетч I2C-сканера здесь.

Добавьте задержку, чтобы дать время дисплею инициализироваться, очистите дисплей и установите белый цвет текста:

delay(2000);
display.clearDisplay();
display.setTextColor(WHITE)

В loop() мы считываем данные с датчика и отображаем температуру и влажность на дисплее.

Получение показаний температуры и влажности от DHT

Температура и влажность сохраняются в переменных t и h соответственно. Считывание температуры и влажности так же просто, как использование методов readTemperature() и readHumidity() объекта dht.

float t = dht.readTemperature();
float h = dht.readHumidity();

Если мы не можем получить показания, выводим сообщение об ошибке:

if (isnan(h) || isnan(t)) {
  Serial.println("Failed to read from DHT sensor!");
}

Отображение показаний датчика на OLED-дисплее

Следующие строки отображают температуру на OLED-дисплее.

display.setTextSize(1);
display.setCursor(0,0);
display.print("Temperature: ");
display.setTextSize(2);
display.setCursor(0,10);
display.print(t);
display.print(" ");
display.setTextSize(1);
display.cp437(true);
display.write(167);
display.setTextSize(2);
display.print("C");

Мы используем метод setTextSize() для определения размера шрифта, setCursor() устанавливает, где текст должен начать отображаться, а метод print() используется для вывода чего-либо на дисплей.

Чтобы вывести температуру и влажность, вам просто нужно передать их переменные в метод print() следующим образом:

display.print(t);

Метка «Temperature» отображается размером 1, а само показание отображается размером 2.

Для отображения символа градуса мы используем шрифт Code Page 437. Для этого вам нужно установить cp437 в true следующим образом:

display.cp437(true);

Затем используйте метод write() для отображения выбранного символа. Символ градуса соответствует символу 167.

display.write(167);

Аналогичный подход используется для отображения влажности:

display.setTextSize(1);
display.setCursor(0, 35);
display.print("Humidity: ");
display.setTextSize(2);
display.setCursor(0, 45);
display.print(h);
display.print(" %");

Не забудьте, что вам нужно вызвать display.display() в конце, чтобы фактически отобразить что-либо на OLED.

display.display();

Демонстрация

После сборки схемы и загрузки кода OLED-дисплей показывает показания температуры и влажности. Показания датчика обновляются каждые пять секунд.

Отображение температуры и влажности DHT22 DHT11 на OLED-дисплее

Устранение неполадок

Если ваш датчик DHT не может получить показания или вы получаете сообщение «Failed to read from DHT sensor», прочитайте наше руководство по устранению неполадок DHT, чтобы помочь вам решить эту проблему.

Если вы получаете ошибку «SSD1306 allocation failed» или OLED ничего не отображает на экране, это может быть одна из следующих проблем:

Неправильный I2C-адрес

I2C-адрес OLED-дисплея, который мы используем – 0x3C. Однако ваш может быть другим. Поэтому убедитесь, что вы проверили I2C-адрес вашего дисплея с помощью скетча I2C-сканера.

SDA и SCL подключены неправильно

Пожалуйста, убедитесь, что выводы SDA и SCL OLED-дисплея подключены правильно.

Заключение

OLED-дисплей предоставляет простой и недорогой способ отображения текста или графики с использованием Arduino. Мы надеемся, что вы нашли это руководство и пример проекта полезными.

Если вам нравится Arduino, обязательно ознакомьтесь со всеми нашими ресурсами по Arduino: