Современные и компактные наручные часы на ардуино

Содержание

Шаг 4: Программное обеспечение

Для часов были использованы следующие библиотеки — см.ниже. Однако некоторые из них нуждались в нескольких модификациях для работы с используемым оборудованием, что будет объяснено ниже.

Библиотеки

  • ANCS Library for Arduino (https://github.com/robotastic/ANCS-Library/tree/master)
  • Bluetooth low energy SDK for Arduino (https://github.com/NordicSemiconductor/ble-sdk-Arduino)
  • U8glib for the screen (https://github.com/olikraus/u8glib)
  • Capacitive Sensing Library (https://playground.arduino.cc/Main/CapacitiveSensor?from=Main.CapSense)

Сделанные изменения заключаются в следующем:

1. Библиотека: ANCS Library for Arduino, Файл: notif.cpp, Строка: 826

Нужно сделать это изменение для того, чтобы модуль Bluefruit LE заработал:

aci_state.aci_pins.spi_clock_divider = SPI_CLOCK_DIV8;
//SPI_CLOCK_DIV8  = 2MHz SPI speed    
//SPI_CLOCK_DIV16 = 1MHz SPI speed    
aci_state.aci_pins.reset_pin              = 9;  // This was changed to 9
aci_state.aci_pins.active_pin             = UNUSED;
aci_state.aci_pins.optional_chip_sel_pin  = UNUSED;

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

2. Библиотека ANCS Library for Arduino, Файл: ancs_data_source.cpp

Замените весь код кодом из файла ancs_data_source.cpp по этой ссылке — https://github.com/robotastic/ANCS-Library/issues/14.

Добавьте следующую строку, прокомментированную ниже в файле ancs_data_source.cpp в строке 217:

case ANCS_NOTIFICATION_ATTRIBUTE_DATE:
	debug_print(F(", Date: "));
	// YYYYMMDDTHHMM
	datetime = (char*)malloc(5); //Add this row! 
	strncpy(datetime, buffer, 4);

3. Библиотека ANCS Library for Arduino, Файл ancs_notification.h

Замените весь код кодом из файла ancs_notification.h по этой ссылке — https://github.com/robotastic/ANCS-Library/issues/14. В Arduino mini pro отсутствует встроенный программер поэтому необходим внешний. Был использован этот: Sparkfun FTDI — https://www.sparkfun.com/products/9873.

Код

Прилагаемый zip-файл ниже содержит код, запущенный на Arduino, и все необходимые библиотеки. Библиотеки изменены, как указано выше. Мы столкнулись с проблемой при попытке скомпилировать код с Arduino IDE 1.8.3 — это связано с известной ошибкой в компиляторе GCC. Мы загрузили и установили Arduino IDE 1.0.6 и смогли скомпилировать и загрузить код.

Шаг 10. Программируем

Если вы этого еще не сделали — скачайте и установите Arduino IDE.

Добавить поддержку Sparkfun Pro Micro

Следуйте инструкциям по установке, чтобы добавить поддержку плат Sparkfun: https://github.com/sparkfun/Arduino_Boards

После установки поддержки не забудьте выбрать правильную плату в Arduino IDE:

Сервис -> Плата -> SparkFun Pro Micro (Tools -> Board -> SparkFun Pro Micro)

Сервис -> Процессор -> ATmega32U4 (3,3 В, 8 МГц) (Tools -> Processor -> ATmega32U4 (3.3V, 8MHz))

Библиотека Adafruit RTClib

Используйте Arduino IDE Library Manager для установки RTClib: https://www.arduino.cc/en/guide/libraries

Библиотека Arduino GFX

Добавьте библиотеку Arduino_GFX в Arduino IDE: https://github.com/moononournation/Arduino_GFX.git

Если вы никогда этого не делали, то просто добавьте библиотеку из GitHub, — нажмите зеленую кнопку «Клонировать или скачать», а затем «Скачать ZIP». Далее в Arduino IDE выберите меню: Эскиз -> Включить библиотеку -> Добавить библиотеку .ZIP … -> выберите загруженный файл ZIP (англ.: Sketch -> Include Library -> Add .ZIP Library… -> ZIP).

Библиотека LowPower

Добавьте библиотеку Arduino_GFX в Arduino IDE: https://github.com/rocketscream/Low-Power.git

Установка такая же, как описано выше.

Основной код часов Arduino  — Watch Core

Пожалуйста, используйте Arduino IDE, скомпилируйте и загрузите RTClibSetRTC.ino, чтобы инициализировать время в RTC. А затем скомпилируйте и загрузите Arduino_Watch.ino.

Генерация пользовательских символов для LCD

Если вы находите символы на дисплее неподходящими и неинтересными, вы можете создать свои собственные символы (глиф) для своего ЖК-дисплея. Пользовательские символы чрезвычайно полезны в том случае, когда вы хотите отобразить символ, который не является частью стандартного набора символов ASCII.

Как мы уже обсуждали ранее в этом руководстве, символ на дисплее формируется в матрице 5×8 пикселей, поэтому вам нужно определить свой пользовательский символ в этой матрице. Для определения символа необходимо использовать функцию createChar() библиотеки LiquidCrystal.

Для использования  createChar()  сначала необходимо назначить массив из 8 байт. Каждый байт (учитывается только 5 бит) в массиве определяет одну строку символа в матрице 5×8. В то время как нули и единицы в байте указывают, какие пиксели в строке должны быть включены, а какие-выключены.

Генератор символов LCD

Создание собственного символа до сих пор было непросто! Поэтому было создано небольшое приложение под названием «Генератор пользовательских символов» для LCD.

Вы видите синюю сетку ниже? Вы можете нажать на любой из 5 × 8 пикселей, чтобы установить/очистить этот конкретный пиксель. И когда вы нажимаете на пиксели, код для символа генерируется рядом с сеткой. Этот код может быть непосредственно использован в вашем скетче Arduino.

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

Следующий скриншот демонстрирует, как вы можете использовать эти пользовательские символы на дисплее.

//  подключаем библиотеку LiquidCrystal:
#include <LiquidCrystal.h>

// Создаем LCD объект. Выводы: (rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// создадим несколько пользовательских символов
byte Heart = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};

byte Bell = {
0b00100,
0b01110,
0b01110,
0b01110,
0b11111,
0b00000,
0b00100,
0b00000
};


byte Alien = {
0b11111,
0b10101,
0b11111,
0b11111,
0b01110,
0b01010,
0b11011,
0b00000
};

byte Check = {
0b00000,
0b00001,
0b00011,
0b10110,
0b11100,
0b01000,
0b00000,
0b00000
};

byte Speaker = {
0b00001,
0b00011,
0b01111,
0b01111,
0b01111,
0b00011,
0b00001,
0b00000
};


byte Sound = {
0b00001,
0b00011,
0b00101,
0b01001,
0b01001,
0b01011,
0b11011,
0b11000
};


byte Skull = {
0b00000,
0b01110,
0b10101,
0b11011,
0b01110,
0b01110,
0b00000,
0b00000
};

byte Lock = {
0b01110,
0b10001,
0b10001,
0b11111,
0b11011,
0b11011,
0b11111,
0b00000
};

void setup() 
{
  // инициализируем LCD и устанавливаем количество столбцов и строк: 
  lcd.begin(16, 2);

  // создание нового символа
  lcd.createChar(0, Heart);
  // создание нового символа
  lcd.createChar(1, Bell);
  // создание нового символа
  lcd.createChar(2, Alien);
  // создание нового символа
  lcd.createChar(3, Check);
  // создание нового символа
  lcd.createChar(4, Speaker);
  // создание нового символа
  lcd.createChar(5, Sound);
  // создание нового символа
  lcd.createChar(6, Skull);
  // создание нового символа
  lcd.createChar(7, Lock);

  // Очищаем LCD дисплей 
  lcd.clear();

  // Печатаем сообщение на LCD.
  lcd.print("Custom Character");
}

// Печатаем все пользовательские символы
void loop() 
{ 
  lcd.setCursor(0, 1);
  lcd.write(byte(0));

  lcd.setCursor(2, 1);
  lcd.write(byte(1));

  lcd.setCursor(4, 1);
  lcd.write(byte(2));

  lcd.setCursor(6, 1);
  lcd.write(byte(3));

  lcd.setCursor(8, 1);
  lcd.write(byte(4));

  lcd.setCursor(10, 1);
  lcd.write(byte(5));

  lcd.setCursor(12, 1);
  lcd.write(byte(6));

  lcd.setCursor(14, 1);
  lcd.write(byte(7));
}

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

byte Heart = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};

В настройках мы должны создать пользовательский символ, используя функцию createChar(). Эта функция принимает два параметра. Первый — это число от 0 до 7, чтобы зарезервировать один из 8 поддерживаемых пользовательских символов. Второй параметр — это имя массива байтов.

// создание нового символа
lcd.createChar(0, Heart);

Далее в цикле для отображения пользовательского символа мы используем функцию write(), а в качестве параметра мы используем номер символа, который мы зарезервировали.

// byte(0) покажет символ Heart (сердце).
lcd.write(byte(0));

Простой будильник на Arduino Uno

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

Перед тем, как приступить, рекомендую ознакомиться со статьями по 7-секционным 4х символьным дисплеям и модулю часов реального времени DS1307, это поможет лучше понять код скетча, а также установить начальное время для модуля реального времени.

Кроме дисплея и модуля реального времени, для будильника будем использовать пьезоизлучатель (спикер), две кнопки, подключенные через резисторы и собственно «мозг» часов — плату Arduino Uno. Заказать все элементы можно по ссылкам внизу статьи или в каталоге, общая стоимость достаточно небольшая.

Схема подключения следующая:

Никаких тонкостей и сложностей подключение вызвать не должно, но не забудьте перепроверить еще раз, что все элементы соединены правильно. Ошибка в подключении может привести к выходу из строя платы. Кнопки, как мы видим, подключены через резисторы (20 кОм). Сделано это для того, чтобы при не нажатой кнопке с соответствующего пина всегда приходило значение LOW.

Все управление будильником производится двумя кнопками, при этом оно сделано максимально простым и удобным, и что-то перепутать и сломать при использовании просто невозможно. При нажатии на первую кнопку (подключена к цифровому пину 7), мы входим в режим установки времени, на индикаторе начинают мигать часы. Второй кнопкой (пин 8) мы меняем значение часов по кругу. После этого нажимаем кнопку 1 и переходим к установке минут, которые настраиваем точно так же. Далее по последнему нажатию на кнопку 1 происходит выход из режима настройки часов.

Время срабатывания будильника устанавливается почти также, только для запуска установки будильника нужно нажать кнопку 2, а часы и минуты устанавливать уже кнопкой 1. Перепутать кнопки довольно сложно: при установке будильника горит двоеточие, а при установке часов — нет. Также при установке будильника в качестве значения часов и минут можно задать прочерк, означающий, что будильник отключен.

Корпус можно сделать любой, на что хватит фантазии: строгий или, наоборот, забавный. Для него можно взять готовую 3D-модель и подправить ее, либо сделать все с нуля:

Используемые компоненты:

  • Arduino Uno:   
  • 7-сегментный дисплей:   
  • модуль часов реального времени:  
  • батарейки CR2032:  
  • пьезоизлучатель:   
  • кнопки:   
  • резисторы:   
  • макетная плата:   
  • провода:   

Модуль умного дома →

Шаг 3. Код проекта

Я просто использую примерный эскиз из библиотеки, который будет содержать множество комментариев:

// DS3231_Serial_Easy
// Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
// web: http://www.RinkyDinkElectronics.com/
//
// A quick demo of how to use my DS3231-library to 
// quickly send time and date information over a serial link
//
// To use the hardware I2C (TWI) interface of the Arduino you must connect
// the pins as follows:
//
// Arduino Uno/2009:
// ----------------------
// DS3231:  SDA pin   -> Arduino Analog 4 or the dedicated SDA pin
//          SCL pin   -> Arduino Analog 5 or the dedicated SCL pin
//
// Arduino Leonardo:
// ----------------------
// DS3231:  SDA pin   -> Arduino Digital 2 or the dedicated SDA pin
//          SCL pin   -> Arduino Digital 3 or the dedicated SCL pin
//
// Arduino Mega:
// ----------------------
// DS3231:  SDA pin   -> Arduino Digital 20 (SDA) or the dedicated SDA pin
//          SCL pin   -> Arduino Digital 21 (SCL) or the dedicated SCL pin
//
// Arduino Due:
// ----------------------
// DS3231:  SDA pin   -> Arduino Digital 20 (SDA) or the dedicated SDA1 (Digital 70) pin
//          SCL pin   -> Arduino Digital 21 (SCL) or the dedicated SCL1 (Digital 71) pin
//
// The internal pull-up resistors will be activated when using the 
// hardware I2C interfaces.
//
// You can connect the DS3231 to any available pin but if you use any
// other than what is described above the library will fall back to
// a software-based, TWI-like protocol which will require exclusive access 
// to the pins used, and you will also have to use appropriate, external
// pull-up resistors on the data and clock signals.
//

#include 

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

void setup()
{
  // Setup Serial connection
  Serial.begin(115200);
  // Uncomment the next line if you are using an Arduino Leonardo
  //while (!Serial) {}
  
  // Initialize the rtc object
  rtc.begin();
  
  // The following lines can be uncommented to set the date and time
  //rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
  //rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
}

void loop()
{
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  
  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());
  
  // Wait one second before repeating :)
  delay (1000);
}

На этом всё, эта библиотека очень проста в использовании.

Как подключить DS1302 к Arduino (RTC)

Для этого занятия нам потребуется:

  • плата Arduino Uno / Arduino Nano / Arduino Mega;
  • модуль DS1302, DS1307 или DS3231;
  • LCD монитор 1602 i2c;
  • провода «папа-мама».


DS1307 схема подключения к Ардуино Уно

Модули часов DS1307 и DS3231 подключаются к плате Ардуино через I2C протокол, как LCD дисплей I2C. Контакт SDA подключается к пину A4, контакт SCL к пину A5 Ардуино Уно. При подключении данных модулей к плате Arduino Mega следует использовать порты SDA (20 пин) и SCL (21 пин). При этом в скетче необходимо снять комментарий в строчке с нужным модулем, а строчку с модулем 1302 наоборот закомментировать.

Скетч. Работа с модулем ds3231 Ардуино DS1307

#include <iarduino_RTC.h>

iarduino_RTC time(RTC_DS1302,6,8,7);  // для модуля DS1302 - RST, CLK, DAT
// iarduino_RTC time(RTC_DS1307);       // для модуля DS1307 с i2C
// iarduino_RTC timeRTC_DS3231);        // для модуля DS3231 с i2C

void setup() {
   delay(300);
   Serial.begin(9600);
   time.begin();
   time.settime(0, 30, 18, 12, 6, 20, 5); // 0  сек, 30 мин, 18 часов, 12, июня, 2020, четверг
}

void loop() {
   // если прошла 1 секунда выводим время
   if (millis() % 1000 == 0) {
      Serial.println(time.gettime("d-m-Y, H:i:s, D"));
      delay(1);
   }
}

Пояснения к коду:

  1. для работы с программой необходимо скачать библиотеку iarduino_RTC.h.
  2. с помощью команды можно установить дату и время, которые будут выводится на монитор порта Arduino IDE каждую секунду.

Функции кнопок

На LCD шилде кнопки подписаны (смотрите на фото). Первые пять из шести доступных кнопок (button) были запрограммированы следующим образом:

Кнопка #1 (подписана SELECT) — это кнопка Menu. Эта кнопка отвечает за отображение листаемого списка доступных функций (таймер, установка будильника).

Кнопка #2 (подписана LEFT) — кнопка Select. Служит для выбора функции. Примечание: также используется для инкремента на 10 , когда выбраны часы, минуты и т.п.

Кнопки #3 и 4 (подписаны UP и DOWN) — кнопки Increment и Decrement (инкремент и декремент). Используются для уменьшения и увеличения часов и минут при настройке таймера или будильника. Используются также для переключения между временами суток AM и PM.

Кнопка #5 (подписана RIGHT) — GO! Используется для принятия выбранного значения (например, настроенных минут или часов).

Кнопка #6 (отмечена RST) — Reset, которая перезагружает наш Arduino.

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

Примеры работы для Espruino

В качестве примера подключим дисплей к управляющей плате Iskra JS.

Подключение к Iskra JS

Для коммуникации понадобится Breadboard Half и соединительные провода «папа-папа».

Вывод Обозначение Пин Iskra JS
1 GND GND
2 VCC 5V
3 VO GND
4 RS P11
5 R/W GND
6 E P12
7 DB0
8 DB1
9 DB2
10 DB3
11 DB4 P5
12 DB5 P4
13 DB6 P3
14 DB7 P2
15 VCC 5V
16 GND GND

Вывод текста

Для вывода программы приветствия, воспользуйтесь скриптом:

hello-amperka.js
// создаём переменную для работы с дисплеем
// HD44780 — контроллер монохромных жидкокристаллических знакосинтезирующих дисплеев
var lcd = require("HD44780").connect(P11,P12,P5,P4,P3,P2);
// печатем первую строку
lcd.print("Hello world");
// устанавливаем курсор в колонку 0, строку 1
// на самом деле это вторая строка, т.к. нумерация начинается с нуля
lcd.setCursor(, 1);
// печатаем вторую строку
lcd.print("Do It Yourself");

Кирилица

Вывод кирилицы на дисплей с помощью платформы Iskra JS доступен через встроенную в дисплей таблицу знакогенератора.

Таблица знакогенератора

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

Для вывода символа на дисплей необходимо передать его номер в шестнадцатеричной системе из таблицы знакогенератора.

Так букве соответствует код в шестнадцатеричной системе. Чтобы передать на экран строку «Яndex», необходимо в явном виде с помощью последовательности встроить в строку код символа:

lcd.print("\xB1ndex");

Вы можете смешивать в одной строке обычные символы и явные коды как угодно. Единственный нюанс в том, что после того, как компилятор в строке видит последовательность , он считывает за ним все символы, которые могут являться разрядами шестнадцатеричной системы даже если их больше двух. Из-за этого нельзя использовать символы из диапазона и следом за двузначным кодом символа, иначе на дисплее отобразится неправильная информация. Чтобы обойти этот момент, можно использовать тот факт, что две строки записанные рядом склеиваются.

Сравните две строки кода для вывода надписи «Яeee»:

lcd.print("\xB1eee"); // ошибка
lcd.print("\xB1"+"eee"); // правильно

Используя полученную информацию выведем на дисплей сообщение «Привет, Амперка!»:

hello-amperka-rus.js
// создаём переменную для работы с дисплеем
// HD44780 — контроллер монохромных жидкокристаллических знакосинтезирующих дисплеев
var lcd = require("HD44780").connect(P11,P12,P5,P4,P3,P2);
// устанавливаем курсор в колонку 5, строку 0
// на самом деле это первая строка, т.к. нумерация начинается с нуля
lcd.setCursor(5, );
// печатаем первую строку
lcd.print("\xA8"+"p"+"\xB8\xB3"+"e\xBF");
// устанавливаем курсор в колонку 3, строку 1
// на самом деле это вторая строка, т.к. нумерация начинается с нуля
lcd.setCursor(3, 1);
// печатаем вторую строку
lcd.print("o\xBF"+" A\xBC\xBE"+"ep\xBA\xB8");;

Переключение страниц знакогенератора

Дисплейный модуль хранит в памяти две страницы знакогенератора. По умолчанию установлена нулевая страница. Для переключения между страницами используйте методы:

// переключение с нулевой страницы на первую
command(0x101010);
// переключение с первой страницы на нулевую
command(0x101000);

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

Рассмотрим пример, в котором одна и та же строка будет отображаться по-разному — в зависимости от выбранной страницы.

change-page.js
// создаём переменную для работы с дисплеем
// HD44780 — контроллер монохромных жидкокристаллических знакосинтезирующих дисплеев
var lcd = require("HD44780").connect(P11,P12,P5,P4,P3,P2);
// создаём переменную состояния
var state = false;
// устанавливаем курсор в колонку 5, строку 0
// на самом деле это первая строка, т.к. нумерация начинается с нуля
lcd.setCursor(5, );
// печатаем первую строку
lcd.print("\x9b\x9c\x9d\x9e\x9f");
 
setInterval(function() {
  // каждую секунду меняем переменую состояния
  state = !state;
  // вызываем функцию смены адреса страницы
  lcdChangePage();
}, 1000);
 
function lcdChangePage () {
  if (state) {
    // устанавливаем 0 станицу знакогенератора (стоит по умолчанию) 
    lcd.write(0b101000, 1);
  } else {
    // устанавливаем 1 станицу знакогенератора
    lcd.write(0b101010, 1);
  }
}


Полную таблицу символов с кодами можно найти в документации к экрану.

Как считывать и рассчитывать время в бинарных часах

Я думаю вы знакомы с бинарными (двоичными) числами, которые включают в себя 0 и 1. Используя эти две цифры, мы можем показывать время, также мы можем конвертировать двоичные числа в десятичные. Используя числа 8 4 2 1 (написанные на нашей печатной плате (см. рисунок) справа), мы можем конвертировать двоичные числа в десятичные.

К примеру, двоичное число 1010 – это десятичное 10. Как это можно определить? Начинаем с самого значимого разряда, он у нас крайний слева в числе 1010 и он равен 1, следовательно нужно умножить 1 на 8. Потом следующий разряд нужно умножить на 4 (он у нас 0, поэтому к сумме ничего не добавляется), затем следующий разряд нужно умножить на 2 (он у нас 1) и крайний справа разряд нужно умножить на 1 и потом все это сложить.

Итого получаем:

А если в расширенном варианте (по всем правилам):

Теперь, если мы увидим следующую картину на наших часах, мы можем легко перевести ее в привычное время.

Как указывалось выше, у нас 6 столбцов и 4 строки светодиодов. Каждые два столбца используются, соответственно, для отображения часов (HH), минут (MM) и секунд (SS). На правой стороне печатной платы мы видим цифры 1, 2, 4 и 8, которые облегчают нам перевод двоичного числа в десятичное.

Теперь рассмотрим как правильно считать время на наших бинарных часах, показанное на предыдущем рисунке. Мы видим, что в первом столбце у нас нет горящих светодиодов, это означает:

В следующем столбце мы видим один горящий светодиод в первой строке, следовательно, в соответствии с цифрами 8 4 2 1 имеем:

То есть число часов (HH), равно 1.

В первом столбце для минут (MM ) мы видим один горящий светодиод в первой строке:

То есть получаем 10 минут потому что этот столбец обозначает десятки минут.

Во втором столбце для минут (MM) мы видим один светодиод, горящий в строке напротив цифры 8, следовательно, имеем:

Таким образом, в сумме мы получили 18 минут.

В первом столбце для секунд (SS) мы видим один горящий светодиод в строке напротив цифры 4, следовательно, получаем:

Во втором столбце для секунд (SS) мы видим два горящих светодиода в строках напротив цифр 4 и 1, следовательно, получаем:

Таким образом, мы получили в сумме 45 секунд.

В итоге мы получили время 01:18:45.

Шаг 1. Комплектующие

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

Плата Arduino

На этот раз мы используем плату Sparkfun Pro Micro 3.3 V 8 MHz.

Дисплей

Используем ST7789 1.3″ IPS LCD.

Литий-полимерный аккумулятор

Возьмем для часов 301420 LiPo.

Зарядник LiPo

Используем плату для зарядки LiPo 15 х 15 мм.

Чип RTC

На этот раз мы используем DS3231M, это встроенный кварцевый генератор, никаких дополнительных компонентов не требуется.

Батарея RTC

Необязательно, только если вы хотите сохранить время, даже если батарея LiPo разряжена. MS412FE — это крошечная перезаряжаемая батарея емкостью 1 мАч, согласно спецификации RTC, 1 мАч может сохранять время в течение многих дней.

Ремешок для часов

Самый простой и недорогой вариант — заказать ремешок для часов из ткани шириной 20 мм.

Дополнительно

Дополнительно могут пригодиться, например, диод 1N5822, четыре 6 мм винта M2, лента из медной фольги и несколько проводов.

Что за идея

Ранее мы делали один сложный проект с цифровыми часами, о котором мы расскажем в следующих уроках, и нашли в процессе несколько проблем. После этого мы решили поделиться этой проблемой со всеми. Основная проблема в том как оценивается длительность секунды.

По факту — сделать правильную секунду в цифровых часах не так просто. Нужно правильно работать с циклами. Мы нашли много комментариев на англоязычных сайтах:

На скриншоте выше видно, что код реализован таким образом, что теперь инкремент s будет выполняться каждую 1 секунду и не больше, в зависимости от времени выполнения цикла loop{}.

В связи с этим резисторы и потенциометры мы полностью удалили.

Кнопки настройки времени вы можете использовать встроенные в микросхему ATmega328P.

pinMode(hs, INPUT_PULLUP) избегает использования внешнего Pullup. Подробнее о INPUT_PULLUP читайте в нашем Справочнике программиста Ардуино.

Избегайте потенциометра ЖК-дисплея.

Контрастность ЖК-дисплея может быть установлена с помощью сигнала PWM (Широтно-импульсная модуляция (ШИМ, англ. pulse-width modulation (PWM))) Arduino.

То же самое для подсветки, которая питается сигналом ШИМ (PWM) Arduino, поэтому её можно установить как вкл/выкл с помощью Arduino.

Распиновка 16х02 символов

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

Hantek 2000 — осциллограф 3 в 1
Портативный USB осциллограф, 2 канала, 40 МГц….

Подробнее

  • GND — должен быть подключен к земле Arduino.
  • VCC — это вывод питание для ЖК-дисплея, к которому мы подключаем 5-вольтовый контакт Arduino.
  • Vo (LCD Contrast) — вывод контролирует контрастность и яркость ЖК-дисплея. Используя простой делитель напряжения с потенциометром, мы можем точно отрегулировать контрастность.
  • RS (Register Select) — этот вывод позволяет Arduino сообщать ЖК-дисплею, отправляются команды или данные. В основном этот вывод используется для дифференциации команд от данных. Например, когда на выводе RS установлено значение LOW, мы отправляем команды на ЖК-дисплей (например, установить курсор в определенном месте, очистить дисплей, сдвинуть дисплей вправо и т. д.). Когда вывод RS установлено значение  HIGH, мы отправляем данные/символы на ЖК-дисплей.
  • R/W (Read/Write) — вывод предназначен для контроля того, что необходимо сделать — считать данные или передать их на ЖК-дисплй. Поскольку мы просто используем этот ЖК-дисплей в качестве устройства вывода, то достаточно на этот вывод подать HIGH уровень, тем самым мы перейдем в режим записи.
  • EN (Enable) — вывод используется для включения дисплея. Это означает, что когда на этом выводе  установлено значение LOW ЖК-дисплей не реагирует на то, что происходит с R/W, RS и линиями шины данных. Когда же на этом выводе HIGH ЖК-дисплей обрабатывает входящие данные.
  • D0-D7 (Data Bus) — это выводы, по которым передаются 8-битные данные на дисплей. Например, если мы хотим отобразить символ «A» в верхнем регистре, мы отправляем на LCD дисплей 0100 0001 (в соответствии с таблицей ASCII) .
  • AK (Anode & Cathode) используются для управления подсветкой LCD дисплея.

Общие сведения об OLED дисплеях

OLED означает “Organic Light emitting diode“, что переводится как органический светоизлучающий диод, или, более коротко – органический светодиод. OLED дисплеи для радиолюбителей изготавливаются по той же самой технологии, что и большинство современных телевизоров, но имеют гораздо меньше пикселов по сравнению с ними. Но устройства на их основе (в том числе и с использованием Arduino) смотрятся потрясающе.

В нашем проекте мы будем использовать монохромный 7-пиновый SSD1306 0.96” OLED дисплей. Причина, по которой мы выбрали данный дисплей, заключается в том, что он может работать с тремя разными протоколами связи, трехпроводный SPI (Serial Peripheral Interface — последовательный интерфейс) режим, четырехпроводный SPI режим и режим IIC. В данной статье мы рассмотрим его подключение по четырехпроводному SPI режиму как самому скоростному из приведенных.

Контакты дисплея и выполняемые ими функции описаны в следующей таблице.

Номер контакта Название контакта Альтернативное название контакта Назначение контакта
1 Gnd Ground земля
2 Vdd Vcc, 5V напряжение питания (в диапазоне 3-5 В)
3 SCK D0, SCL, CLK контакт синхронизации (clock pin). Применяется в интерфейсах I2C и SPI
4 SDA D1, MOSI контакт данных. Применяется в интерфейсах I2C и SPI
5 RES RST, RESET контакт сброса модуля. Применяется в интерфейсе SPI
6 DC A0 контакт команд (Data Command pin). Применяется в интерфейсе SPI
7 CS Chip Select (выбор чипа) используется когда несколько устройств взаимодействуют по интерфейсу SPI

Сообществом Arduino разработано достаточно много библиотек для работы с подобными дисплеями. Мы выбрали из них библиотеку Adafruit_SSD1306 как весьма простую и в то же время содержащую достаточно много полезных функций. Но если ваш проект имеет жесткие ограничения по памяти/скорости, то тогда вам лучше использовать библиотеку U8g поскольку она работает быстрее и занимает меньше места в памяти.

Сборка модуля часов реального времени

Фото

Пояснения

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

Нанесите немного припоя на отрицательный контакт батареи.

Установите два резистора 2.2 КОм и керамический конденсатор

Как именно вы их расположите — неважно. Полярность не имеет значения.
После этого установите кристалл (также симметрично), держатель (холдер) для батарейки и чип часов реального времени.
Чип модуля реального времени надо установить таким образом, чтобы отметка (паз) на чипе располагалась в соответствии с обозначением на монтажной плате

Внимательно посмотрите на фото слева, там чип установлен верно.

Чтобы холдер для батарейки не выпадал, лучше его припаять сверху.
После этого переверните плату и и припаяйте оставшиеся контакты.

Удалите остатки контактов от резисторов, кристалла и конденсатора.

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

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