Проблема с LCD 1602a на разных скетчах требуется подстройка контрастности

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Привет, гуру и форумчане!

Я - новичок в работе с Arduino.Может спрошу глупость, прошу заранее простить.

Проблема вот какая: при изменении скетча каждый раз требуется подстройка контрастности.

Вот 2 скетча, простейших, на мой взгляд.

Вот первый.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);   

void setup()
{
 lcd.begin(16, 2);  // Инициализирует LCD 16x2
  lcd.setCursor(2,0);           // Установить курсор на первыю строку
  lcd.print("Hello, world");    // Вывести текст
  lcd.setCursor(0,1);           // Установить курсор на вторую строку
  lcd.print("www.robotchip.ru");    // Вывести текст
}

void loop()
{
}

Вот второй.

#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);}

LCD подключен без I2C, для каждого скетча требуется регулировка контрастности. Почему?

К тому же, во втором скетче, примерно после 10 секунд работы начинает помаргивать экран.

Я пока только осваиваю этот ПЛК, поэтому на начальных этапах требуется помощь.

Заранее спасибо всем откликнувшимся.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Это я уже понял из других материалов Тырнета, а вот с контрастностью нет...

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

bwn
Offline
Зарегистрирован: 25.08.2014

Наверно, это в песочницу.

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Песочница - это немного обидно, но, наверное, справедливо...

Нарисовал 2 скетча, но не могу понять, почему в одном случае на LCD отображается информация, а во втором нет

1-й скетч.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int Cnt=0;

void setup()
{
 lcd.begin(16, 2);  // Инициализирует LCD 16x2
  //lcd.setCursor(0,0);           // Установить курсор на первыю строку
  lcd.print("Hello, world");    // Вывести текст
  lcd.setCursor(0,1);           // Установить курсор на вторую строку
  lcd.print("*Proba*");    // Вывести текст
}

void loop()
{
}

2-й скетч.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int Cnt=0;

void setup()
{
 lcd.begin(16, 2);  // Инициализирует LCD 16x2
  //lcd.setCursor(0,0);           // Установить курсор на первыю строку
  lcd.print("Hello, world");    // Вывести текст
  lcd.setCursor(0,1);           // Установить курсор на вторую строку
  lcd.print("*Proba*");    // Вывести текст
}

void loop()
{
  if (millis()%1000==0)
     {
      
     }

}

Разница только в проверке условия во 2-м скетче, но при этом на LCD отображаются только прямоугольники вместо значений...

Может кто подкинет идею?

Заранее спасибо.

forfrends
Offline
Зарегистрирован: 24.02.2015

Потому что для инициализации дисплея нужно время, а за это время функция "Setup" успевает проскочить без вывода картинки..

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

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  lcd.begin(16, 2);
  lcd.print("hello, world!");
}

void loop() {
  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);
  delay(300);  //      <<<<<<<<<<<<<<<<<
}

 

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Может тогда стоит добавить паузу ДО setCursor?

Но всё равно спасибо, попробую - отпишусь...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Homo Faber пишет:

Может тогда стоит добавить паузу ДО setCursor?

ДО lcd.begin(16, 2); добавьте.

С вот таким дисплеем была заморочка. На ардуине работат, а на таком же чипе без загрузчика - нет. Выяснилось, что при включении питания, он не успевает аппаратно проинициализироваться, а на него уже команды прут.

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Вот, творчески переработал свою же заготовку сигнализации протечек. Добавил вывод на LCD.


#include <Servo.h>
#include <LiquidCrystal.h>

int water;
Servo myservo;
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);
int Prz1=0;
int Prz2=0;
int Alr=1;
int Snd=1;
void setup()
{
  pinMode(A0, INPUT);
  pinMode(4, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(2, INPUT_PULLUP);
  myservo.attach(3);
  lcd.begin(16, 2);  // Инициализирует LCD 16x2
//  Serial.begin(9600);
}

void loop()
{
  water = analogRead(A0);
//  Serial.println(water);
  if (water>100)
      {
       digitalWrite(4,HIGH);
       myservo.write(90);
       if (digitalRead(2)==0) Alr=0;
       if (Prz1==0)
          {
           lcd.clear();
           lcd.setCursor(0,0);           // Установить курсор на первыю строку
//           lcd.print("Datchik #1");    // Вывести текст
           lcd.write("Datchik #1");    // Вывести текст
           Prz1=1;
           Prz2=0;
          }
       if (Alr==1)
          {
           if (Snd==1)
              {
               tone(6, 500);
               Snd=0;
              }
           else
              {
               tone(6, 1000);
               Snd=1;
              }
//           noTone(6)
          }
       else noTone(6);  
      }
  else
      {
       digitalWrite(4,LOW);  
       myservo.write(0);
       noTone(6);
       Alr=1;
       Snd=1;
       if (Prz2==0)
          {
           lcd.clear();
           lcd.setCursor(0,0);           // Установить курсор на первыю строку
//           lcd.print("NORMA");    // Вывести текст
           lcd.write("NORMA");    // Вывести текст
           Prz1=0;
           Prz2=1;
          }
      }
  delay(1000);
}

Проблема с контрастностью не исчезла, каждый раз перед запуском приходится выводить потенциометр в крайнее положение (+5В) и потом аккуратно двигать в сторону GND. После увлажнения датчика всё срабатывает (светодиод, зуммер, сервопривод), надпись на мониторе исчезает, вместо неё появляются прямоугольники, после осушивания датчика приямоугольники тоже пропадают и во втором ряду на 3-м месте появляется мигающий курсор. Пробовал LCD.Print и LCD.Write, разницы не увидел, хотя была надежда...

Есть подозрение, что сам LCD1602 типа помирает.

Кто-нибудь может подсказать выбрасывать LCD или ещё есть надежда?

Заранее спасибо!

Morroc
Offline
Зарегистрирован: 24.10.2016

Я бы напряжение питания LCD проверил. На полвольта меняется - уже плывет контраст (ну на моих так).

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Проверил, при увлажнении датчика и срабатывании сервопривода напряжение плывёт, порядка 0,5В.

Отключил сервопривод, пищалку и зуммер, всё равно перепад порядка 0,1В. Никаких изменений в работе LCD.

Поставил более мощный источник (до 2А на выходе) перепад стал около 0,05В, а работает LCD как и раньше...

Может ещё какие идеи будут?

Подумал, может на питание LCD отдельный источник поставить?

Morroc
Offline
Зарегистрирован: 24.10.2016

Homo Faber пишет:

Подумал, может на питание LCD отдельный источник поставить?

Да не, это уже как то ненормально.

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Подключил сервопривод и подсветку LCD на отдельное питание и добавил задержку перед инициализацией LCD. Вроде работает...

А как должна выглядеть индикация на LCD, символы должны быть тёмными или светлыми?

У меня, если символы светлые - продолжается ерунда (см. предыдущие сообщения), а если тёмные, то в новом варианте вроде работает (в предыдущем не работало в любом варианте).

#include <Servo.h>
#include <LiquidCrystal.h>

int water;
Servo myservo;
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);
int Prz1=0;                     // Признак разрешения вывода на экран АВАРИИ
int Prz2=0;                     // Признак разрешения вывода на экран НОРМЫ
int Alr=1;                      // Признак разрешения звука
int Snd=1;                      // Признак тона
int Cnt;                        // Сётчик для начальной задержки и мигания зелёного светодиода
void setup()
{
  pinMode(A0, INPUT);           // Датчик протечки
  pinMode(4, OUTPUT);           // Красный светодиод
  pinMode(6, OUTPUT);           // Пищалка
  pinMode(13, OUTPUT);          // Зелёный светодиод
  pinMode(2, INPUT_PULLUP);     // Кнопка с подтягивающим резистором
  myservo.attach(3);            // Серводвигатель на 3-м выводе
  myservo.write(0);             // Серводвигатель - ОТКРЫТО

  for (Cnt=1; Cnt<=3; Cnt++)    // Мигание зелёным светодиодом
      {
       digitalWrite(13,HIGH);
       delay(500);
       digitalWrite(13,LOW);
       delay(500);
      }
  lcd.begin(16, 2);             // Инициализирует LCD 16x2
//  Serial.begin(9600);
}

void loop()
{
  water = analogRead(A0);           
//  Serial.println(water);
  if (water>100)
      {
       digitalWrite(4,HIGH);          // Включение красного светодиода
       digitalWrite(13,LOW);          // Выключение зелёного светодиода
       myservo.write(90);             // Серводвигатель - ЗАКРЫТО
       if (digitalRead(2)==0) Alr=0;  // Нажата кнопка - ЗВУК ВЫКЛ
       if (Prz1==0)
          {
           lcd.clear();               // Очистить экран
           lcd.setCursor(0,0);        // Установить курсор на первыю строку
           lcd.write("Datchik #1");   // Вывести текст
           Prz1=1;
           Prz2=0;
          }
       if (Alr==1)                    // Если ЗВУК ВКЛ
          {
           if (Snd==1)
              {
               tone(6, 500);          // Пищалка низкий тон
               Snd=0;
              }
           else
              {
               tone(6, 1000);         // Пищалка высокий тон
               Snd=1;
              }
          }
       else noTone(6);                // Нет звука
      }
  else
      {
       digitalWrite(4,LOW);           //Выключение красного светодиода
       digitalWrite(13,HIGH);         //Включение зелёного светодиода
       myservo.write(0);              //Серводвигатель в ОТКРЫТО
       noTone(6);                     // Нет звука
       Alr=1;
       Snd=1;
       if (Prz2==0)
          {
           lcd.clear();
           lcd.setCursor(0,0);        // Установить курсор на первую строку
           lcd.write("NORMA");        // Вывести текст
           Prz1=0;
           Prz2=1;
          }
      }
  delay(1000);                        // Задержка 1 сек.
}

Вот такой получился код. Понимаю - не идеал, пока учусь.

Буду признателен за любые замечания и советы.

PS. На низком тоне звук стал "блеющим", может кто сталкивался?

Morroc
Offline
Зарегистрирован: 24.10.2016

Homo Faber пишет:

А как должна выглядеть индикация на LCD, символы должны быть тёмными или светлыми?

Знакомест почти не должно быть видно (но все таки чуть чуть остается) - мне кажется так оптимально по видимости.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Homo Faber пишет:
добавил задержку перед инициализацией LCD. 

Я ж Вам про это ещё неделю назад писал - #8! тогда не поверили, и не стали пробовать? :)))

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Т.е. всё таки тёмные символы на светлом фоне?

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Я не "не поверил", а решил "творчески" переосмыслить.

Когда всёв голове уложилось - попробовал и получилось.

Тем не менее - СПАСИБО за совет.

Morroc
Offline
Зарегистрирован: 24.10.2016

Homo Faber пишет:

Т.е. всё таки тёмные символы на светлом фоне?

Бывает и так и так, но контрастностью это не перевернуть - как видится так и должно быть, но как можно четче.

Вот на первой картике как мне кажется оптимально настроено - слегка проглядывают "квадратики", если меньше контраст - бледные символы будут, если больше - "квадратики" повылазят под символами.

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Странно, у меня контрастностью можно вывести хоть тёмный шрифт:

 

 

 

Хоть светлый:

 

Немного не в фокусе получилось, но суть, я думаю, видна.

Так вот, когда шрифт тёмный - сообщения выводятся нормально, а когда светлый начинаются проблемы.

При АВАРИИ вместо надписи в верхнем ряду выводятся квадратики, а при возврате к НОРМЕ, на 3-м знакоместе 2-го ряда появляется мигающий курсор.

Не могу понять в чём дело-то. Может всё таки дело в LCD? Или в кривых ручках?

bwn
Offline
Зарегистрирован: 25.08.2014

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

Homo Faber
Offline
Зарегистрирован: 25.05.2019

Да нет, со всех сторон одинаково...

Morroc
Offline
Зарегистрирован: 24.10.2016

Такого хитрого дисплея у меня не было :) У него обозначение есть какое нибудь ? Может даташит найдется.

Homo Faber
Offline
Зарегистрирован: 25.05.2019

На оборотной стороне 1602А написано. И фсё...