Closed igor-iOS closed 8 years ago
Please provide a link to the DS3231 shield being used.
The other difference from my code in issue #5 is the addition of calls to digitalWrite() and Serial.println() in the ISR. These have absolutely no business in an ISR. I'm surprised that it works at all. Actually digitalWrite() would probably be OK in the ISR, but I'd move it out to loop() anyway as there is no downside to doing so.
Secondly, since Alarm2 is not used, we must ensure that it is disabled. Else it will probably trigger at some unexpected time and hold the interrupt line low.
This code works for me.
#include <DS3232RTC.h> //http://github.com/JChristensen/DS3232RTC
#include <Streaming.h> //http://arduiniana.org/libraries/streaming/
#include <Time.h> //http://playground.arduino.cc/Code/Time
#include <Wire.h> //http://arduino.cc/en/Reference/Wire
#define SQW_PIN 2
void setup(void)
{
Serial.begin(9600);
// while(!Serial);
//setSyncProvider() causes the Time library to synchronize with the
//external RTC by calling RTC.get() every five minutes by default.
setSyncProvider(RTC.get);
Serial << "RTC Sync";
if (timeStatus() != timeSet){
Serial << " FAIL!";
}
Serial << endl;
pinMode(13, OUTPUT);
printDateTime( RTC.get() );
Serial << endl;
//Disable the default square wave of the SQW pin.
RTC.squareWave(SQWAVE_NONE);
//Attach an interrupt on the falling of the SQW pin.
//digitalWrite(SQW_PIN, HIGH); //redundant with the following line
pinMode(SQW_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(SQW_PIN), alarmIsr, FALLING);
RTC.setAlarm(ALM1_EVERY_SECOND, 1, 0, 0, 1); //daydate parameter should be between 1 and 7
RTC.alarm(ALARM_1); //ensure RTC interrupt flag is cleared
RTC.alarmInterrupt(ALARM_1, true);
RTC.alarmInterrupt(ALARM_2, false);
RTC.alarm(ALARM_2); //ensure RTC interrupt flag is cleared
}
volatile boolean alarmIsrWasCalled = false;
void alarmIsr()
{
// digitalWrite(13, !digitalRead(13));
// Serial.println("!");
// RTC.alarm(ALARM_1);
alarmIsrWasCalled = true;
}
void loop(void)
{
if (alarmIsrWasCalled){
if (RTC.alarm(ALARM_1)) {
digitalWrite(13, !digitalRead(13));
printDateTime( RTC.get() );
Serial << " --> Alarm 1!" << endl;
}
alarmIsrWasCalled = false;
}
}
void printDateTime(time_t t)
{
Serial << ((day(t)<10) ? "0" : "") << _DEC(day(t)) << ' ';
Serial << monthShortStr(month(t)) << " " << _DEC(year(t)) << ' ';
Serial << ((hour(t)<10) ? "0" : "") << _DEC(hour(t)) << ':';
Serial << ((minute(t)<10) ? "0" : "") << _DEC(minute(t)) << ':';
Serial << ((second(t)<10) ? "0" : "") << _DEC(second(t));
}
Regarding pullup resistors, one is required for the interrupt signal but the code enables the internal pullup and this is sufficient.
Pullups are also required on the I2C SDA and SCL lines. The Wire library enables the internal pullups, and while this will often work, the internal pullups are technically not strong enough, so external pullups must be added. When using the default I2C bus speed of 100kHz, 10K is OK but 4.7K is better. When running the bus at 400kHz, I use 2.2K.
When multiple I2C devices are on the bus, only one pair of pullups is required. When using breakout boards, be sure to check if each has its own pullups. Duplicate pullups are OK as long as the resistance (the resistors would be in parallel) doesn't fall too low and overload the GPIO pins.
Sorry, I was too busy and could not reply. Yes, I know about the fact that ISR procedures should contatin as less code as possible, and it is also strange for me that it works in some cases. I also attemted to add
detachInterrupt(digitalPinToInterrupt(SQW_PIN));
in setup() function before setting alarms. Seems that it helped. Thanks, I also turned off alarm2, seems to wrk fine. About the shield - I bought it in a local store, so the description is in russian. But here is how it looks: http://www.kosmodrom.com.ua/pic/DS3231-BIG-MODUL-1.jpg Possibly, zs-042 is some chinese noname breakout board for DS3231.
Hi, guys I'm using a very simple sketch where alarm1 fires every second and alarm2 is not used. This is the only difference from @JChristensen's code form this issue: https://github.com/JChristensen/DS3232RTC/issues/5 . I still cannot specify the exact case when it happens, but here's what I found: If I switch the power of the whole board off/on or press "reset" button on Arduino, randomly in some cases alarms stop firing. If I only switch the power of ds3232 (in real, ds3231) shield, alarms always stop firing in all cases. The battery is installed and I've checked the correct work by getting time from the RTC after power off/on and it was definitely correct. Unfortunately, I don't have an oscilloscope to check whether it's some signal on SQW pin or not. What I also found is that if we pull of the jumper from SQW to Arduino INT pin, and then reconnect it, program starts to work correctly. This is really strange for me and I cannot find the solution. I checked this on both power from 5V and 3.3V. Maybe I should use pull-up resistors somewhere? I also tested this on Arduino Micro and Arduino Mega1280, with different interrupt inputs, but result is still the same. I tried to use SQWAVE_1_HZ instead of alarm1, the signal is also handled in the interrupt vector. Made all the types of power switches that are mentioned above, and all works fine constantly. So I guess the problem is about resetting the alarm flags, but have no idea what to add and where.