Hi
I have some code here which is mostly working really well but then - sometimes, for some reason, it sets the clock to 2036. And it reliably sets it wrongly, so to speak, so I think it's a programming error.
This is the output from the serial monitor:-
Time to set the clock initially
RTC before: 2012-02-18 16:28:03
RTC after : 2012-02-18 16:28:05
Time update successful
Time to set the clock at 16:28:10
RTC before: 2012-02-18 16:28:10
RTC after : 2036-02-07 06:28:17
Time update successful
And here the code:-
#include <Bounce.h>
#include <Wire.h>
#include "RTClib.h"
#include <Servo.h>
#include <SPI.h>
#include <Ethernet.h>
#if ARDUINO < 100
#include <UDP.h>
#else
#include <EthernetUdp.h> // New from IDE 1.0
#endif
byte mac[] = {
0x00, 0x11, 0x22, 0x33, 0xFB, 0x11 };
EthernetClient client;
unsigned int localPort = 8888;
byte timeServer[] = {
193, 79, 237, 14}; // ntp1.nl.net NTP server
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte pb[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
#if ARDUINO >= 100
EthernetUDP Udp;
#endif
Servo servo1;
#define ledPin1 8 // the number of the LED pin
#define buttonPin 2 // the number of the button pin
const int pinSpeaker = 7;
int buttonState = LOW; // used to set the button state
int LedState1 = LOW; // used to set the LED state
int LedState2 = LOW; // used to set the LED state if LED was already on
long LedOnDuration = 10000; // time to keep the LED on for (10s)
long FlashRate = 400; // time to keep the LED on for (0.4s)
long previousMillis1 = 0; // will store last time LED was updated for press 1
long previousMillis2 = 0; // will store last time LED was updated for press 2
//The pips
unsigned int pip1 = 0;
unsigned int pip2 = 0;
unsigned int pip3 = 0;
unsigned int pip4 = 0;
unsigned int pip5 = 0;
unsigned int pip6 = 0;
unsigned int RTCUD = 0;
unsigned int INITIALSET = 0;
// Instantiate a Bounce object with a 20 millisecond debounce time
Bounce nursery = Bounce( buttonPin, 100);
int nurseryvalue;
RTC_DS1307 RTC;
enum {
OFF, ON, FLASH};
void setup()
{
pinMode(buttonPin,INPUT);
pinMode(ledPin1,OUTPUT);
pinMode(pinSpeaker, OUTPUT);
digitalWrite(ledPin1, OFF);
servo1.attach(6);
LedState1 = OFF;
LedState2 = OFF;
Serial.begin(57600);
Wire.begin();
RTC.begin();
Serial.println("Annunciator Panel v0.6");
Ethernet.begin(mac);
Udp.begin(localPort);
Serial.println();
if (! RTC.isrunning()) {
Serial.println("The RTC is NOT running/set!");
}
}
void loop() {
DateTime now = RTC.now();
nursery.update ( );
nurseryvalue = nursery.read();
unsigned long currentMillis = millis();
if (millis() > 30000 && INITIALSET < 1)
{
Serial.print("Time to set the clock initially");
Serial.println();
RTCUD = 1;
}
// if (now.hour() == 17 && now.minute() == 50 && now.second() == 10)
if (now.hour() == 16 && now.minute() == 28 && now.second() == 10)
{
if (RTCUD < 1)
{
Serial.print("Time to set the clock at 16:28:10");
Serial.println();
RTCUD = 1;
}
}
if (now.hour() == 16 && now.minute() == 28 && now.second() == 50)
{
if (RTCUD < 1)
{
Serial.print("Time to set the clock at 16:28:50");
Serial.println();
RTCUD = 1;
}
}
if (RTCUD == 1)
{
Serial.print("RTC before: ");
PrintDateTime(RTC.now());
Serial.println();
sendNTPpacket(timeServer);
delay(1000);
if ( Udp.available() ) {
#if ARDUINO < 100
Udp.readPacket(pb, NTP_PACKET_SIZE);
#else
Udp.read(pb, NTP_PACKET_SIZE); // New from IDE 1.0,
#endif
unsigned long t1, t2, t3, t4;
t1 = t2 = t3 = t4 = 0;
for (int i=0; i< 4; i++)
{
t1 = t1 << 8 | pb[16+i];
t2 = t2 << 8 | pb[24+i];
t3 = t3 << 8 | pb[32+i];
t4 = t4 << 8 | pb[40+i];
}
float f1,f2,f3,f4;
f1 = ((long)pb[20] * 256 + pb[21]) / 65536.0;
f2 = ((long)pb[28] * 256 + pb[29]) / 65536.0;
f3 = ((long)pb[36] * 256 + pb[37]) / 65536.0;
f4 = ((long)pb[44] * 256 + pb[45]) / 65536.0;
const unsigned long seventyYears = 2208988800UL;
t1 -= seventyYears;
t2 -= seventyYears;
t3 -= seventyYears;
t4 -= seventyYears;
t4 += 1;
if (f4 > 0.4) t4++;
RTC.adjust(DateTime(t4));
Serial.print("RTC after : ");
PrintDateTime(RTC.now());
Serial.println();
Serial.println("Time update successful");
RTCUD = 0; // RTC has been set for the morning / evening
INITIALSET = 1; // RTC has been initially set
}
else
{
Serial.println("Time update unsuccessful");
}
}
if (nurseryvalue == HIGH)
{
if (buttonState == OFF)
{
// button pressed
//===============
buttonState = ON;
if (LedState1 == OFF)
{
// the button's pressed and LED is OFF
// turn it ON
//====================================
Serial.print("button 1 pressed @");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
digitalWrite(ledPin1, ON);
LedState1 = ON;
/*servo1.write(230);
delay(1500); // wait for a second
*/
previousMillis1 = currentMillis;
}
else if (LedState1 == ON)
{
// if the button's pressed and LED is ON
// start FLASHing
//======================================
digitalWrite(ledPin1, OFF);
LedState1 = FLASH;
/*
servo1.write(230);
delay(1500);
*/
Serial.print("button 2 pressed @");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
previousMillis1 = currentMillis;
}
}
}
else
{
buttonState = OFF;
servo1.write(30);
}
if (previousMillis1 + LedOnDuration < currentMillis)
{
// If the predefined interval has elapsed for the first button press
// turn led OFF
//==================================================================
digitalWrite(ledPin1, OFF);
LedState1 = OFF;
}
if (LedState1 == FLASH && previousMillis2 + FlashRate < currentMillis)
{
// If the predefined interval has elapsed for the second button press
// make the LED 'flash' by toggling it
//===================================================================
digitalWrite(ledPin1, !digitalRead(ledPin1));
previousMillis2 = currentMillis;
}
}
void PrintDateTime(DateTime t)
{
char datestr[24];
sprintf(datestr, "%04d-%02d-%02d %02d:%02d:%02d ", t.year(), t.month(), t.day(), t.hour(), t.minute(), t.second());
Serial.print(datestr);
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(byte *address)
{
// set all bytes in the buffer to 0
memset(pb, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
pb[0] = 0b11100011; // LI, Version, Mode
pb[1] = 0; // Stratum, or type of clock
pb[2] = 6; // Polling Interval
pb[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
pb[12] = 49;
pb[13] = 0x4E;
pb[14] = 49;
pb[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
#if ARDUINO < 100
Udp.sendPacket( pb,NTP_PACKET_SIZE, address, 123); //NTP requests are to port 123
#else
// IDE 1.0 compatible:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(pb,NTP_PACKET_SIZE);
Udp.endPacket();
#endif
}
Any idea why the second setting (i.e. the timed one, not the initial set) sets the time to 2036? I think 2036 is one of the values returned in the UDP message...
THANKS