Paul Staron / Mbed 2 deprecated DCF77Clock_Nokia

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 "MobileLCD.h"
00003 
00004 MobileLCD lcd(p5, p6, p7, p8, p9);
00005 DigitalIn dcfSignalIn(p21);//conection to NON inverting output of dcf module
00006 DigitalOut dcfLED (LED1);//received DCF signal
00007 
00008 //variable
00009 char paritycheck,paritym,parityu,paritydmy;
00010 char testu,testm,testdmy;
00011 char min,minh,minl;
00012 char hourh,hourl;
00013 char w_day;
00014 char day,dayh,dayl;
00015 char monthh,monthl;
00016 char yearh,yearl;
00017 char summertime;
00018 int dcf_array[61];
00019   
00020 //makro,s
00021 void getbit();
00022 void dcf_check();
00023 void lcd_date_print();
00024 void lcd_time_print();
00025 void bit_map_draw();
00026 void bit_print();
00027 void parity_calc();
00028 void reset_rtc();
00029 void local_time();
00030 void set_rtc();
00031 void s_display();
00032 void drawgraph();
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 is_leap;           // Leap year flag (NOT actually transmitted but calculated)
00042     bool sample50;          // dcf sample at 50mS into the start of the second
00043     bool sample150;         // dcf sample at 150mS into the start of the second
00044     int  second;            // dcf second (NOT actually transmitted but calculated)
00045 } 
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 oled_date_print();
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"};
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();}
00139         if (status == 3 && dcf_sec == 1) {set_time();}
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 (dcfSignalIn) {dcf_error = 1;}
00179                break;}                
00180             case 10: { // 500mS after start of second (signal error if true)
00181                 if (dcfSignalIn) {dcf_error = 1;}
00182                break;}
00183             case 12: { // 600mS after start of second (signal error if true)
00184                 if (dcfSignalIn) {dcf_error = 1;}
00185                break;}                                                   
00186           }           
00187         if (interrupt_counter==1)
00188            {
00189             if (dcfSignalIn){nosignal=1;}
00190             else nosignal++;              
00191             if (nosignal>5){nosignal=2; status = 0; restart();} 
00192             if (dcf_error == 1 && delay == 1) {dcf_error = 0; status = 0;restart();}                      
00193            }           
00194         if (interrupt_counter==3)
00195            {
00196              lcd.locate(0,4); lcd.foreground (CYAN);
00197              lcd.printf("Bit %d   ",dcf_status.sample150);           
00198              if (start==0) {lcd.foreground (RED);lcd.printf("No Sync ");}             
00199            if (start==1)
00200             {
00201                 dcf_array[dcf_sec]=dcf_status.sample150;
00202                 lcd.foreground (GREEN);
00203                 lcd.printf("In Sync ");  
00204                     if (insecond_counter==1)
00205                     {
00206                         dcf_sec=0;x=0;y=5;dcf_array[58] = 0; bmd=0;        
00207                          if (r == 1){r=0;}
00208                             else {r=1;}
00209                         }        
00210             if (dcf_sec > 2) {status = 1;}                 
00211             if (dcf_sec > 20 && dcf_sec < 59 ) {bit_print();}
00212             if (dcf_sec > 60) {dcf_error = 1;bit_map_draw();status = 4;dcf_sec=0;dcf_error = 0;}  
00213             if (sync==1) {dcf_sec++;}                     
00214                 }     
00215              }             
00216       if (sync==0 ) {
00217             if (dcfSignalIn) {interrupt_counter =0 ;sync=1;}                
00218         }                
00219 } // End of ISR
00220 
00221 int main()
00222 {     
00223     lcd.locate (1,2);
00224     lcd.foreground (WHITE);
00225     lcd.printf("DCF77 Clock");
00226     lcd.locate (1,4);
00227     lcd.printf("Nokia 6610 LCD");
00228     lcd.locate (1,6);
00229     lcd.printf("Signal pin 21");
00230     wait (5);lcd.cls();r = 1;             
00231     bit_map_draw();dcf_sec=0;bmd=1;start=0;zero_bit=0;
00232     status = 0; start_delay=1;
00233     d.start();  
00234     if (dcfSignalIn) {interrupt_counter =0 ;sync=1;}                    
00235     Ticker10ms.attach(& myISR, .05 ); //Setup Ticker to call myISR every 50 ms
00236             
00237   while (true) {
00238     loop();                           // Continuously get dcf time and Display data interrupted by the Ticker every 50ms
00239    }    
00240 }
00241 
00242 void dcf_check()
00243 { 
00244         parity_calc();
00245         paritycheck= testu or testm or testdmy;        
00246         if (year>99) paritycheck=1;
00247         if (month>12) paritycheck=1;
00248         if (day>31) paritycheck=1;
00249         if (hour>23) paritycheck=1;
00250         if (min>59) paritycheck=1;       
00251         if (paritycheck) {        
00252         status = 4;       
00253         }
00254      else {
00255             status = 3;
00256         }       
00257 }
00258 void showClock()
00259 {
00260    lcd.locate(0,0);lcd.foreground (WHITE);
00261    lcd.printf("%02d:%02d:%02d", hour, minute, second);
00262    lcd.locate(0,1);
00263    lcd.printf("%s %02d %s'20%02d", weekDayName[dayofweek], dayofmonth, monthName[month-1], year);
00264    lcd.locate(0,2);
00265    if (summertime) {lcd.foreground (RED);lcd.printf("Summer Time ");}
00266    else {lcd.foreground (BLUE);lcd.printf("Winter Time ");}
00267    lcd.foreground (RED);lcd.printf("%s",leapText[dcf_status.is_leap]);
00268    if (status==0) {lcd.foreground (WHITE);}
00269    if (status==1) {lcd.foreground (CYAN);}
00270    if (status==2) {lcd.foreground (BLUE);}
00271    if (status==3) {lcd.foreground (GREEN);}
00272    if (status==4) {lcd.foreground (RED);}
00273    lcd.locate(0,15);
00274    lcd.printf(statusText[status]);
00275 }
00276 
00277 void bit_print()
00278 {
00279     if (r==1) {lcd.foreground (MAGENTA);}    // alternate bit draw colour
00280     else {lcd.foreground (WHITE);}
00281     lcd.locate(x+3,(y+1));
00282     lcd.printf("%d",dcf_status.sample150);
00283     (y)++;
00284     if ((dcf_sec)==27){(y)=13;}   
00285     if ((dcf_sec)==28){(y)=5;(x)=(x)+2;lcd.printf("          ");}     
00286     if ((dcf_sec)==34){(y)=13;}       
00287     if ((dcf_sec)==35){(y)=5;(x)=(x)+2;}
00288     if ((dcf_sec)==41){(y)=5;(x)=(x)+2;}
00289     if ((dcf_sec)==44){(y)=5;(x)=(x)+2;}
00290     if ((dcf_sec)==49){(y)=5;(x)=(x)+2;}              
00291 }
00292 
00293 void bit_map_draw()
00294 {
00295     lcd.foreground (YELLOW);(x)=0,(y)=5;
00296     lcd.locate(x,y);lcd.printf("   M H D d M Y"); 
00297     lcd.locate(x,y+1);lcd.printf(" 1 i o a a o e");
00298     lcd.locate(x,y+2);lcd.printf(" 2 n u t y n a"); 
00299     lcd.locate(x,y+3);lcd.printf(" 4 u r e   t r");
00300     lcd.locate(x,y+4);lcd.printf(" 8 t       h  "); 
00301     lcd.locate(x,y+5);lcd.printf("10 e          ");
00302     lcd.locate(x,y+6);lcd.printf("20            ");
00303     lcd.locate(x,y+7);lcd.printf("40            ");
00304     lcd.locate(x,y+8);lcd.printf("80            "); 
00305     lcd.locate(x,y+9);lcd.printf(" P arity      "); 
00306 }
00307 
00308 void loop()
00309 {   
00310     if (interrupt_counter == 0) {
00311     showClock();   
00312     lcd.locate(10,12);lcd.foreground (WHITE);lcd.printf("%02d",dcf_sec);
00313     } 
00314   }
00315   
00316 void set_time()
00317 {
00318             second = dcf_sec;
00319             minute=p_minute;
00320             hour=p_hour;
00321             dayofweek=p_dayofweek;
00322             dayofmonth=p_dayofmonth;
00323             month=p_month;
00324             year=p_year;
00325 }
00326 
00327 void restart()
00328 {
00329 start=0;s=0;x=0;y=5;dcf_sec=0;dcf_error=0;
00330 insecond_counter=0;zero_bit=0;start_delay=1;
00331 }
00332 
00333 void parity_calc()
00334 {
00335 //calculate summer/winter time----------------------------------------------------------------------
00336     summertime = dcf_array[17] & 1;
00337 //calculate hour--------------------------------------------------------------------------------------
00338     hourh = dcf_array[34] * 20 + dcf_array[33] * 10;
00339     hourl = dcf_array[32] * 8 + dcf_array[31] * 4 + dcf_array[30] * 2 + dcf_array[29] * 1;
00340     p_hour = hourh + hourl;
00341 //calculate minutes------------------------------------------------------------------------------------
00342     minl = dcf_array[24] * 8 + dcf_array[23] * 4 + dcf_array[22] * 2 + dcf_array[21] * 1;
00343     minh = dcf_array[27] * 40 + dcf_array[26] * 20 +dcf_array[25] * 10;
00344     p_minute = minh + minl;
00345 //calculate day of week--------------------------------------------------------------------------------
00346     p_dayofweek = dcf_array[44] * 4 +dcf_array[43] * 2 + dcf_array[42] * 1;
00347 //calculate day----------------------------------------------------------------------------------------
00348     dayl = dcf_array[39] * 8 + dcf_array[38] * 4 + dcf_array[37] * 2 + dcf_array[36] * 1;
00349     dayh = dcf_array[41] * 20 + dcf_array[40] * 10;
00350     p_dayofmonth=dayh+dayl;
00351 //calculate month--------------------------------------------------------------------------------------
00352     monthh = dcf_array[49] * 10;
00353     monthl = dcf_array[48] * 8 + dcf_array[47] * 4 + dcf_array[46] * 2 + dcf_array[45] * 1;
00354     p_month = monthh +monthl;
00355 //calculate year---------------------------------------------------------------------------------------
00356     yearh = dcf_array[57] * 80 + dcf_array[56] * 40 + dcf_array[55] * 20 + dcf_array[54] * 10;
00357     yearl = dcf_array[53] * 8 +dcf_array[52] * 4 + dcf_array[51] * 2 + dcf_array[50] * 1;
00358     p_year = yearh+yearl;
00359 //calculate parity
00360     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];
00361     parityu =dcf_array[29] + dcf_array[30] + dcf_array[31] + dcf_array[32] + dcf_array[33] + dcf_array[34] + dcf_array[35];
00362     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];
00363 //test parity------------------------------
00364     testu=parityu & 1;
00365     testm=paritym & 1;
00366     testdmy=paritydmy & 1;
00367   }
00368