В этом уроке расскажу, как работать с 0,96-дюймовый SSD1306 OLED-дисплем в среде Arduino IDE . Покажу как вывести текст и нарисовать фигуры . Как выводить текст на русском языке покажу в следующем уроке.
Для урока понадодиться:
OLED-дисплей,
который я буду использовать в этом
уроке, - это модель
SSD1306: 0,96-дюймовый с
разрешением
128×64 пикселя, как показано
на фото ниже.
OLED-дисплей
не требует подсветки, что приводит к
хорошему контрасту в темный период
времени. Кроме того, его пиксели потребляют
энергию только тогда, когда они включены,
поэтому
OLED-дисплей потребляет меньше
энергии, по сравнению с другими
дисплеями.
Дисплей
поможет вам автоматизировать ваше
производства, а полиэтиленовый рукав
поковать вашу продукцию. Где
полиэтиленовый
рукав купить
? На сайте МТ-ПАК
ТОРГ.
Модель, которую я использую, имеет четыре контакта и взаимодействует с любым микроконтроллером, используя протокол связи I2C. Есть, которые используют протокола связи SPI. Есть модели, которые поставляются с дополнительным выводом сброса.
Дисплей
OLED SSD1306 Описание подключения.
Поскольку
OLED-дисплей использует протокол связи
I2C, подключение очень простое. Как
подключить к Arduino UNO или Arduino NANO смотрите
в таблице ниже.
Pin |
Arduino UNO или Arduino NANO |
Vin |
5v |
GND |
GND |
SCL |
A5 |
SDA |
A4 |
Схема
подключения
SSD1306
к
Arduino
UNO
Существует
несколько библиотек, доступных для
управления
OLED-дисплеем. В этом уроке я
буду использовать две библиотеки
Adafruit: библиотеку Adafruit_SSD1306 и библиотеку
Adafruit_GFX
.
Для установки этих библиотек
выполните следующие действия.
1.
Откройте Arduino IDE и перейдите в раздел
Скетч > Подключить библиотеку >
управление библиотеками.
Должен открыться менеджер библиотеки.
2. Укажите “ SSD1306” в поле поиска, выберете из списка и установите библиотеку от Adafruit SSD1306
3. Аналогично установите вторую библиотеку, для этого в поле поиска укажите “ GFX”
4. После установки библиотеки перезагрузите среду разработки Arduino.
Тестирование
OLED-дисплея
После
подключения
OLED-дисплея к Arduino и установки
всех необходимых библиотек, вы можете
использовать один пример из библиотеки,
чтобы увидеть, все ли работает правильно.
В
вашей
среде разработки Arduino, выберите
Файл > Примеры > Adafruit SSD1306 и выберете
тип вашего дисплея. В моем случае это
128х64_i2c.
Вот код примера для моего дисплея SSD1306
#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 4 // 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(9600); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64 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, SSD1306_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, SSD1306_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, SSD1306_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, SSD1306_WHITE); display.display(); delay(1); } for(i=display.height()-1; i>=0; i-=4) { display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_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, SSD1306_WHITE); display.display(); delay(1); } for(i=display.height()-1; i>=0; i-=4) { display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_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, SSD1306_WHITE); display.display(); delay(1); } for(i=0; i<display.width(); i+=4) { display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_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, SSD1306_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, SSD1306_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, SSD1306_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, SSD1306_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, SSD1306_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, SSD1306_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, SSD1306_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, SSD1306_INVERSE); display.display(); delay(1); } delay(2000); } void testdrawchar(void) { display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_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(SSD1306_WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.println(F("Hello, world!")); display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text display.println(3.141592); display.setTextSize(2); // Draw 2X-scale text display.setTextColor(SSD1306_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(SSD1306_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, SSD1306_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 дисплей не имеет pin сброса, вы должны установить переменную OLED_RESET в значение -1, как показано ниже.
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Не
забудьте выбрать нужную плату и COM порт
в меню Инструменты.
Загрузите
код в
Arduino, после чего вы должны получить
серию различных анимаций, как показано
на фота ниже.
Если
ваш OLED-дисплей ничего не показывает:
Убедитесь,
что OLED-дисплей правильно подключен к
Ардуино.
Также вы должны изменить
OLED-адрес в следующей строке, например
на 0x3D, если это необходимо. В
моем
случае адрес 0x3C.
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Библиотека
Adafruit для OLED-дисплея
поставляется с
несколькими функциями для вывода текста.
В этом разделе вы узнаете, как писать и
прокручивать текст с помощью функций
библиотеки.
“Hello, world!”
OLED-дисплей
Следующий код отображает
Hello, world! сообщение на дисплее.
#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() { }
После загрузки кода вот, что вы получите в вашем дисплее.
Рассмотрим скетч подробнее.
Импорт
библиотек
Во-первых,
вам нужно импортировать необходимые
библиотеки. Библиотека для использования
I2C и библиотеки Adafruit для вывода информации
на дисплей: Adafruit_GFX и Adafruit_SSD1306
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h>
Инициализация OLED-дисплея
Затем,
вы определяете свою ширину и высоту
дисплея. В этом примере я использую
OLED-дисплей 128×64. Если вы используете
другие размеры, вы можете изменить это
в переменных SCREEN_WIDTH и SCREEN_HEIGHT
#define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels
Затем
инициализируйте экранный объект, с
шириной и высотой, определенными ранее
с помощью протокола связи I2C (&Wire).
dafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Параметр
(-1) означает, что ваш OLED-дисплей не имеет
pin сброса. Если ваш OLED-дисплей имеет пин
сброса, то он должен быть подключен к
GPIO. В этом случае вы должны передать
номер GPIO.
В setup () инициализируйте
последовательный монитор на скорости
передачи данных 9600 бод для отладки.
Serial.begin(9600);
Инициализируйте
OLED-дисплей с помощью метода begin() следующим
образом
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println("SSD1306 allocation failed"); for(;;); // Don't proceed, loop forever }
Этот фрагмент выводит сообщение на последовательный монитор, если вы не можете подключиться к дисплею.
Так
же, вам может потребоваться изменить
адрес OLED. В моем
случае адрес 0x3C.
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Рассказывал
об этом выше.
После инициализации дисплея добавьте двухсекундную задержку, чтобы OLED имел достаточно времени для инициализации перед написанием текста.
delay(2000);
Очистить
дисплей, установить размер шрифта, цвет
и написать текст.
После
инициализации дисплея очистите буфер
дисплея с помощью метода clearDisplay().
display.clearDisplay();
Перед
написанием текста, вам нужно установить
размер текста, цвет и где текст будет
отображаться в OLED.
Установите размер шрифта с помощью метода setTextSize().
Установите цвет шрифта с помощью метода setTextColor().
display.setTextColor(WHITE);
WHITE
устанавливает белый шрифт и черный
фон.
Определите позицию, с которой
начинается текст, используя метод
setCursor(x, y). В этом случае, вы устанавливаете
текст, чтобы начать с координат (0,10).
Наконец,
можно отправить текст на дисплей с
помощью метода println (), как показано ниже.
display.println("Hello, world!");
Затем,
вам нужно вызвать метод display (), чтобы
фактически отобразить текст на экране.
startscrollright(0x00,
0x0F): прокрутка текста слева
направо
startscrollleft(0x00, 0x0F): прокрутка
текста справа налево
Следующий
скетч реализует методы прокрутки текста:
#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); }
Нарисуйте фигуры на 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);
Вы
получите черный треугольник, а фон будет
подсвечен.
Код
для рисование всех фигур
Загрузите
следующий скетч в Arduino, который реализует
каждый фрагмент кода, который я
рассмотрел ранее, и выведет все фигуры.
#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() { }
Планировал добавить вывод русского текста на дисплей SSD1306, но урок получился и так большой. Поэтому вывод русского текст будет в следующем уроке.
Понравилась статья? Поделитесь ею с друзьями:
Вернуться в раздел: Уроки Arduino: Подключение датчиков и модулей к Arduino Дата публикации 22 ноября , 2019
Читайте также
Возникла проблема с подключением двух дисплеев на одну шину. Перемычку для смены адреса на одном перепаял, по отдельности работают, а вместе не могу правильно написать код. подскажите пожалуйста...
Комментарии
Войдите или Зарегистрируйтесь И Вы сможете общаться на форуме и оставлять комментарии без капчи.