Руководство по I2C OLED-дисплею с Arduino
В этой статье показано, как использовать I2C OLED-дисплей SSD1306 размером 0.96 дюйма с Arduino. Мы покажем некоторые функции OLED-дисплея, как подключить его к плате Arduino и как выводить текст, рисовать фигуры и отображать bitmap-изображения. В конце мы создадим проект-пример, который отображает показания температуры и влажности.
Знакомство с OLED-дисплеем 0.96 дюйма
Органический светоизлучающий диодный (OLED) дисплей, который мы будем использовать в этом руководстве — модель SSD1306: монохромный дисплей размером 0.96 дюйма с разрешением 128x64 пикселя, как показано на следующем рисунке.
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);
Библиотеки
Для управления OLED-дисплеем вам нужны библиотеки adafruit_SSD1306.h и adafruit_GFX.h. Следуйте приведенным ниже инструкциям для установки этих библиотек.
Откройте Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Должен открыться менеджер библиотек.
Введите «SSD1306» в поле поиска и установите библиотеку SSD1306 от Adafruit.
После установки библиотеки SSD1306 от Adafruit введите «GFX» в поле поиска и установите библиотеку.
После установки библиотек перезапустите Arduino IDE.
Советы по написанию текста с использованием этих библиотек
Вот некоторые функции, которые помогут вам работать с библиотекой OLED-дисплея для вывода текста или рисования простой графики.
display.clearDisplay()– все пиксели выключеныdisplay.drawPixel(x,y, color)– рисует пиксель по координатам x,ydisplay.setTextSize(n)– устанавливает размер шрифта, поддерживаются размеры от 1 до 8display.setCursor(x,y)– устанавливает координаты для начала вывода текстаdisplay.print("message")– выводит символы в позиции x,ydisplay.display()– вызовите этот метод, чтобы изменения вступили в силу
Тестирование OLED-дисплея
После подключения OLED-дисплея к Arduino и установки всех необходимых библиотек вы можете использовать один из примеров библиотеки, чтобы проверить, что всё работает правильно.
В Arduino IDE перейдите в File > Examples > 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)
Загрузите код на плату 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:
Давайте кратко рассмотрим, как работает код.
Импорт библиотек
Сначала вам нужно импортировать необходимые библиотеки. Библиотека 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.
Рисование фигур на OLED-дисплее
Библиотека Adafruit OLED предоставляет полезные методы для рисования пикселей, линий и фигур. Давайте кратко рассмотрим эти методы.
Рисование пикселя
Чтобы нарисовать пиксель на OLED-дисплее, вы можете использовать метод drawPixel(x, y, color), который принимает в качестве аргументов координаты x и y, где появляется пиксель, и цвет. Например:
display.drawPixel(64, 32, WHITE);
Рисование линии
Используйте метод drawLine(x1, y1, x2, y2, color) для создания линии. Координаты (x1, y1) указывают начало линии, а координаты (x2, y2) указывают, где линия заканчивается. Например:
display.drawLine(0, 0, 127, 20, WHITE);
Рисование прямоугольника
Метод drawRect(x, y, width, height, color) предоставляет простой способ нарисовать прямоугольник. Координаты (x, y) указывают верхний левый угол прямоугольника. Затем вам нужно указать ширину, высоту и цвет:
display.drawRect(10, 10, 50, 30, WHITE);
Вы можете использовать fillRect(x, y, width, height, color) для рисования залитого прямоугольника. Этот метод принимает те же аргументы, что и drawRect().
Библиотека также предоставляет методы для отображения прямоугольников со скругленными углами: drawRoundRect() и fillRoundRect(). Эти методы принимают те же аргументы, что и предыдущие методы, плюс радиус скругления углов. Например:
display.drawRoundRect(10, 10, 30, 50, 2, WHITE);
Или залитый скругленный прямоугольник:
display.fillRoundRect(10, 10, 30, 50, 2, WHITE);
Рисование окружности
Чтобы нарисовать окружность, используйте метод drawCircle(x, y, radius, color). Координаты (x,y) указывают центр окружности. Вы также должны передать радиус в качестве аргумента. Например:
display.drawCircle(64, 32, 10, WHITE);
Аналогично, для создания залитой окружности используйте метод fillCircle() с теми же аргументами:
display.fillCircle(64, 32, 10, WHITE);
Рисование треугольника
Используйте метод 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);
Инверсия
Библиотека предоставляет дополнительный метод, который можно использовать с фигурами или текстом: метод invertDisplay(). Передайте true в качестве аргумента для инверсии цветов экрана или false для возврата к исходным цветам.
Если вы вызовете следующую команду после определения треугольника:
display.invertDisplay(true);
Вы получите инвертированный треугольник следующим образом:
Код – Рисование фигур
Загрузите следующий скетч, который реализует каждый фрагмент кода, рассмотренный ранее, и последовательно отображает все фигуры.
/*********
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.
Затем используйте конвертер изображения в C-массив для преобразования изображения в массив. Мы использовали LCD Image Converter.
Запустите программу и начните с нового изображения. Перейдите в Image > Import и выберите bitmap-изображение, которое вы создали ранее.
Перейдите в Options > Conversion и на вкладке Prepare выберите следующие параметры:
Type: Monochrome, Threshold Dither
Main Scan Direction: Top to Bottom
Line Scan Direction: Forward
Перейдите на вкладку Image и выберите следующие параметры:
Split to rows
Block size: 8 bit
Byte order: Little-Endian
Затем нажмите 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() {
}
После загрузки кода вот что мы получили на дисплее.
Отображение температуры и влажности на OLED-дисплее с Arduino
В этом разделе мы создадим проект, который отображает показания температуры и влажности на OLED-дисплее. Мы получим температуру и влажность с помощью датчика температуры и влажности DHT11. Если вы не знакомы с датчиком DHT11, прочитайте следующую статью:
Необходимые компоненты
Для выполнения этого проекта вам понадобятся следующие компоненты:
Arduino – Читайте Лучшие стартовые наборы Arduino
Схема подключения
Соберите схему, следуя приведенной ниже схеме подключения.
Примечание: если вы используете модуль с датчиком DHT, он обычно имеет только три вывода. Выводы должны быть подписаны, чтобы вы знали, как их подключить. Кроме того, многие из этих модулей уже имеют встроенный подтягивающий резистор, поэтому вам не нужно добавлять его в схему.
Установка библиотек
Перед продолжением убедитесь, что вы установили библиотеки «adafruit_GFX.h» и «adafruit_SSD1306.h» для управления OLED-дисплеем.
Для этого проекта вам также понадобятся две дополнительные библиотеки для считывания данных с датчика DHT: библиотека DHT и библиотека Adafruit_Sensor. Следуйте приведенным ниже шагам для установки этих библиотек.
1. Откройте Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Должен открыться менеджер библиотек.
2. Введите «DHT» в поле поиска и установите библиотеку DHT от Adafruit.
3. После установки библиотеки DHT от Adafruit введите «Adafruit Unified Sensor» в поле поиска. Прокрутите вниз, чтобы найти библиотеку, и установите её.
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-дисплей показывает показания температуры и влажности. Показания датчика обновляются каждые пять секунд.
Устранение неполадок
Если ваш датчик 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: