How to simply use ds1302 rtc module with arduino board and lcd screen

Исходный код программы

Далее приведен полный текст программы. Работа нашего проекта продемонстрирована на видео, приведенном в конце статьи.

Arduino

#include<LiquidCrystal.h> //подключение библиотеки для работы с ЖК дисплеем
#define ledPin 7
LiquidCrystal lcd(8,9,10,11,12,13);
float value = 3035; //Preload timer value (3035 for 4 seconds)
void setup()
{
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print(«ARDUINO TIMERS»);
delay(2000);
lcd.clear();

pinMode(ledPin, OUTPUT);
pinMode(2,INPUT);
pinMode(4,INPUT);

noInterrupts(); // отключаем все прерывания

TCCR1A = 0;
TCCR1B = 0;
TCNT1 = value; // preload timer
TCCR1B |= (1 << CS10)|(1 << CS12); // 1024 prescaler (коэффициент деления предделителя)
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt ISR (разрешаем вызов процедуры обработки прерывания переполнения счетчика)
interrupts(); // разрешаем все прерывания
}
ISR(TIMER1_OVF_vect) // процедура обработки прерывания переполнения счетчика
{
TCNT1 = value; // preload timer
digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //включаем и выключаем светодиод
}
void loop()
{
if(digitalRead(2) == HIGH)
{
value = value+10; //Incement preload value
}
if(digitalRead(4)== HIGH)
{
value = value-10; //Decrement preload value
}
lcd.setCursor(0,0);
lcd.print(value);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

#include<LiquidCrystal.h>            //подключение библиотеки для работы с ЖК дисплеем
#define ledPin 7

LiquidCrystallcd(8,9,10,11,12,13);

floatvalue=3035;//Preload timer value (3035 for 4 seconds)

voidsetup()

{

lcd.begin(16,2);

lcd.setCursor(,);

lcd.print(«ARDUINO TIMERS»);

delay(2000);

lcd.clear();

pinMode(ledPin,OUTPUT);

pinMode(2,INPUT);

pinMode(4,INPUT);

noInterrupts();// отключаем все прерывания

TCCR1A=;

TCCR1B=;

TCNT1=value;// preload timer

TCCR1B|=(1<<CS10)|(1<<CS12);// 1024 prescaler (коэффициент деления предделителя)

TIMSK1|=(1<<TOIE1);// enable timer overflow interrupt ISR (разрешаем вызов процедуры обработки прерывания переполнения счетчика)

interrupts();// разрешаем все прерывания

}

ISR(TIMER1_OVF_vect)// процедура обработки прерывания переполнения счетчика

{

TCNT1=value;// preload timer

digitalWrite(ledPin,digitalRead(ledPin)^1);//включаем и выключаем светодиод

}

voidloop()

{

if(digitalRead(2)==HIGH)

{

value=value+10;//Incement preload value

}

if(digitalRead(4)==HIGH)

{

value=value-10;//Decrement preload value

}

lcd.setCursor(,);

lcd.print(value);

}

Getting Started

Hook up your TinyRTC module according to the diagram below — the pink DS line is not needed, as that’s for the temperature sensor.

Next, download the Time and DS1307RTC libraries and place the resulting folders in your /libraries folder.

Exit and relaunch the Arduino environment to load in the libraries and examples.

You’ll find two examples in the DS1307RTC menu: upload and run the SetTime example first — this will set the RTC to the correct time. The actual code is not worth going into detail with, just know that you need to run it once to perform the initial time synchronisation.

Next, look at the example usage with ReadTest.

Note that we’ve also included the core Wire.h library — this comes with Arduino and is used for communicating over I2C. Upload the code, open up the serial console at 9600 baud, and watch and your Arduino outputs the current time every second. Marvellous!

The most important code in the example is creating a tmElements_t tm — this a structure that we’ll populate with the current time; and the RTC.read(tm) function, which gets the current time from the RTC module, puts it into our tm structure, and returns true if everything went well. Add your debug or logic code inside that «if» statement, such as printing out the time or reacting to it.

Now that you know how to get the right time with Arduino, you could try rewriting the sunrise alarm project or create an LED word clock — the possibilities are endless! What will you make?

15 Windows Command Prompt (CMD) Commands You Must Know

The command prompt is still a powerful Windows tool. Here are the most useful CMD commands every Windows user needs to know.

Read Next

About The Author

James Bruce
(709 Articles Published)

James has a BSc in Artificial Intelligence and is CompTIA A+ and Network+ certified. When he’s not busy as Hardware Reviews Editor, he enjoys LEGO, VR, and board games. Before joining MakeUseOf, he was a lighting technician, English teacher, and data center engineer.

More
From James Bruce

Ошибки дребезга

Для устрашения вас предположу, что измеряем частоту вращения двигателя от индуктивного датчика зажигания. То есть, грубо говоря, на высоковольтный провод намотан кусок кабеля и мы измеряем индукцию в нём. Это довольно распространённый метод, не правда ли? Что же здесь сложного может быть? Самая главная проблема — современные системы зажигания, они дают не один импульс, а сразу пачку.

Примерно так:

Но даже обычная система зажигания даёт переходные процессы:

Старинные же кулачковые контактные вообще показывают замечательные картинки.

Как с этим бороться? Частота вращения не может вырасти мгновенно, не даст инерция. Кроме того, в начале статьи я предложил ограничить частоту сверху разумными рамками. Отсчёты, что происходят слишком часто можно просто игнорировать.

Другой вид помех — это пропадание отсчётов. Из-за той же инерции у вас не может измениться частота в два раза за одну миллисекунду. Понятно, что это зависит от того, что вы собственно измеряете. Частота биения крыльев комара может, вероятно и за миллисекунду упасть до нуля.

Функции счёта времени

Данные функции возвращают время, прошедшее с момента запуска микроконтроллера. Таких функций у нас две:

  • millis() – Возвращает количество миллисекунд, прошедших с запуска. Возвращает unsigned int, от 1 до 4 294 967 295 миллисекунд (

50 суток), имеет разрешение 1 миллисекунда, после переполнения сбрасывается в 0. Работает на системном таймере Timer 0micros() – Возвращает количество микросекунд, прошедших с запуска. Возвращает unsigned int, от 4 до 4 294 967 295 микросекунд (

70 минут), имеет разрешение в 4 микросекунды, после переполнения сбрасывается в 0. Работает на системном таймере Timer 0

Вы спросите, а как время со старта МК поможет нам организовать действия по времени? Очень просто, схема вот такая:

  • Выполнили действие
  • Запомнили текущее время со старта МК (в отдельную переменную)
  • Ищем разницу между текущим временем и запомненным
  • Как только разница больше нужного нам времени “Таймера” – выполняем действие и так по кругу

Реализация такого “таймера на millis()” выглядит вот так:

Напомню, что uint32_t это второе название типа данных unsigned long, просто оно короче в записи. Почему переменная должна быть именно такого типа? Потому что функция millis() возвращает именно этот тип данных, т.е. если мы сделаем нашу переменную например типа int, то она переполнится через 32.7 секунды. Но миллис тоже ограничен числом 4 294 967 295, и при переполнении тоже сбросится в 0. Сделает он это через 4 294 967 295 / 1000 / 60 / 60 / 24 = 49.7 суток. Значит ли это, что наш таймер “сломается” через 50 суток? Нет, данная конструкция спокойно переживает переход через 0 и работает дальше, не верьте диванным экспертам, проверьте =)

Вернёмся к вопросу многозадачности: хотим выполнять одно действие два раза в секунду, второе – три, и третье – 10. Нам понадобится 3 переменные таймера и 3 конструкции с условием:

И вот так мы можем например 10 раз в секунду опросить датчик, фильтровать значения, и два раза в секунду выводить показания на дисплей. И три раза в секунду мигать лампочкой. Почему нет?

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

Работа программного обеспечения

Интерфейс DS5000

Программа, приведённая в Приложении, написана для взаимодействия DS5000 с DS1307 с помощью двухпроводного интерфейса. DS5000 запрограммирован с использованием макетной платы DS5000T фирмы Dallas Semiconductor, которая позволяет использовать ПК в качестве терминала ввода/вывода. Программные средства KIT5K поставляемые вместе с макетной платой DS5000T обеспечивают высокоуровневый интерфейс для загрузки программных приложений в DS5000 или установки его параметров через Program command. Программное обеспечение KIT5K содержит эмулятор терминала ввода/вывода, чтобы позволить пользователю запускать программные приложения в микроконтроллер DS5000, который связан с пользователем через COM порт ПК.

Исходный код DS1307

Первый раздел исходного кода, расположенный в Приложении, используется при конфигурации DS5000 для последовательного соединения с ПК. Также в начале кода находится подпрограмма MASTER_CONTROLLER, которая используется для управления демонстрационной программой.

Подпрограммы, которые следуют непосредственно за подпрограммой MASTER_CONTROLLER, являются драйверами низкого уровня и служат для управления двухпроводным интерфейсом. Они не являются индивидуальными для DS1307, а могут быть использованы с любым совместимым с двухпроводным интерфейсом «ведомым» устройством. Вот эти подпрограммы:

SEND_START

Подпрограмма используется для генерации состояния START на двухпроводной шине.

SEND_STOP

Подпрограмма используется для генерации состояния STOP на двухпроводной шине.

SEND_BYTE

Подпрограмма посылает 8-разрядное слово (первым является старший значащий бит (MSB)) по двухпроводной шине и девятый тактовый импульс для импульса подтверждения приёма.

READ_BYTE

Подпрограмма читает 8-разрядное слово с двухпроводной шины. Она проверяет очищен ли флаг LASTREAD после того, как считан последний байт из «ведомого» устройства. Если это был не последний байт, то DS5000 посылает импульс подтверждения по девятому тактовому импульсу, а если это был последний считанный байт из «ведомого» устройства, то DS5000 посылает «неподтверждение».

SCL_HIGH

Подпрограмма осуществляет переход линии SCL из низкого в высокое состояние и обеспечивает высокое состояние линии SCL перед продолжением.

DELAY и DELAY_4

Эти две подпрограммы включены для обеспечения сохранения временной диаграммы двухпроводной шины.

Остальная часть кода, включённая в приложение, специально предназначена для демонстрации функций DS1307. Продемонстрированы следующие функции:

Setting Time

Время считывается с клавиатуры и сохраняется в сверхоперативной памяти DS5000. Затем оно передаётся по двухпроводной шине в DS1307.

Set RAM

Одиночный байт в шестнадцатеричном виде считывается с клавиатуры и записывается в RAM DS1307.

Read Date/Time

Дата и время считываются по двухпроводной шине и сохраняются в сверхоперативной памяти DS5000. Затем они выводятся на экран. Это продолжается до тех пор, пока не будет нажата кнопка на клавиатуре.

OSC On/OSC Off

Тактовый генератор DS1307 может быть включен или выключен.

SQW/OUT On/SQW/OUT Off

Функция SQW/OUT может быть включена или выключена. Она будет переключаться на частоте 1 Гц.

Таблица 1. AC электрические характеристики

Параметр Символ Эффективноезначение Единицы
Тактовая частота SCL fSCL 59 кГц
Время свободного состояния шины между состояниями STOP и START tBUF 5.7 мкс
Время удержания(повторенного) состояния START tHD:STA 6.2 мкс
Период низкого состояния тактового импульса SCL tLOW 10.5 мкс
Период высокого состояния тактового импульса SCL tHIGH 6.5 мкс
Время установки для повторного состояния START tSU:STA 5.3 мкс
Время удержания данных tHD:DAT 5.5 мкс
Время установки данных tSU:DAT 3.1 мкс
Время установки для состояния STOP tSU:STO 5.4 мкс

Заключение

Было показано, как правильно подсоединять напрямую DS1307 или любое двухпроводное «ведомое» устройство к 8051-совместимому микроконтроллеру. Соединение должно быть таким, чтобы временная диаграмма двухпроводного интерфейса на микроконтроллере не нарушалась драйверами низкого уровня. Для этого в программный код должны быть включены подпрограммы задержки. Приведённых в таблице 1 эффективных значений, придерживались при конфигурации аппаратной части, описанной в данном техническом руководстве.

Документация

  Rus Пример программы на языке Асемблер
  100 Kb Engl Исходный фаил
  Rus Описание интерфейса I2C
  Програмное обеспечение микроконтроллеров MCS-51
  200 Kb Engl Описание DS1307 — часы реального времени с IIC интерфейсом

Главная —
Микросхемы —
DOC —
ЖКИ —
Источники питания —
Электромеханика —
Интерфейсы —
Программы —
Применения —
Статьи

Характеристики и подключение датчиков DHT11 и DHT22

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

В большинстве случаев DHT11 или DHT22 доступен в двух вариантах: как отдельный датчик в виде пластикового корпуса с металлическими контактами или как готовый модуль с датчиком и припаянными элементами обвязки. Второй вариант гораздо проще использовать в реальных проектах и крайне рекомендуется для начинающих.

Датчик DHT11

  • Потребляемый ток – 2,5 мА (максимальное значение при преобразовании данных);
  • Измеряет влажность в диапазоне от 20% до 80%. Погрешность может составлять до 5%;
  • Применяется при измерении температуры в интервале от 0 до 50 градусов (точность – 2%)
  • Габаритные размеры: 15,5 мм длина; 12 мм широта; 5,5 мм высота;
  • Питание – от 3 до 5 Вольт;
  • Одно измерение в единицу времени (секунду). То есть, частота составляет 1 Гц;
  • 4 коннектора. Между соседними расстояние в 0,1 ”.

Датчик DHT22

  • Питание – от 3 до 5 Вольт;
  • Максимальный ток при преобразовании – 2,5 мА;
  • Способен измерять влажность в интервале от 0% до 100%. Точность измерений колеблется от 2% до 5%;
  • Минимальная измеряемая температура – минус 40, максимальная – 125 градусов по Цельсию (точность измерений – 0,5);
  • Устройство способно совершать одно измерение за 2 секунд. Частота – до 0,5 ГЦ;
  • Габаритные размеры: 15,1 мм длина; 25 мм широта; 5,5 мм высота;
  • Присутствует 4 коннектора. Расстояние между соседними – 0,1 ‘;

Очевидно, что при использовании в ардуино датчика температуры и влажности DHT11 устройство выдаст менее точные значения, чем DHT22. У аналога больший диапазон измеряемых значений, но и цена соответствующая. Датчик температуры и влажности DHT22, как и его аналог, имеет один цифровой выход, соответственно снимать показания можно не чаще, чем один раз в 1-2 секунды.

Writing datetime #

Create a new patch . We’ll use it only once to write the current time to the memory of RTC module so that it has a proper base point.

  • Put an node from the library onto the patch. This node describes an RTC breakout board which communicates via I2C. By default, the I2C device address of the RTC at the pin is which is correct for the most DS1307 modules. The pin of the node outputs the value which contains everything to operate the device.
  • Add a node from the library onto the patch. This node’s function is to write time and date to the permanent memory of the RTC board. The pin inputs a type value to be written. The pin triggers a new write. The output pin notifies writing complete.
  • Link the pin of the node with the pin of the node.
  • The value at the pin means that we write the once after the boot of the device.

The node requires the date and time values having a type. The node is used to pack year, month, day, and hours, minutes, seconds into a type value.

  • Put the node onto the patch.
  • Link the output pin of the node with the pin of the node.
  • Fill the , , , , , and pins with values. Each pin contains a description of what form this values should be.

For example, we set the current date. Now it is the 17-th of September of the 2018 year, and the time is 14 hours 44 minutes and about 31 seconds. To set this date and time values to the RTC, we fill the pins with values.

  • The year value to the pin.
  • number of the September month to the pin.
  • number of the day of the month to the pin.
  • number of the hours to the pin.
  • number of the minutes to the pin.
  • number of the seconds to the pin.

The patch to set up the real-time clock is completed. Let’s quickly load it into the Arduino board, to make the difference between the real and written time be only a few seconds.

Once the board is flashed the RTC module will get the correct current time value which automatically ticks and not get lost as long as the module is powered by either its battery or the device itself. However, note that the time gets re-written on every boot to that exact value we have set. So, if you will reset your board after an hour, it will overwrite the correct time with the now-obsolete hour-lagging value. To protect from this effect it is a good idea to remove the uploaded time setting program. Upload an empty patch right after to clear.

We won’t need the patch anymore.

Функция delayMicroseconds()

Функция delayMicroseconds() является разновидностью функции delay(). Разница заключается в количестве и точности отсчета времени. Функция delay() позволяет отсчитывать время с точностью до 1 миллисекунды, в то время как delayMicroseconds() с точностью до 1 микросекунды.

Значение, которое можно указать в параметре, находиться в диапазоне от 0 до 16383. Для более длинных временных интервалов следует использовать функцию delay() или несколько раз использовать delayMicroseconds().

#define outPin 8
void setup()
{
pinMode(outPin, OUTPUT); // контакт 8 как выход
}
void loop()
{
digitalWrite(outPin, HIGH); // контакт 8 высокое состояние
delayMicroseconds(50); // пауза 50 микросекунд
digitalWrite(outPin, LOW); // контакт 8 низкое состояние
delayMicroseconds(50); // пауза 50 микросекунд
}

Этот пример генерирует меандр с периодом 100 микросекунд и заполнением 50%.

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

Подробнее

Резюме

Платформа Arduino предоставляет нам несколько способов выполнения задержки в своем проекте. С помощью delay вы можете быстро поставить на паузу выполнение скетча, но при этом заблокируете работу микроконтроллера. Использование команды millis позволяет обойтись в ардуино без delay, но для этого потребуется чуть больше программировать. Выбирайте лучший способ в зависимости от сложности вашего проекта. Как правило, в простых скетчах и при задержке меньше 10 секунд используют delay. Если логика работы сложнее и требуется большая задержка, то вместо delay лучше использовать millis.

«>

Задержки

Простейшей с точки зрения использования функцией времени является задержка, их у нас две:

  • delay(time) – “Приостанавливает” выполнение кода на time миллисекунд. Дальше функции delay выполнение кода не идёт, за исключением прерываний. Использовать рекомендуется только в самых крайних или тех случаях, когда delay не влияет на скорость работы устройства. time принимает тип данных unsigned long и может приостановить выполнение на срок от 1 мс до

50 суток (4 294 967 295 миллисекунд) с разрешением в 1 миллисекунду. Работает на системном таймере Timer 0delayMicroseconds(time) – Аналог delay(), приостанавливает выполнение кода на time микросекунд. time принимает тип данных unsigned long и может приостановить выполнение на срок от 4 мкс до

70 минут (4 294 967 295 микросекунд) с разрешением 4 микросекунды. Работает на системном таймере Timer 0

Задержки использовать очень просто:

И вот мы можем делать какое-то действие два раза в секунду. А что делать, если нам нужно выполнять одно действие два раза в секунду, а другое – три? А третье – 10 раз в секунду например. Сразу привыкаем к той мысли, что задержки лучше вообще не использовать в реальном коде. Разве что delayMicroseconds, он бывает нужен для генерации каких-то протоколов связи. Нормальным инструментом для тайм-менеджмента своего кода являются функции, которые считают время со старта МК.

Пример проекта с i2C модулем часов и дисплеем

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

В проекте используется простой четырехразрядный индикатор на микросхеме TM1637. Устройство обладает двухпроводным интерфейсом и обеспечивает 8 уровней яркости монитора. Используется только для показа времени в формате часы:минуты. Индикатор прост в использовании и легко подключается. Его выгодно применять для проектов, когда не требуется поминутная или почасовая проверка данных. Для получения более полной информации о времени и дате используются жидкокристаллические мониторы.

Модуль часов подключается к контактам SCL/SDA, которые относятся к шине I2C. Также нужно подключить землю и питание. К Ардуино подключается так же, как описан выше: SDA – A4, SCL – A5, земля с модуля к земле с Ардуино, VCC -5V.

Индикатор подключается просто – выводы с него CLK и DIO подключаются к любым цифровым пинам на плате.

Скетч. Для написания кода используется функция setup, которая позволяет инициализировать часы и индикатор, записать время компиляции. Вывод времени на экран будет выполнен с помощью loop.

    #include     #include "TM1637.h"    #include "DS1307.h" //нужно включить все необходимые библиотеки для работы с часами и дисплеем.    char compileTime[] = __TIME__; //время компиляции.    #define DISPLAY_CLK_PIN 10    #define DISPLAY_DIO_PIN 11 //номера с выходов Ардуино, к которым присоединяется экран;    void setup()    {    display.set();    display.init(); //подключение и настройка экрана.    clock.begin(); //включение часов.    byte hour = getInt(compileTime, 0);    byte minute = getInt(compileTime, 2);    byte second = getInt(compileTime, 4); //получение времени.    clock.fillByHMS(hour, minute, second); //подготовка для записывания в модуль времени.    clock.setTime(); //происходит запись полученной информации во внутреннюю память, начало считывания времени.    }    void loop()    {    int8_t timeDisp; //отображение на каждом из четырех разрядов.    clock.getTime();//запрос на получение времени.    timeDisp = clock.hour / 10;    timeDisp = clock.hour % 10;    timeDisp = clock.minute / 10;    timeDisp = clock.minute % 10; //различные операции для получения десятков, единиц часов, минут и так далее.    display.display(timeDisp); //вывод времени на индикатор    display.point(clock.second % 2 ? POINT_ON : POINT_OFF);//включение и выключение двоеточия через секунду.    }    char getInt(const char* string, int startIndex) {    return int(string - '0') * 10 + int(string) - '0'; //действия для корректной записи времени в двухзначное целое число. В ином случае на экране будет отображена просто пара символов.    }    

После этого скетч нужно загрузить и на мониторе будет показано время.

Программу можно немного модернизировать. При отключении питания выше написанный скетч приведет к тому, что после включения на дисплее будет указано время, которое было установлено при компиляции. В функции setup каждый раз будет рассчитываться время, которое прошло с 00:00:00 до начала компиляции. Этот хэш будет сравниваться с тем, что хранятся в EEPROM, которые сохраняются при отключении питания.

Для записи и чтения времени в энергонезависимую память или из нее нужно добавить функции EEPROMWriteInt и EEPROMReadInt. Они нужны для проверки совпадения/несовпадения хэша с хэшем, записанным в EEPROM.

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

В результате в коде нужно будет указать новую библиотеку (для жидкокристаллических экранов это LiquidCrystal), и добавить в функцию loop() строки для получения даты.

Алгоритм работы следующий:

  • Подключение всех компонентов;
  • Загрузка скетча;
  • Проверка – на экране монитора должны меняться ежесекундно время и дата. Если на экране указано неправильное время, нужно добавить в скетч функцию RTC.write (tmElements_t tm). Проблемы с неправильно указанным временем связаны с тем, что модуль часов сбрасывает дату и время на 00:00:00 01/01/2000 при выключении.
  • Функция write позволяет получить дату и время с компьютера, после чего на экране будут указаны верные параметры.

Скетч для работы с датчиками DHT11 и DHT22 в Arduino

#include "DHT.h"
#define DHTPIN 2 // Тот самый номер пина, о котором упоминалось выше
// Одна из следующих строк закоментирована. Снимите комментарий, если подключаете датчик DHT11 к arduino
DHT dht(DHTPIN, DHT22); //Инициация датчика
//DHT dht(DHTPIN, DHT11);
void setup() {
  Serial.begin(9600);
  dht.begin();
}
void loop() {
  delay(2000); // 2 секунды задержки
  float h = dht.readHumidity(); //Измеряем влажность
  float t = dht.readTemperature(); //Измеряем температуру
  if (isnan(h) || isnan(t)) {  // Проверка. Если не удается считать показания, выводится «Ошибка считывания», и программа завершает работу
    Serial.println("Ошибка считывания");
    return;
  }
  Serial.print("Влажность: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Температура: ");
  Serial.print(t);
  Serial.println(" *C "); //Вывод показателей на экран
}

После загрузки скетча и подключения датчика, результат измерений можно посмотреть в окне монитора порта. Там будут выводиться значения температуры и влажности. Если что-то пошло не так, проверьте правильность подключения датчика, соответствие номера порта на плате Arduino и в скетче, надежность контактов.
Если все работает и датчик дает показания, можете провести эксперименты. Например, поместить датчик в более холодное место или подышать на него, отслеживая при этом изменения . Если при запотевании уровень влажности увеличивается, значит датчик работает исправно. Подуйте на него тонкой струйкой – влажность уменьшится и температура вернется в норму.

На этом этапе вы сможете заметить разницу между реальным значением температуры и показаниями датчика с ардуино. Точность DHT11 гораздо хуже точности DHT22, о чем мы уже говорили в этой статье. Если у вас есть оба датчика, подключите их к плате Arduino и сравните результаты. По моему опыту, в среднем расхождение составляет больше градуса. Учитывайте это, используя эти датчики в своих проектах.

Регистры таймеров в Arduino Uno

Для изменения конфигурации таймеров в плате Arduino Uno используются следующие регистры:

1. Timer/Counter Control Registers (TCCRnA/B) – управляющие регистры таймера/счетчика

Эти регистры содержат основные управляющие биты таймера и используются для управления предварительными делителями частоты (предделителями) таймера. Они также позволяют управлять режимом работы таймера с помощью битов WGM.

Формат этих регистров:

Предделитель (Prescaler)

Биты CS12, CS11, CS10 в регистре TCCR1B устанавливают коэффициент деления предделителя, то есть скорость часов таймера. В плате Arduino Uno можно установить коэффициент деления предделителя равный 1, 8, 64, 256, 1024.

2. Timer/Counter Register (TCNTn) – регистры таймера/счетчика

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

Формула для расчета заранее загружаемого значения (preloader value) для необходимого интервала времени (Time) в секундах выглядит следующим образом:

TCNTn = 65535 – (16x106xTime in sec / Prescaler Value)

Откуда берется величина 16х106? Здесь все просто — это переведенная в Герцы частота кварцевого генератора 16 МГц.

Чтобы для таймера 1 (timer1) задать время равное 2 секундам, при коэффициент деления предделителя (Prescaler Value) равном 1024, получим:

TCNT1 = 65535 – (16x106x2 / 1024) = 34285

Часы с выводом на экран Nokia 5110

Следующий урок — часы на Arduino, которые также простые для сборки, где вы сможете установить дату и время на последовательном мониторе.

В этом уроке используются лишь несколько компонентов — только перемычки, Arduino и дисплей Nokia 5110/3110.

Комплектующие

Детали, используемые в этом проекте ниже.

Оборудование

  • Arduino UNO и Genuino UNO × 1
  • Adafruit дисплей Nokia 5110 × 1
  • Соединительные провода (универсальные) × 1
  • Резистор 221 Ом × 1

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

Схема соединения

Соединяем детали часов на Ардуино как на схеме выше:

  • контакт pin 3 — последовательный тактовый выход (SCLK) // pin 3 — Serial clock out (SCLK)
  • контакт pin 4 — выход серийных данных (DIN) // pin 4 — Serial date out (DIN)
  • контакт pin 5 — дата / выбор команды (D / C) // pin 5 — date/Command select (D/C)
  • контакт pin 6 — выбор ЖК-чипа (CS / CE) // pin 6 — LCD chip select (CS/CE)
  • контакт pin 7 — сброс ЖК (RST) // pin 7 — LCD reset (RST)

Код урока

Код второй версии часов вы можете скачать или скопировать ниже.

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

Adafruit_PCD8544 display = Adafruit_PCD8544(3,4,5,6,7);

int second,minute, hour, day, mounth,year; 
unsigned long UtlTime; 

void setup() 
pinMode(2,OUTPUT);
UtlTime=0;   {   

minute=0;   
hour=0;   
day=0;   
mounth=0;   
year=0;   
Serial.begin(9600);   
  display.begin();
  display.setContrast(50); // Adjust the display contrast
  display.clearDisplay();   //Apaga o buffer e o display
  display.setTextSize(1);  //Seta o tamanho do texto
  display.setTextColor(BLACK); //Seta a cor do texto      
   
display.print(" date e hour ");   
display.setCursor(0,10);   
display.print(" com Arduino");   
display.display();
delay (5000); 

//Configura o minute   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("minute: ");
display.display();
Serial.print("\nin between minute:");  
while(minute==0)   {     
if (Serial.available() > 0)     
{       
minute= Serial.parseInt();     
}   
}   
display.print(minute);   
display.display();
delay(1000); 

//Configura a hour   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("hour: ");   
display.display();
Serial.print("\nin between hour:"); 
while(hour==0)   
{     
if (Serial.available() > 0)     
{       
hour= Serial.parseInt();     
}   
}   
display.print(hour);   
display.display();
delay(1000);    

//Configura o day   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("day: ");
display.display();   
Serial.print("\nin between day:");   
while(day==0)   
{     
if (Serial.available() > 0)     
{       
day= Serial.parseInt();     
}   
}   
display.print(day);   
display.display();
delay(1000);    

//Configura o mês   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("mounth: "); 
display.display();  
Serial.print("\nin between mounth:");  
while(mounth==0)   
{     
if (Serial.available() > 0)     
{       
mounth= Serial.parseInt();     
}   
}   
display.print(mounth);  
 display.display();
delay(1000);    

//Configura o year   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("year: ");   
display.display();
Serial.print("\nin between year:");   
while(year==0)   
{     
if (Serial.available() > 0)     
{       
year= Serial.parseInt();     
}   
}   
display.print(year);   

display.display();   
delay(1000);
display.clearDisplay(); 

} 

void loop() 
{   

if(millis()-UtlTime<0)   
{     
UtlTime=millis();   
}   
else   
{     
second=int((millis()-UtlTime)/1000);   
}   
if(second>59)   
{     
second=0;     
minute++;     
UtlTime=millis();     
if(minute>59)     
{       
hour++;       
minute=0;       
if(hour>23)       
{         
day++;         
hour=0;         
if(mounth==1||mounth==3||mounth==5||mounth==7||mounth==8||mounth==10||mounth==12)         
{           
if(day>31)           
{             
day=1;             
mounth++;             
if(mounth>12)             
{               
year++;               
mounth=1;             
}           
}         
}         
else if(mounth==2)         
{           
if(year%400==0)           
{             
if(day>29)             
{               
day=1;               
mounth++;             
}           
}           
else if((year%4==0)&&(year%100!=0))           
{             
if(day>29)             
{              
day=1;               
mounth++;             
}           
}           
else           
{             
if(day>28)             
{               
day=1;               
mounth++;             
}           
}         
}         
else         
{           
if(day>30)           
{             
day=1;             
mounth++;           
}         
}       
}     
}   
}    

display.clearDisplay(); 
delay(1000); 
Serial.print(day);   
Serial.print("/");   
Serial.print(mounth);   
Serial.print("/");   
Serial.print(year);   
Serial.println();      

display.setCursor(0,0);   
display.print("date ");   
display.print(day);   
display.print("/");   
display.print(mounth);   
display.print("/");   
display.print(year);

 
display.display();
Serial.print(hour);   
Serial.print(":");   
Serial.print(minute);   
Serial.print(":");   
Serial.print(second);   
Serial.print("\n");   
Serial.println();      

display.setCursor(0,10);   
display.print("hour ");   
display.print(hour);   
display.print(":");   
display.print(minute);   
display.print(":");   
display.print(second); 
display.display();
char tecla;
tecla = Serial.read();
if(tecla=='1'){
digitalWrite(2,LOW);
}
if(tecla=='2'){
  digitalWrite(2, HIGH);
}

}