Ардуино (Arduino). #21
Часы на RTC DS3231, с расширенными функциями
Этот проект является продолжением раннего проекта часов Часы на RTC DS3231 и TM1637 . По просьбе моего знакомого Константина К. добавил вывод на экран дисплея температуру. А потом вспомнил, что читатели сайта просили добавить будильник, что и сделал. Потом дошла очередь и до барометра. Получились не обычные такие часы, а часы с расширенными функциями .
При модернизировании предыдущего проекта #8 Часы на RTC DS3231 и TM1637 вышло, что проще написать всё по новому, поэтому программа была написана заново. Схема тоже усложнилась добавлением разными компонентами.
Схема часов
Схема часов немного сложнее, чем в предыдущем проекте. Добавлен активный Buzzer для сигнала будильника. Добавлен светодиод для индикации активности будильника. Добавлена ещё одна кнопка для установки будильника. Добавлен датчик температуры DS1820 . Добавлен модуль абсолютного давления BMP280 . Замечу, что для него требуется напряжение питания +3,3В. Если использовать Arduino Uno R3 или Arduino Nano , то у них на платах уже имеется стабилизатор на +3,3В. Если же использовать Arduino Pro Mini , то придётся добавить такой стабилизатор дополнительно или, как вариант, запитать датчик от +5В через два последовательно соединённых диода 1N4148 .
Блок питания используется импульсный, обратноходовый. Выдаёт +6.5 В. Это напряжение подаётся на стабилизатор Arduino Pro Mini – на контакт RAW. Можно использовать БП на +5В, но тогда подавать питание нужно на контакт VCC.
Выключатель SA2 можно не ставить. Работающий будильник можно отключить нажав на кнопку ALARM .
Pic 1. Схема электрическая принципиальная для скетча #21
Монтажную схему см. ниже. Резистор R2 можно ставить от 4.7кОм до 12кОм. Чем больше сопротивление, тем тусклее будет светить светодиод HL2. Вполне нормально светит при R2 = 10кОм.
Pic 2. Схема монтажная для скетча #21
Скетч часов
Далее представлен скетч. Рассмотрю некоторые его особенности. В предыдущем проекте у автора для мигания точек используется сигнал с модуля реального времени с контакта SQW , который подаётся на контакт 2 Ардуино. Но оказывается не все модули имеют такой сигнал и чтобы сделать программу более универсальную – отказался от этого и мигание точек делаю за счёт Timer1 .
Так как в модуле реального времени имеется встроенный датчик температуры, то используем его, если не подключен внешний датчик семейства DS1820 . При включении часов идёт тестирование подключения датчика температуры DS1820 . При его наличии температура выводится с него.
Во время начального теста, если датчик DS1820 не подключен, то на индикаторе выводится 2 секунды тип 3231 встроенного датчика температуры DS3231 . Если датчик температуры DS1820 подключен, то выводится его тип 1820 2 секунды. После чего выводится разрешение датчика в 3-м и 4-м разрядах 2 секунды. Максимальное разрешение датчика DS1820 равно 12 бит. Далее, если подключен датчик абсолютного давления BMP280 , то на индикаторе на 2 секунды выводится сообщение 280P . Если в схеме нет датчика абсолютного давления BMP280 , то программа переходит к выводу времени.
Весь код подробно закомментирован, с его пониманием, надеюсь, проблем не будет. Хочу лишь обратить внимание, что когда происходит запись значения в EEPROM , то индикатор гашу на 300 мс, чтобы видеть, что команда записи отработала – индикация записи.
Для вывода отрицательных температур с датчика DS1820 была сделана доработка. Теперь если использовать внешний подключаемый датчик, то можно измерять температуру и за пределами жилища. Эта доработка в опубликованном скетче.
2021-12-22
Сам скетч, его варианты и библиотеки можно скачать ниже в подразделе Приложение .
Показать скетч
/*********************************************************************
2021-11-30 Mr.ALB Начало проекта
Создание часов с расширенными функциями:
Часы на 4-х разрядном 7 сегментном индикаторе TM1637
и модуле реального времени DS3231 + датчик температуры
встроенный в DS3231 и датчик температуры внешний DS1820
http://mralb.ru/sections/programming/arduino_21.php
Основа:
©2018-11-25 Mr.ALB Часы на RTC DS3231 и TM1637
http://mralb.ru/sections/programming/arduino_8.php
ПОДКЛЮЧЕНИЕ:
Модуль RTC DS3231:
SCL - A5
SDA - A4
VCC - 5V
GND - GND
Кнопки управления подключить на пины и на GND
Датчик DS1820:
1 GND - GND
2 DQ - через 4.7кОм к VCC, и DQ к pin11
3 VCC - 5V
Buzzer - любой активный на 5 В. К pin13
ИСТОРИЯ ИЗМЕНЕНИЙ:
2021-11-30 MrALB v2.0 Переделка на библиотеку <DS3231.h>
вывод температуры со встроенного датчика температуры
модуля времени DS3231
вывод SQW не используется, мигание точек через Timer1
2021-12-01 MrALB Добавлен будильник
2021-12-02 MrALB v2.1 Добавлен датчик температуры DS1820
Примечание: Если нет датчика DS1820, то температура
выводится по датчику DS3231
2021-12-04 Mr.ALB Доработка, отладка
2021-12-05 Mr.ALB Добавлен модуль давления BMP280
2021-12-07 Mr.ALB Оптимизация
2021-12-08 Mr.ALB Оптимизация
2021-12-22 Mr.ALB Вывод отрицательных температур
На ногу 2 присоединить через резистор 1к светодиод,
он будет показывать минус,
когда температура отрицательная.
В библиотеку TM1637 добавлен минус
2021-12-25 Mr.ALB Оптимизация + переделка сигнала будильника
2021-12-26 Mr.ALB Оптимизация + вкл/выкл. будильника
2022-01-02 Константин К. функция проверки сегментов при включении
2022-01-04 Mr.ALB Оптимизация кода
2022-01-05 Mr.ALB Константик К. выявил ошибку:
При настройке яркости возникает отставание времени
из-за обнуления секунд.
Ошибка устранена.
2022-01-14 Mr.ALB Проверка работы скетча с LGT8F328P - работает
Среда Arduino IDE 1.8.19
2022-02-12 Mr.ALB Вывод значений времени, температуры, давления по секундам
***** ОПИСАНИЕ *****
КНОПКИ:
[Set] - Установка
[ALARM] - Будильник
[H] - Час
[M] - Минута
[Brightness] - Яркость
При включении идёт тестирование подключения датчика температуры DS1820.
Если датчик не подключен, то на индикаторе выводится 2 секунды
тип "3231" встроенного датчика температуры DS3231.
Если датчик температуры DS1820 подключен, то выводится
его тип "1820" 2 секунды.
Далее выводится разрешение датчика в 3-м и 4-м разрядах 2 секунды.
Для настройки времени, нажать кнопку [Set] и удерживая её
нажимать кнопки [H] и [M] для задания требуемого времени.
В начальный момент настройки на дисплее выводится текущее время.
Для задания уставки будильника нажать кнопку [ALARM] и удерживая её
нажимать кнопки [H] и [M] для задания требуемого времени
срабатывания будильника. В начальный момент настройки на дисплее
выводится заданное ранее время будильника.
Для включения будильника нажать кнопку [ALARM] 1...2 секунды.
При включении будильника засветится светодиод HL2 - Будильник установлен.
Для отключения будильника, при светящемся HL2, нажать кнопку [ALARM]
1...2 секунды. Индикация отключения будильника - потухший светодиод HL2.
Для установки уровня яркости индикатора, нажать кнопку [Set] и удерживая
её нажимать кнопку [Brightness]. Всего 7 градаций яркости.
Изменение идёт по кругу от 1 до 7 и заново.
Примечание: Из-за дребезга кнопок возможно недосрабатывание
- повторить манипуляции с кнопками.
Архив:
Библиотеки https://disk.yandex.ru/d/GAB2psiXtsH8cg
Скетч https://disk.yandex.ru/d/WRQKZAjv9D3PKw
******************************************************************/
// Для индикатора 4-х разрядного 7 сегментного + дополнения
#include "TM1637_mralb.h" // Изменённая библиотека
#include < DS3231. h> // Для часов реального времени
#include < TimerOne . h> // Подключение библиотеки Таймер1
#include < OneWire . h> // OneWire для DS1820
#include < EEPROM . h> // Для EEPROM, запись яркости
#include < DallasTemperature . h> // Для DS1820
#include < Adafruit_BMP280. h> // для BMP280
// Установка OneWire на Pin11, к которому подключен DS18B20
#define ONE_WIRE_BUS 11
OneWire oneWire(ONE_WIRE_BUS);
// Установка DallasTemperature для работы по OneWire
DallasTemperature sensors(& oneWire);
// Переменные для DS1820
int term;
byte addr[8], type_s;
byte resolution;
bool flagDS; // Флаг наличия DS1820
bool flagMinusTerm = false ; // Флаг отр. темпер.
// 4-х разрядный 7 сигментный индикатор TM1637
#define CLK 6
#define DIO 7
TM1637 tm1637(CLK, DIO); // Создание объекта индикатора
DS3231 dsClock; // Создание объекта часов
RTCDateTime dt; // Перемен. времени
RTCAlarmTime da; // Перем. будильника
/***********************************************************
Чтобы всё заработало необходимо
1. Сканером I2C найти адрес BMP280
или в библиотеке <Adafruit_BMP280.h>
1) Изменить адрес #define BMP280_ADDRESS (0x77)
на адрес #define BMP280_ADDRESS (0x76)
2) Закоментировать библиотеку #include <Adafruit_Sensor.h>
***********************************************************/
Adafruit_BMP280 bmp;// Создаём объект барометра
/*************************************************
мБар - мм рт. ст.
1013.2472 - 760 k=1.33322
1005.24788 - 754
*************************************************/
// Коэффициент для перевода Па в мм рт.ст.
float kp = 133.322;
// Переменные давления
int press_now;
// Кнопки установки времени
#define buttonHour 5 // Часы
#define buttonMin 4 // Минуты
#define buttonSet 3 // Установка
#define buttonBR 8 // Кнопка яркости
#define buttonAlarm 9 // Кнопка установки будильника
#define PIN_ALARM_SET 10 // Индикатор установки будильника
byte brightness = 1; // Яркость, от 1 до 7 2020-01-02
byte addrBR = 6; // Адрес в EEPROM для записи яркости
boolean flag_br = false ; // Флаг для записи яркости
boolean flag_null = false ;// Флаг для гашения незначащего нуля
// Переменная для прерывания мигания точек
volatile boolean flag;
int8_t TimeDisp[4]; // Массив для цифр индикатора
#define SEC_2 2000000 // 2 секунды
bool flagSetTime = false ; // Флаг изменения времени
bool flag_time = true ;
bool flag_alarm = false ;
bool flag_alarm_on = false ;
//int32_t time_now, time_check; // Интервал времени
bool flagInterrupt; // Флаг прерывания
bool flagPress = false ; // Флаг давления
byte typeDataDisplay = 0; // Тип выводимых данных:
// 0 - время
// 1 - температура
// 2 - давление
/*********************
Настройка скетча
*********************/
void setup ()
{
//Serial.begin(9600);
pinMode (buttonHour, INPUT_PULLUP ); // Кнопка изменения часов
pinMode (buttonMin, INPUT_PULLUP ); // Кнопка изменения минут
pinMode (buttonSet, INPUT_PULLUP ); // Кнопка разрешения установок
pinMode (buttonAlarm, INPUT_PULLUP ); // Кнопка установок будильника
pinMode (buttonBR, INPUT_PULLUP ); // Кнопка изменения яркости
pinMode (LED_BUILTIN , OUTPUT ); // Активный буззер будильника
pinMode (PIN_ALARM_SET, OUTPUT ); // Светодиод устав.будильника
digitalWrite (LED_BUILTIN , LOW ); // Выключим светодиод на pin13
//Serial.println("dsClock.begin()");
dsClock. begin (); // Старт часов
//Serial.println("tm1637.init()");
tm1637. init (); // Инициализация индикатора
// Установка начальной яркости
tm1637. set(brightness );
fnDisplayTest(); // Проверка всех сегментов
// Установка значений из EEPROM
// Считывание яркости из EEPROM 2020-01-02
byte setBR = EEPROM . read (addrBR);
if (setBR >= 0 && setBR < 8 && setBR != brightness )
tm1637. set(setBR);
// Инициализация прерывания на 500 мс
Timer1 . initialize (500000);
// Старт установки датчика DS1820
sensors. begin ();
flagDS = false ; // Нет датчика DS1820
// Установка в массив типа датчика 3231
TimeDisp[0] = 3;
TimeDisp[1] = 2;
TimeDisp[2] = 3;
TimeDisp[3] = 1;
// Проверяем наличие DS1820
if (sensors. getAddress (addr, 0))
{
flagDS = true ; // Подключен DS1820
/* Определяем устройство и его параметры */
//Считываем точность датчика
resolution = sensors. getResolution ();
if (resolution < 10) sensors. setResolution (10);
// Вывод на индикаторе типа датчика 1820
TimeDisp[0] = 1;
TimeDisp[1] = 8;
TimeDisp[2] = 2;
TimeDisp[3] = 0;
fnDisplay(flag_time);
delay (2000); // 2 секунды
// Вывод разрешения/точности измерения
TimeDisp[0] = 18; // Пусто
TimeDisp[1] = 18;
TimeDisp[2] = resolution / 10;
TimeDisp[3] = resolution % 10;
} // End setup DS1820
//Serial.println("End setup DS1820");
tm1637. point (POINT_OFF ); // Выключить точки
fnDisplay(flag_time); // Вывод на индикатор
delay (2000); // 2 секунды
//Serial.println("bmp.begin()");
if (bmp. begin ()) // Check bmp280
{
flagPress = true ; // Подключен датчик BMP280
// Выводим на индикатор 280P
TimeDisp[0] = 2;
TimeDisp[1] = 8;
TimeDisp[2] = 0;
TimeDisp[3] = 17; // Символ P
fnDisplay(flag_time);
delay (2000); // 2 секунды
} // End check bmp280
//Serial.println("End setup()");
} // End setup()
/**************************
*** Основная программа ***
**************************/
void loop ()
{
// Читаем время из модуля DS3231
dt = dsClock. getDateTime();
// Проверка будильника
fnCheckAlarms();
// Проверка интервала времени для индикации
if // Вывод времени
(
dt. second >= 0 && dt. second < 16 ||
dt. second >= 20 && dt. second < 36 ||
dt. second >= 40 && dt. second < 56
)
{
// Переход к индикации времени
flag_time = true ;
typeDataDisplay = 0;
}
if // Вывод температуры
(
dt. second >= 16 && dt. second < 18 ||
dt. second >= 36 && dt. second < 38 ||
dt. second >= 56 && dt. second < 58
)
{
// Переход к индикации температуры
flag_time = false ;
typeDataDisplay = 1;
}
if // Вывод давления
(
dt. second >= 18 && dt. second < 20 ||
dt. second >= 38 && dt. second < 40 ||
dt. second >= 58 && dt. second < 60
)
{
// Переход к индикации давления
flag_time = false ;
typeDataDisplay = 2;
}
fnTimeDisp(flag_time, false );// Заполняем массив
/***************************************************
Обработка кнопок для установки времени и яркости
Изменения при одновременном совместном нажитии
на кнопку buttonSet и кнопки управления H или M
*/
while (! digitalRead (buttonSet)) // SET H:M o BR
{
dt = dsClock. getDateTime();
//Заполняем массив значений
fnTimeDisp(flag_time, false );
// Выводим на индикатор заполненный массив
fnDisplay(flag_time);
// 2022-01-05 Mr.ALB устранение ошибки настройки
if (! digitalRead (buttonBR))
{ // Настройка яркости индикатора
brightness ++ ;
if (brightness > 7) brightness = 1;
tm1637. set(brightness );
flag_br = true ;
}
else // Настройка не яркости, а времени
{
if (! digitalRead (buttonHour))
{ // Часы
dt. hour ++ ; // Прибавляем единицу к часам
if (dt. hour > 23) dt. hour = 0;
fnSetTime(); // Установка времени
}
if (! digitalRead (buttonMin))
{ // Минуты
dt. minute ++ ; // Прибавляем единицу к минутам
if (dt. minute > 59) dt. minute = 0;
fnSetTime(); // Установка времени
}
}
delay (200);
} // End SET H:M o BR
/***************************************************
Обработка кнопок для установки будильника
Изменения при одновременном совместном нажитии
на кнопку buttonAlarm и кнопки управления H или M
*/
uint32_t t;
t = micros ();
while (! digitalRead (buttonAlarm))
{
if // Вкл./Выкл. будильника
(
digitalRead (buttonMin) &&
digitalRead (buttonHour) &&
micros () - t >= SEC_2
)
{ // Инвертируем значение
flag_alarm_on = ! flag_alarm_on;
if (flag_alarm_on)
{ // Проверка звука 2022-03-09
digitalWrite (LED_BUILTIN , HIGH );
delay (100);
digitalWrite (LED_BUILTIN , LOW );
}
break ; // Выход из цикла while()
}
da = dsClock. getAlarm1();
//Заполняем массив значений будильника
fnTimeDisp(flag_time, true );
// Выводим на индикатор
fnDisplay(flag_time);
if (! digitalRead (buttonHour))
{ // Часы
da. hour ++ ; // прибавляем единицу к часам
if (da. hour > 23) da. hour = 0;
fnSetArarm();
}
if (! digitalRead (buttonMin))
{ // Минуты
da. minute ++ ;
if (da. minute > 59) da. minute = 0;
fnSetArarm();
}
uint32_t tt;
tt = micros ();
while (micros () - tt < 150000);
}
// Вкл./Выкл. индикации активности будильника
if (flag_alarm_on)
digitalWrite (PIN_ALARM_SET, HIGH );
//if (!flag_alarm_on && digitalRead(PIN_ALARM_SET))
if (! flag_alarm_on)
{
digitalWrite (PIN_ALARM_SET, LOW );
// Выключаем сигнал, если он есть
digitalWrite (13, LOW );
}
// Запись значения яркости в EEPROM
// при отжатой кнопке buttonSet
if (flag_br == true && digitalRead (buttonSet) == HIGH )
{
flag_br = false ;
Timer1 . detachInterrupt (); // Остановка прерывания
EEPROM . write (addrBR, brightness );
// Гашение экрана как индикация записи
tm1637. clearDisplay ();
delay (300);
Timer1 . attachInterrupt (blink );// Включение прерывания
}
// Выводим на индикатор массив с данными
fnDisplay(flag_time);
}
/***********************************************
*** Подпрограммы ***
***********************************************/
/********************************************
Функция установки времени часов в DS3231
Секунды сбрасываем в 0
2022-01-04 Mr.ALB
*******************************************/
void fnSetTime()
{
dsClock. setDateTime
(
dt. year ,
dt. month ,
dt. day ,
dt. hour ,
dt. minute ,
0
);
}
/*************************************************
Функция: Установка времени будильника в DS3231
************************************************/
void fnSetArarm()
{
dsClock. setAlarm1
(
0,
da. hour ,
da. minute ,
0,
DS3231_MATCH_H_M_S
);
}
/*****************************************
Функция проверки всех сегментов
тест сегментов, поджигаем все на 2 сек
2022-01-02 Константин К.
****************************************/
void fnDisplayTest()
{
TimeDisp[0] = 8;
TimeDisp[1] = 8;
TimeDisp[2] = 8;
TimeDisp[3] = 8;
tm1637. point (POINT_ON ); // Включить точки
fnDisplay(flag_time);
delay (2000); // 2 секунды горят все сегменты
tm1637. point (POINT_OFF ); // Выключить точки
tm1637. clearDisplay (); // Гашение экрана
delay (200); // 0.2 секунды
}
/*************************
Функция мигания точек
************************/
void blink ()
{
flag = ! flag;
tm1637. point (flag);
}
/**********************
Проверка будильника
2021-12-25 Mr.ALB
**********************/
void fnCheckAlarms()
{
if
(dsClock. isAlarm1() && flag_alarm_on)
{
// Сработал будильник
// Заполняем массив значений временем
// т.к. должны всегда видеть время в
// момент срабатывания будильника
fnTimeDisp(true , false );
tm1637. point (POINT_ON ); // Включить точки
// Выводим на индикатор массив с данными
fnDisplay(flag_time);
// Поднятие флага будильника
flag_alarm = true ;
// Включаем сигнал
// Сигнал пульсирующий
// .5 секунды звук
// .5 секунды пауза
long t;
for (byte j = 0; j < 28; j++ )
{
t = millis ();
while (millis () - t < 500)
{
// Звук .5 секунды
digitalWrite (LED_BUILTIN , HIGH );
// Если нажата кнопка Будильник
if (! digitalRead (buttonAlarm))
{
flag_alarm = false ;
break ;
}
}
t = millis ();
while (millis () - t < 500)
{
// Пауза .5 секунды
digitalWrite (LED_BUILTIN , LOW );
// Если нажата кнопка Будильник
if (! digitalRead (buttonAlarm))
{
flag_alarm = false ;
break ;
}
}
// Если нажата кнопка Будильник
if (! digitalRead (buttonAlarm))
{
flag_alarm = false ;
break ;
}
}
if (flag_alarm == false )
// Выключить звук
digitalWrite (LED_BUILTIN , LOW );
}
}
/**********************
Вывод на индикатор
**********************/
void fnDisplay(bool flgT)
{
if (! flgT) // Если выводим температуру или давление
tm1637. point (POINT_OFF );// Выключить точки
// Вывод значений на индикатор
if (TimeDisp[0] != 0)
{ // Если первое значение не 0, то выводим
if (flag_null) flag_null = false ; // Сбросим флаг нуля
tm1637. display (0, TimeDisp[0]); // Вывод первой цифры
}
else if (! flag_null)
{
// Иначе гашение незначащего нуля
// Гасим один первый раз при смене на 0
flag_null = true ; // Выставим флаг нуля
tm1637. display (0, 18); //Гасим 0 разряд
}
tm1637. display (1, TimeDisp[1]); // Вывод второй цифры
tm1637. display (2, TimeDisp[2]); // Вывод третьей цифры
tm1637. display (3, TimeDisp[3]); // Вывод четвёртой цифры
}
/*******************************
Массив значений на индикатор
*******************************/
void fnTimeDisp(bool flgT, bool flagSetAlarm)
{
// Заполняем массив значениями для отпаравки на индикатор
if (flgT)
{ // Флаг вывода времени
if (flagInterrupt == false )
{
flagInterrupt = true ; // Флаг прерывания ON
// Подключение прерывания для мигания точек
Timer1 . attachInterrupt (blink );
}
if (flagSetAlarm == true )
{ // Если флаг настройки будильника
// Заполняем массив значениями будильника
TimeDisp[0] = da. hour / 10; // Десятки часов
TimeDisp[1] = da. hour % 10; // Единицы часов
TimeDisp[2] = da. minute / 10;// Десятки минут
TimeDisp[3] = da. minute % 10;// Единицы минут
tm1637. point (POINT_ON );// Включить точки
}
else
{ // Иначе
// Заполняем массив значениями времени
TimeDisp[0] = dt. hour / 10; // Десятки часов
TimeDisp[1] = dt. hour % 10; // Единицы часов
TimeDisp[2] = dt. minute / 10;// Десятки минут
TimeDisp[3] = dt. minute % 10;// Единицы минут
}
}
else
{ // Иначе если флаг не времени, то
// Заполняем массив значениями температуры
// Остановка прерывания, чтобы точки не мигали
Timer1 . detachInterrupt ();
flagInterrupt = false ;
if (typeDataDisplay == 1)
{
// Получение значения температуры
if (flagDS)
{ // Если есть DS1820
// Обновление значения датчика DS1820
sensors. requestTemperatures ();
term = (int )sensors. getTempC (addr);
//term=-9;//симуляция температуры
// Обработка отрицательных температур--
if (term < 0 && flagMinusTerm == false )
// Выставим флаг отр. температуры
flagMinusTerm = true ;
if (term > 0 && flagMinusTerm == true )
// Снимаем флаг отр. температуры
flagMinusTerm = false ;
// Значение температуры переводим в
// Абсолютное значение
term = abs (term);
//-------------------------------------
}
else
{
// Если нет DS1820, то
// Читаем температуру из DS3231
term = (int )dsClock. readTemperature ();
}
// Заполняем массив для вывода на индикатор
if (flagMinusTerm)
{
TimeDisp[0] = 19; //Минус
if (term < 10)
{
TimeDisp[1] = term; // Единицы t°
TimeDisp[2] = 16; // Символ ° - градус
TimeDisp[3] = 12; // Символ C - Цельсия
// На индикаторе типа: -9°C
}
else
{
TimeDisp[1] = term / 10; // Десятки t°
TimeDisp[2] = term % 10; // Единицы t°
TimeDisp[3] = 16; // Символ ° - градус
// На индикаторе типа: -26°
}
}
else
{ // Иначе, если температура положительная
TimeDisp[0] = term / 10; // Десятки t°
TimeDisp[1] = term % 10; // Единицы t°
TimeDisp[2] = 16; // Символ ° - градус
TimeDisp[3] = 12; // Символ C - Цельсия
// На индикаторе типа: 26°C
}
}
if (flagPress && typeDataDisplay == 2)
{ // Если подключен датчик BMP280
// Считывание давления и переводим в мм рт. ст.
// +0.5 мм рт.ст. – поправка при калибровке
// (укажите значение своей поправки)
press_now = (int )(bmp. readPressure() / kp + .5);
// Заполняем массив для вывода на индикатор
TimeDisp[0] = press_now / 100;
TimeDisp[1] = (press_now - TimeDisp[0] * 100) / 10;
TimeDisp[2] = (press_now - TimeDisp[0] * 100) % 10;
TimeDisp[3] = 17; // Символ P - Давление
// На индикаторе типа: 754P
}
}
}
Скрыть
Перечень элементов
U1 – Arduino UNO R3 , Arduino Pro Mini или другое.
U2 – Модуль питания AC-DC на 5...6 В.
U3 – Модуль стабилизатора на +3,3 В, если нет на плате Arduino .
U4 – Модуль датчика абсолютного давления BMP280 .
DD1 – Датчик температуры семейства DS1820 .
RTC1 – Модуль реального времени DS3231 .
R1 – Резистор 4.7 кОм (при наличии датчика DS1820 ).
R2 – Резистор 10 кОм (4.7кОм...12кОм).
HL1 – Дисплей 4-х разрядный 7-и сегментный TM1637.
HL2 – Светодиод красный.
SA1 – Выключатель (любой).
SA2 – Выключатель (любой).
SB1...SB5 – Микрокнопка (любая).
BA1 – Buzzer активный.
Конструкция часов
Законченной конструкции на данный момент у меня нет. Всё собиралось на макетных панельках с использованием Arduino Uno R3. Возможно, что впоследствии, как будет сделана законченная конструкция, то тут добавлю фото реализации.
Далее несколько фото макетного варианта.
Pic 3. Мой макетный вариант. Вывод времени
Pic 4. Мой макетный вариант. Вывод температуры
Pic 5. Мой макетный вариант. Вывод атмосферного давления
Константин К. сделал свой вариант этих часов с использованием mp3 проигрывателя, который озвучивает заданные часы. Вместо обычного семисегментного индикатора сделан самодельный на красных 5 мм светодиодах. Ниже на ряде фото реализация конструкции.
Pic 6. Часы с mp3 проигрывателем. Вывод времени
Pic 7. Часы с mp3 проигрывателем. Вывод температуры с датчика DS18B20
Pic 8. Часы с mp3 проигрывателем. Вывод атмосферного давления
Далее фото конструкции. Как всё устроено внутри.
Pic 9. Часы с mp3 проигрывателем. Платы часов
Pic 10. Часы с mp3 проигрывателем. Платы часов
Pic 11. Часы с mp3 проигрывателем. Задняя крышка снята
Pic 12. Часы с mp3 проигрывателем. Задняя крышка и панель с платами
Pic 13. Часы с mp3 проигрывателем. Самодельный индикатор
Сзади на крышке установлены кнопки управления и отверстия под звуковой излучатель.
Pic 14. Часы с mp3 проигрывателем. Вид сзади
Pic 15. Часы с mp3 проигрывателем. Вид индикатора в темноте
Часы с mp3 проигрывателем
VIDEO
Продолжительность фильма 0:39 [мм:сс] В этом видео демонстрация работы звукового сигнала в конструкции Константина К.
Доработка
2021-12-13 Переделка на вариант без bmp280. Тогда скетч использует всего
10066 байт и его можно записать в
AVR ATMega168P . Этот скетч можно скачать по ссылке ниже.
2021-12-22 Доработка скетча для вывода на индикатор отрицательных температур. Если датчик
DS1820 сделать внешним, то можно измерять внешние температуры в диапазоне от -55°С до +125°С. Чтобы этот скетч работал, скачайте изменённую библиотеку
<TM1637_mralb.h> , которая находится в архиве:
my_Clock_Lib.rar
2022-01-05 Константик К. выявил ошибку: При настройке яркости возникает отставание времени из-за обнуления секунд. Ошибка устранена.
2022-02-02 Использование новой библиотеки
<TM1637new.h> . Улучшение включения будильника. Оптимизация кода.
2022-02-02 Доработка скетча для Константина К. – часы с mp3 и пультом, см. в Приложении
konst_clock_pult_mp3_4.rar .
2022-02-02 Создание на основе новой библиотеки
<TM1637new.h> вариантов часов: с датчиком давления
BMP280 , с датчиком температуры
DS1820 . Все скетчи опробованы на
Arduino UNO ,
Arduino Nano ,
LGT8F328P .
2022-02-06 В новой библиотеке выявлен глюк – не выводится 0. При использовании функции
void TM1637::displayInt(int value) .
2022-02-12 Вывод значений: времени, температуры, давления привязан к секундам, что уменьшило объём программы:
Скетч использует 15342 байт (51%) памяти устройства.
2022-03-09 Проверка звука при установке будильника.
2022-04-02 Изменил программу под единичный вывод температуры и давления. Смотрите архивы с этой же меткой времени.
После этой тучи доработок пришёл к мнению, что всю программу часов следует переделать и в итоге получилась гораздо более совершенная программа, смотрите на странице проект #28 Часы на RTC DS3231, с расширенными функциями v3 .
Приложение
Используемые библиотеки и программы:
2021-12-04
2021-12-22
2022-01-05
2022-02-02
2022-04-02
Спасибо за внимание! Анатолий Беляев
На развитие сайта и проектов Arduino
Ниже на форме выберите/укажите сумму и источник перевода:
Кошелёк Ю-money или Карта банка: Visa , Master Card , МИР , Alfa-bank
Yoomoney .ru
9516
Другим способом оказать помощь на развитие сайта .
2021-12-04 . Mr.ALB