Часы на TM1637 и DS3231. Странный баг
- Войдите на сайт для отправки комментариев
Ср, 30/12/2020 - 18:04
/////////НАСТРОЙКИ/////////////
#define BRIG_NIGHT 0 // Яркость ночью
#define BRIG_DAY 7 // Яркость днем
#define HOUR_NIGHT 22 // Час, когда начинается ночь
#define HOUR_DAY 8 // Час, когда начинается день
#define MODE_CLOCK 0 // Режим переключения цифр (0-без эффекта 1-с эффектом номер один 2 - с эффектом номер два)
#define PERIOD_ON 300 // Период на который включается двоеточие
#define PERIOD_OFF 700 // Период на который выключается двоеточие
/////////ПИНЫ ПОДКЛЮЧЕНИЯ/////////////
#define CLK 8 // Куда подключен дисплей TM1637 (пин CLK)
#define DIO 9 // Куда подключен дисплей TM1637 (пин DIO)
//////////ДЛЯ РАЗРАБОТЧИКА/////////////
#include "GyverTM1637.h"
#include <microDS3231.h>
MicroDS3231 rtc;
GyverTM1637 disp(CLK, DIO);
int hour_now;
int minute_now;
bool flag;
void setup() {
Serial.begin(9600);
Serial.setTimeout (100);
if (HOUR_DAY < HOUR_NIGHT) {
flag = true;
} else {
flag = false;
}
disp.clear();
if (flag) {
if (rtc.getHours() >= HOUR_NIGHT || rtc.getHours() < HOUR_DAY) {
disp.brightness(BRIG_NIGHT);
} else {
disp.brightness(BRIG_DAY);
}
} else {
if (rtc.getHours() >= HOUR_NIGHT && rtc.getHours() < HOUR_DAY) {
disp.brightness(BRIG_NIGHT);
} else {
disp.brightness(BRIG_DAY);
}
}
hour_now = rtc.getHours();
minute_now = rtc.getMinutes();
if (MODE_CLOCK == 0) {
disp.displayClock(hour_now, minute_now);
} else if (MODE_CLOCK == 1) {
disp.displayClockScroll(hour_now, minute_now, 70);
} else if (MODE_CLOCK == 2) {
disp.displayClockTwist(hour_now, minute_now, 35);
}
}
void loop() {
delay (50);
timer_point ();
update_disp ();
parse_serial ();
day_night_change ();
}
void day_night_change () {
static unsigned long timer;
if (millis () - timer >= 1000 || millis () < timer) {
timer = millis ();
if (flag) {
if (rtc.getHours() >= HOUR_NIGHT || rtc.getHours() < HOUR_DAY) {
disp.brightness(BRIG_NIGHT);
} else {
disp.brightness(BRIG_DAY);
}
} else {
if (rtc.getHours() >= HOUR_NIGHT && rtc.getHours() < HOUR_DAY) {
disp.brightness(BRIG_NIGHT);
} else {
disp.brightness(BRIG_DAY);
}
}
}
}
void parse_serial () {
if (Serial.available ()) {
int hours_setting = Serial.parseInt ();
int minutes_setting = Serial.parseInt ();
int seconds_setting = Serial.parseInt ();
Serial.print ("Set ");
Serial.print (hours_setting);
Serial.print (":");
Serial.print (minutes_setting);
Serial.print (":");
Serial.println (seconds_setting);
rtc.setTime(seconds_setting, minutes_setting, hours_setting, 0, 0, 2000);
}
}
void update_disp () {
if (rtc.getHours() != hour_now || rtc.getMinutes() != minute_now) {
hour_now = rtc.getHours();
minute_now = rtc.getMinutes();
if (MODE_CLOCK == 0) {
disp.displayClock(hour_now, minute_now);
} else if (MODE_CLOCK == 1) {
disp.displayClockScroll(hour_now, minute_now, 70);
} else if (MODE_CLOCK == 2) {
disp.displayClockTwist(hour_now, minute_now, 35);
}
}
}
void timer_point () {
static unsigned long timer = 0;
static bool flag_point;
static int period;
if (flag_point) {
period = PERIOD_ON;
} else {
period = PERIOD_OFF;
}
if (millis () - timer >= period || millis () < timer) {
timer = millis ();
flag_point = !flag_point;
disp.point(flag_point);
}
}
Иногда случается странный баг - все сегменты гаснут, кроме первого и продолжается это примерно полсекунды-секунду. Потом все нормально. Проблема в программной или аппаратной части?
Добавьте break (помечен BUGFIX):
void TM1637::writeByte(int8_t wr_data) { uint8_t i,count1; for(i=0;i<8;i++) //sent 8bit data { digitalWrite(Clkpin,LOW); if(wr_data & 0x01)digitalWrite(Datapin,HIGH);//LSB first else digitalWrite(Datapin,LOW); delayMicroseconds(3); wr_data >>= 1; digitalWrite(Clkpin,HIGH); delayMicroseconds(3); } digitalWrite(Clkpin,LOW); //wait for the ACK digitalWrite(Datapin,HIGH); digitalWrite(Clkpin,HIGH); pinMode(Datapin,INPUT); while(digitalRead(Datapin)) { count1 +=1; if(count1 == 200)// { pinMode(Datapin,OUTPUT); digitalWrite(Datapin,LOW); count1 =0; break; //BUGFIX } pinMode(Datapin,INPUT); } pinMode(Datapin,OUTPUT); }Обращайся к гайверу, на его форум
int GyverTM1637::writeByte(int8_t wr_data) { uint8_t i, count1; for (i = 0; i < 8; i++) //sent 8bit data { digitalWrite(Clkpin, LOW); if (wr_data & 0x01)digitalWrite(Datapin, HIGH); //LSB first else digitalWrite(Datapin, LOW); wr_data >>= 1; digitalWrite(Clkpin, HIGH); } digitalWrite(Clkpin, LOW); //wait for the ACK digitalWrite(Datapin, HIGH); digitalWrite(Clkpin, HIGH); pinMode(Datapin, INPUT); delayMicroseconds(50); uint8_t ack = digitalRead(Datapin); if (ack == 0) { pinMode(Datapin, OUTPUT); digitalWrite(Datapin, LOW); } delayMicroseconds(50); pinMode(Datapin, OUTPUT); delayMicroseconds(50); return ack; }У меня этот участок по-другому выглядит