Browse files

pic32 RTC initialised with NTP through WiFly

pic32 RTC initialised with NTP through WiFly
  • Loading branch information...
1 parent 293f962 commit e3b43a25431511302495b78b8ddd3faf83a6537f rei-vilo committed Jan 10, 2012
Showing with 625 additions and 0 deletions.
  1. +192 −0 Examples/NTP_Clock/NTP_Clock.pde
  2. +307 −0 Examples/NTP_Clock/Time.cpp
  3. +126 −0 Examples/NTP_Clock/Time.h
View
192 Examples/NTP_Clock/NTP_Clock.pde
@@ -0,0 +1,192 @@
+//
+// Double Clock
+//
+// NTP time through WiFly to initialise PIC32 internal clock
+//
+// © http://sites.google.com/site/vilorei
+// CC = BY NC SA
+//
+//
+// *** WiFly configuration
+//
+// set uart baud 38400
+// set wlan auth 3
+// set wlan channel 0
+// set wlan ssid "your LAN name"
+// set wlan phrase "your LAN key"
+// set wlan hide 1
+// set ip dhcp 1
+// set wlan join 1
+// save
+// reboot
+//
+// See
+// User Manual and Command Reference 802.11 b/g Wireless LAN Modules
+// WIFLY GSX
+// RN-131G, RN-131C, RN-134, RN-121, RN-123 & RN-125, RN-370
+// from
+// Roving Networks http://www.rovingnetworks.com
+//
+// *** for Unix -> date time conversion
+// time.c - low level time and date functions
+// Copyright (c) Michael Margolis 2009
+//
+//
+// *** pic32_RTC
+//
+// © http://sites.google.com/site/vilorei
+// CC = BY NC SA
+//
+// Jun 19, 2011 version 1 - initial release
+// Nov 21, 2011 version 2 - all functions made private
+// to avoid collusion between pic32_RTC and I2C_Clock
+//
+// based on Paul_L chipKITRTCC library
+//
+// Additional 32.768 kHz crystal required.
+//
+// See
+// Section 6: Oscillators
+// Section 29: Real-Time Clock and Calendar (RTCC)
+// from
+// PIC32 Family Reference Manual on Microchip website
+//
+
+#include "pic32_RTC.h"
+#include "time.h"
+
+pic32_RTC myRTC;
+time_t myTime;
+
+
+void setup() {
+ Serial.begin(19200);
+ Serial.print("\n\n\n***\n");
+
+ Serial.print("\n");
+ Serial.print("* NTP acquisition");
+
+ Serial1.begin(38400);
+ delay(200);
+
+ // exit previous command mode, if any
+ Serial1.print("exit\r");
+ delay(100);
+ Serial1.flush();
+
+ // enter command mode
+ Serial1.print("$$$");
+ while (!Serial1.available());
+ Serial1.flush();
+
+ Serial1.print("show t t\r");
+ while (!Serial1.available());
+
+ uint8_t c;
+ boolean flagLoop = false;
+ boolean flagRTC = false;
+ uint8_t offset = 0;
+ char buffer[6];
+ for (int i=0; i<6; i++) buffer[i]=0;
+
+ while ( (flagLoop==false) && (Serial1.available()) ) {
+ c = Serial1.read();
+ delay(1);
+
+ switch(c) {
+ case '\r':
+ case '\n': // new line
+ if (flagRTC) {
+ flagLoop = true;
+ }
+ else {
+ offset = 0;
+ for (int i=0; i<6; i++) buffer[i]=0;
+ flagRTC = false;
+ }
+ break;
+
+ case '=': // first term
+ if (strcmp(buffer, "RTC")==0) {
+ flagRTC = true;
+ myTime = 0;
+ }
+ break;
+
+ default:
+ if (flagRTC) {
+ myTime *= 10;
+ myTime += (c-0x30);
+ }
+ else {
+ buffer[offset] = c;
+ offset++;
+ }
+ }
+ }
+
+ if (!flagLoop) {
+ Serial.print("\n Error \n");
+ }
+ else {
+ Serial.print("\n year \t");
+ Serial.print(year(myTime), DEC);
+ Serial.print("\n month \t");
+ Serial.print(month(myTime), DEC);
+ Serial.print("\n day \t");
+ Serial.print(day(myTime), DEC);
+
+ Serial.print("\n hour \t");
+ Serial.print(hour(myTime), DEC);
+ Serial.print("\n minute \t");
+ Serial.print(minute(myTime), DEC);
+ Serial.print("\n second \t");
+ Serial.print(second(myTime), DEC);
+ Serial.print("\n");
+
+ myRTC.set(year(myTime), month(myTime), day(myTime), hour(myTime), minute(myTime), second(myTime));
+
+ Serial.print("\n");
+ Serial.print("* pic32 RTC");
+ Serial.print("\n");
+
+ Serial.print(myRTC.WhoAmI());
+ Serial.print("\n");
+ myRTC.get();
+ Serial.print(myRTC.dayWeek());
+ Serial.print("\t");
+ Serial.print(myRTC.date());
+ Serial.print("\t");
+ Serial.print(myRTC.time());
+ Serial.print("\n");
+ }
+
+ // flush Serial1 and potential messages
+ Serial1.flush();
+
+ // exit command mode
+ Serial1.print("exit\r");
+ delay(100);
+ Serial1.flush();
+
+
+}
+
+void loop() {
+ myRTC.get();
+
+ Serial.print(myRTC.dayWeek());
+ Serial.print("\t");
+ Serial.print(myRTC.date());
+ Serial.print("\t");
+ Serial.print(myRTC.time());
+
+ Serial.print("\n");
+ delay(800);
+}
+
+
+
+
+
+
View
307 Examples/NTP_Clock/Time.cpp
@@ -0,0 +1,307 @@
+/*
+ time.c - low level time and date functions
+ Copyright (c) Michael Margolis 2009
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ 6 Jan 2010 - initial release
+ 12 Feb 2010 - fixed leap year calculation error
+ 1 Nov 2010 - fixed setTime bug (thanks to Korman for this)
+*/
+
+//#if ARDUINO >= 100
+//#include <Arduino.h>
+//#else
+#include <WProgram.h>
+//#endif
+
+#include "Time.h"
+
+static tmElements_t tm; // a cache of time elements
+static time_t cacheTime; // the time the cache was updated
+static time_t syncInterval = 300; // time sync will be attempted after this many seconds
+
+void refreshCache( time_t t){
+ if( t != cacheTime)
+ {
+ breakTime(t, tm);
+ cacheTime = t;
+ }
+}
+
+int hour() { // the hour now
+ return hour(now());
+}
+
+int hour(time_t t) { // the hour for the given time
+ refreshCache(t);
+ return tm.Hour;
+}
+
+int hourFormat12() { // the hour now in 12 hour format
+ return hourFormat12(now());
+}
+
+int hourFormat12(time_t t) { // the hour for the given time in 12 hour format
+ refreshCache(t);
+ if( tm.Hour == 0 )
+ return 12; // 12 midnight
+ else if( tm.Hour > 12)
+ return tm.Hour - 12 ;
+ else
+ return tm.Hour ;
+}
+
+uint8_t isAM() { // returns true if time now is AM
+ return !isPM(now());
+}
+
+uint8_t isAM(time_t t) { // returns true if given time is AM
+ return !isPM(t);
+}
+
+uint8_t isPM() { // returns true if PM
+ return isPM(now());
+}
+
+uint8_t isPM(time_t t) { // returns true if PM
+ return (hour(t) >= 12);
+}
+
+int minute() {
+ return minute(now());
+}
+
+int minute(time_t t) { // the minute for the given time
+ refreshCache(t);
+ return tm.Minute;
+}
+
+int second() {
+ return second(now());
+}
+
+int second(time_t t) { // the second for the given time
+ refreshCache(t);
+ return tm.Second;
+}
+
+int day(){
+ return(day(now()));
+}
+
+int day(time_t t) { // the day for the given time (0-6)
+ refreshCache(t);
+ return tm.Day;
+}
+
+int weekday() { // Sunday is day 1
+ return weekday(now());
+}
+
+int weekday(time_t t) {
+ refreshCache(t);
+ return tm.Wday;
+}
+
+int month(){
+ return month(now());
+}
+
+int month(time_t t) { // the month for the given time
+ refreshCache(t);
+ return tm.Month;
+}
+
+int year() { // as in Processing, the full four digit year: (2009, 2010 etc)
+ return year(now());
+}
+
+int year(time_t t) { // the year for the given time
+ refreshCache(t);
+ return tmYearToCalendar(tm.Year);
+}
+
+/*============================================================================*/
+/* functions to convert to and from system time */
+/* These are for interfacing with time serivces and are not normally needed in a sketch */
+
+// leap year calulator expects year argument as years offset from 1970
+#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
+
+static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0
+
+void breakTime(time_t time, tmElements_t &tm){
+// break the given time_t into time components
+// this is a more compact version of the C library localtime function
+// note that year is offset from 1970 !!!
+
+ uint8_t year;
+ uint8_t month, monthLength;
+ unsigned long days;
+
+ tm.Second = time % 60;
+ time /= 60; // now it is minutes
+ tm.Minute = time % 60;
+ time /= 60; // now it is hours
+ tm.Hour = time % 24;
+ time /= 24; // now it is days
+ tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1
+
+ year = 0;
+ days = 0;
+ while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
+ year++;
+ }
+ tm.Year = year; // year is offset from 1970
+
+ days -= LEAP_YEAR(year) ? 366 : 365;
+ time -= days; // now it is days in this year, starting at 0
+
+ days=0;
+ month=0;
+ monthLength=0;
+ for (month=0; month<12; month++) {
+ if (month==1) { // february
+ if (LEAP_YEAR(year)) {
+ monthLength=29;
+ } else {
+ monthLength=28;
+ }
+ } else {
+ monthLength = monthDays[month];
+ }
+
+ if (time >= monthLength) {
+ time -= monthLength;
+ } else {
+ break;
+ }
+ }
+ tm.Month = month + 1; // jan is month 1
+ tm.Day = time + 1; // day of month
+}
+
+time_t makeTime(tmElements_t &tm){
+// assemble time elements into time_t
+// note year argument is offset from 1970 (see macros in time.h to convert to other formats)
+// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9
+
+ int i;
+ time_t seconds;
+
+ // seconds from 1970 till 1 jan 00:00:00 of the given year
+ seconds= tm.Year*(SECS_PER_DAY * 365);
+ for (i = 0; i < tm.Year; i++) {
+ if (LEAP_YEAR(i)) {
+ seconds += SECS_PER_DAY; // add extra days for leap years
+ }
+ }
+
+ // add days for this year, months start from 1
+ for (i = 1; i < tm.Month; i++) {
+ if ( (i == 2) && LEAP_YEAR(tm.Year)) {
+ seconds += SECS_PER_DAY * 29;
+ } else {
+ seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0
+ }
+ }
+ seconds+= (tm.Day-1) * SECS_PER_DAY;
+ seconds+= tm.Hour * SECS_PER_HOUR;
+ seconds+= tm.Minute * SECS_PER_MIN;
+ seconds+= tm.Second;
+ return seconds;
+}
+/*=====================================================*/
+/* Low level system time functions */
+
+static time_t sysTime = 0;
+static time_t prevMillis = 0;
+static time_t nextSyncTime = 0;
+static timeStatus_t Status = timeNotSet;
+
+getExternalTime getTimePtr; // pointer to external sync function
+//setExternalTime setTimePtr; // not used in this version
+
+#ifdef TIME_DRIFT_INFO // define this to get drift data
+time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync
+#endif
+
+
+time_t now(){
+ while( millis() - prevMillis >= 1000){
+ sysTime++;
+ prevMillis += 1000;
+#ifdef TIME_DRIFT_INFO
+ sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift
+#endif
+ }
+ if(nextSyncTime <= sysTime){
+ if(getTimePtr != 0){
+ time_t t = getTimePtr();
+ if( t != 0)
+ setTime(t);
+ else
+ Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync;
+ }
+ }
+ return sysTime;
+}
+
+void setTime(time_t t){
+#ifdef TIME_DRIFT_INFO
+ if(sysUnsyncedTime == 0)
+ sysUnsyncedTime = t; // store the time of the first call to set a valid Time
+#endif
+
+ sysTime = t;
+ nextSyncTime = t + syncInterval;
+ Status = timeSet;
+ prevMillis = millis(); // restart counting from now (thanks to Korman for this fix)
+}
+
+void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
+ // year can be given as full four digit year or two digts (2010 or 10 for 2010);
+ //it is converted to years since 1970
+ if( yr > 99)
+ yr = yr - 1970;
+ else
+ yr += 30;
+ tm.Year = yr;
+ tm.Month = mnth;
+ tm.Day = dy;
+ tm.Hour = hr;
+ tm.Minute = min;
+ tm.Second = sec;
+ setTime(makeTime(tm));
+}
+
+void adjustTime(long adjustment){
+ sysTime += adjustment;
+}
+
+timeStatus_t timeStatus(){ // indicates if time has been set and recently synchronized
+ return Status;
+}
+
+void setSyncProvider( getExternalTime getTimeFunction){
+ getTimePtr = getTimeFunction;
+ nextSyncTime = sysTime;
+ now(); // this will sync the clock
+}
+
+void setSyncInterval(time_t interval){ // set the number of seconds between re-sync
+ syncInterval = interval;
+}
View
126 Examples/NTP_Clock/Time.h
@@ -0,0 +1,126 @@
+/*
+ time.h - low level time and date functions
+*/
+
+/*
+ July 3 2011 - fixed elapsedSecsThisWeek macro (thanks Vincent Valdy for this)
+ - fixed daysToTime_t macro (thanks maniacbug)
+*/
+
+#ifndef _Time_h
+#define _Time_h
+
+#include <inttypes.h>
+
+typedef unsigned long time_t;
+
+typedef enum {timeNotSet, timeNeedsSync, timeSet
+} timeStatus_t ;
+
+typedef enum {
+ dowInvalid, dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday
+} timeDayOfWeek_t;
+
+typedef enum {
+ tmSecond, tmMinute, tmHour, tmWday, tmDay,tmMonth, tmYear, tmNbrFields
+} tmByteFields;
+
+typedef struct {
+ uint8_t Second;
+ uint8_t Minute;
+ uint8_t Hour;
+ uint8_t Wday; // day of week, sunday is day 1
+ uint8_t Day;
+ uint8_t Month;
+ uint8_t Year; // offset from 1970;
+} tmElements_t, TimeElements, *tmElementsPtr_t;
+
+//convenience macros to convert to and from tm years
+#define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year
+#define CalendarYrToTm(Y) ((Y) - 1970)
+#define tmYearToY2k(Y) ((Y) - 30) // offset is from 2000
+#define y2kYearToTm(Y) ((Y) + 30)
+
+typedef time_t(*getExternalTime)();
+//typedef void (*setExternalTime)(const time_t); // not used in this version
+
+
+/*==============================================================================*/
+/* Useful Constants */
+#define SECS_PER_MIN (60UL)
+#define SECS_PER_HOUR (3600UL)
+#define SECS_PER_DAY (SECS_PER_HOUR * 24UL)
+#define DAYS_PER_WEEK (7UL)
+#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK)
+#define SECS_PER_YEAR (SECS_PER_WEEK * 52UL)
+#define SECS_YR_2000 (946684800UL) // the time at the start of y2k
+
+/* Useful Macros for getting elapsed time */
+#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
+#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
+#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
+#define dayOfWeek(_time_) ((( _time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday
+#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY) // this is number of days since Jan 1 1970
+#define elapsedSecsToday(_time_) (_time_ % SECS_PER_DAY) // the number of seconds since last midnight
+// The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971
+// Always set the correct time before settting alarms
+#define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day
+#define nextMidnight(_time_) ( previousMidnight(_time_) + SECS_PER_DAY ) // time at the end of the given day
+#define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY) ) // note that week starts on day 1
+#define previousSunday(_time_) (_time_ - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time
+#define nextSunday(_time_) ( previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time
+
+
+/* Useful Macros for converting elapsed time to a time_t */
+#define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN)
+#define hoursToTime_t ((H)) ( (H) * SECS_PER_HOUR)
+#define daysToTime_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011
+#define weeksToTime_t ((W)) ( (W) * SECS_PER_WEEK)
+
+/*============================================================================*/
+/* time and date functions */
+int hour(); // the hour now
+int hour(time_t t); // the hour for the given time
+int hourFormat12(); // the hour now in 12 hour format
+int hourFormat12(time_t t); // the hour for the given time in 12 hour format
+uint8_t isAM(); // returns true if time now is AM
+uint8_t isAM(time_t t); // returns true the given time is AM
+uint8_t isPM(); // returns true if time now is PM
+uint8_t isPM(time_t t); // returns true the given time is PM
+int minute(); // the minute now
+int minute(time_t t); // the minute for the given time
+int second(); // the second now
+int second(time_t t); // the second for the given time
+int day(); // the day now
+int day(time_t t); // the day for the given time
+int weekday(); // the weekday now (Sunday is day 1)
+int weekday(time_t t); // the weekday for the given time
+int month(); // the month now (Jan is month 1)
+int month(time_t t); // the month for the given time
+int year(); // the full four digit year: (2009, 2010 etc)
+int year(time_t t); // the year for the given time
+
+time_t now(); // return the current time as seconds since Jan 1 1970
+void setTime(time_t t);
+void setTime(int hr,int min,int sec,int day, int month, int yr);
+void adjustTime(long adjustment);
+
+/* date strings */
+#define dt_MAX_STRING_LEN 9 // length of longest date string (excluding terminating null)
+char* monthStr(uint8_t month);
+char* dayStr(uint8_t day);
+char* monthShortStr(uint8_t month);
+char* dayShortStr(uint8_t day);
+
+/* time sync functions */
+timeStatus_t timeStatus(); // indicates if time has been set and recently synchronized
+void setSyncProvider( getExternalTime getTimeFunction); // identify the external time provider
+void setSyncInterval(time_t interval); // set the number of seconds between re-sync
+
+/* low level functions to convert to and from system time */
+void breakTime(time_t time, tmElements_t &tm); // break time_t into elements
+time_t makeTime(tmElements_t &tm); // convert time elements into time_t
+
+
+#endif /* _Time_h */
+

0 comments on commit e3b43a2

Please sign in to comment.