Demo program for the Oled display
Diff: main.cpp
- Revision:
- 1:793dbd6d6498
- Parent:
- 0:94bf5ec759da
- Child:
- 2:1eac3ea8c6e8
--- a/main.cpp Thu Jan 08 12:05:23 2015 +0000 +++ b/main.cpp Fri Jan 09 00:11:48 2015 +0000 @@ -1,53 +1,675 @@ #include "mbed.h" #include "OLED32028P1T.h" -/* - This display requires 5v, 200mA power supply, serial and reset connections are 3.3v - 5v. - Set Oled to any serial port. It is Target dependant, some platforms may not work at - higher baud rates. Set baud rates as per the list in .cpp file, NOT in the program. - Freescale KLxx MCU's will only work upt to 128k baud and some have been defined. -*/ + +OLED32028P1T oled(PTE0,PTE1,PTA12); // Oled Display tx, rx, rs +InterruptIn SignalIn(PTC1); // conection of output NON-inverting DCF module +DigitalOut SignalLED(LED3); // indicates DCF signal on Mbed + +Timer T1,T2,T3; +Ticker Ticker50ms; // DCF IRQ timer + +#define clkx 110 //this point represent the x center of the clock where maths is done +#define clky 138 //this point represent the y center of the clock where maths is done + +char timebuf[40]; +char datebuf[40]; +char paritycheck,paritym,parityu,paritydmy; +char testu,testm,testdmy,summertime; +char min,minh,minl,hourh,hourl,day,dayh,dayl,monthh,monthl,yearh,yearl; +char weekDayName[7][4] = {"Sun","Mon","Tue","Wed","Thu", "Fri","Sat"}; +char monthName[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +char MAX_DAY[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // Max days in a month for a non-leap year +char statusText[6][20] = {"Waiting Synchronise"," Wait for 21st bit ","Reading Signal data"," Checking Parity "," Last Minute Okay "," Signal error "}; +char leapSymbol[2][10] = {" ", "Leap Year"}; -OLED32028P1T oled(PTB17,PTB16,PTC0); // Oled Display TX, RX, RESET +int hour,minute,second,dayofweek,dayofmonth,month,year,nextsec,DCF; +int RTCsecond,RTCminute,RTChour,RTCdayofweek,RTCdayofmonth,RTCmonth,RTCyear; +int xbuffer,ybuffer,IRQ; +int xs,ys,xm,ym,xh,yh,x,y; +int handHour=60,handMin=75,handSec=78; //RTC clock hand sizes +int numposx=105,numposy=135; // RTC clock number screen posistion + +int start,sync,SignalStatus,nosignal,laststart,loop,interrupt_counter,dcf_sec,error_count; +int tz,rtcset,rtcset_times; +int r=255,g=255,b=255; +int draw_graph,dcf_good,signal_error,dcf_error,display; +int p_minute,p_hour,p_dayofweek,p_dayofmonth,p_month,p_year; +int dcf_array[61]; + +float angleH,angleM,angleS; +float fsecond,fminute; + +typedef unsigned char byte; + +struct tm t; + +void RTCsetclock(),RTCset(),RTCread(),RTCclock(),RTCclockdraw(),RTCclockupdate(); +void dcfISR(),dcfIRQ(),checkSIGNAL(),signal(),DCFbitprint(); +void DCFclock(),DCFloop(),DCFshowClock(),DCFtestparity(); +void DCFcheck(),bitprint(),DCFdrawgraph(); +void DCFbitmapdraw(),DCFparitycalc(),DCFbitstatus(),DCFbitstatus2(); +void DCFsetTime(); -char timebuffer[50]; -char datebuffer[50]; +struct SignalStatus { + bool is_leap; // Leap year flag (NOT actually transmitted but calculated) + bool DCFsample50; // dcf sample at 50mS into the start of the second, seocnd marker pulse + bool DCFsample150; // dcf sample at 150mS into the start of the second, bit=1 if high, 0 if low + bool DCFsample300; // dcf sample at 300mS into the start of the second, error if high + bool DCFsample500; // dcf sample at 500mS into the start of the second, error if high + bool DCFsample600; // dcf sample at 600mS into the start of the second, error if high + unsigned char frame; // Received MSF framing code 01111110 + int second; // MSF-DCF second (NOT actually transmitted but calculated) +} dcf_status; + + +// Return the maximum day in month for a given month & year +byte maxDay(byte year, byte month) +{ + byte lastday, leap; + leap = year%4 == 0 && year%100 !=0 || year%400 == 0; + lastday = MAX_DAY[month - 1]; + dcf_status.is_leap = leap > 0 ? 1 : 0; + if ((leap > 0) && (month == 2)) + lastday++; + return lastday; +} -int main() { - - oled.init(); // initialise the display. This will start at 9600 baud then auto set - // to the higher baud rate as set in the .cpp file - // This can be called at any time in the program to restart the display - // if required, display power down for instance. +int main() { + + SignalLED=1; + oled.init(); + oled.clear(); + oled.setTextBackgroundType(TEXT_OPAQUE); + oled.setFontSize(FONT12X16);oled.setFontColor(oled.toRGB(255,255,0)); + oled.setFontColor(oled.toRGB(255,255,0)); + oled.drawText(2,0,(FONT12X16),"--drawText vs. printf--",oled.toRGB(255,0,255)); + oled.drawText(2,22,(FONT5X7),"Use drawText as much as possible, it's nearly twice",oled.toRGB(255,255,255)); + oled.drawText(2,23,(FONT5X7),"as fast as printf. Make sure the serial stream is",oled.toRGB(255,255,255)); + oled.drawText(2,24,(FONT5X7),"NOT",oled.toRGB(255,0,0)); + oled.drawText(6,24,(FONT5X7),"interrupted when printing.",oled.toRGB(255,255,255)); + if (time(NULL) < 1396310400) {set_time(1396310400);} + T3.start(); - oled.clear(); - oled.setTextBackgroundType(TEXT_OPAQUE); - oled.setFontColor(WHITE); // some predefined colours + while(T3<10){ + oled.setFontColor(oled.toRGB(0,255,255)); + oled.locate (12,18); + oled.printf("Next page in %2.1f seconds ",10 - T3.read()); + + time_t seconds = time(NULL); + strftime(timebuf, 32, "RTC %I:%M:%S %p", localtime(&seconds)); + strftime(datebuf, 32, "%a %d %b %Y ", localtime(&seconds)); + + T1.start(); + oled.drawText(2,2,(FONT12X16),timebuf,oled.toRGB(255,255,0)); + oled.drawText(2,3,(FONT12X16),datebuf,oled.toRGB(255,255,0)); + T1.stop(); + + T2.start(); + oled.setFontColor(oled.toRGB(0,255,0)); + oled.setFontSize(FONT12X16); + oled.locate (2,6); + oled.printf("%s",timebuf); + oled.locate (2,7); + oled.printf("%s",datebuf); + T2.stop(); - oled.drawText(1,1,(FONT12X16)," --RTC Clock Time-- ",oled.toRGB(255,255,255)); - oled.setFontSize(FONT12X16); - oled.setFontColor(oled.toRGB(255,255,0)); + oled.setFontColor(oled.toRGB(255,255,255)); + oled.setFontSize(FONT8X12); + oled.locate (4,6); + oled.printf("drawText time %3.2f mS",T1.read()*1000);T1.reset(); + oled.locate (4,11); + oled.printf("printf time %3.2f mS",T2.read()*1000);T2.reset(); + } + T3.reset(); + while(1){ + IRQ=0; + SignalLED=1; + RTCclock(); + } + + } + +void RTCclock() +{ + while(IRQ==0){ + oled.disableTouch();oled.clear(); + oled.setTextBackgroundType (TEXT_TRANSPARENT); + RTCclockdraw(); + oled.drawTextButton(1, 200, 210,(oled.toRGB(0,100,100)),(FONT12X16),(oled.toRGB(255,255,255)), 1, 1, "DCF Clock"); + oled.drawTextButton(1, 252, 185,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, "Set RTC"); + oled.setTextBackgroundType (TEXT_OPAQUE); + oled.drawText(0,0,(FONT12X16),"RTC Clock",oled.toRGB(255,0,0)); + oled.enableTouch();oled.resetTouchArea(); + + while(IRQ==0){ + oled.setFontSize(FONT12X16);oled.locate(0,1); + oled.setFontColor(oled.toRGB(255,255,255)); + time_t seconds = time(NULL); + strftime(timebuf, 32, "%I:%M:%S %p", localtime(&seconds)); + strftime(datebuf, 32, "%a %d %b %Y ", localtime(&seconds)); + oled.drawText(11,0,(FONT12X16),timebuf,oled.toRGB(255,255,0)); + oled.drawText(11,1,(FONT12X16),datebuf,oled.toRGB(255,255,0)); + + if (seconds != nextsec) {RTCclockupdate();nextsec=seconds;} + oled.getTouch(&xbuffer,&ybuffer); + + oled.setFontSize(FONT5X7);oled.locate(40,6); // this shows touch position + oled.printf("X %03d Y %03d ",xbuffer,ybuffer); // and can be removed + + if((xbuffer>195 && xbuffer<300) && (ybuffer>205 && ybuffer<220)){DCFclock();} + if((xbuffer>240 && xbuffer<300) && (ybuffer>182 && ybuffer<200)){RTCsetclock();} + } + } + } + +void RTCclockdraw() +{ + (x)=0; + while ((x)<60){ + x++;angleS=(x)*6; // clock minute markers in angle form + xs=(sin((angleS*3.14)/180)) * 90; // X component of markers + ys=(cos((angleS*3.14)/180)) * 90; // Y component of markers + oled.drawLine(clkx,clky,clkx+xs,clky-ys,oled.toRGB(255,255,255)); + } + (x)=0; + while ((x)<13){ + x++;angleS=(x)*30; // clock hour markers in angle form + xs=(sin((angleS*3.14)/180)) * 90; // X component of markers + ys=(cos((angleS*3.14)/180)) * 90; // Y component of markers + oled.drawLine(clkx,clky,clkx+xs,clky-ys,oled.toRGB(0,255,255)); + if (x==1) oled.drawTextGraphic(numposx +(xs+8),numposy + (ys+8), FONT5X7, "5", 1, 1, oled.toRGB(255,255,255)); + if (x==2) oled.drawTextGraphic(numposx +(xs+10),numposy + (ys+4), FONT5X7, "4", 1, 1, oled.toRGB(255,255,255)); + if (x==3) oled.drawTextGraphic(numposx +(xs+10),numposy + (ys), FONT5X7, "3", 1, 1, oled.toRGB(255,255,255)); + if (x==4) oled.drawTextGraphic(numposx +(xs+10),numposy + (ys-4), FONT5X7, "2", 1, 1, oled.toRGB(255,255,255)); + if (x==5) oled.drawTextGraphic(numposx +(xs+8),numposy + (ys-8), FONT5X7, "1", 1, 1, oled.toRGB(255,255,255)); + if (x==6) oled.drawTextGraphic(numposx +(xs),numposy + (ys-8), FONT5X7, "12", 1, 1, oled.toRGB(255,255,255)); + if (x==7) oled.drawTextGraphic(numposx +(xs-4),numposy + (ys-8), FONT5X7, "11", 1, 1, oled.toRGB(255,255,255)); + if (x==8) oled.drawTextGraphic(numposx +(xs-10),numposy + (ys-4), FONT5X7, "10", 1, 1, oled.toRGB(255,255,255)); + if (x==9) oled.drawTextGraphic(numposx +(xs-4),numposy + (ys), FONT5X7, "9", 1, 1, oled.toRGB(255,255,255)); + if (x==10) oled.drawTextGraphic(numposx +(xs-4),numposy + (ys+4), FONT5X7, "8", 1, 1, oled.toRGB(255,255,255)); + if (x==11) oled.drawTextGraphic(numposx +(xs),numposy + (ys+8), FONT5X7, "7", 1, 1, oled.toRGB(255,255,255)); + if (x==12) oled.drawTextGraphic(numposx +(xs+3),numposy + (ys+8), FONT5X7, "6", 1, 1, oled.toRGB(255,255,255)); + } + oled.setPenSize(0); + oled.drawCircle(clkx,clky,80,oled.toRGB(0,0,0)); + oled.setPenSize(1); + oled.drawCircle(clkx,clky,80,oled.toRGB(255,255,255)); + oled.drawCircle(clkx,clky,90,oled.toRGB(255,255,255)); + (x)=0; +} + +void RTCsetclock() +{ + oled.disableTouch();oled.clear(); + oled.drawText(0,0,(FONT12X16)," --Manual set RTC Time--",oled.toRGB(0,255,0)); + oled.setTextBackgroundType (TEXT_TRANSPARENT); + oled.drawTextButton(1, 265, 200,(oled.toRGB(0,100,100)),(FONT5X7),(oled.toRGB(255,255,255)), 1, 1, " Back "); + oled.drawTextButton(1, 10, 200,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, " Reset RTC "); + oled.drawTextButton(1, 120, 200,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, " Set RTC "); + oled.drawTextButton(1, 16, 115,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, "+"); + oled.drawTextButton(1, 16, 140,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, "-"); + oled.drawTextButton(1, 52, 115,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, "+"); + oled.drawTextButton(1, 52, 140,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, "-"); + oled.drawTextButton(1, 88, 115,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, "+"); + oled.drawTextButton(1, 88, 140,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, "-"); + + oled.drawTextButton(1, 174, 115,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, "+"); + oled.drawTextButton(1, 174, 140,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, "-"); + oled.drawTextButton(1, 208, 115,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, " + "); + oled.drawTextButton(1, 208, 140,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, " - "); + oled.drawTextButton(1, 270, 115,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, " + "); + oled.drawTextButton(1, 270, 140,(oled.toRGB(0,100,100)),(FONT8X12),(oled.toRGB(255,255,255)), 1, 1, " - "); + oled.setTextBackgroundType (TEXT_OPAQUE); + RTCread(); + second=RTCsecond;minute=RTCminute;hour=RTChour;dayofweek=RTCdayofweek;dayofmonth=RTCdayofmonth;month=RTCmonth;year=RTCyear; + + while(IRQ==0){ + + oled.enableTouch(); + time_t seconds = time(NULL); + strftime(timebuf, 32, "%H:%M:%S", localtime(&seconds)); + strftime(datebuf, 32, "%a %d %b' %Y", localtime(&seconds)); + oled.drawText(0,2,(FONT12X16),timebuf,oled.toRGB(255,255,255)); + oled.drawText(10,2,(FONT12X16),datebuf,oled.toRGB(255,255,255)); + + oled.getTouch(&xbuffer,&ybuffer); + if((xbuffer>240 && xbuffer<290) && (ybuffer>190 && ybuffer<210)){RTCclock();} + if((xbuffer>20 && xbuffer<109) && (ybuffer>190 && ybuffer<210)){set_time(1396310400);} + if((xbuffer>120 && xbuffer<195) && (ybuffer>195 && ybuffer<210)){RTCset();RTCread(); + second=RTCsecond;minute=RTCminute;hour=RTChour;dayofweek=RTCdayofweek;dayofmonth=RTCdayofmonth;month=RTCmonth;year=RTCyear; + } + + if((xbuffer>25 && xbuffer<40) && (ybuffer>124 && ybuffer<140)){hour++;} + if((xbuffer>25 && xbuffer<40) && (ybuffer>146 && ybuffer<160)){hour--;} + if((xbuffer>58 && xbuffer<74) && (ybuffer>124 && ybuffer<140)){minute++;} + if((xbuffer>58 && xbuffer<74) && (ybuffer>146 && ybuffer<160)){minute--;} + if((xbuffer>90 && xbuffer<105) && (ybuffer>124 && ybuffer<140)){second++;} + if((xbuffer>90 && xbuffer<105) && (ybuffer>146 && ybuffer<160)){second--;} + if((xbuffer>170 && xbuffer<186) && (ybuffer>124 && ybuffer<140)){dayofmonth++;} + if((xbuffer>170 && xbuffer<186) && (ybuffer>146 && ybuffer<160)){dayofmonth--;} + if((xbuffer>200 && xbuffer<230) && (ybuffer>124 && ybuffer<140)){month++;} + if((xbuffer>200 && xbuffer<230) && (ybuffer>146 && ybuffer<160)){month--;} + if((xbuffer>258 && xbuffer<288) && (ybuffer>124 && ybuffer<140)){year++;} + if((xbuffer>258 && xbuffer<288) && (ybuffer>146 && ybuffer<160)){year--;} + oled.disableTouch(); + + if (second >= 60) {second = 0;} + if (second < 0) {second = 59;} + if (minute >= 60) {minute = 0;} + if (minute < 0) {minute = 59;} + if (hour >= 24) {hour = 0;} + if (hour < 0) {hour = 23;} + if (dayofweek > 6){dayofweek = 0;} + if (dayofweek < 0){dayofweek = 6;} + if (month > 12) {month = 1;} + if (month < 1) {month = 12;} + if (dayofmonth <1) {dayofmonth = maxDay(year, month);} + if (dayofmonth > maxDay(year, month)) {dayofmonth = 1;} + if (year > 99) {year = 1;} + if (year < 0) {year = 99;} + + + oled.setFontSize(FONT12X16);oled.locate(1,6); + oled.setFontColor(oled.toRGB(60,255,255)); + oled.printf("%2d:%02d:%02d ",hour,minute,second); + oled.printf("%s %02d %s' 20%02d",weekDayName[dayofweek],dayofmonth,monthName[month-1],year); + } - while(1){ - - time_t seconds = time(NULL); - - strftime(timebuffer, 32, "RTC %I:%M:%S %p", localtime(&seconds)); - strftime(datebuffer, 32, "%a %d %b %Y ", localtime(&seconds)); - - oled.drawText(2,3,(FONT12X16),timebuffer,oled.toRGB(255,255,0)); // print using drawText is faster - oled.drawText(2,4,(FONT12X16),datebuffer,oled.toRGB(255,128,0)); +} +void RTCclockupdate() +{ + RTCread(); + fsecond = (RTCsecond/12); + fminute = (RTCminute/12); + if (x==1){ //Erase all hands + oled.drawLine(clkx,clky,clkx+xs,clky-ys,oled.toRGB(0,0,0)); // Erase Second's hand + oled.drawLine(clkx,clky,clkx+xm,clky-ym,oled.toRGB(0,0,0)); // Erase Minute's hand + oled.drawLine(clkx,clky,clkx+xh,clky-yh,oled.toRGB(0,0,0)); // Erase Hour's hand + } + //Calculations to get the second point of the clock hands. (first point is always the center of the clock) + angleS=(RTCsecond*6); //seconds in angle form, 360 degrees divided by 60 seconds = 6, x6 to get current angle + xs=(sin((angleS*3.14)/180)) * handSec; //get X component of the second's hand + ys=(cos((angleS*3.14)/180)) * handSec; //get Y component of the second's hand + angleM=((RTCminute*6) + fsecond); //minutes in angle form, 360 degrees divided by 60 minutes = 6, add seconds fraction, x6 to get current angle + xm=(sin((angleM*3.14)/180)) * handMin; //get X component of the minutes's hand + ym=(cos((angleM*3.14)/180)) * handMin; //get Y component of the minutes's hand + angleH=(((RTChour*5) + (fminute))*6); //hours in angle form, 360 degrees multiply hours by 5 hours = 60, add minute fraction, x6 to get angle + xh=(sin((angleH*3.14)/180)) * handHour; //get X component of the hours's hand + yh=(cos((angleH*3.14)/180)) * handHour; //get Y component of the hours's hand + x=1; + //Draw current time hands + oled.drawLine(clkx,clky,clkx+xm,clky-ym,oled.toRGB(255,255,255)); + oled.drawLine(clkx,clky,clkx+xh,clky-yh,oled.toRGB(0,255,255)); + oled.drawLine(clkx,clky,clkx+xs,clky-ys,oled.toRGB(255,255,0)); + oled.setPenSize(0); + oled.drawCircle(clkx,clky,5,oled.toRGB(255,255,255)); // Draw the center of the second's hand +} + +void RTCread() +{ + time_t seconds = time(NULL); + char buffer[80]; + strftime(buffer, 2,"%S", localtime(&seconds)); + RTCsecond = atoi(buffer); + strftime(buffer, 2,"%M", localtime(&seconds)); + RTCminute = atoi(buffer); + strftime(buffer, 2,"%H", localtime(&seconds)); + RTChour = atoi(buffer); + strftime(buffer, 2,"%d", localtime(&seconds)); + RTCdayofmonth = atoi(buffer); + strftime(buffer, 2,"%w", localtime(&seconds)); + RTCdayofweek = atoi(buffer); + strftime(buffer, 2,"%m", localtime(&seconds)); + RTCmonth = atoi(buffer); + strftime(buffer, 2,"%y", localtime(&seconds)); + RTCyear = atoi(buffer); +} + +void RTCset() +{ + t.tm_sec = (second); // 0-59 + t.tm_min = (minute); // 0-59 + t.tm_hour = (hour); // 0-23 + t.tm_mday = (dayofmonth); // 1-31 + t.tm_mon = (month-1); // 0-11 DCF "0" = Jan, -1 added for Mbed RCT clock format + t.tm_year = ((year)+100); // year since 1900, current DCF year + 100 + 1900 = correct year + if (DCF==1) {set_time(mktime(&t)-3600);} // set RTC clock to DCF -1 hour for GMT time zone + else {set_time(mktime(&t));} // set RTC clock to local time zone + DCF=0; +} + +// **************************** DCF clock ********************************************** + +void DCFclock() +{ + oled.clear();DCFbitmapdraw();RTCread(); + second=RTCsecond;minute=RTCminute;hour=RTChour;dayofweek=RTCdayofweek;dayofmonth=RTCdayofmonth;month=RTCmonth;year=RTCyear; + if(tz==0) {oled.drawText(0,0,(FONT8X12)," RTC Clock Time (GMT)",oled.toRGB(255,0,0));} + if (tz==1) {oled.drawText(0,0,(FONT8X12)," RTC Clock Time (CET)",oled.toRGB(255,0,0));} + if (tz==2) {oled.drawText(0,0,(FONT8X12)," RTC Clock Time (EET)",oled.toRGB(255,0,0));} + if (tz==3) {oled.drawText(0,0,(FONT8X12)," RTC Clock Time (MSK)",oled.toRGB(255,0,0));} + oled.drawText(22,5,(FONT8X12)," DCF Time (CET)",oled.toRGB(255,255,0)); + oled.setTextBackgroundType (TEXT_TRANSPARENT); + oled.drawTextButton(1, 270, 140,(oled.toRGB(0,100,100)),(FONT5X7),(oled.toRGB(255,255,255)), 1, 1, " Back "); + oled.setTextBackgroundType (TEXT_OPAQUE); + draw_graph=0;DCFdrawgraph(); + oled.drawLine(155,190,169,190, oled.toRGB(225, 255, 255)); + oled.drawLine(169,190,169,203, oled.toRGB(225, 255, 255)); + oled.drawLine(170,203,287,203, oled.toRGB(255,255,255)); + oled.drawLine(287,190,287,203, oled.toRGB(225, 255, 255)); + oled.drawLine(288,190,305,190, oled.toRGB(225, 255, 255)); + oled.drawText(0,26,(FONT5X7)," 0 start min hour Dt dy mon year 60",oled.toRGB(255,0,0)); + oled.setTouchArea(240,140,290,160); + start=0;sync=0;x=0;y=5;r=0;SignalStatus=0;laststart=2;loop=0;interrupt_counter = 0;dcf_sec=0;error_count=0; + + Ticker50ms.attach(& dcfISR, .05); + + while (IRQ==0) { + if (loop==0) { + DCFloop(); // Continuously get dcf time and Display data every second interrupted by the Ticker every 50ms + loop=1;} + } + oled.clear(); +} + +void DCFloop() +{ + if (interrupt_counter == 0) { + if (start == 0) {dcf_sec=0;} + if (dcf_sec == 0){dcf_array[58] = 0;} + if (dcf_good==1 && dcf_sec==2) {DCF=1;RTCset();} + } + + if (interrupt_counter == 1) { + oled.setFontSize(FONT12X16); + oled.locate(15,5);oled.setFontColor(oled.toRGB(255,255,255)); + oled.printf("%02d:%02d:%02d", hour, minute, second); + oled.locate(3,13);oled.setFontColor(oled.toRGB(255,255,255)); + oled.setFontSize(FONT12X16);oled.printf("%02d",dcf_sec); + } + + if (interrupt_counter==2){ + if (rtcset==0) { + oled.drawText(33,2,(FONT5X7),"RTC -- un-set -- ",oled.toRGB(255,0,0));} + if (rtcset==1) { + oled.drawText(33,2,(FONT5X7),"RTC *** set *** ",oled.toRGB(0,255,0));} + oled.setFontSize(FONT12X16);oled.locate(0,1); + oled.setFontColor(oled.toRGB(255,255,255)); + RTCread(); + oled.printf("%2d:%02d:%02d",RTChour,RTCminute,RTCsecond); + } + + if (interrupt_counter == 4) { + if (dcf_sec > 59) {dcf_sec = 0;} + if (dcf_sec>20 && signal_error==1) {DCFbitmapdraw();DCFdrawgraph();start=0;signal_error=0;SignalStatus=5;} + if (dcf_sec == 57) {oled.drawText(36,7,(FONT8X12)," ",oled.toRGB(0,0,0));} + if (start == 0 && signal_error==0) {SignalStatus=0;} + } + + if (interrupt_counter == 6 && dcf_sec > 0){ + if (dcf_sec==1){DCFdrawgraph();SignalStatus = 1;} + oled.setPenSize(1); oled.drawRectangle(11, 229, (dcf_sec*5), 8, oled.toRGB(0,255,0));draw_graph=0; + if (signal_error==1) {DCFdrawgraph();signal_error=0;SignalStatus=5;} + } + + if (interrupt_counter == 7){ + DCFbitstatus(); + if (dcf_sec == 21){SignalStatus=2;r = !r;} + if (dcf_sec > 20 && dcf_sec < 59 ) {DCFbitprint();} + } + + if (interrupt_counter == 8){ + if (start==1){dcf_array[dcf_sec]=dcf_status.DCFsample150;} + oled.setFontSize(FONT12X16);oled.locate(0,2); + oled.setFontColor(oled.toRGB(255,255,255)); + oled.printf("%s %02d %s' 20%02d",weekDayName[RTCdayofweek],RTCdayofmonth,monthName[RTCmonth-1],RTCyear); + } + + if (interrupt_counter == 10) { + oled.setFontSize(FONT8X12);oled.locate(23,8);oled.setFontColor(oled.toRGB(255,255,255)); + oled.printf("%s %02d %s' 20%02d", weekDayName[dayofweek], dayofmonth, monthName[month-1], year); + if (summertime) oled.drawText(23,9,(FONT8X12),"Summer Time",oled.toRGB(255,128,0)); + else oled.drawText(23,9,(FONT8X12),"Winter Time",oled.toRGB(0,255,255)); + oled.drawText(23,10,(FONT8X12),leapSymbol[dcf_status.is_leap],oled.toRGB(0,255,160)); + } + + if (interrupt_counter == 11 & second == 1) { + oled.setFontSize(FONT5X7);oled.locate(34,5); + oled.setFontColor(oled.toRGB(255,255,255)); + oled.printf("RTC set x %d", rtcset_times); + } + + if (interrupt_counter == 12){ + if (SignalStatus==0) {oled.drawText(26,20,(FONT5X7),statusText[SignalStatus],oled.toRGB(255,255,255));} + if (SignalStatus==1) {oled.drawText(26,20,(FONT5X7),statusText[SignalStatus],oled.toRGB(255,255,0));} + if (SignalStatus==2) {oled.drawText(26,20,(FONT5X7),statusText[SignalStatus],oled.toRGB(0,255,255));} + if (SignalStatus==3) {oled.drawText(26,20,(FONT5X7),statusText[SignalStatus],oled.toRGB(0,0,255));} + if (SignalStatus==4) {oled.drawText(26,20,(FONT5X7),statusText[SignalStatus],oled.toRGB(0,255,0));} + if (SignalStatus==5) { + oled.drawText(26,20,(FONT5X7),statusText[SignalStatus],oled.toRGB(255,0,0)); + oled.drawText(36,7,(FONT8X12)," ",oled.toRGB(0,0,0)); + start=0;SignalStatus=0;sync=0; + } + } + + if (interrupt_counter==13){ + if (start==0 && laststart != start) {oled.drawText(26,18,(FONT5X7),("No Sync"),oled.toRGB(255,0,0));laststart=start;} + if (start==1 && laststart != start) {oled.drawText(26,18,(FONT5X7),("In Sync"),oled.toRGB(0,255,0));laststart=start;} + } - oled.locate(3,6); // print start posistion x,y in characters (not pixels) - oled.setFontSize(FONT12X16); // Font size - - oled.setFontColor(oled.toRGB(255,255,255)); // 'R' 'G' 'B' can be set for upto 16 million colurs - oled.printf(timebuffer); // print using printf is slower than drawText + if (interrupt_counter>13){ + oled.getTouch(&xbuffer,&ybuffer); + if (display==0){ + if((xbuffer>2 && xbuffer<318) && (ybuffer>2 && ybuffer<238)){ + oled.displayControl(0x01,0x01);display=1; + oled.resetTouchArea();}} + if((xbuffer>240 && xbuffer<290) && (ybuffer>140 && ybuffer<160)){ + SignalIn.rise(NULL);Ticker50ms.detach();IRQ=1;} + } + + if (interrupt_counter == 19){DCFbitstatus();} + +} + +void DCFtestparity() +{ + rtcset=0;DCFparitycalc(); + paritycheck= testu or testm or testdmy; + if (p_year>99) paritycheck=1; + if (p_month>12) paritycheck=1; + if (p_dayofmonth>31) paritycheck=1; + if (p_hour>23) paritycheck=1; + if (p_minute>59) paritycheck=1; + if (paritycheck) {dcf_good=0;SignalStatus = 5;} // bad parity + else {dcf_good=1;SignalStatus = 4;} // good parity +} + +void DCFsetTime() +{ + second = dcf_sec; + minute=p_minute; + hour=p_hour; + dayofweek=p_dayofweek; + dayofmonth=p_dayofmonth; + month=p_month; + year=p_year; + oled.drawText(36,7,(FONT8X12),"*",oled.toRGB(0,255,0)); +} +void DCFbitprint() +{ + if (r==1) {oled.setFontColor(oled.toRGB(0,0,255));} // alternate bit draw colour + else {oled.setFontColor(oled.toRGB(255,255,255));} + oled.setFontSize(FONT8X12); + if (dcf_sec==21){x=5;y=7;} + if (dcf_sec==28){x=5;y=15;oled.locate(5,15);oled.printf(" ");} + if (dcf_sec==29){x=7;y=7;} + if (dcf_sec==35){x=7;y=15;} + if (dcf_sec==36){x=9;y=7;} + if (dcf_sec==42){x=11;y=7;} + if (dcf_sec==45){x=13;y=7;} + if (dcf_sec==50){x=15;y=7;} + oled.locate(x,y); + oled.printf("%d",dcf_status.DCFsample150); + y++; +} + +void DCFbitmapdraw() +{ + x=2,y=6; + oled.drawText(x-2,y,(FONT8X12)," Dcf M H D d M Y",oled.toRGB(255,255,0)); + oled.drawText(x,y+1,(FONT8X12)," 1 i o a a o e",oled.toRGB(255,255,0)); + oled.drawText(x,y+2,(FONT8X12)," 2 n u t y n a",oled.toRGB(255,255,0)); + oled.drawText(x,y+3,(FONT8X12)," 4 u r e t r",oled.toRGB(255,255,0)); + oled.drawText(x,y+4,(FONT8X12)," 8 t h ",oled.toRGB(255,255,0)); + oled.drawText(x,y+5,(FONT8X12),"10 e ",oled.toRGB(255,255,0)); + oled.drawText(x,y+6,(FONT8X12),"20 ",oled.toRGB(255,255,0)); + oled.drawText(x,y+7,(FONT8X12),"40 ",oled.toRGB(255,255,0)); + oled.drawText(x,y+8,(FONT8X12),"80 ",oled.toRGB(255,255,0)); + oled.drawText(x,y+9,(FONT8X12)," P arity ",oled.toRGB(255,255,0)); + oled.drawLine(8,83,135,83, oled.toRGB(0, 255, 0)); + oled.drawLine(35,70,35,195, oled.toRGB(0, 255, 0)); +} +void DCFdrawgraph() +{ + if (draw_graph==0){ + oled.setPenSize(0); + oled.drawRectangle(10,228,300,8,oled.toRGB(0,0,0)); + oled.setPenSize(1); + oled.drawRectangle(10,227,302,10,oled.toRGB(255,255,255)); + oled.drawLine(10,220,10,237,oled.toRGB(255,255,255)); + oled.drawLine(312,220,312,237,oled.toRGB(255,255,255)); + oled.drawLine(111,220,111,237,oled.toRGB(255,255,255)); //start + oled.drawLine(156,220,156,237,oled.toRGB(225,255,255)); //min + oled.drawLine(186,220,186,237,oled.toRGB(255,255,225)); //hour + oled.drawLine(216,220,216,237,oled.toRGB(225,255,225)); //date + oled.drawLine(231,220,231,237, oled.toRGB(225, 255, 225));//day + oled.drawLine(256,220,256,237, oled.toRGB(225, 255, 225));//month + oled.drawLine(301,220,301,237, oled.toRGB(225, 255, 225));//year + draw_graph=1; + } +} +void DCFbitstatus() +{ + oled.locate(29,22); + oled.setFontSize(FONT5X7); + oled.setFontColor(oled.toRGB(255,0,0)); + oled.printf("%d %d %d %d %d",dcf_status.DCFsample50,dcf_status.DCFsample150,dcf_status.DCFsample300,dcf_status.DCFsample500,dcf_status.DCFsample600); + oled.setPenSize(0); + if (!dcf_status.DCFsample50) {oled.drawRectangle(170,190,11,12, oled.toRGB(0,0,0));} + else {oled.drawRectangle(170,190,11,12, oled.toRGB(255,255,255));} + if (!dcf_status.DCFsample150) {oled.drawRectangle(182,190,11,12, oled.toRGB(0,0,0));} + else {oled.drawRectangle(182,190,11,12, oled.toRGB(255,255,255));} + if (!dcf_status.DCFsample300) {oled.drawRectangle(194,190,11,12, oled.toRGB(0,0,0));} + else {oled.drawRectangle(194,190,11,12, oled.toRGB(255,255,255));} + if (!dcf_status.DCFsample500) {oled.drawRectangle(206,190,23,12, oled.toRGB(0,0,0));} + else {oled.drawRectangle(206,190,23,12, oled.toRGB(255,255,255));} + if (!dcf_status.DCFsample600) {oled.drawRectangle(230,190,56,12, oled.toRGB(0,0,0));} + else {oled.drawRectangle(230,190,56,12, oled.toRGB(0,0,255));} +} + +void DCFparitycalc() +{ +//calculate summer/winter time---------------------------------------------------------------------- + summertime = dcf_array[17] & 1; +//calculate hour-------------------------------------------------------------------------------------- + hourh = dcf_array[34] * 20 + dcf_array[33] * 10; + hourl = dcf_array[32] * 8 + dcf_array[31] * 4 + dcf_array[30] * 2 + dcf_array[29] * 1; + p_hour = hourh + hourl; +//calculate minutes------------------------------------------------------------------------------------ + minl = dcf_array[24] * 8 + dcf_array[23] * 4 + dcf_array[22] * 2 + dcf_array[21] * 1; + minh = dcf_array[27] * 40 + dcf_array[26] * 20 +dcf_array[25] * 10; + p_minute = minh + minl; +//calculate day of week-------------------------------------------------------------------------------- + p_dayofweek = dcf_array[44] * 4 +dcf_array[43] * 2 + dcf_array[42] * 1; +//calculate day---------------------------------------------------------------------------------------- + dayl = dcf_array[39] * 8 + dcf_array[38] * 4 + dcf_array[37] * 2 + dcf_array[36] * 1; + dayh = dcf_array[41] * 20 + dcf_array[40] * 10; + p_dayofmonth=dayh+dayl; +//calculate month-------------------------------------------------------------------------------------- + monthh = dcf_array[49] * 10; + monthl = dcf_array[48] * 8 + dcf_array[47] * 4 + dcf_array[46] * 2 + dcf_array[45] * 1; + p_month = monthh +monthl; +//calculate year--------------------------------------------------------------------------------------- + yearh = dcf_array[57] * 80 + dcf_array[56] * 40 + dcf_array[55] * 20 + dcf_array[54] * 10; + yearl = dcf_array[53] * 8 +dcf_array[52] * 4 + dcf_array[51] * 2 + dcf_array[50] * 1; + p_year = yearh+yearl; +//calculate parity + paritym = dcf_array[21] + dcf_array[22] + dcf_array[23] + dcf_array[24] + dcf_array[25] + dcf_array[26] +dcf_array[27] +dcf_array [28]; + parityu =dcf_array[29] + dcf_array[30] + dcf_array[31] + dcf_array[32] + dcf_array[33] + dcf_array[34] + dcf_array[35]; + paritydmy =dcf_array[36] + dcf_array [37] + dcf_array [38] + dcf_array [39] + dcf_array[40] + dcf_array[41] + dcf_array [42] + dcf_array [43] + dcf_array[44] + dcf_array [45] + dcf_array[46] + dcf_array [47] + dcf_array[48] + dcf_array[49] + dcf_array[50] + dcf_array[51] + dcf_array [52] + dcf_array[53] + dcf_array[54] + dcf_array[55] + dcf_array[56] + dcf_array[57] + dcf_array[58]; +//test parity------------------------------ + testu=parityu & 1; + testm=paritym & 1; + testdmy=paritydmy & 1; + } + +void dcfIRQ(void) +{ + if (sync==0){ + interrupt_counter = 0;sync=1;dcf_sec=0;error_count=0; + Ticker50ms.attach(& dcfISR, .05); + } +} + +void dcfISR() //This is the interrupt service routine (ISR) that is called every 50ms +{ + interrupt_counter++;loop=0; + + SignalLED = SignalIn; // Show dcfSignal state on LED + + if (interrupt_counter == 20) { // 50mS x 20 = 1000mS = 1 Second + interrupt_counter = 0;second++;dcf_sec++; + if (start==0) dcf_sec=0; + } + if (interrupt_counter == 0){ + if (dcf_sec==58) {SignalStatus = 3;} + if (dcf_sec==59) {DCFtestparity();} + if (dcf_good==1 && dcf_sec==1) {DCFsetTime();} + } + if (second >= 60) {++minute;second -=60;} + if (minute >= 60) {++hour;minute-=60;} + if (hour >= 24) {hour -=24;++dayofweek;++dayofmonth;} + if (dayofweek > 6) dayofweek = 0; + if (dayofmonth > maxDay(year, month)) {dayofmonth = 1;month++;} + if (month > 12) {month = 1;year++;} + if (year > 99) year = 1; + + switch (interrupt_counter) { + case 1: { // 50mS after start of second pulse + dcf_status.DCFsample50 = (SignalIn); + break;} + case 3: { // 150mS after start of second pulse (bit "1" dcf Data) + dcf_status.DCFsample150 = (SignalIn); + break;} + case 6: { // 300mS after start of second (signal error if true) + dcf_status.DCFsample300 = (SignalIn); + if (SignalIn) {dcf_error = 1;} + break;} + case 10: { // 500mS after start of second (signal error if true) + dcf_status.DCFsample500 = (SignalIn); + if (SignalIn) {dcf_error = 1;} + break;} + case 12: { // 600mS after start of second (signal error if true) + dcf_status.DCFsample600 = (SignalIn); + if (SignalIn) {dcf_error = 1;} + break;} + } + if (dcf_status.DCFsample50==0 && dcf_sec<58){sync=0;} + + if (interrupt_counter==1){ + if (SignalIn){nosignal=1;} + else nosignal++; + if (nosignal>5){nosignal=2; SignalStatus = 5;signal_error=1;} + } - oled.locate(3,7); - oled.printf(datebuffer); - + if (interrupt_counter==15){ + if (!dcf_status.DCFsample150 && !dcf_status.DCFsample50) {sync=0;start=1;} + } + if (interrupt_counter==18){ + if (dcf_error==1) {error_count++;dcf_error=0;} + if (error_count > 3 && sync==1) {error_count = 0;signal_error=1;} + } - wait(.2); - } -} \ No newline at end of file +} // End of ISR + \ No newline at end of file