Paul Staron / Mbed 2 deprecated KL25Z_DCF77_OLED160

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "OLED160G1.h"
00003 
00004 OLED160G1 oled(PTD3,PTD2,PTD1);// Oled Display tx, rx, rs
00005 DigitalIn dcfSignalIn(PTE20);//conection to NON inverting output of dcf module
00006 
00007 DigitalOut dcfLED (LED1);// dcf signal Pulse
00008 
00009 //variable
00010 char paritycheck,paritym,parityu,paritydmy;
00011 char testu,testm,testdmy;
00012 char bit;
00013 char min,minh,minl;
00014 char hourh,hourl;
00015 char w_day;
00016 char day,dayh,dayl;
00017 char monthh,monthl;
00018 char yearh,yearl;
00019 char summertime;
00020 int dcf_array[61];
00021   
00022 //makro,s
00023 void dcf_check();
00024 void showRtcDate();
00025 void oled_time_print();
00026 void bit_map_draw();
00027 void bit_print();
00028 void parity_calc();
00029 void drawgraph();
00030 void showRTC();
00031 void showRtcDate();
00032 void setRTC();
00033 
00034 Timer d;
00035 Ticker Ticker10ms;
00036 
00037 #define ZERO 1e-10
00038 #define isBetween(A, B, C) (((A-B) > -ZERO) && ((A-C) < ZERO))
00039 
00040 struct status {
00041    // bool status;       // Last minute received OK counts parity test results
00042     bool is_leap;           // Leap year flag (NOT actually transmitted but calculated)
00043     bool sample50;          // dcf sample at 70mS into the start of the second
00044     bool sample150;         // dcf sample at 170mS into the start of the second
00045     int  second;            // dcf second (NOT actually transmitted but calculated)
00046 } dcf_status;
00047 
00048 struct dcf {
00049     char dut1;               // DUT1 (0.1 - 0.8)
00050     char dut2;               // DUT2 (-0.1 - -0.8)
00051     char year;               // Year (00 - 99)
00052     char month;              // Month (01 - 12)
00053     char dayofmonth;         // Day of month (01 - 31)
00054     char dayofweek;          // Day of week (Sunday=0 Saturday=6)
00055     char hour;               // Hour (00 - 23)
00056     char minute;             // Minute (00 - 59)   
00057 } dcf_time;
00058 
00059 // Global variables
00060 int in_sec_counter = 0;
00061 int interrupt_counter = 0;
00062 int hour = 12;
00063 int minute = 0;
00064 int second = 0;
00065 int dayofweek = 6;
00066 int dayofmonth = 1;
00067 int month = 1;
00068 int year = 0;
00069 int nosignal;
00070 int start;
00071 int zero_bit;
00072 int dcf_sec;
00073 int s,x,y,r;
00074 int bmd;
00075 int sync;
00076 int p_minute;
00077 int p_hour;
00078 int p_dayofweek;
00079 int p_dayofmonth;
00080 int p_month;
00081 int p_year;
00082 int dcf_error;
00083 int status;
00084 int insecond_counter;
00085 int delay;
00086 int start_delay;
00087 typedef unsigned char byte;
00088 void loop();
00089 void oled_time_print();
00090 void showRtcDate();
00091 void drawgraph();
00092 void bit_map_draw();
00093 void set_time();
00094 void restart();
00095 
00096 // Various text strings used in display
00097 char weekDayName[7][4] = {"Sun","Mon","Tue","Wed","Thu", "Fri","Sat"};
00098 char monthName[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
00099 char statusText[5][17] = {"Waiting Sync    ","Reading dcf data","Checking Parity ","Last Minute Okay","Signal error    "};
00100 char leapText[2][10] = {"         ", "Leap Year"};
00101 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
00102 
00103 // Return the maximum day in month for a given month & year
00104 
00105 byte maxDay(byte year, byte month)
00106 {
00107     byte lastday, leap;
00108     leap = year%4 == 0 && year%100 !=0 || year%400 == 0;
00109     lastday = MAX_DAY[month - 1];
00110     dcf_status.is_leap = leap > 0 ? 1 : 0;
00111     if ((leap > 0) && (month == 2))
00112         lastday++;
00113     return lastday;
00114 }
00115 
00116 int dayOfWeek(int y, int m, int d)   // 0 = Sunday
00117 {
00118     static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
00119     y -= m < 3;
00120     return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
00121 }
00122 
00123 void myISR()  //This is the interrupt service routine (ISR) that is called every 50ms 
00124 {   
00125     interrupt_counter++;
00126      
00127   dcfLED = !dcfSignalIn;  // Show dcfSignal state on LED
00128      
00129     if (interrupt_counter == 20) { // 50mS x 20 = 1000mS = 1 Second
00130         interrupt_counter = 0;
00131         second++;insecond_counter++;
00132         if (d.read()> 2) {d.reset();d.start();delay=1;}
00133         else {delay=0;}
00134         if (second > 2) {start_delay=0;}
00135         if (dcf_error==1) {status = 4;} 
00136        }
00137         if (dcf_sec==58) {status = 2;}
00138         if (dcf_sec==59) {dcf_check();} // check parity
00139         if (status == 3 && dcf_sec == 1) {set_time();} // set DCF clock if good data
00140                  
00141     if (second >= 60) {
00142         ++minute;
00143         second -=60;
00144     }
00145     if (minute >= 60) {
00146         ++hour;
00147         minute-=60;
00148     }
00149     if (hour >= 24) {
00150         hour -=24;
00151         ++dayofweek;
00152         ++dayofmonth;
00153     }
00154     if (dayofweek > 6)
00155         dayofweek = 0;
00156 
00157     if (dayofmonth > maxDay(year, month)) {
00158         dayofmonth = 1;
00159         month++;
00160     }
00161     if (month > 12) {
00162         month = 1;
00163         year++;
00164     }
00165     if (year > 99)
00166         year = 1;
00167            
00168         switch (interrupt_counter) {          
00169             case 1:{  // 50mS after start of second pulse
00170                 dcf_status.sample50 = (dcfSignalIn);
00171                break;}
00172             case 3: { // 150mS after start of second pulse (bit "1" dcf Data)
00173                 dcf_status.sample150 = (dcfSignalIn);                
00174                 if (!dcf_status.sample150 && !dcf_status.sample50 && start_delay==0) {zero_bit=1;sync=0;insecond_counter=0;start=1;}
00175                 else {zero_bit=0;}
00176                break;}
00177             case 6: { // 300mS after start of second (signal error if true)
00178                 if (status == 3 && dcf_sec == 1) {setRTC();} // set RTC clock if good data
00179                 if (dcfSignalIn) {dcf_error = 1;}
00180                break;}                
00181             case 10: { // 500mS after start of second (signal error if true)
00182                 if (dcfSignalIn) {dcf_error = 1;}
00183                break;}
00184             case 12: { // 600mS after start of second (signal error if true)
00185                 if (dcfSignalIn) {dcf_error = 1;}
00186                break;}                                                   
00187           } 
00188            
00189         if (interrupt_counter==1)
00190            {
00191             if (dcfSignalIn){nosignal=1;}
00192             else nosignal++;              
00193             if (nosignal>5){nosignal=2; status = 0; restart();} 
00194             if (dcf_error == 1 && delay == 1) {dcf_error = 0; status = 0;restart();}                      
00195            }            
00196         if (interrupt_counter==3)
00197            {
00198              oled.locate(18,4);oled.setFontColor(oled.toRGB(0,0,255));
00199              oled.printf("Bit %d",dcf_status.sample150); 
00200              if (start==0) {oled.drawText(18,13,(OLED_FONT5X7),"No Sync ",oled.toRGB(255,0,0));}
00201              
00202            if (start==1)
00203             {
00204                 dcf_array[dcf_sec]=dcf_status.sample150;
00205                 oled.drawText(18,13,(OLED_FONT5X7),"In Sync ",oled.toRGB(0,255,0));
00206                     if (insecond_counter==1)
00207                     {
00208                         dcf_sec=0;x=0;y=5;dcf_array[58] = 0; bmd=0;        
00209                          if (r == 1){r=0;}
00210                             else {r=1;}
00211                         }        
00212             if (dcf_sec > 2) {status = 1;}                 
00213             if (dcf_sec > 20 && dcf_sec < 59 ) {bit_print();}
00214             if (dcf_sec > 60) {dcf_error = 1;bit_map_draw();status = 4;dcf_sec=0;dcf_error = 0;}  
00215             if (sync==1) {dcf_sec++;}                     
00216                 }     
00217              }              
00218       if (sync==0) {
00219             if (dcfSignalIn) {interrupt_counter =0 ;sync=1;} // synchronise interrupt counter to DCF sync pulse               
00220         }         
00221 } // End of ISR
00222 
00223 int main()
00224 {     
00225     oled.init();
00226     oled.eraseScreen();
00227     oled.setTextBackgroundType(OLED_SET_TEXT_OPAQUE);
00228     oled.drawText(1,1,(OLED_FONT8X12),"DCF77 Atomic Clock",oled.toRGB(255,0,0));
00229     oled.drawText(1,3,(OLED_FONT8X12)," Freescale KL25Z",oled.toRGB(0,255,0));
00230     oled.drawText(1,5,(OLED_FONT8X12),"   4D Systems",oled.toRGB(0,0,255));
00231     oled.drawText(1,7,(OLED_FONT8X12)," Oled160 Display",oled.toRGB(255,255,0));    
00232     wait(1);
00233     oled.eraseScreen();bit_map_draw();
00234     oled.drawText(17,6,(OLED_FONT5X7),"DCF Time",oled.toRGB(255,255,0));
00235     dcf_sec=0;bmd=1;start=0;zero_bit=0;r = 1;
00236     status = 0; start_delay=1;
00237     d.start();showRtcDate();  
00238     if (dcfSignalIn) {interrupt_counter =0 ;sync=1;}                    
00239     Ticker10ms.attach(& myISR, .05 ); //Setup Ticker to call myISR every 50 ms
00240             
00241   while (true) {
00242     loop();                           // Continuously get dcf time and Display data interrupted by the Ticker every 50ms
00243    }    
00244 }
00245 
00246 void dcf_check()
00247 { 
00248         parity_calc();
00249         paritycheck= testu or testm or testdmy;        
00250         if (year>99) paritycheck=1;
00251         if (month>12) paritycheck=1;
00252         if (day>31) paritycheck=1;
00253         if (hour>23) paritycheck=1;
00254         if (min>59) paritycheck=1;       
00255         if (paritycheck) {        
00256         status = 4; // bad parity      
00257         }
00258      else {
00259             status = 3; // good parity
00260         }       
00261 }
00262 
00263 void bit_print()
00264 {
00265     if (r==1) {oled.setFontColor(oled.toRGB(255,0,255));}    // alternate bit draw colour
00266     else {oled.setFontColor(oled.toRGB(255,255,255));}
00267     oled.locate(x+3,(y+1));
00268     oled.printf("%d",dcf_status.sample150);
00269     (y)++;
00270     if ((dcf_sec)==27){(y)=13;}   
00271     if ((dcf_sec)==28){(y)=5;(x)=(x)+2;oled.printf("          ");}     
00272     if ((dcf_sec)==34){(y)=13;}       
00273     if ((dcf_sec)==35){(y)=5;(x)=(x)+2;}
00274     if ((dcf_sec)==41){(y)=5;(x)=(x)+2;}
00275     if ((dcf_sec)==44){(y)=5;(x)=(x)+2;}
00276     if ((dcf_sec)==49){(y)=5;(x)=(x)+2;}              
00277 }
00278 
00279 void bit_map_draw()
00280 {
00281     (x)=0,(y)=4;
00282       oled.drawText(x,y,(OLED_FONT5X7),"   M H D d M Y",oled.toRGB(255,255,0));
00283     y++;   
00284     oled.drawText(x,y+1,(OLED_FONT5X7)," 1 i o a a o e",oled.toRGB(255,255,0));    
00285     oled.drawText(x,y+2,(OLED_FONT5X7)," 2 n u t y n a",oled.toRGB(255,255,0));    
00286     oled.drawText(x,y+3,(OLED_FONT5X7)," 4 u r e   t r",oled.toRGB(255,255,0));    
00287     oled.drawText(x,y+4,(OLED_FONT5X7)," 8 t       h  ",oled.toRGB(255,255,0));    
00288     oled.drawText(x,y+5,(OLED_FONT5X7),"10 e          ",oled.toRGB(255,255,0));    
00289     oled.drawText(x,y+6,(OLED_FONT5X7),"20            ",oled.toRGB(255,255,0));    
00290     oled.drawText(x,y+7,(OLED_FONT5X7),"40            ",oled.toRGB(255,255,0));   
00291     oled.drawText(x,y+8,(OLED_FONT5X7),"80            ",oled.toRGB(255,255,0));     
00292     oled.drawText(x,y+9,(OLED_FONT5X7)," P arity       ",oled.toRGB(255,255,0));   
00293     oled.drawLine(2,43,85,43, oled.toRGB(255, 0, 0));
00294     oled.drawLine(14,33,14,118, oled.toRGB(255, 0, 0)); 
00295 }
00296 void showClock()
00297 {
00298    oled.setFontSize(OLED_FONT5X7);
00299    oled.locate(17,8);oled.setFontColor(oled.toRGB(255,255,255));
00300    oled.printf("%02d:%02d:%02d", hour, minute, second);
00301    oled.locate(17,9);
00302    oled.printf("%02d/%02d/%02d",dayofmonth,month,year);
00303    if (summertime) {oled.drawText(17,10,(OLED_FONT5X7),"Summer",oled.toRGB(255,100,100));}               
00304    else {oled.drawText(17,10,(OLED_FONT5X7),"Winter",oled.toRGB(0,255,255));} 
00305    oled.drawText(17,11,(OLED_FONT5X7),leapText[dcf_status.is_leap],oled.toRGB(0,255,160)); 
00306    if (status==0) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(255,255,255));}
00307    if (status==1) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(0,255,255));}
00308    if (status==2) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(0,0,255));}
00309    if (status==3) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(0,255,0));}
00310    if (status==4) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(255,0,0));}
00311 } 
00312 void loop()
00313 {   
00314     if (interrupt_counter == 0) {  // refresh local time at the first 50mS of every second
00315     showClock(); 
00316     showRTC(); 
00317     oled.setFontSize(OLED_FONT5X7); 
00318     oled.locate(9,12);oled.setFontColor(oled.toRGB(255,255,255));oled.printf("%02d",dcf_sec);
00319     oled.setFontSize(OLED_FONT5X7);
00320  } 
00321 }
00322   
00323 void showRTC()
00324 {
00325     time_t seconds = time(NULL);
00326     char buffer[40];
00327     strftime(buffer, 40, "%I:%M:%S %p", localtime(&seconds));
00328     oled.drawText(1,0,(OLED_FONT8X12),buffer,oled.toRGB(255,255,255));
00329 }
00330 
00331 void showRtcDate()
00332 {
00333     time_t seconds = time(NULL);    
00334     char buffer[40];
00335     strftime(buffer, 40, "%a %d %b %Y", localtime(&seconds));
00336     oled.drawText(1,1,(OLED_FONT8X12),buffer,oled.toRGB(255,255,255)); 
00337 }
00338 
00339 void setRTC()
00340 {
00341             //Mbed rtc clock set
00342             struct tm t;
00343             t.tm_sec = (second-1);        // 0-59
00344             t.tm_min = (minute);     // 0-59
00345             t.tm_hour = (hour);   // 0-23
00346             t.tm_mday = (dayofmonth);    // 1-31
00347             t.tm_mon = (month-1);     // 0-11 DCF "0" = Jan, -1 added for Mbed RCT clock format
00348             t.tm_year = ((year)+100);  // year since 1900,  current DCF year + 100 + 1900 = correct year
00349             set_time(mktime(&t)-3600);
00350             time_t seconds = mktime(&t);               
00351             showRtcDate(); // Print DATE once per minute
00352             if (summertime==0) {oled.drawText(19,0,(OLED_FONT5X7),"Winter",oled.toRGB(0,255,255));}               
00353             else {oled.drawText(19,0,(OLED_FONT5X7),"Summer",oled.toRGB(255,128,128));}
00354    
00355 }
00356   
00357 void set_time()
00358 {
00359             second = dcf_sec;
00360             minute=p_minute;
00361             hour=p_hour;
00362             dayofweek=p_dayofweek;
00363             dayofmonth=p_dayofmonth;
00364             month=p_month;
00365             year=p_year;
00366 }
00367 
00368 void restart()
00369 {
00370 start=0;s=0;x=0;y=5;dcf_sec=0;dcf_error=0;
00371 insecond_counter=0;zero_bit=0;start_delay=1;
00372 }
00373 
00374 void parity_calc()
00375 {
00376 //calculate summer/winter time----------------------------------------------------------------------
00377     summertime = dcf_array[17] & 1;
00378 //calculate hour--------------------------------------------------------------------------------------
00379     hourh = dcf_array[34] * 20 + dcf_array[33] * 10;
00380     hourl = dcf_array[32] * 8 + dcf_array[31] * 4 + dcf_array[30] * 2 + dcf_array[29] * 1;
00381     p_hour = hourh + hourl;
00382 //calculate minutes------------------------------------------------------------------------------------
00383     minl = dcf_array[24] * 8 + dcf_array[23] * 4 + dcf_array[22] * 2 + dcf_array[21] * 1;
00384     minh = dcf_array[27] * 40 + dcf_array[26] * 20 +dcf_array[25] * 10;
00385     p_minute = minh + minl;
00386 //calculate day of week--------------------------------------------------------------------------------
00387     p_dayofweek = dcf_array[44] * 4 +dcf_array[43] * 2 + dcf_array[42] * 1;
00388 //calculate day----------------------------------------------------------------------------------------
00389     dayl = dcf_array[39] * 8 + dcf_array[38] * 4 + dcf_array[37] * 2 + dcf_array[36] * 1;
00390     dayh = dcf_array[41] * 20 + dcf_array[40] * 10;
00391     p_dayofmonth=dayh+dayl;
00392 //calculate month--------------------------------------------------------------------------------------
00393     monthh = dcf_array[49] * 10;
00394     monthl = dcf_array[48] * 8 + dcf_array[47] * 4 + dcf_array[46] * 2 + dcf_array[45] * 1;
00395     p_month = monthh +monthl;
00396 //calculate year---------------------------------------------------------------------------------------
00397     yearh = dcf_array[57] * 80 + dcf_array[56] * 40 + dcf_array[55] * 20 + dcf_array[54] * 10;
00398     yearl = dcf_array[53] * 8 +dcf_array[52] * 4 + dcf_array[51] * 2 + dcf_array[50] * 1;
00399     p_year = yearh+yearl;
00400 //calculate parity
00401     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];
00402     parityu =dcf_array[29] + dcf_array[30] + dcf_array[31] + dcf_array[32] + dcf_array[33] + dcf_array[34] + dcf_array[35];
00403     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];
00404 //test parity------------------------------
00405     testu=parityu & 1;
00406     testm=paritym & 1;
00407     testdmy=paritydmy & 1;
00408   }
00409