8 (800) 350-30-16

Подключение дисплея с I2C интерфейсов

Дата: / Категория: Дисплеи / Автор: DOC_tr

В последнее время часто стали приходить вопросы о нерабочих / проблемах с подключением / каких-то косяках (нужное подчеркнуть) с I2C LCD1602 дисплеем.

Ну я и решил в этом разобраться - почему у людей это вызывает такую проблему. Давайте посмотрим.

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

Подключение достаточно простое - в любом случае 4 провода вставить намного легче чем подключать все 16, и происходит по следующей схеме.

Рассмотрим пример - подключать все будем с помощью данной библиотеки и следующего скетча

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("ROBOM.ru");
lcd.setCursor(8, 1);
lcd.print("LCD 1602");
}
void loop()
{
lcd.setCursor(0, 1);
lcd.print(millis()/1000);
delay(1000);
}

Так как экран даже не инициализировался (при включении должен мигнуть) то тут дело либо в экране, либо в скетче. Проверив все дисплеи и отбросив мысль о том, что вся партия бракованная, я начал изучать скетч и код библиотеки.

Так как в данной библиотеке единственное что указывает на связь дисплея и Arduino это адрес - 0x27, будем искать правильный адрес. Для этого в библиотеке Wire есть метод beginTransmission. Как написано в официальной документации - начинает передачу на устройство I2C с указанного адреса.

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

#include <Wire.h>

void setup(){
Wire.begin();
Serial.begin(9600);
Serial.println("\nI2C Сканер");
}

void loop(){
byte error, address;
bool nDevices;
Serial.println("Сканируем...");
nDevices = false;
for(address = 1; address < 127; address++ )
{
Wire.beginTransmission(address);
error = Wire.endTransmission();

if (error == 0)
{
Serial.print("I2C адpес 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices = true;
break;
}
else if (error==4)
{
Serial.print("Неизвестная ошибка. Адрес 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (!nDevices)
Serial.println("I2C не найден\n");
else
Serial.println("успешно\n");
delay(5000);
}

В процессе сканирования мы увидим следующую картину

И как видим - адрес нашего устройства далеко не 0x27, хотя все русскоязычные мануалы твердят о том что он установлен по умолчанию, и использовать нужно только его.

Внесем небольшие изменения в наш скетч (Измененный кусок выделен)

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
void setup()
{
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("ROBOM.ru");
lcd.setCursor(8, 1);
lcd.print("LCD 1602");
}
void loop()
{
lcd.setCursor(0, 1);
lcd.print(millis()/1000);
delay(1000);
}

Ничего не произошло, но дисплей, хотя бы, начал инициализироваться при загрузке скетча.

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

Ну на этом наверное все. Если у вас возникают проблемы с ним, то сканер и отвертка вам в помощь ;)

UPD. Информация от нашего читателя

Во первых - видимо у всех дисплеев разный адрес, потому что у некоторых работает с адресом 0x27. В любом случае перед использованием лучше узнать с помощью сканера требуемый адрес.

Во вторых - если у вас дисплей никак не хочет включаться, то найдите в библиотеке из данной статьи следующие строчки (17 - 20)

inline size_t LiquidCrystal_I2C::write(uint8_t value) {
send(value, Rs);
return 0;
}

И замените здесь

return 0;

на

return 1;

Теги: #LCD1602, #I2C

Ваша оценка:

Рейтинг: 8.3 (Оценок: 6)

Комментарии (1):

Вася
2016-11-10 18:32
Спасибо, дисплей заработал!

Комментарий:

Copyright © RobOM.ru 2016 г. Все права защищены