Программа для микроконтроллера (1)
Программа это то, что микроконтроллер будет выполнять. Вот она:
https://www.chipdip.ru/products/sketch/9000318627
А ещё здесь:
https://www.chipdip.ru/product0/9000318627
… из раздела «Техническая документация» можно и нужно скачать целую компанию архивов и PDF-описаний.
Архивы с библиотеками у меня распаковались в вот такие папки:
Чтобы понять, что тут зачем надо узнать точные названия этих устройств:
1] Часы (RTC (Real Time Clock) — модуль на базе чипа DS1307)
2] Пищалка
3] Реле (Power PCB Relay RT1, troyka-реле)
4] Дисплей (0.96inch OLED SSD1306)
5] Джойстик (3d-джойстик, troyka-модуль)
6] Датчик (DHT11 Humidity & Temperature Sensor)
Кое-что (т.е что для чего) уже понятно. К контролеру можно прицепить что угодно. Внутри контроллера тоже есть какая-то программа, управляющая самим контроллером. А для внешних подключенных устройств часто требуются подгружать какие-то свои программы, управляющие этими устройствами. Эти программы и содержаться в библиотеках, которые надо загрузить.
Стандартные библиотеки (в т.ч для работы с самим микроконтроллером) есть в папке Arduino:
Начало программы:
В программе должно быть описано всё, что она делает. Но чтобы что-то делать должен быть подключен весь нужный инструментарий. Потому обращаю внимание на список ссылок на библиотеки в самом верху (после «#include»). Это ещё пригодится. А пока соберу со всего текста названия функций, т.е отдельных кусков программы, вызываемых откуда-то при каких-то условиях.
Первая, которую вижу setup(). Прямых аналогий не назвать. Но само название указывает на то, что это что-то выполняемое при включении этой штуковины.
loop() – название тоже ясно указывает что это программа, которая постоянно выполняется. Т.е выполнилось нечто, там написанное, и сразу же запускается ещё раз. Надо, например, информацию о времени перерисовывать на экране. Постоянный запуск одной и той же программы перерисовки позволяет это делать.
UpdateTime(tmElements_t* TimeVal) – а вот и явная (судя по тому же названию) перерисовка времени на экране. Программа должна быть короткая и простая. Вот она:
void UpdateTime(tmElements_t* TimeVal)
{
display.setTextColor(WHITE); //установка неинверсного отображения
display.setTextSize(TIME_SIZE); //установка размера текста
display.setCursor(HOUR_HOR_POS, HOUR_VER_POS); //установка курсора
//вывод времени
if (TimeVal->Hour < 10)
display.print("0");
display.print(TimeVal->Hour);
display.print(":");
if (TimeVal->Minute < 10)
display.print("0");
display.print(TimeVal->Minute);
}
Смысл тут, по-моему, понятен. На дисплее в определённых местах рисуются вначале часы потом минуты. Намного интереснее то, откуда он берёт экранные координаты в которых это надо нарисовать (HOUR_HOR_POS, HOUR_VER_POS) и прочие константы (обычно они пишутся большими буквами).
Берёт он это всё из файла clock.h, подключенного там где библиотеки:
Конкретно это не библиотека а список установок проекта. Микроконтроллеру такой файл не нужен. Его написание – своеобразная программистская аккуратность, при которой проще работать. Захочу я, например, прицепить реле не к порту №3 а к какому-то другому порту. Если нет этого файла мне надо будет искать все обращения к порту (по цифре «3») по всему тексту. Это и долго и ненадёжно. Проще тут поменять значение одной константы RELAY_PIN на какое-то другое.
Функции UpdateDate(tmElements_t* TimeVal), UpdateTemp() – явная отрисовка на экране даты и температуры с влажностью.
CheckAlarm(tmElements_t* TimeVal) название тоже довольно определённо указывает на то, что это проверка будильника (пищалки).
Текст тоже короткий:
void CheckAlarm(tmElements_t* TimeVal)
{ //если будильник не включен и совпадение времени будильника с текущим временем
if ((!AlarmSetFlag) && (TimeVal->Hour == AlarmHour) && (TimeVal->Minute == AlarmMinute))
{
digitalWrite(RELAY_PIN, HIGH); //включение реле
//digitalWrite(BUZZER_PIN, HIGH);
Buzzer.play(NOTE_A3); //включение пищалки
AlarmSetFlag = true; //установка флага включения будильника
}
//иначе
else if ((AlarmSetFlag) && ((TimeVal->Hour != AlarmHour) || (TimeVal->Minute != AlarmMinute)))
AlarmSetFlag = false; //стирание флага включения будильника
}
… и действительно включающий пищалку и реле при совпадении времени будильника с текущим временем (если эти устройства не включены ранее, т.е ещё НЕ AlarmSetFlag)
Происхождением константы NOTE_A3, т.е тем откуда берётся нота звучания, поинтересуюсь чисто для порядка. Из tone.h она берётся:
Хорошо видно удобство таких файлов. Название ноты хоть что-то говорит тем, кто разбирается в музыке. Частота звучания (или что тут в виде цифры) никому ничего не говорит. Но именно её надо сообщать машине. Подобные define – перевод с человеческого на машинный, позволяющий всем читать на удобном языке. Человек читает NOTE_xx, а машина получает нужную ей цифру.
Функцию ChangeSettings() читать не буду. Это явно какой-то длинный диалог, устанавливающий дату, время и время будильника.
ChangeAlarmState(tmElements_t* TimeVal) Выключение будильника, что ли (раз раньше было включение)?
void ChangeAlarmState(tmElements_t* TimeVal)
{
display.clearDisplay();
if (!AlarmFlag) //если будильник выключен
{
AlarmFlag = true; //установка флага включения будильника
//отображение символа "а"
display.setTextSize(ALARM_SIZE);
display.setCursor(ALARM_HOR_POS, ALARM_VER_POS);
display.print("a");
}
else //иначе
{
AlarmFlag = false; //стирание флага включения будильника
}
EEPROM.write(ALARM_FLAG_ADR, AlarmFlag); //запись состояния будильника в память
UpdateTemp();
UpdateDate(TimeVal);
UpdateTime(TimeVal);
display.display();
delay(500);
}
Нет. Это явное сохранение куда-то информации о времени, когда должен срабатывать будильник. То, куда сохраняется, называется EEPROM. Строго говоря непонятно зачем. Ведь можно записывать в какую-то переменную (типа тех, что между include и void setup()). Но если так сделать, время будильника пропадёт при отключении электричества. Придётся после выключения и включения опять устанавливать. Загадочную постоянную память (типа жёсткого диска или флэшки) EEPROM надо искать в стандартных библиотеках хотя бы потому что я такого к контроллеру не подключаю (значит она внутри).
Я нашла ещё одно хранилище библиотек в папке Arduino:
Имя «hardware» наводит на мысль, что это компоненты платы. Команда
EEPROM.write(ALARM_FLAG_ADR, AlarmFlag);
… явно засовывает флажок-включение (т.е цифру 1) в какой-то адрес памяти. Конкретно в ячейку 102,судя по тому что написано в clock.h:
#define ALARM_HOUR_ADR 100
#define ALARM_MINT_ADR (ALARM_HOUR_ADR + 1)
#define ALARM_FLAG_ADR (ALARM_MINT_ADR + 1)
Так работает местная постоянная (не пропадающая при выключении питания) память радуя тем, что она есть))).
|