MicroBit clock based on DS3231

Dependencies:   ds3231 microbit

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 
00002 /*
00003 The MIT License (MIT)
00004 
00005 Copyright (c) 2016 British Broadcasting Corporation.
00006 This software is provided by Lancaster University by arrangement with the BBC.
00007 
00008 Permission is hereby granted, free of charge, to any person obtaining a
00009 copy of this software and associated documentation files (the "Software"),
00010 to deal in the Software without restriction, including without limitation
00011 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00012 and/or sell copies of the Software, and to permit persons to whom the
00013 Software is furnished to do so, subject to the following conditions:
00014 
00015 The above copyright notice and this permission notice shall be included in
00016 all copies or substantial portions of the Software.
00017 
00018 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00021 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00022 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00023 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00024 DEALINGS IN THE SOFTWARE.
00025 
00026 DS3231 libs
00027 * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
00028 *
00029 * Permission is hereby granted, free of charge, to any person obtaining a
00030 * copy of this software and associated documentation files (the "Software"),
00031 * to deal in the Software without restriction, including without limitation
00032 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00033 * and/or sell copies of the Software, and to permit persons to whom the
00034 * Software is furnished to do so, subject to the following conditions:
00035 *
00036 * The above copyright notice and this permission notice shall be included
00037 * in all copies or substantial portions of the Software.
00038 *
00039 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00040 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00041 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00042 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00043 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00044 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00045 * OTHER DEALINGS IN THE SOFTWARE.
00046 *
00047 * Except as contained in this notice, the name of Maxim Integrated
00048 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00049 * Products, Inc. Branding Policy.
00050 *
00051 * The mere transfer of this software does not imply any licenses
00052 * of trade secrets, proprietary technology, copyrights, patents,
00053 * trademarks, maskwork rights, or any other form of intellectual
00054 * property whatsoever. Maxim Integrated Products, Inc. retains all
00055 * ownership rights.
00056 **********************************************************************
00057 Copyright  David Wright 2016. DAW9000.
00058 Feel free to copy, ammend , or do what you will but a shout out would be nice :)
00059 */
00060 
00061 /* This program uses the Maxim Integrated DS3231 library to create a BBC MicroBit
00062 Clock. Requires a DS3231 Real Time clock connected to pin 19 and 20.
00063 
00064 Recommended that an edge connector is used for DS3231 connection.
00065 
00066 Program will display :-
00067     Date then Time then Temp (from DS3231 not MicroBit as it seems for
00068     accurate as to ambient temp.)
00069     Pressing Button B and keeping it pressed between rotations ie at the end
00070     of each display cycle will change mode cyclically.
00071     1. Date, Time, Temp
00072     2. Date only.
00073     3. Time only.
00074     4. Temp only.
00075     5. Time and Temp
00076 I am sure better things can be done here! Improvements welcome.
00077 
00078 Pressing Buttons A and B together and keeping pressed as above will take
00079 you into clock setting mode.
00080 Clock is set :-
00081 Year, Month, Day, Hour, Minute, Second, Day of Week (1 to 7 eg Sun=7 but you can
00082 make any day the start of week ie Sun=1).
00083 Setting is done after DATE and again after TIME. So if only setting date
00084 you can abort after the msg "Date Set".
00085 
00086 If in setting mode abort changes by powering off at any time.
00087 
00088 This again can be improved .... not the easiest to set date and time with
00089 no keypad and limited screen!
00090 
00091 DS3231 has 2 alarms, so alarm clock feature with speaker/music attached to
00092 MicroBit is a good future mod.
00093 !
00094 
00095 */
00096 #include "MicroBit.h"
00097 #include "ds3231.h"
00098 MicroBit uBit;
00099 int iss,imm,ihh,idow,iDD,iMM,iYY;
00100 ManagedString ss,mm,hh,dOw,DD,MM,YY, txtMonth, txtDay, tempOut;
00101 ManagedString tsep = ":";
00102 ManagedString dsep = "/";
00103 Ds3231 mRTC(I2C_SDA0, I2C_SCL0);
00104 uint16_t rtn;
00105 uint16_t rval;
00106 uint16_t rtn1;
00107 ds3231_time_t mTime = {0,0,0,false,false};  // 24 hr mode -  seconds,minutes,hours,am_pm(pm=1,am=0),mode(0=24,1=12hr)
00108 ds3231_calendar_t mCalendar; // day(day of week),date(day),month,year
00109 ds3231_alrm_t mAlarm; // seconds,minutes,hours, day of week, day, rate1,rate2,rate3,rate4,am_pm,mode,day_date(use dayofweek=0,use date day=1)
00110 //Seconds and am1 not used for alarm2
00111 uint16_t mTemp; // raw temp data
00112 uint16_t DOW; //day of week
00113 char * weekdaya[7]= {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"} ;
00114 char * montha[12]= {"January","February","March","April","May","June","July","August","September","October","November","December"};
00115 int displayMode = 0;
00116 
00117 // predeclare functions
00118 void getTimeAndDate();
00119 void setTimeAndDate();
00120 void displayTimeAndDate();
00121 void displayDate();
00122 void displayTime();
00123 void displayTemp();
00124 void displaySeconds();
00125 
00126 
00127 void getTimeAndDate()
00128 {
00129     // get date and time and populate data vars
00130     mTime.mode=false; //24 hour
00131     rval = mRTC.get_time(&mTime); // get time
00132     mTemp = mRTC.get_temperature(); // get temperature
00133     rtn = mRTC.get_calendar(&mCalendar); //get date
00134     YY = (int)(mCalendar.year + 2000); // 4 digit
00135     txtMonth = montha[((int)mCalendar.month)-1];
00136     txtDay = weekdaya[((int)mCalendar.day)-1];
00137     iss = (int)mTime.seconds;
00138     imm = (int)mTime.minutes;
00139     ihh = (int)mTime.hours;
00140     idow = (int)mCalendar.day;
00141     iDD = (int)mCalendar.date;
00142     iMM = (int)mCalendar.month;
00143     iYY = (int)mCalendar.year;
00144     ManagedString s1 (iss / 10);
00145     ManagedString s2 (iss % 10);
00146     ss = s1 + s2;
00147     ManagedString m1 (imm / 10);
00148     ManagedString m2 (imm % 10);
00149     mm = m1 + m2;
00150     ManagedString h1 (ihh / 10);
00151     ManagedString h2 (ihh % 10);
00152     hh = h1 + h2;
00153     ManagedString D1 (iDD / 10);
00154     ManagedString D2 (iDD % 10);
00155     DD = D1 + D2;
00156     ManagedString M1 (iMM / 10);
00157     ManagedString M2 (iMM % 10);
00158 
00159     // lets setup the Temperature here too
00160     mTemp = mTemp / 256;
00161     ManagedString tmp(mTemp);
00162     tempOut=(tmp + "degC");
00163 
00164 
00165 }
00166 void setTimeAndDate()
00167 {
00168     int rVal;
00169     int setYear, setMonth, setDay, setDOW, setHours, setMinutes, setSeconds;
00170     bool setMode, setAM_PM;
00171     getTimeAndDate(); // get latest
00172 
00173     uBit.display.clear();
00174     uBit.display.scroll(" Set Date & Time?");
00175     uBit.sleep(1000);
00176     uBit.display.clear();
00177     uBit.display.scroll(" Btn A & Btn B to change values");
00178 
00179     setYear = iYY;
00180     uBit.display.scroll("Year(yy):" + setYear);
00181     while (!(uBit.buttonAB.isPressed() )) {
00182         if (uBit.buttonA.isPressed()) setYear--;
00183         if (uBit.buttonB.isPressed()) setYear++;
00184         if (setYear < 0) setYear=99;
00185         if (setYear > 99) setYear=0;
00186         uBit.display.scroll(setYear);
00187     }
00188 
00189     setMonth = iMM;
00190     uBit.display.scroll("Month:" + setMonth);
00191     while (!(uBit.buttonAB.isPressed() )) {
00192         if (uBit.buttonA.isPressed()) setMonth--;
00193         if (uBit.buttonB.isPressed()) setMonth++;
00194         if (setMonth < 1) setMonth=12;
00195         if (setMonth > 12) setMonth=1;
00196         uBit.display.scroll(setMonth);
00197     }
00198 
00199     setDay = iDD;
00200     uBit.display.scroll("Day:" + setDay);
00201     while (!(uBit.buttonAB.isPressed())) {
00202         if (uBit.buttonA.isPressed()) setDay--;
00203         if (uBit.buttonB.isPressed()) setDay++;
00204         if (setDay < 1) setDay=31;
00205         if (setDay > 31) setDay=1; // make better using month?
00206         uBit.display.scroll(setDay);
00207     }
00208 
00209     setDOW = idow;
00210     uBit.display.scroll("Day of week(1-7):" + setDOW);
00211     while ( !(uBit.buttonAB).isPressed()) {
00212         if ( uBit.buttonA.isPressed() ) setDOW--;
00213         if (uBit.buttonB.isPressed())   setDOW++;
00214         if (setDOW < 1) setDOW=7;
00215         if (setDOW > 7) setDOW=1;
00216         uBit.display.scroll(setDOW);
00217     }
00218 
00219     uBit.display.scroll("Press AB to set Date");
00220     //  uBit.display.scroll("Press RESET to abort"); too much text!!
00221     while ( !(uBit.buttonAB.isPressed()) ) {
00222         uBit.display.scroll(setDay);
00223         uBit.display.scroll("/");
00224         uBit.display.scroll(setMonth);
00225         uBit.display.scroll("/");
00226         uBit.display.scroll(setYear);
00227     }
00228 
00229     if (uBit.buttonAB.isPressed()) {
00230         // set date
00231         mCalendar.day = setDOW;
00232         mCalendar.date = setDay;
00233         mCalendar.month = setMonth;
00234         mCalendar.year = setYear;
00235         rVal = mRTC.set_calendar(mCalendar);
00236     }
00237     if (rVal == 0) uBit.display.scroll("Date set.");
00238     else uBit.display.scroll("Oops something went BANG!");
00239     /* 12/24 hour setting is a bit of a palava for a MicroBit screen so
00240        limit to 24 hour clock....
00241         uBit.display.scroll("12 or 24 hour clock?");
00242         setMode = false; // default 24 hour
00243         setAM_PM = false; // default
00244         while ( !(uBit.buttonA.isPressed()) or !(uBit.buttonB.isPressed())) {
00245             uBit.display.scroll("Press A for 24 or B for 12");
00246         }
00247         if (uBit.buttonA.isPressed()) {
00248             setMode = true; //12 hr clock
00249             // am or pm?
00250             while ( !(uBit.buttonA.isPressed()) or !(uBit.buttonB.isPressed())) {
00251                 uBit.display.scroll("OK 12hr - AM or PM?");
00252                 uBit.display.scroll("A for AM or B for PM");
00253             }
00254             if (uBit.buttonA.isPressed()) setAM_PM = true;
00255             if (uBit.buttonB.isPressed()) setAM_PM = false;
00256         }
00257         if (uBit.buttonB.isPressed()) setMode = false; */
00258     setMode = false; // 24 hour clock only
00259     //if ((setMode==true) and (ihh>12)) setHours = ihh-12;
00260     // else setHours = ihh;
00261     setHours = ihh;
00262     uBit.display.scroll("Hours:" + setHours);
00263     while ( !(uBit.buttonAB).isPressed()) {
00264         if ( uBit.buttonA.isPressed() ) setHours--;
00265         if (uBit.buttonB.isPressed())   setHours++;
00266         if (setHours < 1) setHours=24;
00267         if (setHours > 24) setHours=1;
00268         //  if ((setMode==true) and (ihh>12))  setHours = ihh-12;
00269         uBit.display.scroll(setHours);
00270     }
00271 
00272 
00273     setMinutes = imm;
00274     uBit.display.scroll("Minutes:" + setMinutes);
00275     while ( !(uBit.buttonAB).isPressed()) {
00276         if ( uBit.buttonA.isPressed() ) setMinutes--;
00277         if (uBit.buttonB.isPressed())   setMinutes++;
00278         if (setMinutes < 0) setMinutes=59;
00279         if (setMinutes > 59) setMinutes=0;
00280         uBit.display.scroll(setMinutes);
00281     }
00282     /* Lets not set seconds, assume zero second for setting
00283        setSeconds = iss;
00284        uBit.display.scroll("Seconds :" + setSeconds);
00285        while ( !(uBit.buttonAB).isPressed()) {
00286            if ( uBit.buttonA.isPressed() ) {
00287                setSeconds--;
00288            }
00289            if (uBit.buttonB.isPressed()) {
00290                setSeconds++;
00291            }
00292            if (setSeconds < 0) setSeconds=59;
00293            if (setSeconds > 59) setSeconds=0;
00294            uBit.display.scroll(setSeconds);
00295       */
00296     setSeconds = 0; // not user set
00297     while ( !(uBit.buttonAB).isPressed()) {
00298         uBit.display.scroll("Press AB to set the time");
00299     }
00300     if (uBit.buttonAB.isPressed()) {
00301         mTime.hours = setHours;
00302         mTime.minutes = setMinutes;
00303         mTime.seconds = setSeconds;
00304         mTime.mode = setMode;
00305         mTime.am_pm = setAM_PM;
00306         rVal = mRTC.set_time(mTime);
00307         if (rVal == 0) uBit.display.scroll("Time is set.");
00308         else uBit.display.scroll("Oops it all gone Pete Tong");
00309     }
00310 
00311 }
00312 
00313 void displayTimeAndDate()
00314 {
00315 
00316     if (displayMode == 0) {
00317         displayDate();
00318         displayTime();
00319         displayTemp();
00320     }
00321     if (displayMode == 1) {
00322         displayDate();
00323     }
00324     if (displayMode == 2) {
00325         displayTime();
00326     }
00327     if (displayMode == 3) {
00328         displayTemp();
00329     }
00330     if (displayMode == 4) {
00331         displayTime();
00332         displayTemp();
00333     }
00334 
00335 }
00336 void displayDate()
00337 {
00338     ManagedString spc(" ");
00339 
00340     ManagedString dateOut(txtDay + spc + DD + spc +  txtMonth + spc + YY);
00341 
00342     uBit.display.scroll(dateOut);
00343 
00344 
00345     uBit.sleep(1000);
00346 }
00347 void displayTime()
00348 {
00349     ManagedString timeOut(hh + tsep + mm);
00350 
00351     uBit.display.scroll(timeOut);
00352 
00353     uBit.sleep(1000);
00354 }
00355 void displayTemp()
00356 {
00357     uBit.display.scroll(tempOut);
00358 
00359 
00360     uBit.sleep(1000);
00361 }
00362 void displaySeconds()
00363 {
00364     uBit.display.scroll(iss);
00365 }
00366 
00367 
00368 
00369 int main(void)
00370 {
00371     // Initialise the micro:bit runtime.
00372     uBit.init();
00373 
00374     while (true) {
00375 
00376         getTimeAndDate();
00377         displayTimeAndDate();
00378         if (uBit.buttonB.isPressed()) {
00379             displayMode ++;
00380             if(displayMode > 4) displayMode=0;
00381         }
00382 
00383         if (uBit.buttonAB.isPressed()) setTimeAndDate();
00384     }
00385 
00386 
00387 // forever, in a power efficient sleep.
00388     release_fiber();
00389 
00390 }