LCD выводит "крякозябры"

GDStaff
Offline
Зарегистрирован: 25.11.2012

Здравствуйте, недавно купил себе Arduino UNO Rev3 и LCD WH1602D-YYK-CTK и сразу появились проблема, в которой, я надеюсь, Вы мне поможите. Попытался подключить его, схему взял со статьи про LiquidCrystal на официальном сайте, и оказалось что у моего LCD контакты + и - противоположны, нежели на схеме, но это пол беды. Первый же пример HelloWorld вызвал у меня шок. Сначало я нечего на экране не увидел, после парочки ресетов я увидел 2 строки постоянно меняющихся символов. Убрал весь код из loop и О БОЖЕ, строка hello, world! всетаки появилась. Потом я вернул код в loop и опять пустой экран. Изменил его для вывода текста (изначально там время работы ардуино) и крякозябры вернулись. В результате я вижу нормальный текст через раз при выводе лишь в setup, или невижу нечего. Либо выводя в loop - я вижу "анимированые" символы, либо опять таки пустой экран. Что это может быть и как это исправить? Очень прошу Вашей помощи.

P.S.: контакты я изначально припаял к LCD, дабы избежать "сопливости" контактов. И еще, один раз я всеже увидел нормально работающий HelloWorld с секундным индикатором работы (официальный скетч), но после записи своего скетча проблемы вернулись опять.

GDStaff
Offline
Зарегистрирован: 25.11.2012

Попробовал пример со страницы
http://robocraft.ru/blog/arduino/503.html
и очень удивился когда первые строки отображались как надо, но затем опять пошли крякозябры. Удивительно уже то, что не по всему экрану, а лишь вместо некоторых букв. Так же добавлялись неведомые пиксели в символы отрисовываемые мной по маске.

Может ли такое происходить из-за того, что я изначально несколько раз подключал LCD по неправильной полярности (питание)?

std
Offline
Зарегистрирован: 05.01.2012

нет, обычно при неверной полярности LCDM начинает жрать очень большой ток (около 2 А), но ему ничего от этого не становится. я убил один из своих экранов, запитав от 9В (их напряжение питания - не выше 7).

поможет вот этот PDF: http://bashel.bashel.ru/info5/sLCD_WS.pdf

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

ждемс народ, может еще что-то посоветуют.

comawhite
comawhite аватар
Offline
Зарегистрирован: 11.01.2013

Либо вы что-то неправильно напаяли, либо ошибка при инициализации дисплея (строчка типа LiquidCrystal lcd(8, 9, 4, 5, 6, 7);)

ian
Offline
Зарегистрирован: 18.02.2013

comawhite пишет:

Либо вы что-то неправильно напаяли, либо ошибка при инициализации дисплея (строчка типа LiquidCrystal lcd(8, 9, 4, 5, 6, 7);)

 

А если "кракозябры" появляются через 20-30 мин. работы? На что здесь грешить?

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>А если "кракозябры" появляются через 20-30 мин. работы? На что здесь грешить?<<

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

А может и в программе ошибки есть. Показывайте.

ian
Offline
Зарегистрирован: 18.02.2013

Вот код (не судите строго, первый опыт):

#include <LiquidCrystalRus.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// подключение ног LCD
// RS pin to digital pin 12
// Enable pin to digital pin 11
// D4 pin to digital pin 5
// D5 pin to digital pin 4
// D6 pin to digital pin 3
// D7 pin to digital pin 2
LiquidCrystalRus lcd(12, 11, 5, 4, 3, 2);

// Data-нога датчика (или датчиков) к 7 пину ардуины
#define ONE_WIRE_BUS 7
// настройка oneWire для работы с любыми другими OneWire девайсами (не только Maxim/Dallas датчиками температуры)
OneWire oneWire(ONE_WIRE_BUS);
// подключаем Dallas Temperature.
DallasTemperature sensors(&oneWire);
void setup(void)
{
// Запуск СОМ-порта. Только для отладки
//Serial.begin(9600);
// Параметры дисплея: 16 символов Х 2 строки
lcd.begin(16, 2);

// создать знак градуса
uint8_t grad[8] = {
  B00110,
  B01001,
  B00110,
  B00000,
  B00000,
  B00000,
  B00000
};
// и записать в символ 0 индикатора
lcd.createChar(0, grad);
// Запуск сенсоров температуры
sensors.begin();
}

void loop(void)
{
  int temp0 = 0;
  int temp1 = 0;
  
  // вызов функции для сбора показаний 
  // со всех датчиков на шине
  sensors.requestTemperatures(); // запрос показаний температуры
// в переменной temp0 - целая часть температуры
  temp0 = int(sensors.getTempCByIndex(0));
  // корректировка показаний
  // из опыта - DS18B20 завышает температуру
  // на 1-2 градуса
  temp0 = temp0 - 1;
  lcd.setCursor(0, 0);
  lcd.print("Улица: ");
  // если температура выше нуля - печатаем +
    if (temp0 > 0) lcd.print("+");
  lcd.print(temp0); // первый датчик
  // печать знака градуса
  lcd.print(char(0));
  
  temp1 = int(sensors.getTempCByIndex(1));
  temp1 = temp1 - 1;  
  lcd.setCursor(0, 1);
  lcd.print("Дом: ");  
    if (temp1 > 0) lcd.print("+");
  lcd.print(temp1); //второй датчик
  lcd.print(char(0));
  delay(10000);
 }

Ардуино - "Северино", самоделка, индикатор WH1602D-TML-CT, 4-битное подключение.

А как правильно рассчитать резисторы контрастности и подсветки? Заранее спасибо!

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

На контраст любой трехногий переменник . Что то от 5 до 100Ком. На посветку постоянный 100-200Ом.

И что то не увидел я в вашей программе lcd.clear();. Хотябы раз в несколько минут , но надо.

ian
Offline
Зарегистрирован: 18.02.2013

Вот где, наверное, собака и порылась... Я всё думал, нужен ли clear? Решил не ставить, для экономии памяти. А придётся... Спасибо!!!

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>Решил не ставить, для экономии памяти<<

Очень сомнительная экономия - шесть байт.

Очищать дисплей хоть изредка необходимо. Даже с точки зрения элементарной логики.

maksim
Offline
Зарегистрирован: 12.02.2012

Врядли дело в этом. Посмотрите код тут , я использовал lcd.clear() только в сетапе. Скорее всего у вас что-то отваливается или проблемы с питанием.

ian
Offline
Зарегистрирован: 18.02.2013

maksim пишет:

Скорее всего у вас что-то отваливается или проблемы с питанием.

Отваливается - вряд ли, всё на пайке, и до подключения индикатора "глюков" не наблюдалось. Питание стабильное, 4.98 в. Длина проводов до индикатора критична? Экранировать не нужно?

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Так в том и дело что в сетапе. Т.е. один раз , при запуске программы.  Дисплей нужно очищать.  Пусть попробует ввести cler.

Если ничего не изменится , значит дело в другом.

maksim
Offline
Зарегистрирован: 12.02.2012

Так вроде как в начале все нормально работает...

ian
Offline
Зарегистрирован: 18.02.2013

Всем спасибо! Проблема решилась укорачиванием проводов к индикатору с 40см. до 10см.

Клапауций
Offline
Зарегистрирован: 10.02.2013

Народ, кто пользует библиотеку LiquidCrystal.h на частотах меньших от 16 МГц, при условии, что вы указали в  boards.txt f_cpu меньше 16000000L?

Исходные данные:

Железо программатора USBasp на atmega8-16PI,

кварц 12 МГц,
bootloader - USBaspLoader,
FUSEOPT_8 = -U hfuse:w:0xc0:m -U lfuse:w:0x9f:m
LOCKOPT = -U lock:w:0x0F:m

юзаемое под arduino как  плата USBaspLoader - USBasp Programmer at 12MHz

boards.txt

#################################################

usbasp.name=USBaspLoader - USBasp Programmer at 12MHz
usbasp.upload.protocol=usbasp
usbasp.upload.maximum_size=6144
usbasp.upload.speed=115200
usbasp.upload.disable_flushing=true
usbasp.build.mcu=atmega8
usbasp.build.f_cpu=16000000L
usbasp.build.core=arduino:arduino
usbasp.build.variant=standard

LCD подключен непосредственно к ISP-разъёму программатора 

LiquidCrystal lcd(0, 1, 10, 11, 12, 13);

Проблема:

Если заметили, в boards.txt стоит f_cpu=16000000L, что есть не совсем правильно - на деле стоит кварц на 12MHz.
При установке реального значения (f_cpu=12000000L) - на индикатор выводится мусор,
Ставлю f_cpu=16000000L или больше - нормально выводится информация.
 
В общем... не пойму - в какую сторону рыть и в чём может быть проблема.
В остальном железка в виде платы для Arduino исправно работает, если закрывать глаза на отставание времени на 25%.
maksim
Offline
Зарегистрирован: 12.02.2012

В самом конце файла LiquidCrystal.ccp есть функция void LiquidCrystal::pulseEnable(void) в ней есть две строки с delayMicroseconds(1); попробуйте заменить на delayMicroseconds(3);. Если не поможет ,то по всему файлу увеличивайте задержки.

Клапауций
Offline
Зарегистрирован: 10.02.2013

maksim пишет:

В самом конце файла LiquidCrystal.ccp есть функция void LiquidCrystal::pulseEnable(void) в ней есть две строки с delayMicroseconds(1); попробуйте заменить на delayMicroseconds(3);. Если не поможет ,то по всему файлу увеличивайте задержки.

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

Не задумывался особо, что у меня все выходы от процессора идут через резисторы 470 Ом (хотелось оставить полную совместимость с железом USBasp) - может в этом проблема глобальная кроется?

Попробовал установить f_cpu=15999999L - есть проблема.

f_cpu=16000000L - нет проблемы.

Походу не в задержках и сопротивлених дело - порою библиотеку, где там явно указано 16000000...

Клапауций
Offline
Зарегистрирован: 10.02.2013

Хакнул глобально.

 

\arduino-1.0.3\hardware\arduino\cores\arduino\wiring.c
 
#elif F_CPU >= 12000000L
std
Offline
Зарегистрирован: 05.01.2012

Чисто академичечкий вопрос: будет ли оно так же тупить при работе меги на 8 МГц от внутреннего RC?

Клапауций
Offline
Зарегистрирован: 10.02.2013

Чисто академический ответ кроется в файле *\arduino-1.0.3\hardware\arduino\cores\arduino\wiring.c

void delayMicroseconds(unsigned int us)
{
	// calling avrlib's delay_us() function with low values (e.g. 1 or
	// 2 microseconds) gives delays longer than desired.
	//delay_us(us);
#if F_CPU >= 20000000L
	// for the 20 MHz clock on rare Arduino boards

	// for a one-microsecond delay, simply wait 2 cycle and return. The overhead
	// of the function call yields a delay of exactly a one microsecond.
	__asm__ __volatile__ (
		"nop" "\n\t"
		"nop"); //just waiting 2 cycle
	if (--us == 0)
		return;

	// the following loop takes a 1/5 of a microsecond (4 cycles)
	// per iteration, so execute it five times for each microsecond of
	// delay requested.
	us = (us<<2) + us; // x5 us

	// account for the time taken in the preceeding commands.
	us -= 2;

#elif F_CPU >= 16000000L
	// for the 16 MHz clock on most Arduino boards

	// for a one-microsecond delay, simply return.  the overhead
	// of the function call yields a delay of approximately 1 1/8 us.
	if (--us == 0)
		return;

	// the following loop takes a quarter of a microsecond (4 cycles)
	// per iteration, so execute it four times for each microsecond of
	// delay requested.
	us <<= 2;

	// account for the time taken in the preceeding commands.
	us -= 2;
#else
	// for the 8 MHz internal clock on the ATmega168

	// for a one- or two-microsecond delay, simply return.  the overhead of
	// the function calls takes more than two microseconds.  can't just
	// subtract two, since us is unsigned; we'd overflow.
	if (--us == 0)
		return;
	if (--us == 0)
		return;

	// the following loop takes half of a microsecond (4 cycles)
	// per iteration, so execute it twice for each microsecond of
	// delay requested.
	us <<= 1;
    
	// partially compensate for the time taken by the preceeding commands.
	// we can't subtract any more than this or we'd overflow w/ small delays.
	us--;
#endif

	// busy wait
	__asm__ __volatile__ (
		"1: sbiw %0,1" "\n\t" // 2 cycles
		"brne 1b" : "=w" (us) : "0" (us) // 2 cycles
	);
}

, а чисто практический - взять и попробовать.

Клапауций
Offline
Зарегистрирован: 10.02.2013

Правильное решение #15 здесь #2

ромаха28
Offline
Зарегистрирован: 17.06.2016

Здравствуйте. Начал знакомится с ардуино,купил уно,кейпад шилд,пару датчиков,дс 18б20 и sht 21.Решил сделать инкубатор,на форуме "перепелка" скачал скетч,все работает,но после нескольких минут работы на экране появляются кракозябры.В чем может быть причина?Прошу помощи!

ромаха28
Offline
Зарегистрирован: 17.06.2016

При нажатии на rst все становится на свои места,потом опять.

JasKo
Offline
Зарегистрирован: 21.11.2015

Проблема в электропитании 100%. Попробуй другой блок питания.

ромаха28
Offline
Зарегистрирован: 17.06.2016

Спасибо за ответ!Сначала пробовал блок 9v, потом на прямую подключил 5,5 v от телефона!все тоже!

 

JasKo
Offline
Зарегистрирован: 21.11.2015

Что кроме экрана подключено? И вообще как подключено? На унах стабилизаторы слабенькие и если все нагрузки питаешь через него - проблемы обеспечены.

ромаха28
Offline
Зарегистрирован: 17.06.2016

Подключено два датчика,реле.Подключение не через стаб,просто к 5в и к земле подключил зарядку от телефона.

Сергей1990
Offline
Зарегистрирован: 13.11.2018

Помогите с решением проблемы. Панель выводит такую ерунду при исполнении стандартного скетча LiquidCrystal и при выводе своего текста.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Мне удалось прочитать, это      Hello, world!

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

 

Сергей1990
Offline
Зарегистрирован: 13.11.2018

как думаете это брак дисплея или проблема в другом?

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

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

Сергей1990
Offline
Зарегистрирован: 13.11.2018

#include <LiquidCrystal.h>
 
 
LiquidCrystal lcd(19, 18, 15, 14, 16, 10);
 
void setup() {
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("1234567890");
  lcd.setCursor(0,2);
  lcd.print("1234567890");
}
 
void loop() {
 
}

вторую строку вообще отказывается отображать

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

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

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Вторая строка это 0,1 а не 0,2........

http://wikihandbk.com/wiki/Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%...

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

По моей табличке 

3  это 0011 0011     у  вас  3   0011 0011

4 это    0011 0100   у вас  <   0011 1100
5 это    0011 0101   у вас  =   0011 1101
6 это    0011 0110   у вас  >   0011 1110

Попробуйте посылать бинарные данные......

Похоже на замыкание между третьим и четвёртым битом справа......

Сергей1990
Offline
Зарегистрирован: 13.11.2018

можно поподробнее про замыкание

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Когда вы ставите в "1" третий бит
у вас почему-то вместе с ним ставится в "1" четвёртый.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

прозвони DB2 и DB3 на икранчеге, нет ли кз

Сергей1990
Offline
Зарегистрирован: 13.11.2018

кз нет между контактами

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

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

2128506
Offline
Зарегистрирован: 16.07.2019

nestandart пишет:

>>Решил не ставить, для экономии памяти<<

Очень сомнительная экономия - шесть байт.

Очищать дисплей хоть изредка необходимо. Даже с точки зрения элементарной логики.

Неловкий вопрос (особенно после стольких лет), но зачем? Это не попытка докопаться, просто действительно не очевидно. Зачем очищать экран? 

saint_byte
Offline
Зарегистрирован: 19.08.2022

Расскажу свой кейс. Возможно у меня были руки крюки изначально. 
Дано Arduino Zero . Маркировка на плате HW-819 . Короче китайский клон с дофига памяти. ( Далее ардуина 1)
Дисплей СA1602F 

Собираю я все это дело на макетке , запускаю и о чудо - крякозябры. Но стабильные как выше описанном случае когда возникает непонятно откуда 1 . Матерился, алфавит собирал , глючит стабильно.  Заколебался .  Но глюки стабильные. Кондюки хотел паять уже . Программно так и сяк извращался. Есть конечно мысля что я там чего-то программно нафигачил и чего-то в постоянной памяти осталось - но это только домыслы и вера в "мистику"
Между дело распечатал типа поддержку дисплея чтоб они удобно были сборкой с переменным резитором что контраст крутить . и проводов было меньше 
Попробывал затем тестовый скетч собрать под чудо mh-tiny live с tiny88   ( Далее ардуина 2) . Потом психанул и припаял прям провода к  ардуине 2. Залил Скетч и запустил - и оно заработало нормально. На удивление LiquidCrystal.h жрет мало памяти . Ну так вот перевернул я ардуину 1 и вижу надпись Logic Level = 3.3 V . Может это 3.3  и есть источник глюков ?