Прості багатофункціональні годинники-барометр-термометр на LCD-дисплеї на контролері PCF8576

Отже, справжній радіолюбитель ніколи не пройде повз електронної техніки, яка приготована на утилізацію. Потрапили мені електронні ваги марки Digi SM100, які вже почали розбирати кольорові металісти. Індикатори їм не знадобилися, тому були мною акуратно витягнуті і залишені до кращих часів.

Переглядаючи час від часу валяються без діла індикатори, закралася думка все ж спробувати їх оживити. На передній панелі дисплея розташовані 25 символів, кожен з яких має 19 сегментів; з 16 формується цифра або буква, і ще три: крапка, кома і трикутник під цифрою. Символи загоряються червоним або зеленим кольором, в залежності від виконання LCD. На самій платі є тільки каталожний номер плати: 14AXLCM0HMSV06, більше ніяких опізнавальних знаків немає. На задній стороні плати розташовані два однакових, запаралелених 6-ти пінових роз'ємів і три мікросхеми PCF8576. Розміри LCD екрану дуже вражаючі: 40 на 227 мм, а розміри цифри/букви — 15х7мм.

Подивившись даташит на PCF8576, легко виявилося, що розпіновка роз'єму наступна:

  1. SDA
  2. SCL
  3. +5v – живлення контролера
  4. GND
  5. +5v – живлення підсвітки
  6. GND

Як бачимо, дисплей повинен легко керуватися по шині I2C. Провівши пошук за назвою контролера, виявилося, що універсальної бібліотеки для роботи з ним немає. Пришлося копати даташит далі. Підключивши дисплей до Ардуїно, і запустивши сканер I2C портів, отримуємо адресу контролера PCF8576 равний 0х38 (B0111000). Але на платі встановлено 3 мікросхеми, відповідно 3 контролера, їх під-адреси визначаються підключенням пінів мікросхеми до землі або живленню, пини А0, А1, А2 (відповідно 7, 8, 9-ї ноги мікросхеми), таким чином, отримуємо під-адресу першого контролера 000, другого — 001, третього – 010.

Для ініціалізації дисплея, достатньо послати кілька команд по шині I2C:

Wire.beginTransmission (0x38) ; //почати передачу по адресі 0х38

Wire.write (B11001000) ; // MODE SET – режим роботи дисплея

Wire.write (B11100000); // DEVICE_SELECT – вибір контролера

Wire.write (B11111000); // BANK_SELECT – не впливає при 1:4 мультиплекс режимі

Wire.write (adr); // вказати адресу

Wire.write (B00000000); // вказати дані

Wire.write (B00000000); // вказати дані

Wire.write (B00000000); // вказати дані

...

Wire.endTransmission () ; // закінчити передачу

Для спрощення розуміння, далі, набори символів будемо називати «банком». Перший банк (лівий набір символів) складається з 8 знакових місць і підпорядковується першому контролеру, відповідно, другий банк (середній) — другому, а третій банк (лівий) складається з 9 знакових місць, підпорядковується третьому контролеру.

Адреса першого сегмента в кожному банку однакова — B00000000. Адреса наступного знакової місця в 1-му і 2-му банку і до 5 символа включно в 3-му банку, відрізняється від попереднього на B00000101. Для зручності звернення до конкретного знакової місця в банку, їх адреси зібрані в масивах pointer_digit12[] (для 1-го і 2-го банків) і pointer_digit3[] (для 3-го). Чому відрізняються адреси знакових місць в 3-му банку? Справа в тому, що в ньому на одне знакове місце більше, не 8, а цілком 9 знакових місць, і розробники просто заощадили на крапці, комі і трикутнику з 6 по 8 знакове місце для можливості розміщення додаткового, 9-го знакового місця.

Тепер розглянемо формування символу на знаковому місці.

На малюнку ви можете бачити розподіл сегментів на знаковому місці. Для формування одного символу потрібно 2 байти, перший байт: hgfedcba, другий — h'g'f'e'd'c'b'a' . Так, наприклад, для виводу символу «0» ланцюг байтів буде: {B00001111, B00001111}, де 1-означає загоріти сегмент, 0 відповідно — загасити. У скетчі, в масиві digit[][2] сформовані необхідні для роботи символи, в основному це цифри і символи типу градуса і т. п. При необхідності, таким чином, не важко сформувати будь-який символ.

Для друку в обраній позиції необхідного символу написана функція: print_digital(byte i, byte j, byte N, boolean z) { // друк символу в обраній позиції (i=банк (1-3), j=позиція(1-8, 9-для 3-го банку), порядковий номер символу в масиві digit[][2] для цифр збігається з порядковим номером, z=кома так/ні). Функція clear(byte N) — стирає всі символи з банку N.

Коли з дисплеєм розібралися — підключаємо по тій же шині I2C годинниковий модуль DS3231 і метеодатчик BMP280. Все — годинник готовий. У лівому банку відображається поточна температура, в центрі — час і поточна дата, у правому банку — поточний тиск і стрілкою вгору, вниз, вказується, куди рухається тиск — підвищується чи знижується. Для установки поточного часу і дати в схемі передбачені три кнопки: ліва і середня змінюють години/хвилини і число/місяць відповідно, права, в режимі показу дати, змінює рік, в режимі показу часу - коригує показання температури. Оскільки метеодатчик стоїть в корпусі годинника, то на його показання впливає нагрів самої Ардуїни, щоб компенсувати цей нагрів і використовується корекція правою кнопкою, причому дана корекція запам'ятовується в енергонезалежній пам'яті.

 Годинники задумувалися, як подарунок фанату ЦСКА, тому, в якості "хранителя екрану" періодично, на дисплей виводиться рядок - "* ЦСКА - ЧЕМПІОН *", втім, можна виводити і будь-яку іншу строку, замінивши масив  S_CSKA[] .

Принципова схема годинника зображена нижче.

Принципова схема годинника

Корпус годинника виготовлений з пластика і обтягнутий шкірою. В остаточному варіанті застосований дисплей з червоним світінням.

  

Список радіоелементів

Обозначення Тип Номінал Кількість Примітка
Плата Arduino
Arduino Nano 3.0
1
Годинник реального часу (RTC)
DS3231
1
Датчик BMP280 1 Датчик температури і тиску
LCD-дисплей 1 На контролері PCF8576
Тактова кнопка 3

Прикреплені файли:

Top