Годинник з VFD індикатора клієнта!
Опубліковано 23.11.2024, 16:41 в категорії YouTube
Думаю ви точно помічали, будучи в магазинах або супермаркетах, різноманітні дисплейчики на яких вам показують решту, назву товару, і усіляке таке. Це так званий "індикатор клієнта", спеціальний прилад який підключається до касового апарату, і касовий апарат на ньому відображає потрібну інформацію. В даній статті поглянемо на один з таких дисплеїв, розберемось що в нього всередині, і навіть підключимо до нього мікроконтролер та зробимо з нього годинник!
Типів індикаторів клієнтів насправді немало. Це і світлодіодні семисегментні, і символьні LCD, вакуумно-люмінесцентні, і навіть повноцінні графічні IPS, LCD, чи що вони туди там ставлять. Світлодіодні семисегментні індикатори зараз і без того дуже поширені, і цікавіше та легше буде самому зібрати те що треба, а не використовувати готовий пристрій, тому їх відкидаємо. Символьні LCD зараз теж можно запросто купити в будь якому магазині пов'язаному з мікроконтролерами. Графічні вже цікавіше, але коштувати вони будуть дуже багато, та і вони відносно нові, тому магазини не поспішають їх позбавлятись. А от вакуумно-люмінесцентні - найцікавіший варіант, і зараз я поясню чому.
По перше, ці дисплейчики вже доволі старі, як і сама технологія вакуумної люмінесценції, тому їх можна знайти задешево на тому ж OLX. По друге - вони доволі круто і ЛАМПОВО виглядають (ну це типу буквально вакуумна лампа, зрозуміли да). Вони мають приємне зелене світіння. По третє - якщо подивитись скільки такі дисплейчики коштують на AliExpress або Ebay, то задешево придбати собі такий у нас виглядає досить привабливо. Але є у таких дисплейчиків і проблема - їх доволі складно живити та керувати ними. Справа в тому що ці дисплеї потребують дві доволі нестандартні напруги.
По перше, напруга для нитки розжарювання -вона доволі маленька, у маленьких індикаторів - в районі вольта, і в ідеалі вона повинна бути змінною, інакше дисплей може нерівномірно світитись. Більш того - змінною не відносно нуля, а відносно якогось вищого потенціалу.
Ну і по друге - напруга на аноди та сітки, ця напруга доволі велика, від 20 до інколи навіть 50В. Тобто що одна що інша напруга разюче відрізняється від мікроконтролерних 5V або 3.3V.
Тому й вигідно брати готовий пристрій - індикатор клієнта, там все вже зробили за нас, живлення, керування, нам залишається посилати дані на дисплей. Наразі на ОЛХ дуже поширені дисплеї від компанії ІКС Техно. В них є дисплей ІКС-Л-2*20. Важливо не сплутати його з ІКС-РКІ-2*20, бо літери всередині показують тип дисплею.
Л - вакумно-люмінесцентний РКІ - відповідно, LCD, тобто рідкокристалічний.
Індикатор клієнту має ніжку та дріт RJ-11 для підключення до касового апарату. Ось звісно і зворотня сторона того що вони старі. Стан корпусу в цього екземпляру такий собі.
Давайте подивимось що всередині. Розкрутивши корпус нас зустрічає сам дисплей. Відкрутивши ще 4 саморізи добираємось до зворотньої сторони плати, де і знаходиться все що нас цікавить. Я прибрав дріт з RJ-11, так як він більше не знадобиться.
Роздивимось кожний блок по порядку.
Живлення
Спочатку йдуть 2 вузли живлення. Вони являють собою звичайні DC-DC перетворювачі на мікросхемі MC34063A. Один робить 5V для живлення мікроконтролеру та низьковольтної логіки, інший робить 39V для живлення анодів та сіток VFD індикатора. Наскільки я розумію, касові апарати можуть видавати доволі широкий спектр напруг, тому тут і зробили окремий перетворювач на 5В, а не просто живлення від 5В блочку. Також до речі тут є діод від переполюсовки живлення, який вже врятував мені дисплей одного разу.
Логіка
Далі йде сам мікроконтролер. В даному випадку це ATmega8A, яка тактується кварцевим резонатором на 16 МГц. Мікроконтролер окрім обробки інформації робить ще 2 важливі речі. По перше, він через транзистор дає свого роду дозвільний сигнал на генерацію анодної напруги. По друге - на частоті 200 кГц він через два транзистори розкачує дросель, або імпульсний трансформатор, і тим самим генерує змінну напругу для нитки розжарювання дисплею.
До речі мікроконтролер тут залочений (заблоковано доступ до програмної пам'яті для запису/зчитування через fuse-біти), і його неможливо ані зчитати, ані навіть стерти без спеціального HVSP програматора або FuseBit Doctor-а. Тому його доведеться перепаювати якщо ви захочете залити туди кастомну прошивку.
А ви повірте, захочете, бо вона дає можливість як мінімум малювати 8 кастомних символів. До речі я писав бібліотеку для роботи з драйвером наявним на платі, переглянути її можна за ось цим посиланням.
До речі, пам'ятаєте про діод від переполюсовки? Одного разу я випадково все ж таки переполюсовав живлення, прям на цьому діоді. Напруга дуже сильно просіла, діод дуже сильно нагрівся, від плати від нагріву ледь не відвалилась доріжка, і все в такому дусі. Діод таки врятував дисплей.
Але що цікаво - після цього мікроконтролер почав себе трішки дивно вести. Спочатку я подумав що попросту вбив мікроконтролер, але потім я побачив деяку закономірність - він працював, але не так як слід, повільніше, наче хтось забув виставити fuse-біти, які відповідають за вибір джерела тактування. Тому я спробував зчитати ці фьюзи, і побачив що дійсно, фьюзи збились! Тому дисплей і працював дивно. Але найголовніше - мікроконтролер розлочився! На жаль я тоді навіть не подумав про те щоб зчитати оригінальну прошивку (навіть не глянув, чи знявся fuse на читання, чи ні), бо був настільки радий що збився fuse на стирання, і тому швиденько очистив мікроконтролер, щоб залити туди свою прошивку. А можливо це був єдиний в житті спосіб зчитати цю залоченну прошивку. Думки про це не дають мені спокою і дотепер...
Драйвер VFD
Далі йде найбільша на платі мікросхема - той самий драйвер, PT6314. Про нього мало що можна сказати, звичайний драйвер, який працює практично так само як і китайські LCD дисплейчики, в яких стоїть драйвер HD44780. Має 8 кастомних символів та цілу таблицю предзаписаних, може керуватись як послідовно так і паралельно, щоправда на цій платі доступний лише послідовний порт керування. Паралельні - підтягнути до землі, тому без ювелірної роботи з підняття ніжок, використовувати паралельний порт не вийде.
На жаль більшість функцій цього драйвера недоступна (очищення екрану, регулювання яскравості, кастомні символи), через залоченний мікроконтролер, і прошивку, в якій це все не реалізували. Єдине що можу сказати цікавого - в цих драйверів є певна кількість модифікацій, в яких додатково до англійської абетки ще є наприклад японська, європейська, або взагалі якісь спеціальні символи. В нашому ж випадку, записана кирилиця, з українськими літерами! Для китайських дисплеїв які зараз можна купити це взагалі рідкість, тому цей дисплей ще й в цьому плані унікальний. Про дану модифікацію немає ні слова в даташиті, мабуть це було якесь спеціальне замовлення компанією ІКС Техно, адже на деяких сайтах можна знайти записи про імпорт даних мікросхем даною компанією. Тому єдине джерело символьної таблиці для цього дисплею, це його паспорт.
RS-232
Ну і на останок, мікросхема ST232C. Вона потрібна щоб перетворювати сигнали протоколу RS232 в сумісний для мікроконтролеру UART. Про неї багато говорити не будемо, бо вона взагалі нам заважає, тому треба її випаяти. Можливо можна і не випаювати, але краще все таки це зробити, це точно додасть стабільності передачі даних, так як на UART шині не буде висіти нічого зайвого. Я зробив це за допомогою паяльного фену.
Виводимо дані
Ініціалізацію драйвера і керування живленням наявний мікроконтролер зробить за нас, достатньо просто посилати на нього дані. Для цього я підпаяв дріт на місце де колись була ніжка RX раніше відпаяної мікросхеми.
Після цього я взяв ESP8266 та написав для неї код. Насправді він мало чим відрізняється від дефолтного Hello World по UART, за виключенням лише того, що після подачі живлення ESP8266 має почекати секунду, щоб дисплей встиг ініціалізуватись, якщо живлення на дисплей та ESP8266 було подано одночасно.
#include <Arduino.h>
// Встановлення курсору:
void setCursorVFD(byte place) {
// EOT SOH P ETB
byte cursor_position[] = {0x04, 0x01, 0x50, place, 0x17};
Serial.write(cursor_position, sizeof(cursor_position));
}
// Очистка дисплею
void clearVFD() {
setCursorVFD(0x31);
Serial.print(" ");
setCursorVFD(0x31);
}
void setup(){
Serial.begin(9600);
delay(1000);
clearVFD();
Serial.print("Hello World!");
}
void loop(){
}
Як бачите, функція очищення дисплею просто шедевральна! Для мене досі загадка, чому ІКС-Техно її не реалізували в прошивці (в паспорті її немає, + я намагався перебирати команди - не знайшов). Скоріше за все це якась умовність роботи касових апаратів. Мабуть вони не посилають команду на очищення, а просто посилають текст, який перезаписує все зайве пробілами, чи шось таке.
Раніше припаяний до дисплею дріт йде до ESP8266 на ніжку TX, також треба об'єднати землю ESP8266 з землею дисплея, і подати живлення на дисплей. Я подав 12В на раніше згаданий діод, бо до нього доволі зручно чіплятись крокодилами, після чого подав живлення на мікроконтролер.
Чудово. А тепер давайте державною.
Serial.print("Привіт Ютуб!");
Іііі, щось пішло не так D:
Справа в тому, що функція Serial.print()
бере текст, і кодує його в певну послідовність байтів. Скоріше за все компілятор робить це кодуючи символи за UTF-8. А в символьній таблиці цього дисплею ми маємо комбінацію з UTF-8 та CP866, тому англійські символи виводяться нормально, а українська - ні. Можливо є якийсь спосіб це обійти, але легше просто через Serial.write()
подавати потрібний байт, та і все. Для облегшення цього процесу я написав невеличкий скрипт на Python, який конвертує строку в послідовність байтів, яку й треба використати. В цілому він працює, але в кодуванні CP866 чомусь немає літери І, тому на ній скрипт ламається, тому я заміняю її на англійську. Це трішки дивно, адже літери Ї та Є там присутні, ну але не про це.
def UTF8_to_hex_CP866(string):
encoded_bytes = string.encode('cp866')
hex_values = [f"0x{byte:02x}" for byte in encoded_bytes]
formatted_hex = "{" + ", ".join(hex_values) + "}"
return formatted_hex
while True:
user_input = input("Input string: ")
user_input = user_input.replace('і', 'i').replace('І', 'I')
result = UTF8_to_hex_CP866(user_input)
print(result)
Давайте спробуємо конвертувати якусь строку, і вивести її на дисплей.
ctl@pop-os:~$ python CP866.py
Input string: Привіт Ютуб!
{0x8f, 0xe0, 0xa8, 0xa2, 0x69, 0xe2, 0x20, 0x9e, 0xe2, 0xe3, 0xa1, 0x21}
Трішки модифікуємо вивід символів:
void setup(){
Serial.begin(9600);
delay(1000);
clearVFD();
byte message[] = {0x8f, 0xe0, 0xa8, 0xa2, 0x69, 0xe2, 0x20, 0x9e, 0xe2, 0xe3, 0xa1, 0x21};
Serial.write(message, sizeof(message));
}
Годинник
Чудово! Тепер, вміючи керувати дисплеєм, та маючи WiFi мікроконтролер, можна зробити безліч цікавих проєктів. Наприклад крутий годинник! Насправді в мене вже давненько є такий годинник, на такому дисплеї, але він доволі сирий, і був заточений чисто під мене. Тому я модифікував прошивку І залив її на GitHub. Ось посилання
Не дивлячись на те, що більшість коду вже було написано, це виявилось доволі складним процесом, бо він включав в себе 2 речі в яких я майже нічого не знаю - HTML/CSS, та JavaScript. І якщо проблема з HTML/CSS вирішилась дуже легко - я просто попросив свою круту подругу написати мені код, то от в JavaScript-і та різних WEB аспектах - довелось розбиратись.
Коли годинник вмикається, він починає шукати збережену в пам'яті мережу WiFi. Якщо він її не знайшов, він підіймає власну мережу, тобто так званий Access Point і сповіщає про це користувача - написавши назву мережі, пароль, та IP адресу за якою треба підключитись.
Користувач з телефону або ноутбуку підключається до цієї мережі, вводить IP в адресну строку браузера, і потрапляє на сторінку налаштування годиннику. В даному випадку є 2 шляхи - можна просто синхронізувати годинник з телефоном або ноутбуком натискаючи відповідну кнопку, і все. Але з часом буде рости похибка, бо китайський RTC модуль не ідеальний, як і все в цьому світі.
Іншим ж шляхом буде ввести дані від своєї WiFi мережі, і тоді годинник зможе підключитись до неї, і через інтернет раз на день брати точний час з NTP серверу. До речі NTP сервер теж можна налаштувати, для цього є відповідне поле. Наприклад в мене, на моєму роутері з OpenWrt, піднятий власний NTP сервер, який працює навіть коли немає інтернету, тому я використовую його (просто вводжу локальний IP роутера - 192.168.1.1). За замовчуванням стоїть один з серверів time.in.ua
Так як NTP сервер повертає час у форматі UTC 0, тобто так званий нульовий часовий пояс, необхідно вручну обирати потрібний часовий пояс. Я не вигадав як це нормально автоматизувати, коли в нас змінюється часовий пояс, тому якщо в когось є ідеї - прошу вас до репозиторію, надсилайте пулл реквести.
До речі якщо годинник після запуску зміг підключитись до WiFi мережі, то він напише свою IP адресу яку йому видає роутер, і за нею теж можна потрапити до налаштувань годиннику, щоб, наприклад, корегувати температуру.
До речі я ж зовсім нічого не розповів за датчик температури. Я поставив звичайний цифровий датчик Dallas 18B20, він підключений до піну D4. Дисплей помітно так нагрівається при роботі, тому краще тримати датчик подалі, інакше дисплей буде вносити помітну таку похибку в значення температури.
Зібрати все треба за цією схемою - під'єднати RTC модуль DS1307, датчик температури, завести живлення, і годинник готовий.
А на цьому в мене все!
Post Scriptum
Це текстова версія відео з мого YouTube каналу. Відео можна переглянути за посиланням