Code:
/*
OLED Display clock
*/
#include <TimeLib.h>
#include <Timezone.h>
#include <SPI.h>
#include <WiFi101.h>
#include <WiFiUdp.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1325.h>
// If using software SPI, define CLK and MOSI
#define OLED_CLK 13
#define OLED_MOSI 11
// These are neede for both hardware & softare SPI
#define OLED_CS 10
#define OLED_RESET 9
#define OLED_DC 8
// WiFi control pin
#define WIFI_EN 18
int status = WL_IDLE_STATUS;
char ssid[] = "*******"; // network SSID
char pass[] = "********"; // network password
int keyIndex = 0; // your network key Index number (needed only for WEP)
// NTP
IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
unsigned int localPort = 2390; // local port to listen for UDP packets
WiFiUDP Udp;
// hardware SPI
Adafruit_SSD1325 display(OLED_DC, OLED_RESET, OLED_CS);
// the setup routine runs once when you press reset:
void setup() {
// time source
setSyncProvider(getTeensyTime);
// sane wifi
pinMode(WIFI_EN, OUTPUT);
enableWifi();
WiFi.setPins(19, 17, 16);
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
display.begin(); // init
display.clearDisplay(); // clears the screen and buffer
if (timeStatus() != timeSet) {
fetchTime();
}
else {
Serial.println("RTC is good, no need to fetch time from network.");
}
}
// the loop routine runs over and over again forever:
void loop() {
char tstr[10] = {0};
// central European Time (Berlin, Prague)
TimeChangeRule myDST = {"CEST", Last, Sun, Mar, 2, 120}; // Daylight time = UTC + 2 hours
TimeChangeRule mySTD = {"CET", Last, Sun, Oct, 2, 60}; // Standard time = UTC + 1 hour
Timezone myTZ(myDST, mySTD);
TimeChangeRule *tcr; //pointer to the time change rule, use to get TZ abbrev /**/
time_t utc = now();
time_t local = myTZ.toLocal(utc, &tcr);/**/
snprintf(tstr, sizeof(tstr)-1, "%02d:%02d:%02d", hour(local), minute(local), second(local));
display.clearDisplay();
display.setCursor(17, 25);
printScn((const char*)(tstr), WHITE, 2);
// every day at 01:55 (am) fetch time from internet to sync things up
if ((hour(local) == 1) && (minute(local) == 55) && (second(local) == 0)) {
fetchTime();
}
delay(450); // make sure we update the display more than twice per second to see every update
}
void printScnXY(const char* text, const int& x, const int& y, const int& col, const int& txtsz) {
display.setTextSize(txtsz);
display.setTextColor(col);
display.setCursor(x, y);
display.println(text);
display.display();
}
void printScn(const char* text, const int& col, const int& txtsz) {
display.setTextSize(txtsz);
display.setTextColor(col);
display.print(text);
display.display();
}
void printlnScn(const char* text, const int& col, const int& txtsz) {
display.setTextSize(txtsz);
display.setTextColor(col);
display.println(text);
display.display();
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
void printWiFiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
printScn("IP: ", WHITE, 1);
char ipprnbuf[17] = {0};
snprintf(ipprnbuf, sizeof(ipprnbuf)-1, "%03d.%03d.%03d.%03d", ip[0], ip[1], ip[2], ip[3]);
printlnScn((const char*)(ipprnbuf), WHITE, 1);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
void fetchTime() {
connectToWifi();
getNtpTime();
}
void enableWifi() {
digitalWrite(WIFI_EN, HIGH); // turn on WiFi module
delay(1000);
}
void disableWifi() {
digitalWrite(WIFI_EN, LOW); // turn off WiFi module
delay(1000);
}
void connectToWifi() {
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
printScnXY("No WiFi device found!", 0, 0, WHITE, 1);
// don't continue:
while (true);
}
display.clearDisplay();
display.setCursor(0, 0);
// attempt to connect to WiFi network:
status = WL_IDLE_STATUS;
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
printlnScn("Connecting to WiFi...", WHITE, 1);
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
printScn("Link: ", WHITE, 1);
printlnScn(ssid, WHITE, 1);
printWiFiStatus();
Serial.println("\nStarting connection to server...");
Udp.begin(localPort);
}
void getNtpTime() {
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
if ( Udp.parsePacket() ) {
Serial.println("NTP packet received");
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = " );
Serial.println(secsSince1900);
// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
// print Unix time:
Serial.println(epoch);
setTime(epoch); // sets volatile time
Teensy3Clock.set(epoch); // supposed to set the battery backed up RTC
srtc_set(epoch); // test, to set the 'real' RTC
// print the hour, minute and second on serial console:
char tstr[10] = {0};
snprintf(tstr, sizeof(tstr)-1, "%02d:%02d:%02d", hour(epoch), minute(epoch), second(epoch));
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.println(tstr);
}
}
time_t getTeensyTime() {
Serial.println("calling getTeensyTime() / Teensy3Clock.get()...");
return Teensy3Clock.get();
}
void srtc_set(unsigned long t) {
// stop the RTC
SNVS_HPCR &= ~(SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS);
while (SNVS_HPCR & SNVS_HPCR_RTC_EN) ; // wait
// stop the SRTC
SNVS_LPCR &= ~SNVS_LPCR_SRTC_ENV;
while (SNVS_LPCR & SNVS_LPCR_SRTC_ENV); // wait
// set the SRTC
SNVS_LPSRTCLR = t << 15;
SNVS_LPSRTCMR = t >> 17;
// start the SRTC
SNVS_LPCR |= SNVS_LPCR_SRTC_ENV;
while (!(SNVS_LPCR & SNVS_LPCR_SRTC_ENV)); // wait
// start the RTC and sync it to the SRTC
SNVS_HPCR |= SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS;
}
Hope I didn't forget to provide any information and that the documentation is sufficient someone can make some sense out of it. Any help is greatly appreciated.