Немного подправил Вашу библиотеку, добавил инверсию цвета, иногда бывает очень полезно, например в меню при выделения пункта закрашенным прямоугольником текст будет инвертироваться:
1. изменить размерность массива видеобуфера и изменить его вывод, сейчас он просто по порядку, а нужно иначе, ктати это будет значительно медленнее чем сейчас работает, но проще либу переделать
2. изменить способ записи для букв, линий и т.д. а массив оставить как есть. сложнее библиотеку переделать, но зато скорость работы должна остаться на том же уровне
Это инверсия всего дисплея, а тут 3-й вариант, это "смотрится" массив и инвертируется, если надо :)
jeka_tm пишет:
А насчет поворота два варианта
1. изменить размерность массива видеобуфера и изменить его вывод, сейчас он просто по порядку, а нужно иначе, ктати это будет значительно медленнее чем сейчас работает, но проще либу переделать
2. изменить способ записи для букв, линий и т.д. а массив оставить как есть. сложнее библиотеку переделать, но зато скорость работы должна остаться на том же уровне
В идеале, хотелось бы, что бы была переменная, задающая поворот, но это долго, хочется по быстрому реализовать, буду разбираться… Смотрю как это сделано в библиотеках u8glib и Ucglib – это жесть!
Если что получится, опубликую здесь.
Кстати, у меня есть пример проверки дисплея 1203 с поддержкой русского языка, без библиотеки, может кому сгодится, работает так же на Arduino STM32:
здравствуйте. я немного изменил библиотеку от jeka_tm . убрал буфер экрана для экономии. пытаюсь выводить на дисплэй свои данные. проблема в том, что дисплэй мигает, когда я пытаюсь CS установить в активное положение, хоть мигает на пол сикунды, но это неприятное явление. а в родной библиотеке такого я не наблюдаю. хочу задать вопрос, почему дисплэй может мигать при подаче CS сигнала на дисплэй?
Убрал буфер. Выводишь по строкам и только текст? Или размер буфера уменьшил в 3 раза например как Хугобосс жертвуя процессорным временем, или может вообще до 1 строки буфер уменьшил?
Вообще не совсем понимаю смысла использовать вышеупомянутую библиотеку, убрав из неё буфер. Вокруг него, или на его основе (как угодно) построен весь принцип вывода изображения. В библиотеке собственно нет функций вывода чего либо на экран (на исключением самого буфера). Есть только запись данных в него. А если его нет то и выводить то нечего. Но я уверен, что Вам видней.
Я бы наверное сделал так:
Сначала подключил рабочую библиотеку и убедился в том что экран правильно подключён и нормально работает. А потом эксперементировать.
не знаю , в чём дело. вот , снял видео. я убедился, что всё работает с вашей библиотеки. сравнил коды вашей библиотеки и на AVRStudio. но с avrstudio не работает без мигания.
питание забыл подать , т.е. питание подавалось от микроконтроллера и я забыл ему на порт лог. 1 включить. так что такое может быть при отключенном питании.
плату я делал три месяца назад, уже забыл , как там разведено было, а увидел, когда проверять начал мультиметром общее напряжение. спасибо за ответы...
Я этим программированием только начал заниматься, и ничего толком не понимаю, мне это надо для разового своего проэкта. И в дальнейшем я не собираюсь заниматься програмированием. Поэтому прошу просто показать как это сделать. В библиотеке есть строка:void SendByte(char mode,unsigned char c);. но вставка данной строки в скетч вызывает ошибку при загрузке:Arduino: 1.8.4 (Windows 8.1), Плата:"Arduino Nano, ATmega328P (Old Bootloader)"
Скетч использует 3226 байт (10%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 891 байт (43%) динамической памяти, оставляя 1157 байт для локальных переменных. Максимум: 2048 байт.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xc7
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xc7
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xc7
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xc7
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xc7
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xc7
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xc7
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xc7
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xc7
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xc7
Да, там есть строка:void Contrast(uint8_t c = 0x0D); Я её попробовал вставить в тело сетап, но опять ошибка при загрузке, хотя скомпилировалась без ошибок.
Arduino: 1.8.4 (Windows 8.1), Плата:"Arduino Nano, ATmega328P (Old Bootloader)"
Скетч использует 3226 байт (10%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 891 байт (43%) динамической памяти, оставляя 1157 байт для локальных переменных. Максимум: 2048 байт.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x43
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x43
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x43
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x43
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x43
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x43
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x43
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x43
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x43
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x43
Проблема загрузки в плату. Помощь по загрузке: http://www.arduino.cc/en/Guide/Troubleshooting#upload .
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
С этим я разобрался, почему-то драйвер слетел, да и USB вход чего-то барахлит. Но потом всё на том же месте и осталось. Если можно просто напиши строки как надо их писать, я просто не знаю если честно, какая транскрипция написания.
Да устранил я эту проблему с программатором, у меня ардуино нано, чего-то перестал USB переходник работать, и я подсоединил внешний переходник. Сейчас загружается, но на экране ничего не видно, а влинком я всегда проверяю когда возникают проблемы с загрузкой. Но повторюсь на дисплее ничего не видно, поэтому и прошу подсказать как правильно написать этот оператор по контрастности, у меня не получается.
А откуда эти 20ms взялись? В даташите на STE2007 ничего похожего не нашел.
dWrite(CS, 0);
delay(20);
dWrite(CS, 1);
( для меня ) Это важно для того чтобы управлять 2-мя пинами (каждый на счету), CE я физически посадил на GND, а RST на VCC но не все оказалось так просто. Утром включаешь девайс и экранчик не стартует, выключаешь-включаешь - стартует и потом весь день стартует при включении безупречно.
Вот как раз и интересно из какой либы ноги растут. Возможно, это просто артефакт, возникший при многократном копировании из либы в либу и это тоже, кстати, чревато неожиданными багами. Иногда можно обойтись RC-цепочкой, не занимать пин контроллера и не вести дорожку через всю плату. На 5110 это делаю примерно вот так :
Вообще ИМХО инициализировать экран сразу после подачи питания на него не самая лучшая идея. Если есть возможность, лучше это делать спустя пол секунды (примерно). А управлять по двум пинам ИМХО, рано или поздно зависает.
Действительно странно. Кудато ж данные отправляются. С учётом того что во вторую и третью строку выводится нормально, а адрес вывода задаётся только для первой строки, вобще странно.
Проверь, в массив заносятся данные при первом выводе.
хм, интересно. После вывода последнего байта последней строки, если продолжают поступать данные, они выводятся с начала экрана?
Да, всё именно так. Кстати, при инициализации дисплея задаётся активная область.
hugoboss317 пишет:
Да, с "m" правильно. Сейчас посмотрел библиотеку для экрана с контроллером PCF8812, там я тоже так делал.
uint8_t step, p, b, m = 3;
switch(page){
case 3: step = 0; break; // 5 для
case 2: step = 3; break; // 2 Nokia
case 1: step = 6; m = 2; break;// 0 3410
Я попробовал сделать вывод не по три, а по четыре странице - экономия памяти в четыре раза, а скорость вывода изображения, соответственно, в четыре раза медленнее - совсем не комфортно.
Поворот экрана, попробовал - работает, текст, картинки поворачиваются, а геометрические фигуры надо корректировать...
Ребята а как из дисплея байты прочесть? Ну к примеру делаю я функцию публичной и шлю запрос на измерение
lcd.SendByte(0,0xDE); // Запрос температуры
Но как потом получить ответ из 7 байт?
Температура расчитывается потом по формуле T 1.875 TD = (ответ)° × – 40 C
Охота термометр замутить без датчиков. И еще вопрос, почему с дисплеем никто по I2C шине не работает? Я так понимаю его единоразово нужно настроить на I2C и потом спокойно с ним на 2х проводах работать.
Дисплей от Nokia 1100 позволяет только записывать данные в память (DDRAM) контроллера дисплея. Чтение из памяти не реализовано, хотя сам контроллер PCF8814 это позволяет. Поэтому, что бы определить, что у вас записано в памяти дисплея, необходимо в микроконтроллере организовывать буфер с данными для дисплея и отслеживать то, что записано, по нему.
Библиотека итак делает полную буферизацию.
Спасибо за библиотеку, она великолепна!!
Немного подправил Вашу библиотеку, добавил инверсию цвета, иногда бывает очень полезно, например в меню при выделения пункта закрашенным прямоугольником текст будет инвертироваться:
//===================================================Нарисовать пиксель void LCD1202::drawPixel (byte x, byte y, boolean color) { if ((x < 0) || (x >= LCD_X) || (y < 0) || (y >= LCD_Y)) return; if (color) LCD_RAM[x+ (y/8)*LCD_X] |= _BV(y%8); else LCD_RAM[x+ (y/8)*LCD_X] &= ~_BV(y%8); }Это:
// Варианты цвета: #define ON 0 //включение #define OFF 1 //выключение #define INV 2 //инверсия //===================================================Нарисовать пиксель void LCD1202::drawPixel (byte x, byte y, boolean color) { if ((x < 0) || (x >= LCD_X) || (y < 0) || (y >= LCD_Y)) return; switch(color){ case 0: LCD_RAM[x+ (y/8)*LCD_X] &= ~_BV(y%8); break; //Off case 1: LCD_RAM[x+ (y/8)*LCD_X] |= _BV(y%8); break; //No case 2: LCD_RAM[x+ (y/8)*LCD_X] ^= 1<<y%8; break; //Invert } }А насчет поворотав инициализации подай команду на поворот и наверно нужно будет указать новое разрешение дисплея, так как буфер будет неправильный
К сожалению, я только начинаю осваивать программирование, помогите понять, куда копать и как.
Я правильно понимаю, что нужно как-то преобразовать массив "LCD_RAM" при отправки его в дисплей, функция void LCD1202::Update() в развёрнутом виде...
//=====================================================Обновить дисплей void LCD1202::Update(){ for(byte p = 0; p < 9; p++){ SendByte(LCD_C, SetYAddr| p); SendByte(LCD_C, SetXAddr4); SendByte(LCD_C, SetXAddr3); for(byte col=0; col < LCD_X; col++){ SendByte(LCD_D, LCD_RAM[(LCD_X * p) + col]); } } }Так инверсия насколько помню итак была. Достаточно поменять color. и обновить дисплей
Вообще либу делал не я, я код выложил, а cres насколько помню его оформил в либу
Надо даташит смотреть и пробовать. Я точно не понмю, там вроде встроенное что то было.
Вот кстати команда на инверсию
А насчет поворота два варианта
1. изменить размерность массива видеобуфера и изменить его вывод, сейчас он просто по порядку, а нужно иначе, ктати это будет значительно медленнее чем сейчас работает, но проще либу переделать
2. изменить способ записи для букв, линий и т.д. а массив оставить как есть. сложнее библиотеку переделать, но зато скорость работы должна остаться на том же уровне
Вот кстати команда на инверсию
Это инверсия всего дисплея, а тут 3-й вариант, это "смотрится" массив и инвертируется, если надо :)
А насчет поворота два варианта
1. изменить размерность массива видеобуфера и изменить его вывод, сейчас он просто по порядку, а нужно иначе, ктати это будет значительно медленнее чем сейчас работает, но проще либу переделать
2. изменить способ записи для букв, линий и т.д. а массив оставить как есть. сложнее библиотеку переделать, но зато скорость работы должна остаться на том же уровне
В идеале, хотелось бы, что бы была переменная, задающая поворот, но это долго, хочется по быстрому реализовать, буду разбираться… Смотрю как это сделано в библиотеках u8glib и Ucglib – это жесть!
Если что получится, опубликую здесь.
Кстати, у меня есть пример проверки дисплея 1203 с поддержкой русского языка, без библиотеки, может кому сгодится, работает так же на Arduino STM32:
#include "wirish.h" //stm32 maple support #include "Print.h" //РАБОТАЕТ на Arduino 1.8.1 to STM32 // Arduino pinout // Nokia 1100 LCD pinout (VDD & VDDI ==> 3.3V, VLED+ connected via 10 ohm resistor to 3.3V) #define PIN_SCE PB7 // 2 XCS Connected via resistor-voltage-divider 1.8K & 3.2K #define PIN_SDIN PB8 // 4 SDA #define PIN_RESET PB6 // 1 XRES #define PIN_SCLK PB9 // 5 SCLK #define LCD_C LOW // Command #define LCD_D HIGH // Data static const byte ASCII[][5] ={ //Font 5x8 0x00, 0x00, 0x00, 0x00, 0x00 , // 0x20 space 0x00, 0x00, 0x5f, 0x00, 0x00 , // 0x21 ! 0x00, 0x07, 0x00, 0x07, 0x00 , // 0x22 " 0x14, 0x7f, 0x14, 0x7f, 0x14 , // 0x23 # 0x24, 0x2a, 0x7f, 0x2a, 0x12 , // 0x24 $ 0x23, 0x13, 0x08, 0x64, 0x62 , // 0x25 % 0x36, 0x49, 0x55, 0x22, 0x50 , // 0x26 & 0x00, 0x05, 0x03, 0x00, 0x00 , // 0x27 ' 0x00, 0x1c, 0x22, 0x41, 0x00 , // 0x28 ( 0x00, 0x41, 0x22, 0x1c, 0x00 , // 0x29 ) 0x14, 0x08, 0x3e, 0x08, 0x14 , // 0x2a * 0x08, 0x08, 0x3e, 0x08, 0x08 , // 0x2b + 0x00, 0x50, 0x30, 0x00, 0x00 , // 0x2c , 0x08, 0x08, 0x08, 0x08, 0x08 , // 0x2d - 0x00, 0x60, 0x60, 0x00, 0x00 , // 0x2e . 0x20, 0x10, 0x08, 0x04, 0x02 , // 0x2f / 0x3e, 0x51, 0x49, 0x45, 0x3e , // 0x30 0 0x00, 0x42, 0x7f, 0x40, 0x00 , // 0x31 1 0x42, 0x61, 0x51, 0x49, 0x46 , // 0x32 2 0x21, 0x41, 0x45, 0x4b, 0x31 , // 0x33 3 0x18, 0x14, 0x12, 0x7f, 0x10 , // 0x34 4 0x27, 0x45, 0x45, 0x45, 0x39 , // 0x35 5 0x3c, 0x4a, 0x49, 0x49, 0x30 , // 0x36 6 0x01, 0x71, 0x09, 0x05, 0x03 , // 0x37 7 0x36, 0x49, 0x49, 0x49, 0x36 , // 0x38 8 0x06, 0x49, 0x49, 0x29, 0x1e , // 0x39 9 0x00, 0x36, 0x36, 0x00, 0x00 , // 0x3a : 0x00, 0x56, 0x36, 0x00, 0x00 , // 0x3b ; 0x08, 0x14, 0x22, 0x41, 0x00 , // 0x3c < 0x14, 0x14, 0x14, 0x14, 0x14 , // 0x3d = 0x00, 0x41, 0x22, 0x14, 0x08 , // 0x3e > 0x02, 0x01, 0x51, 0x09, 0x06 , // 0x3f ? 0x32, 0x49, 0x79, 0x41, 0x3e , // 0x40 @ 0x7e, 0x11, 0x11, 0x11, 0x7e , // 0x41 A 0x7f, 0x49, 0x49, 0x49, 0x36 , // 0x42 B 0x3e, 0x41, 0x41, 0x41, 0x22 , // 0x43 C 0x7f, 0x41, 0x41, 0x22, 0x1c , // 0x44 D 0x7f, 0x49, 0x49, 0x49, 0x41 , // 0x45 E 0x7f, 0x09, 0x09, 0x09, 0x01 , // 0x46 F 0x3e, 0x41, 0x49, 0x49, 0x7a , // 0x47 G 0x7f, 0x08, 0x08, 0x08, 0x7f , // 0x48 H 0x00, 0x41, 0x7f, 0x41, 0x00 , // 0x49 I 0x20, 0x40, 0x41, 0x3f, 0x01 , // 0x4a J 0x7f, 0x08, 0x14, 0x22, 0x41 , // 0x4b K 0x7f, 0x40, 0x40, 0x40, 0x40 , // 0x4c L 0x7f, 0x02, 0x0c, 0x02, 0x7f , // 0x4d M 0x7f, 0x04, 0x08, 0x10, 0x7f , // 0x4e N 0x3e, 0x41, 0x41, 0x41, 0x3e , // 0x4f O 0x7f, 0x09, 0x09, 0x09, 0x06 , // 0x50 P 0x3e, 0x41, 0x51, 0x21, 0x5e , // 0x51 Q 0x7f, 0x09, 0x19, 0x29, 0x46 , // 0x52 R 0x46, 0x49, 0x49, 0x49, 0x31 , // 0x53 S 0x01, 0x01, 0x7f, 0x01, 0x01 , // 0x54 T 0x3f, 0x40, 0x40, 0x40, 0x3f , // 0x55 U 0x1f, 0x20, 0x40, 0x20, 0x1f , // 0x56 V 0x3f, 0x40, 0x38, 0x40, 0x3f , // 0x57 W 0x63, 0x14, 0x08, 0x14, 0x63 , // 0x58 X 0x07, 0x08, 0x70, 0x08, 0x07 , // 0x59 Y 0x61, 0x51, 0x49, 0x45, 0x43 , // 0x5a Z 0x00, 0x7f, 0x41, 0x41, 0x00 , // 0x5b [ 0x02, 0x04, 0x08, 0x10, 0x20 , // 0x5c backslash 0x00, 0x41, 0x41, 0x7f, 0x00 , // 0x5d ] 0x04, 0x02, 0x01, 0x02, 0x04 , // 0x5e ^ 0x40, 0x40, 0x40, 0x40, 0x40 , // 0x5f _ 0x00, 0x01, 0x02, 0x04, 0x00 , // 0x60 ` 0x20, 0x54, 0x54, 0x54, 0x78 , // 0x61 a 0x7f, 0x48, 0x44, 0x44, 0x38 , // 0x62 b 0x38, 0x44, 0x44, 0x44, 0x20 , // 0x63 c 0x38, 0x44, 0x44, 0x48, 0x7f , // 0x64 d 0x38, 0x54, 0x54, 0x54, 0x18 , // 0x65 e 0x08, 0x7e, 0x09, 0x01, 0x02 , // 0x66 f 0x0c, 0x52, 0x52, 0x52, 0x3e , // 0x67 g 0x7f, 0x08, 0x04, 0x04, 0x78 , // 0x68 h 0x00, 0x44, 0x7d, 0x40, 0x00 , // 0x69 i 0x20, 0x40, 0x44, 0x3d, 0x00 , // 0x6a j 0x7f, 0x10, 0x28, 0x44, 0x00 , // 0x6b k 0x00, 0x41, 0x7f, 0x40, 0x00 , // 0x6c l 0x7c, 0x04, 0x18, 0x04, 0x78 , // 0x6d m 0x7c, 0x08, 0x04, 0x04, 0x78 , // 0x6e n 0x38, 0x44, 0x44, 0x44, 0x38 , // 0x6f o 0x7c, 0x14, 0x14, 0x14, 0x08 , // 0x70 p 0x08, 0x14, 0x14, 0x18, 0x7c , // 0x71 q 0x7c, 0x08, 0x04, 0x04, 0x08 , // 0x72 r 0x48, 0x54, 0x54, 0x54, 0x20 , // 0x73 s 0x04, 0x3f, 0x44, 0x40, 0x20 , // 0x74 t 0x3c, 0x40, 0x40, 0x20, 0x7c , // 0x75 u 0x1c, 0x20, 0x40, 0x20, 0x1c , // 0x76 v 0x3c, 0x40, 0x30, 0x40, 0x3c , // 0x77 w 0x44, 0x28, 0x10, 0x28, 0x44 , // 0x78 x 0x0c, 0x50, 0x50, 0x50, 0x3c , // 0x79 y 0x44, 0x64, 0x54, 0x4c, 0x44 , // 0x7a z 0x00, 0x08, 0x36, 0x41, 0x00 , // 0x7b { 0x00, 0x00, 0x7f, 0x00, 0x00 , // 0x7c | 0x00, 0x41, 0x36, 0x08, 0x00 , // 0x7d } 0x10, 0x08, 0x08, 0x10, 0x08 , // 0x7e ~ 0x00, 0x00, 0x00, 0x00, 0x00 , // 0x7f 0x7e, 0x11, 0x11, 0x11, 0x7e , // 0x80 A // Русские символы. Для вывода используется кодировка CP1251 0x7f, 0x49, 0x49, 0x49, 0x33 , // 0x81 Б 0x7f, 0x49, 0x49, 0x49, 0x36 , // 0x82 В 0x7f, 0x01, 0x01, 0x01, 0x03 , // 0x83 Г 0xe0, 0x51, 0x4f, 0x41, 0xff , // 0x84 Д 0x7f, 0x49, 0x49, 0x49, 0x41 , // 0x85 E 0x77, 0x08, 0x7f, 0x08, 0x77 , // 0x86 Ж 0x41, 0x49, 0x49, 0x49, 0x36 , // 0x87 З 0x7f, 0x10, 0x08, 0x04, 0x7f , // 0x88 И 0x7c, 0x21, 0x12, 0x09, 0x7c , // 0x89 Й 0x7f, 0x08, 0x14, 0x22, 0x41 , // 0x8A K 0x20, 0x41, 0x3f, 0x01, 0x7f , // 0x8B Л 0x7f, 0x02, 0x0c, 0x02, 0x7f , // 0x8C M 0x7f, 0x08, 0x08, 0x08, 0x7f , // 0x8D H 0x3e, 0x41, 0x41, 0x41, 0x3e , // 0x8E O 0x7f, 0x01, 0x01, 0x01, 0x7f , // 0x8F П 0x7f, 0x09, 0x09, 0x09, 0x06 , // 0x90 P 0x3e, 0x41, 0x41, 0x41, 0x22 , // 0x91 C 0x01, 0x01, 0x7f, 0x01, 0x01 , // 0x92 T 0x47, 0x28, 0x10, 0x08, 0x07 , // 0x93 У 0x1c, 0x22, 0x7f, 0x22, 0x1c , // 0x94 Ф 0x63, 0x14, 0x08, 0x14, 0x63 , // 0x95 X 0x7f, 0x40, 0x40, 0x40, 0xff , // 0x96 Ц 0x07, 0x08, 0x08, 0x08, 0x7f , // 0x97 Ч 0x7f, 0x40, 0x7f, 0x40, 0x7f , // 0x98 Ш 0x7f, 0x40, 0x7f, 0x40, 0xff , // 0x99 Щ 0x01, 0x7f, 0x48, 0x48, 0x30 , // 0x9A Ъ 0x7f, 0x48, 0x30, 0x00, 0x7f , // 0x9B Ы 0x00, 0x7f, 0x48, 0x48, 0x30 , // 0x9C Э 0x22, 0x41, 0x49, 0x49, 0x3e , // 0x9D Ь 0x7f, 0x08, 0x3e, 0x41, 0x3e , // 0x9E Ю 0x46, 0x29, 0x19, 0x09, 0x7f , // 0x9F Я 0x20, 0x54, 0x54, 0x54, 0x78 , // 0xA0 a 0x3c, 0x4a, 0x4a, 0x49, 0x31 , // 0xA1 б 0x7c, 0x54, 0x54, 0x54, 0x28 , // 0xA2 в 0x7c, 0x04, 0x04, 0x04, 0x0c , // 0xA3 г 0xe0, 0x54, 0x4c, 0x44, 0xfc , // 0xA4 д 0x38, 0x54, 0x54, 0x54, 0x18 , // 0xA5 e 0x6c, 0x10, 0x7c, 0x10, 0x6c , // 0xA6 ж 0x44, 0x44, 0x54, 0x54, 0x28 , // 0xA7 з 0x7c, 0x20, 0x10, 0x08, 0x7c , // 0xA8 и 0x7c, 0x41, 0x22, 0x11, 0x7c , // 0xA9 й 0x7c, 0x10, 0x10, 0x28, 0x44 , // 0xAA к 0x20, 0x44, 0x3c, 0x04, 0x7c , // 0xAB л 0x7c, 0x08, 0x10, 0x08, 0x7c , // 0xAC м 0x7c, 0x10, 0x10, 0x10, 0x7c , // 0xAD н 0x38, 0x44, 0x44, 0x44, 0x38 , // 0xAE o 0x7c, 0x04, 0x04, 0x04, 0x7c , // 0xAF п 0x7C, 0x14, 0x14, 0x14, 0x08 , // 0xB0 p 0x38, 0x44, 0x44, 0x44, 0x20 , // 0xB1 c 0x04, 0x04, 0x7c, 0x04, 0x04 , // 0xB2 т 0x0C, 0x50, 0x50, 0x50, 0x3C , // 0xB3 у 0x30, 0x48, 0xfc, 0x48, 0x30 , // 0xB4 ф 0x44, 0x28, 0x10, 0x28, 0x44 , // 0xB5 x 0x7c, 0x40, 0x40, 0x40, 0xfc , // 0xB6 ц 0x0c, 0x10, 0x10, 0x10, 0x7c , // 0xB7 ч 0x7c, 0x40, 0x7c, 0x40, 0x7c , // 0xB8 ш 0x7c, 0x40, 0x7c, 0x40, 0xfc , // 0xB9 щ 0x04, 0x7c, 0x50, 0x50, 0x20 , // 0xBA ъ 0x7c, 0x50, 0x50, 0x20, 0x7c , // 0xBB ы 0x7c, 0x50, 0x50, 0x20, 0x00 , // 0xBC ь 0x28, 0x44, 0x54, 0x54, 0x38 , // 0xBD э 0x7c, 0x10, 0x38, 0x44, 0x38 , // 0xBE ю 0x08, 0x54, 0x34, 0x14, 0x7c , // 0xBF я }; /* void LcdCharacter(char character){ unsigned char type = *character; if(type>=128) x=x-3; while(*character); LcdWrite(LCD_D, 0x00); for (int index = 0; index < 5; index++) LcdWrite(LCD_D, ASCII[character - 0x20][index]); } */ void LcdCharacter(char character){ LcdWrite(LCD_D, 0x00); if(character<128) character = character-32; if(character>=144 && character<=175) character = character-48; if(character>=128 && character<=143) character = character+16; if(character>=176 && character<=191) character = character-48; if(character>191) return; for (int index = 0; index < 5; index++) LcdWrite(LCD_D, ASCII[character][index]); //LcdWrite(LCD_D, ASCII[character - 0x20][index]); } void LcdClear(void){ for (int index = 0; index < 864 ; index++) LcdWrite(LCD_D, 0x00); } void LcdInitialise(void){ digitalWrite(PIN_RESET, LOW); digitalWrite(PIN_RESET, HIGH); LcdWrite(LCD_C, 0x2F); // Charge pump ON LcdWrite(LCD_C, 0x24); // Vop MSB *Don't change* LcdWrite(LCD_C, 0x40); // Vop LSB *Here you can change contrast* =80 LcdWrite(LCD_C, 0xA4); // A4 = normal display mode, A5 = all pixels ON //LcdWrite(LCD_C, 0xA6); // A6 = normal display mode, A7 = all pixels INVERSE //LcdWrite(LCD_C, 0xA0); // A0 = Отразить экран по оси Х, C0 = Отразить экран по оси Y (A1 что делает?!) //LcdWrite(LCD_C, 0xC8); // разворот картинки на 180 гр. LcdWrite(LCD_C, 0xAF); // Display ON } void LcdString(char *characters){ while (*characters) { LcdCharacter(*characters++); } } void LcdWrite(byte dc, byte data){ digitalWrite(PIN_SDIN, dc); // dc is sampled with the first rising SCLK edge digitalWrite(PIN_SCE, LOW); // LCD enable digitalWrite(PIN_SCLK, HIGH); // First rising SCLK edge digitalWrite(PIN_SCLK, LOW); shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data); // SDIN is sampled at the rising edge of SCLK. digitalWrite(PIN_SCE, HIGH); } void setup(void){ pinMode(PIN_SCE, OUTPUT); pinMode(PIN_RESET, OUTPUT); pinMode(PIN_SDIN, OUTPUT); pinMode(PIN_SCLK, OUTPUT); digitalWrite(PIN_RESET, LOW); digitalWrite(PIN_SCE, HIGH); digitalWrite(PIN_SCLK, LOW); LcdInitialise(); LcdClear(); LcdWrite(LCD_C, 0xA7); // Inverted display delay(400); LcdWrite(LCD_C, 0xA6); // Normal display } void loop(void){ //LcdString("Nokia 1203 LCD Hello World"); LcdString("АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"); LcdString("абвгдеёжзийклмнопрстуфхцчшщъыьэюя"); delay(5000); LcdClear(); }здравствуйте. я немного изменил библиотеку от jeka_tm . убрал буфер экрана для экономии. пытаюсь выводить на дисплэй свои данные. проблема в том, что дисплэй мигает, когда я пытаюсь CS установить в активное положение, хоть мигает на пол сикунды, но это неприятное явление. а в родной библиотеке такого я не наблюдаю. хочу задать вопрос, почему дисплэй может мигать при подаче CS сигнала на дисплэй?
Привет. Не встречал такого ни разу
Убрал буфер. Выводишь по строкам и только текст? Или размер буфера уменьшил в 3 раза например как Хугобосс жертвуя процессорным временем, или может вообще до 1 строки буфер уменьшил?
без буфера вывожу текст. графики построить не удастся. но для текста подойдёт.
графики построить не удастся
Удастся. Было бы желание, ну или, в данном случаи, необходимость.
А причём тут CS и мигание? Или не подсветка мигает. Тогда что и как вообще мигает? Раскройте понятие.
мигает не подсветка, а сами пиксели, тоесть гаснут все , когда я ставлю cs=0 . может там что-то с питанием. завтра проверю.
Вообще не совсем понимаю смысла использовать вышеупомянутую библиотеку, убрав из неё буфер. Вокруг него, или на его основе (как угодно) построен весь принцип вывода изображения. В библиотеке собственно нет функций вывода чего либо на экран (на исключением самого буфера). Есть только запись данных в него. А если его нет то и выводить то нечего. Но я уверен, что Вам видней.
Я бы наверное сделал так:
Сначала подключил рабочую библиотеку и убедился в том что экран правильно подключён и нормально работает. А потом эксперементировать.
Вот вот. Для вывода просто по строкам уже есть библиотеки
не знаю , в чём дело. вот , снял видео. я убедился, что всё работает с вашей библиотеки. сравнил коды вашей библиотеки и на AVRStudio. но с avrstudio не работает без мигания.
https://youtu.be/RwwIUGzY3TM
Хз страннно. Как будто очистка экрана включена с выводом, а наложение это наложение
наложение я сам сделал, чтобы было видно смену картинки.
Кидай код без лишних функций
//=========================================================Отправка 9 бит void Sendbyte(uint8_t mode, uint8_t command){ uint8_t c=command; cs1202_0_start; (mode)? data1202_1 : data1202_0; sck1202_0; asm("nop"); sck1202_send; asm("nop"); for(uint8_t i=0;i<8;i++){ asm("nop"); sck1202_0; (c & 0x80) ? data1202_1 : data1202_0; asm("nop"); sck1202_send; c <<= 1; } data1202_1; //sck1202_0; cs1202_1_end; return ; } uint8_t getmassnum(uint8_t c) { if (c>'9'||c<'0') { if (c=='-') return 11; if (c=='+') return 10; if (c==' ') return 13; if (c=='.') return 12; if (c=='%') return 17; if (c=='c') return 14; if (c=='M') return 16; if (c=='p') return 15; if(c='=') return 18; if (c=='А') return 27; if (c='Д') return 26 ; if (c=='В') return 23; if (c='Ы') return 28; if (c='Л') return 24 ; else return 0; } // mm return c-'0'; } //============== void print_my_string16(unsigned char *s,uint8_t X,uint8_t Y,uint8_t leght) { if (Y>6) Y=6; uint8_t i=0,j;uint16_t massnum; Sendbyte(LCD_C, SetYAddr | Y); Sendbyte(LCD_C, SetXAddr3 | ((X&0x7F)>>4)); Sendbyte(LCD_C, SetXAddr4 | (X&0x0F)); while (i<leght) { massnum=getmassnum(s[i]); massnum=massnum*20; for (j=0;j<10;j++) { Sendbyte(LCD_D, mass10x16[massnum+j]); } i++; } i=0; Sendbyte(LCD_C, SetYAddr | (Y+1)); Sendbyte(LCD_C, SetXAddr3 | ((X&0x7f)>>4)); Sendbyte(LCD_C, SetXAddr4 | ((X&0x0F))); cs1202_0_start; while (i<leght) { massnum=getmassnum(s[i]); massnum=massnum*20+10; for (j=0;j<10;j++) { Sendbyte(LCD_D, mass10x16[massnum+j]); } i++; } cs1202_1_end; } //===================================================Инициализация дисплея void lcdInicialize(){ // Инициализация дисплея res1202_0_res; _delay_loop_2(10000); res1202_1; sck1202_0; data1202_0; cs1202_0_start; _delay_loop_2(22000); cs1202_1_end; Sendbyte(LCD_C,0x2F); // Power control set(charge pump on/off) Sendbyte(LCD_C,0xA4); // all point off Sendbyte(LCD_C,0xAF); // экран вкл/выкл Sendbyte(0,0x85); // contrast Sendbyte(0,0xA6); Sendbyte(0,0xc0); //noreverse clear(); //Update(); }Ух а переписал то как)) Было же читаемо
я ж пока для себя писал. не заморачиватесь. я спросил, может , кто знает. буду дальше пытаться. этот код под avr studio.
питание забыл подать , т.е. питание подавалось от микроконтроллера и я забыл ему на порт лог. 1 включить. так что такое может быть при отключенном питании.
И все? Разве такие вещи не проверяются в первую очередь?
плату я делал три месяца назад, уже забыл , как там разведено было, а увидел, когда проверять начал мультиметром общее напряжение. спасибо за ответы...
Всем привет! Подключил к Ардуино нано дисплей Nokia 1110i/ И выскочила проблема, текст еле видно, как поднять контрастность этого дисплея. Вот скетч:
#include <PCF8814.h> PCF8814 Lcd(13,11,10,6); // LCD sets SPI SCLK: 7 pin, SDA: 8 pin, CS: 9 pin. RESET: 6 pin void setup() { Lcd.Init(); Lcd.GotoXY(6,2); Lcd.Print("Hello"); Lcd.GotoXY(4,4); Lcd.PrintWide("WORLD"); Lcd.Rect(0,0,95,67,FILL_OFF,PIXEL_ON); Lcd.Circle(48,34,32,FILL_OFF,PIXEL_ON); } void loop() { }Сразу скажу питание дисплея 2.8 вольта, подсветка 3.6 вольта.
А в библиотеке разве нет?
Для установки контрастности в контроллер PCF8814 нужно послать команду 0x20, а затем значение от 0 до 31 прибавив его к 0х80.
т.е. 0х80 это минимальная а 0х1F максимальная.
Я этим программированием только начал заниматься, и ничего толком не понимаю, мне это надо для разового своего проэкта. И в дальнейшем я не собираюсь заниматься програмированием. Поэтому прошу просто показать как это сделать. В библиотеке есть строка:void SendByte(char mode,unsigned char c);. но вставка данной строки в скетч вызывает ошибку при загрузке:Arduino: 1.8.4 (Windows 8.1), Плата:"Arduino Nano, ATmega328P (Old Bootloader)"
У меня этой библиотеки нет, поэтому я не знаю какие функции там есть. Но физически для данного контроллера (экрана) такая возможность есть.
Откройте файл библиотеки с расширением .h, там среди протатипов функций должно быть что то вроде setContrast(......., ......)
Эту функцию нучно, со своим значением, поместить в тело setup()
Да, там есть строка:void Contrast(uint8_t c = 0x0D); Я её попробовал вставить в тело сетап, но опять ошибка при загрузке, хотя скомпилировалась без ошибок.
ошибка при загрузке, хотя скомпилировалась без ошибок.
это как?
Вам не отвечает програматор.
Так эту проблему и решайте сначала. Посмотрите в настройках правильно ли Вы его выбрали?
С этим я разобрался, почему-то драйвер слетел, да и USB вход чего-то барахлит. Но потом всё на том же месте и осталось. Если можно просто напиши строки как надо их писать, я просто не знаю если честно, какая транскрипция написания.
Ещё раз. Проблема изначально не с кодом.
Ардуино не видит программатора. А почему, это я уж не знаю что там наворочено.
Наверное надо вернуться к "блинку".
Да устранил я эту проблему с программатором, у меня ардуино нано, чего-то перестал USB переходник работать, и я подсоединил внешний переходник. Сейчас загружается, но на экране ничего не видно, а влинком я всегда проверяю когда возникают проблемы с загрузкой. Но повторюсь на дисплее ничего не видно, поэтому и прошу подсказать как правильно написать этот оператор по контрастности, у меня не получается.
Ну попробуй максимальную установить
Всем привет, прокоментируйте пожалуйста откуда в библиотеке эти манипуляции с CS ?
// Инициализация дисплея
Неа. Вот RST насколько помню можно просто подтянуть к 3.3В. Просто кто то использует кто то нет. И остается 3 самых главных пина.
20мс это из либы одной. Там писали при инициализации нужно время. А чем тебе мешает? Это один раз делается.
Хочешь по 2 пинам получай такие глюки, я тоже как то пытался. Не помню что конкретно, но решил для себя что минимум 3 пина.
Если пинов не хватает это не значит что именно дисплей нужно мучать, остальное посмотри. В конце концов можно другой чип применить
Вот как раз и интересно из какой либы ноги растут. Возможно, это просто артефакт, возникший при многократном копировании из либы в либу и это тоже, кстати, чревато неожиданными багами. Иногда можно обойтись RC-цепочкой, не занимать пин контроллера и не вести дорожку через всю плату. На 5110 это делаю примерно вот так :
Вообще ИМХО инициализировать экран сразу после подачи питания на него не самая лучшая идея. Если есть возможность, лучше это делать спустя пол секунды (примерно). А управлять по двум пинам ИМХО, рано или поздно зависает.
20мс при включении тебе погоды не сделают. Хочешь совсем все вычистить? Так я пробовал, еще что нибудь удалишь начинается нестабильная работа
Господа, помогите решить проблемку.
Я переписал библиотеку PCF8814_NEW под очень распространённый дисплей OLED SSD1306 I2C 128x64.
Либа понравилоась тем, что буфер экрана разделён на части и позволяет экономить оперативу, которой в ATTiny85 всего 510 байт.
Переписанная библиотека тут: https://yadi.sk/d/ClFdmug86PqpXg
Всё работает, но есть проблема - первая строка, высотой 8 пикселей, затираеться, не пойму почему.
Так должно быть: https://yadi.sk/i/TLmKN5iklvaqrw
А получаеться так, в процессе обновления экрана: https://yadi.sk/i/9Sqwgu5xY-TZUg
Действительно странно. Кудато ж данные отправляются. С учётом того что во вторую и третью строку выводится нормально, а адрес вывода задаётся только для первой строки, вобще странно.
Проверь, в массив заносятся данные при первом выводе.
Я уже и под I2C и под SPI интерфейс написал - результат тот же: что-то с алгоритмом отправки массива в дисплей.
Только по SPI побыстрее будет :)
Кстати, нашёл алгорит поворота выводимого изображения, надо будет опробовать...
Надо разбираться дальше...
Ураа!
Всё заработало: буфер экрана на ТРИ строки, а у дисплея ВОСЕМЬ строк, И буфер переписываеться ТРИ раза, для "своей" полуСтраницы.
Имеем:
Получаеться, что последняя полустраница должна быть не на ТРИ строки, а на ДВЕ, иначе, почему-то несуществующяя строка 9-я переноситься на первую.
Делаем для 3-й полуСтроницы условие m=2
uint8_t step, p, b, m = 3; switch(page){ case 3: step = 0; break; case 2: step = 3; break; case 1: step = 6; m=2; break; }хм, интересно. После вывода последнего байта последней строки, если продолжают поступать данные, они выводятся с начала экрана?
Да, с "m" правильно. Сейчас посмотрел библиотеку для экрана с контроллером PCF8812, там я тоже так делал.
uint8_t step, p, b, m = 3; switch(page){ case 3: step = 0; break; // 5 для case 2: step = 3; break; // 2 Nokia case 1: step = 6; m = 2; break;// 0 3410хм, интересно. После вывода последнего байта последней строки, если продолжают поступать данные, они выводятся с начала экрана?
Да, всё именно так. Кстати, при инициализации дисплея задаётся активная область.
Да, с "m" правильно. Сейчас посмотрел библиотеку для экрана с контроллером PCF8812, там я тоже так делал.
uint8_t step, p, b, m = 3; switch(page){ case 3: step = 0; break; // 5 для case 2: step = 3; break; // 2 Nokia case 1: step = 6; m = 2; break;// 0 3410Я попробовал сделать вывод не по три, а по четыре странице - экономия памяти в четыре раза, а скорость вывода изображения, соответственно, в четыре раза медленнее - совсем не комфортно.
Поворот экрана, попробовал - работает, текст, картинки поворачиваются, а геометрические фигуры надо корректировать...
Ребята а как из дисплея байты прочесть? Ну к примеру делаю я функцию публичной и шлю запрос на измерение
lcd.SendByte(0,0xDE); // Запрос температуры
Но как потом получить ответ из 7 байт?
Температура расчитывается потом по формуле T 1.875 TD = (ответ)° × – 40 C
Охота термометр замутить без датчиков. И еще вопрос, почему с дисплеем никто по I2C шине не работает? Я так понимаю его единоразово нужно настроить на I2C и потом спокойно с ним на 2х проводах работать.
Кстати: lcd.SendByte(0,0xA7); // инверсия цвета
Дисплей от Nokia 1100 позволяет только записывать данные в память (DDRAM) контроллера дисплея. Чтение из памяти не реализовано, хотя сам контроллер PCF8814 это позволяет. Поэтому, что бы определить, что у вас записано в памяти дисплея, необходимо в микроконтроллере организовывать буфер с данными для дисплея и отслеживать то, что записано, по нему.
потому-что у меня дисплей 1202, он китайцами посажен на плату, которая работаето только по SPI 7-ми битному.
а чо там в 7 бит китайцы запихнуть умудрились?