DS3231 не срабатывает будильник

tw911
Offline
Зарегистрирован: 22.10.2013

Добрый день! Никак не могу разобраться с будильником на данной микросхеме. Никак не хочет подниматься флаг. Выставляю 0x0D в 0x80, минуты и секунды. По идее не смотря на день должен при совпадении часов и минут подняться флаг A2F. Но этого почему то не происходит. Какие типовые ошибки? Код я весь вываливать не хочу, скажу лишь что немного дописал библиотеку отсюда http://lesson.iarduino.ru/page/podklyuchenie-rtc-chasy-realnogo-vremeni-...

А именно добавил свои переменные и несколько функций

 

//установка будильника
void		RTC::setalarm(int RTC_hours, int RTC_minutes){
			RTC_func_WRITE_ALARM(RTC_hours,RTC_minutes);
			RTC_func_READ_ALARM();
}

void		RTC::getalarm(){
			RTC_func_READ_ALARM();
}

void		RTC::RTC_func_READ_ALARM(){
	alarm_h=RTC_func_READ_REG(0x0C);//часы
	alarm_m=RTC_func_READ_REG(0x0B);//минуты
	alarmflag=RTC_func_READ_REG(0x0F);//читаем регистр состояния
	alarm_d=RTC_func_READ_REG(0x0D);//читаем регистр даты
}

void		RTC::RTC_func_WRITE_ALARM(int RTC_hours, int RTC_mintues){
	if(RTC_hours<=24 && RTC_hours>=0){
		RTC_func_WRITE_REG(0x0C,RTC_hours);
	}
	if(RTC_mintues<=60 && RTC_mintues>=0){
		RTC_func_WRITE_REG(0x0B,RTC_mintues);
	}
	RTC_func_WRITE_REG(0x0D,0x80); //установка регистра даты
}

И сам код скетча такой:

#include "RTC.h"
RTC timeModule;
void setup()
{
  /* add setup code here */
	timeModule.begin(RTC_DS3231);
	Serial.begin(9600);
	timeModule.setalarm(15,6);
}

void loop()
{
	timeModule.gettime();
	timeModule.getalarm();
	Serial.print("Time: ");
	Serial.print(timeModule.gettime("H:i:s"));
	Serial.print(" Alarm: ");
	Serial.print(timeModule.alarm_h);
	Serial.print(":");
	Serial.print(timeModule.alarm_m);
	Serial.print(":");
	Serial.println(timeModule.alarm_s);
	Serial.print("Flag=");
	Serial.println(timeModule.alarmflag,BIN);
	Serial.print("Day:");
	Serial.println(timeModule.alarm_d,BIN);
	delay(100);
}

В результате флаг нифига не поднимается(:

Time: 15:05:59 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:00 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:00 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:00 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:00 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:00 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:00 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:00 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:00 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:01 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:01 Alarm: 15:6:0
Flag=1000
Day:10000000
Time: 15:06:01 Alarm: 15:6:0
Flag=1000
Day:10000000

Что это такое? А, ну да, ноль в конце таймера просто пробовал и с 1 и со вторым таймером, результат одинаков, alarm_s 0 по умолчанию.

tw911
Offline
Зарегистрирован: 22.10.2013

Отвечу сам себе. Забыл про BCD. Всем спасибо.

RomulRS
Offline
Зарегистрирован: 21.02.2016

Здравствуйте. Даже зарегистрировался, чтобы написать Вам:) Выложите, пожалуйста, сюда и подкорректированную библиотеку и скетч. Очень актуально. 

И вопрос: А нельзя ли считать показания часов и при совпадении с заданным значением, подать питание на реле освещения? Имеется в виду без использования SQW.

UPDATE. Отвечу сам на свой вопрос: Можно при помощи:

// time.seconds  секунды     0-59
// time.minutes  минуты      0-59
// time.hours    часы        1-12
// time.Hours    часы        0-23
// time.midday   полдень     0-1 (0-am, 1-pm)
// time.day      день месяца 1-31
// time.weekday  день недели 0-6 (1-понедельник, 6-суббота, 0-воскресенье)
// time.month    месяц       1-12
// time.year     год         0-99
 
Пример кода, для включения светодиода с 23.00.00 до 23.59.59:
 
      if(time.Hours == 23) 
    { 
      digitalWrite(led, HIGH);
      delay(3600000);
      digitalWrite(led, LOW);
    }
 
Остаётся вопрос, зачем же всё-таки нужен SQW, если можно обойтись и без него? Плюс меньше проводов, и больше свободных ног на Ардуино.
bwn
Offline
Зарегистрирован: 25.08.2014

RomulRS пишет:

Остаётся вопрос, зачем же всё-таки нужен SQW, если можно обойтись и без него? Плюс меньше проводов, и больше свободных ног на Ардуино.

Он нужен, чтобы разбудить спящую ардуину, чтобы та запустила код и включила реле.))))

Гриша
Offline
Зарегистрирован: 27.04.2014

RomulRS пишет:
      if(time.Hours == 23) 

    { 
      digitalWrite(led, HIGH);
      delay(3600000);
      digitalWrite(led, LOW);
    }

я использую "остановку" иногда, но такого даже я не делаю... поразило кол-во знаков. 

RomulRS
Offline
Зарегистрирован: 21.02.2016

Гриша пишет:

я использую "остановку" иногда, но такого даже я не делаю... поразило кол-во знаков. 

Недавно начал программировать. Поэтому такие печальные скетчи. Сейчас занялся "многозадачностью". Тот кусок скетча лучше заменить на:

  if(time.Hours == 13 && time.minutes == 54)
  {
  digitalWrite(led, HIGH);
  }
  if(time.Hours == 13 && time.minutes == 55)
  {
  digitalWrite(led, LOW);
  }
И тогда светодиод загорится в 13.54 и потухнет в 13.55. Никак не влияя на отображение информации о текущем времени, температуре и т.д.
Правда здесь есть один нюанс, если  вы выберете большой промежуток времени, например 1 час и в течение этого часа произойдет просадка напряжения в сети и ардуина обесточится, то свет не включится, т.к. текущее значение уже не будет равно значению в условии if.
Поэтому приведу пример работы светодиода в независимости от того, в какой момент вы включили ардуину:
  if(8 <= time.Hours <= 22)
  {
  digitalWrite(led, HIGH);
  }
  else
  {
  digitalWrite(led, LOW);
  }
Если сейчас время с 8:00 до 22:00, то светодиод горит. Правда ещё не придумал как быть и с минутами.

 

bwn
Offline
Зарегистрирован: 25.08.2014

RomulRS пишет:

Если сейчас время с 8:00 до 22:00, то светодиод горит. Правда ещё не придумал как быть и с минутами.

Простенько, час*60+минуты

RomulRS
Offline
Зарегистрирован: 21.02.2016

Заметил две ошибки в своём последнем скетче. А именно if(8 <= time.Hours <= 22) не выключала в 22:00 светодиод. Исправил на if(8 <= time.Hours && time.Hours <= 21). Вот правильный вариант:

if(8 <= time.Hours && time.Hours <= 21)
  {
  digitalWrite(led, HIGH);
  }
  else
  {
  digitalWrite(led, LOW);
  }

bwn пишет:

Простенько, час*60+минуты

Если вас не затруднит, можете дать ответ скетчем?

Гриша
Offline
Зарегистрирован: 27.04.2014

RomulRS пишет:

bwn пишет:

Простенько, час*60+минуты

Если вас не затруднит, можете дать ответ скетчем?

Так а в чем трудность? Bwn вполне разумно предложил не париться и все перевести в минуты (перевод величин изучают в четвертом классе общеобразовательной школы)

unsigned long time = (time.Hours*60) + time.minutes;// текущее время в минутах, можно и int использовать
unsigned long TStart1 = 60; // int
unsigned long TStop1 = 61; // int
 if(TStart1 <= time && TStop1 >= time)
  {
  digitalWrite(led, HIGH);
  }
  else
  {
  digitalWrite(led, LOW);
  }
  // не вижу необходимости лезть в часы каждый раз, достаточно 1 раз в минуту или реже, остальное делается на millis, а часами корректируем 

 

tw911
Offline
Зарегистрирован: 22.10.2013

Я тут почти закончил проект программировать, и хочу написать о своих мыслях.

Во первых, выбранная бибилиотека, для работы с DS3231 не совсем подходит. Пришлось дописать несколько функций. В самом модуле есть 2 аппаратных будульника, которые могут по установке флагов дергать вывод, и тем самым, в определенные моменты будить дуину. Мне это было нафиг не надо, но вот сами будильники я испоьзовал.

Во вторых, самое главное, в моем случае, что я уже не стал переписывать  это работе с переводом из BCD и обратно. В моем случае(динамическая индикация на 4 разряда) было бы куда выгоднее использовать сразу значения в BCD и получать значения простым смещением, чем выделать разряды для индикации делением на цело и остатком.

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

Дописанную библиотеку выкладывать не буду, потому что это порнография с точки зрения ее автора. Я думаю, если много кода уже не написано под эту либу, лучше взяь другую.