Наоборот: частые обращения к датчику приводят к его разогреву и, как следствие, он будет показывать собственную температуру вместо температуры окружающей среды.
Я бы не назвал такое поведение адекватным.
Они и так неравномерно меняются. Единственный способ менять их равномерно - менять в тот момент, когда минута (секунда) сменяется в самих часах. Тогда они будут меняться точно раз в минуту (секунду).
Вот таблица настройки будильников из даташита
Как видите, чтобы прерывание срабатывало раз в секунду, нужно завести первый будильник, установив все биты настройки в 1.
А чтобы раз в минуту - завести второй будильник, также указав все биты настройки в 1.
Прерывание будет прилетать на ногу SQW (кажется, у неё нормальный уровень высокий, а когда прерывание - низкий, но могу забыть, надо проверить).
Это можно делать руками, а также это может сделать любая библиотека, умеющая настраивать будильники.
Я тут в другой теме писал коллеге про эту библиотеку:
Можно ли в этой библиотеке настраивать будильники, я даже смотреть не буду (может и можно, но смотреть не буду просто из гигиенических соображений). Переделайте на нормальную библиотеку, тогда посмотрим.
Не пробуйте. Делайте правильно (я описал как). Любые Ваши “уменьшить/увеличить” - это просто “полировка задницы”, а её сколько не полируй, она всё равно задницей останется.
Еще переделал, и добавил мигания устанавливаемыми параметрами, не знаю корректно ли такое решение но другого пока не придумал, времени сейчас на хобби стало меньше. Я так понимаю, что все неправильные интервалы связанны с использованием delay в библиотеке. Если будет желание, позже попробую переписать под другую библиотеку.
#include <LedControl.h>
#include <iarduino_RTC.h>
#include <DHT11.h>
#include <Wire.h>
#include <VirtualButton.h>
#define VB_DEB 50
#define VB_CLICK 100
struct MyBtn : public VButton {
MyBtn(uint8_t pin) {
_pin = pin;
pinMode(_pin, INPUT_PULLUP);
}
bool tick() {
return poll(!digitalRead(_pin));
}
uint8_t _pin;
};
MyBtn setButt(2);
MyBtn upButt(3);
MyBtn downButt(4);
LedControl LC = LedControl(12, 11, 10, 3);
iarduino_RTC watch(RTC_DS3231);
DHT11 dht11(5);
const int brightSetPin = A0;
const int dividerDotsPin = 6;
int dividerDotsState = LOW;
int mode = 0;
long previousMillis = 0;
unsigned long buttonTimer = 0;
unsigned long tempHumidityTimer = 0;
unsigned long emptyTimer = 0;
int temperature = 0;
int humidity = 0;
void ButtonSetControl();
void ShowTime();
void Divider();
void ShowEmptyPlace();
void setup() {
delay(300);
Serial.begin(9600);
watch.begin();
Wire.begin();
for (int ledS = 0; ledS < 3; ledS++) {
LC.shutdown(ledS, false);
LC.clearDisplay(ledS);
}
pinMode(dividerDotsPin, OUTPUT);
//watch.settime(0,28,18,10,1,24,2) ;
}
void loop() {
static byte tik = 0;
if (millis() - buttonTimer > 20) {
buttonTimer = millis();
setButt.tick();
upButt.tick();
downButt.tick();
ButtonSetControl();
ShowEmptyPlace();
if (tik >= 25) {
watch.gettime();
Divider();
ShowTime();
tik = 0;
}
tik++;
}
if (millis() - tempHumidityTimer > 60000) {
tempHumidityTimer = millis();
int temperature = dht11.readTemperature();
int humidity = dht11.readHumidity();
}
Serial.println(mode);
}
void ButtonSetControl() {
if ((setButt.click()) || (setButt.step())) {
mode++;
if (mode > 7) { mode = 0; }
}
if (mode) {
if ((upButt.click()) || (upButt.step())) {
switch (mode) {
/* сек */ case 1:
watch.settime(0, -1, -1, -1, -1, -1, -1);
break;
/* мин */ case 2:
watch.settime(-1, (watch.minutes == 59 ? 0 : watch.minutes + 1), -1, -1, -1, -1, -1);
break;
/* час */ case 3:
watch.settime(-1, -1, (watch.Hours == 23 ? 0 : watch.Hours + 1), -1, -1, -1, -1);
break;
/* дни */ case 4:
watch.settime(-1, -1, -1, (watch.day == 31 ? 1 : watch.day + 1), -1, -1, -1);
break;
/* мес */ case 5:
watch.settime(-1, -1, -1, -1, (watch.month == 12 ? 1 : watch.month + 1), -1, -1);
break;
/* год */ case 6:
watch.settime(-1, -1, -1, -1, -1, (watch.year == 99 ? 0 : watch.year + 1), -1);
break;
/* д.н.*/ case 7:
watch.settime(-1, -1, -1, -1, -1, -1, (watch.weekday == 6 ? 0 : watch.weekday + 1));
break;
}
}
if ((downButt.click()) || (downButt.step())) {
switch (mode) {
/* сек */ case 1:
watch.settime(0, -1, -1, -1, -1, -1, -1);
break;
/* мин */ case 2:
watch.settime(-1, (watch.minutes == 0 ? 59 : watch.minutes - 1), -1, -1, -1, -1, -1);
break;
/* час */ case 3:
watch.settime(-1, -1, (watch.Hours == 0 ? 23 : watch.Hours - 1), -1, -1, -1, -1);
break;
/* дни */ case 4:
watch.settime(-1, -1, -1, (watch.day == 1 ? 31 : watch.day - 1), -1, -1, -1);
break;
/* мес */ case 5:
watch.settime(-1, -1, -1, -1, (watch.month == 1 ? 12 : watch.month - 1), -1, -1);
break;
/* год */ case 6:
watch.settime(-1, -1, -1, -1, -1, (watch.year == 0 ? 99 : watch.year - 1), -1);
break;
/* д.н.*/ case 7:
watch.settime(-1, -1, -1, -1, -1, -1, (watch.weekday == 0 ? 6 : watch.weekday - 1));
break;
}
}
}
}
void ShowTime() {
int brightSetVol = analogRead(brightSetPin) / 50;
if (brightSetVol < 0) { brightSetVol = 2; }
for (int ledS = 0; ledS < 3; ledS++) {
LC.setIntensity(ledS, brightSetVol);
}
LC.setDigit(0, 0, watch.Hours / 10, false);
LC.setDigit(0, 1, watch.Hours % 10, true);
LC.setDigit(0, 2, watch.minutes / 10, false);
LC.setDigit(0, 3, watch.minutes % 10, true);
LC.setDigit(0, 4, watch.seconds / 10, false);
LC.setDigit(0, 5, watch.seconds % 10, false);
switch (watch.weekday) {
case 0: // ПН
LC.setRow(0, 6, 0b01110110);
LC.setRow(0, 7, 0b00110111);
break;
case 1: // ВТ
LC.setRow(0, 6, 0b01111111);
LC.setRow(0, 7, 0b00001111);
break;
case 2: // СР
LC.setRow(0, 6, 0b01001110);
LC.setRow(0, 7, 0b01100111);
break;
case 3: // ЧТ
LC.setRow(0, 6, 0b00110011);
LC.setRow(0, 7, 0b00001111);
break;
case 4: // ПТ
LC.setRow(0, 6, 0b01110110);
LC.setRow(0, 7, 0b00001111);
break;
case 5: // СБ
LC.setRow(0, 6, 0b01001110);
LC.setRow(0, 7, 0b00011111);
break;
case 6: // НД
LC.setRow(0, 6, 0b00110111);
LC.setRow(0, 7, 0b00111101);
break;
}
LC.setDigit(1, 0, watch.day / 10, false);
LC.setDigit(1, 1, watch.day % 10, true);
LC.setDigit(1, 2, watch.month / 10, false);
LC.setDigit(1, 3, watch.month % 10, true);
LC.setDigit(1, 4, 2, false);
LC.setDigit(1, 5, 0, false);
LC.setDigit(1, 6, watch.year / 10, false);
LC.setDigit(1, 7, watch.year % 10, false);
if (temperature < 0) {
LC.setRow(2, 0, 0b0000001);
}
LC.setDigit(2, 1, temperature / 10, false);
LC.setDigit(2, 2, temperature % 10, false);
LC.setRow(2, 3, 0b01100011);
LC.setRow(2, 4, 0b01001110);
LC.setDigit(2, 5, humidity / 10, false);
LC.setDigit(2, 6, humidity % 10, false);
LC.setRow(2, 7, 0b00110111);
}
void Divider() {
unsigned long currentMillis = millis();
int interval = 500;
if (mode == 0) {
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
dividerDotsState = !dividerDotsState;
digitalWrite(dividerDotsPin, dividerDotsState);
}
if (mode) {
digitalWrite(dividerDotsPin, LOW);
}
}
}
void ShowEmptyPlace() {
if (mode) {
if (millis() - emptyTimer > 1000) {
emptyTimer = millis();
switch (mode) {
case 1:
LC.setChar(0, 5, 0b0100000, false);
LC.setChar(0, 4, 0b0100000, false);
break;
case 2:
LC.setChar(0, 2, 0b0100000, false);
LC.setChar(0, 3, 0b0100000, true);
break;
case 3:
LC.setChar(0, 0, 0b0100000, false);
LC.setChar(0, 1, 0b0100000, true);
break;
case 4:
LC.setChar(1, 0, 0b0100000, false);
LC.setChar(1, 1, 0b0100000, true);
break;
case 5:
LC.setChar(1, 2, 0b0100000, false);
LC.setChar(1, 3, 0b0100000, true);
break;
case 6:
LC.setChar(1, 6, 0b0100000, false);
LC.setChar(1, 7, 0b0100000, false);
break;
case 7:
LC.setChar(0, 6, 0b0100000, false);
LC.setChar(0, 7, 0b0100000, false);
break;
}
}
}
}
Нашел включение сообщений о предупреждениях и понял что не зря на эту библиотеку ругаются. Больше к ней не притронусь…
void ShowEmptyPlace() {
Вот вот, и я об этом))
Опять кто-то виноват, но не сам))
В библиотеке RTC , что вы используете, вообще-то делеев поти нет(кроме одного 1мс и другого 20мкс, и они ни на что не влияют). А вот VirtualButton.h даже Гайвер не советует использовать, мол она устарела.
Вызов функции библиотеки RTC, тоже как делей, тормозит другие процессы. Поэтому надо как можно реже обращаться к модулю. В идеале 1 раз в секунду, считать из него данные в переменные, и больше не беспокоить модуль до следующей секунды.
Как обращаться к модулю ровно 1раз в секунду объяснил
ЕвгенийП в #88.
Для этого надо освоить работу с прерываниями(не сложно,всё разжёвано). Можно даже упрощённый вариант, не по ALARMy, а по сигналу от модуля частотой 1Гц
Так сказать вопрос сначала:
А что и где в этом коде делается?
И следом совет, от «бывалого» - пиши комментарии. Через время сам нифига не поймёшь где и что и зачем это было сделано ![]()
Сразу возник вопрос к админам форума:
Это ж так не должно быть! Поверено на двух браузерах!
И номера строк пропали…
уже пару недель такая хрень.
Сегодня, вроде всё починилось, но потом опять. Думаю, что какие-то работы идут, надо подождать.
Буквально вчера - такого (у меня) не было. Да и номера строк вчера отображались.
Спасибо за ответ, попробую еще разобраться с прерываниями. Значит правильно будет обновлять дисплей по сигналу прерывания с SQW раз в секунду на пин D2 или D3 ?
Если раз в секунду ардуина будет переключатся на прерывание, не буде ли влиять это на установку времени кнопками? Нужно создать функцию обработки прерывания, которая будет по поступлению сигнала вызывать ShowTime()?
Virtul Button поменяю на другую.
Для кнопок много уже лет использую kakmyc_btn
Рекомендую!!!
Максимально короткой




