LCD 1602 и "свои" символы

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

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

имеется LCD 1602, подключенный через регистр сдвига, для экономии выводов ардуино. Используется библиотека LiquidCrystal_SR_LCD3, LCD прекрасно выводит значения датчиков и вообще английский текст, с кириллицей пришлось выкручиваться

char temp[]={84, 101, 188, 190, 101, 112, 97, 191, 121, 112, 97, '\0'};
    lcd.print(temp); //Температура

Такое тоже все работает, и я пошел дальше с разработкой своих символов...нашел статью и сделал по ней один символ

uint8_t temp_cel[8] =
{
B00111,
B00101,
B00111,
B00000,
B00000,
B00000,
B00000
}; //закодировано в двоичной системе значек градуса

потом в void setup() указал lcd.createChar(1, temp_cel);

и вызываю на LCD (кусок кода)

char temp2[]={'\1', 67, '\0'}; //Отрисовка градусов Цельсия
    lcd.setCursor ( 0, 2 );
    lcd.print( val );
    lcd.print( temp2 );

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

Решил еще еще символов наделать, все делал так же, менял только значение lcd.createChar(1, temp_cel); (выделил жирным), НО вместо того, чтобы отобразить символ - показывает просто 3и полоски :(

Все перепробовал уже - помогите пожалуйста разобраться...

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

Дисплей поддерживает до 8-ми дополнительных символов.

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

еще покопался и нашел статью

попробовал из нее код и переработал под себя

#include <LiquidCrystal_SR_LCD3.h>
const int PIN_LCD_STROBE         =  5;  // Out: LCD IC4094 shift-register strobe
const int PIN_LCD_DATA           =  6;  // Out: LCD IC4094 shift-register data
const int PIN_LCD_CLOCK          =  4;  // Out: LCD IC4094 shift-register clock
/* Описываем наш символ в виде массива битовых масок.
 * Каждый символ - это восемь масок по пять бит.
 * тут 8 - высота клетки экрана
 */
uint8_t man_with_hat[8] =
{
  B01110,
  B11111,
  B00000,
  B01010,
  B00100,
  B10001,
  B01110,
  B00000,
};


/* Объявляем объект нашего дисплея */
LiquidCrystal_SR_LCD3 lcd(PIN_LCD_DATA, PIN_LCD_CLOCK, PIN_LCD_STROBE);

void setup()
{
  /* Регистрируем собственный символы с кодом 1 */
  lcd.createChar(1, man_with_hat);

  /* Начинаем работу с дисплееем */
  lcd.begin(16, 2);
   lcd.print("\1");
}

void loop()
{

}

вместо "мордочки" как в примере отображает символ квадратика в правом верхнем углу....ничего не понимаю как так...

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

Если хотите больше то можно попробовать написать функцию? которая каждый раз переписывает символ.

void Symbol(byte *symbol) {
  lcd.createChar(1, symbol);
  lcd.print('\1');
}
Symbol(man_with_hat);

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

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

а именно

// Original LiquidCrystal library that can be inherited from to support other
// connectivity:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home

#include <LiquidCrystal_SR_LCD3.h>

// Standard HD44780 20x4 LCD display driven via 3 output pins to a 4094 8-bit
// shift register like 74HC4094 pebblev2's MC14094

// This demo was written for the PebbleV2 to test LiquidCrystal_SR_LCD3, but it
// should work with other LiquidCrystal Displays that are 20x4.
// http://www.freetronics.com/pages/pebble-v2
// https://github.com/lukeweston/pebble20

// Data are the input bits
// Clock tells the SR that the data pin holds the next valid bit
// Strobe gets data input to be made visible on the parallel output pins.

const int PIN_LCD_STROBE         =  5;  // Out: LCD IC4094 shift-register strobe
const int PIN_LCD_DATA           =  6;  // Out: LCD IC4094 shift-register data
const int PIN_LCD_CLOCK          =  4;  // Out: LCD IC4094 shift-register clock
//const int PIN_LCD_BACKLIGHT      =  5;  // Out: LCD backlight (PWM)

// srdata / srclock / strobe
LiquidCrystal_SR_LCD3 lcd(PIN_LCD_DATA, PIN_LCD_CLOCK, PIN_LCD_STROBE);

// Creat a set of new characters
byte heart[8] = {
  0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000
};

byte smiley[8] = {
  0b00000, 0b00000, 0b01010, 0b00000, 0b00000, 0b10001, 0b01110, 0b00000
};

byte frownie[8] = {
  0b00000, 0b00000, 0b01010, 0b00000, 0b00000, 0b00000, 0b01110, 0b10001
};

byte armsDown[8] = {
  0b00100, 0b01010, 0b00100, 0b00100, 0b01110, 0b10101, 0b00100, 0b01010
};

byte armsUp[8] = {
  0b00100, 0b01010, 0b00100, 0b10101, 0b01110, 0b00100, 0b00100, 0b01010
};
byte man_with_hat[8] =
{
  0b01110,
  0b11111,
  0b00000,
  0b01010,
  0b00100,
  0b10001,
  0b01110,
  0b00000,
};
void setup(){
    //pinMode(PIN_LCD_BACKLIGHT, OUTPUT);
    //analogWrite(PIN_LCD_BACKLIGHT, 80);

    lcd.begin(16, 2);               // initialize the lcd 

    // load characters to the LCD
    lcd.createChar(0, smiley);
    lcd.createChar(1, frownie);
    lcd.createChar(2, armsDown);  
    lcd.createChar(3, armsUp);  
    lcd.createChar(4, heart);
    lcd.createChar(5,man_with_hat);

    lcd.home ();                   // go home
    lcd.setCursor (0, 0);
    //lcd.print(F("LiquidCrystal_SRLCD3"));  
    //lcd.setCursor (0, 1);
    //lcd.print(F("he.."));
    //lcd.setCursor (0, 2);
    //lcd.print(F("..lo"));
    //lcd.setCursor (0, 3);
    //lcd.print(F("World "));
    lcd.print(char(4));
    lcd.print(char(2));
    lcd.print(char(3));
    lcd.print(char(1));
    lcd.print(char(0));
    lcd.print(char(5));
    
}

void loop()
{
    
}

этот код работает отлично - выводит в одну строку все разработанные символы символы

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

Так в чем проблема то?

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

уф...объяснить бы мне вам все нюансы...

в общем о коде, котором я сказал что он рабочий, я попробовал по его аналогии подставить в свой код и сделать вывод на LCD, так вот он выводит на например по запросу символ1 не тот, который я включил в код, а как будто из памяти загруженного ранее кода

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

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

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

помогло, но отображает уже не из "памяти", а просто полоски :(

на всякий пожарный тема, в которой я мудрил как подключить LCD по 3 проводам

В общем вместо символа градуса

byte temp_cel[8] =
{
0b00111,
0b00101,
0b00111,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
};

и объявления символа lcd.createChar(1, temp_cel);

в коде

void printTemp(void) {

    lcd.setCursor ( 0, 0 );
    //lcd.print(F("Temperature"));
    char temp[]={84, 101, 188, 190, 101, 112, 97, 191, 121, 112, 97, '\0'};
    lcd.print(temp); //Температура
    lcd.setCursor ( 0, 2 );
    lcd.print(sensors.getTempCByIndex(0));
    lcd.setCursor ( 10, 2 );
    lcd.print(char(1));
}

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

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

никак не удается победить со "своими" символами :(

решил задать другой вопрос - а где вообще можно посмотреть таблицу символов?

Например использую программку - lcdHd44780.exe которая пребразовывает символы...взял зашел в MS Word и тупо нашел значек градуса, копипаст и в программку - она показала мне {176, '\0'}; //° но вместо символа градуса, как мне необходимо отображает почему то Ю :(

Посидел в инете и нашел такую штуку - Таблица символов CGRAM

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

char temp2[]={0xEF, 0x43,'\0'}; //Отрисовка градусов Цельсия
    lcd.print(temp2);

Взял из статьи в встретилось...Первые 16 ячеек CGRAM имеют особое значение. При желании, в них могут быть записаны любые пользовательские символы, которых нет таблице (сразу после включения модуля в них находится случайная информация). Но как это сделать?

В общем сумел победить проблему с выводом "своих" символов...дело как всегда было не в бобине..

lcd.begin(16, 2);               // initialize the lcd 
   lcd.createChar(1, temp_cel);
   lcd.createChar(2, mois_cap);
   lcd.createChar(3, lightning);
Вот так надо!
а у меня было перед инициализацией ЖК
usr-bin
Offline
Зарегистрирован: 04.09.2012

ага.. разобрался значит..

zugni
Offline
Зарегистрирован: 14.06.2015

#include <LiquidCrystal_SR_LCD3.h>

как мне переделать вот под такой дисплей

 #include <LiquidCrystal_I2C.h>

подскажите 

pycm1k
Offline
Зарегистрирован: 23.01.2016

Добрый вечер. Подскажите, вывожу "свои" символы для отображения русских букв на lcd1602. Через раз первый символ в первой либо во второй строке прорисовывается не так как надо. Пробовал менять дисплей и мк, не помогло. В протеусе рисуется все как надо.

crazy-coder
Offline
Зарегистрирован: 20.07.2015

хм, действительно проблемная тема... предистория:

приобрел Arduino keypad + LCD Shield удобная штука для прототипирования, надел на UNO/Leonardo/Mega и все почти готовое устройство :) Один недостаток дисплейчик без русификации... Как-то вспомнил, что в дисплей вроде бы можно загружать свои символы/шрифты... Почитал что попалось что-то не помогло. Потом как то полез в исходник LiquidCrystal.cpp и обнаружил интересный метод createChar попробовал использовать тоже не получилось, тупо эффекта ноль, в чем дело так и не понял...

Позже пришла идея поискать пример кода нашлось:

#include <LiquidCrystal.h>

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

byte smiley[8] = {
  B00000,
  B10001,
  B00000,
  B00000,
  B10001,
  B01110,
  B00000,
};

void setup() {
  lcd.createChar(0, smiley);
  lcd.begin(16, 2);  
  lcd.write(byte(0));
}

void loop() {}

этот на удивление сработал! заметьте строчки с загрузкой шрифта и инициализация стоят в обратном порядке!!!

И вот самый прикол, стоило их поменять местами, все перестало работать!!! Опять углубляться не стал, понял только что эта функция действительно требует особого внимания и осторожности, возможно нет/недостаточная задержка, в доках по этому поводу мало написано.

Вполне возможно что нужно послать комманду:

lcd.command(LCD_SETDDRAMADDR);

 

arduinec
Offline
Зарегистрирован: 01.09.2015

crazy-coder пишет:

И вот самый прикол, стоило их поменять местами, все перестало работать!

После загрузки символов нужна небольшая задержка. Можно (например) выполнить команду: lcd.home() - установка курсора в нулевую позицию (внутри неё есть задержка на 2 мс).

Пример как из загружаемых символов мультики делать:
http://arduino.ru/forum/programmirovanie/etyud-multik-na-lcd-1602

crazy-coder
Offline
Зарегистрирован: 20.07.2015

Да нет, тут в чем-то другом проблема.

Прикупил Arduino Keypad + LCD Shield на базе 1602 дисплея, китаец, русский не понимает в принципе, портировал код от ShadS на Arduino. Точнее только взаимствовал шрифты. Используя мощь Си++ отнаследовался от стандартного LiquidCrystal, переопределил несколько методов и назвал LiquidCrystalCyr. Использование примитивное и привычное для тех кто знаком с LiquidCrystal. Выложил исходники

Glinka0
Offline
Зарегистрирован: 13.03.2017

Из книги Джереми Блума

crazy-coder
Offline
Зарегистрирован: 20.07.2015

тут как-то проблематично что-то прочитать...

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

crazy-coder пишет:

тут как-то проблематично что-то прочитать...

хватит тупить - найди и скачай книгу

crazy-coder
Offline
Зарегистрирован: 20.07.2015

я не туплю, с вопросом я разобрался... а как книга то называется?

arduino328
Offline
Зарегистрирован: 01.09.2016

crazy-coder пишет:

Да нет, тут в чем-то другом проблема.

Используя мощь Си++ отнаследовался от стандартного LiquidCrystal, переопределил несколько методов и назвал LiquidCrystalCyr.

Напиши с помощью свой библиотеки слово ЗАГЛУБЛЯЮЩИЙ.

arduino328
Offline
Зарегистрирован: 01.09.2016

crazy-coder пишет:

а как книга то называется?

Похоже: Блум Джереми - Изучаем Arduino - 2015

crazy-coder
Offline
Зарегистрирован: 20.07.2015

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

ЗЫ: Пошел в школу впитывать новые знания! Пятый раз в первый класс! :)

arduino328
Offline
Зарегистрирован: 01.09.2016

crazy-coder пишет:

Злые вы... Ежу понятно, что конкретно это слово написать полностью не получится

Не такие уж и злые. И почему полностью не получится?

3arЛy6ЛЯЮЩuЙ (2 цифры, 4 английские и 5 русских букв).

Вот ещё известная фраза только из аглийских букв: C HoBblM rogoM!