Часы на TM1637 и DS3231. Странный баг

Савелий
Offline
Зарегистрирован: 26.10.2019
/////////НАСТРОЙКИ/////////////

#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);
  }
}

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

Green
Offline
Зарегистрирован: 01.10.2015

Добавьте 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);
  
}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Обращайся к гайверу, на его форум

Савелий
Offline
Зарегистрирован: 26.10.2019
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;
}

У меня этот участок по-другому выглядит