路之遥电子网

注册

 

发新话题 回复该主题

[教程] Fireduino使用实例01.Fireduino 网络万年历 [复制链接]

1#
前言

Fireduino 网络万年历是一个可以通过wifi联网,通过NTP协议获取到网络时间,并且使用RTC运行时钟以及万年历显示的示例,其中万年历可以显示从1583开始的公历以及星期,并且可以通过按键翻阅日历。

操作流程

  • 上电后进行TFT初始化和WIFI初始化,进行WIFI连接并且在TFT上进行提示。
  • 通过网络NTP协议获取网络时间,并且写入到RTC中,如果NTP获取失败,将在星期右侧显示字符“-_-||”表示同步失败,下次同步成功后可以消除该状态。
  • 进入“时钟”界面,在TFT上显示表盘、星期、日期以及时间。
  • 短按按Mode键同步NTP网络时间。
  • 长按Mode键后循环切换主显示界面,主要有"时钟"界面、"本月日历"界面以及"翻阅万年历"界面。
  • "本月日历"界面显示年份、月份以及本月日历(包含星期)以及高亮显示今日位置,无切换界面外的按键响应。
  • “翻阅万年历”界面可以通过按键翻阅日历。短按MODE 切换位,短按UP、DOWN调相应值,长按快速UP、DOWN调相应值。
硬件连接Fireduino

Fireduino 作为主MCU,为驱动TFT、RTC、KEY等提供逻辑运行环境。

TFT

TFT 为显示设备,主要提供显示表盘以及时间字符、日历显示。



RTC

RTC 是板载的RTC独立单元,用于保存和获取实时时间,使用的为HYM8563,挂载在I2C1 接口,Fireduino 为此提供了专门的RTC库可供直接使用。



按键

按键用于修改切换显示界面、同步NTP时间以及浏览日历。

软件逻辑界面

网络万年历主要分为如下几个界面

  1. // status of display
  2. #define MODE_DISPLAY_TIME    0      //显示表盘、今日星期、日期以及时间
  3. #define MODE_DISPLAY_CAL    1      //显示本月日历
  4. #define    MODE_BROWSE_CAL        2      //翻阅日历
复制代码
事件

事件由按键触发,为事件处理提供依据

  1. #define EVENT_MODE         1     //模式键抬起事件
  2. #define EVENT_UP         2     // UP事件      
  3. #define EVENT_DOWN               3     // DOWN事件
  4. #define EVENT_MODE_CHANG      4     // 模式改变时间
  5. #define EVENT_MODE_CLICK     5     //模式键按下事件
复制代码
按键处理

本示例使用了3个按键,使用了pin 5、6、7,每20ms 扫描一次按键状态,支持长按和短按。

按键扫描

每20ms扫描一次。

  1. void key_sacn(void)
  2. {
  3.     unsigned char pin_level = 0;
  4.     if(digitalRead(5) == HIGH)
  5.     {
  6.         pin_level |= KEY_MODE;
  7.     }
  8.     if(digitalRead(6) == HIGH)
  9.     {
  10.         pin_level |= KEY_UP;
  11.     }
  12.     if(digitalRead(7) == HIGH)
  13.     {
  14.         pin_level |= KEY_DOWN;
  15.     }

  16.     key_trg = pin_level&(pin_level^key_count);
  17.     key_count = pin_level;
  18. }
复制代码
按键处理

根据状态,生成事件

  1. void key_proc(void)
  2. {
  3.     if(key_trg & KEY_UP)
  4.     {
  5.         event_key = EVENT_UP    ;
  6.     }

  7.     if(key_count & KEY_UP)
  8.     {
  9.         up_count++;
  10.         if(up_count > 100)
  11.         {
  12.             up_count = 80 + up_count_i;
  13.             if(up_count_i++ >100)
  14.             {
  15.                 up_count_i = 100;
  16.             }
  17.             event_key = EVENT_UP;
  18.         }
  19.     }
  20.     else
  21.     {
  22.         up_count = 0;
  23.         up_count_i = 0;
  24.     }

  25. }
复制代码
显示处理

根据不同模式,显示不同界面。


  • MODE_DISPALY_TIME 模式显示时钟表盘及今日星期、日期和时间。
  • MODE_DISPALY_CAL 模式显示本月日历,显示年份、月份、星期以及高亮显示今日日期位置。
  • MODE_BROWSE_CAL 模式显示可翻阅的日历,可修改年份和月份,修改的位会相应的闪烁。
事件处理

事件处理在按键处理之后,根据时间对于不同的处理。

  1. void event_proc(void)
  2. {
  3.     if(event_key)
  4.     {
  5.         switch(event_key)
  6.         {
  7.             case EVENT_MODE :
  8.                 .....
  9.             break;
  10.             case EVENT_UP :
  11.                 .....                          
  12.              break;
  13.             case MODIFY_HOUR :
  14.                 .....                
  15.             break;
  16.             case EVENT_DOWN :
  17.                 .....              
  18.             break;
  19.             case EVENT_MODE_CHANG :
  20.                 .....  
  21.             break;
  22.         }
  23.          event_key = 0;
  24.     }
  25. }
复制代码
绘图处理
  1. void clear_all(void);                                //清除整个屏幕
  2. void clear_dial(void);                               //清除表盘
  3. void clear_time_pointer(void);                       //清除表指针
  4. void clear_time_txt(unsigned char flash_bit);        //清除时钟界面显示的文本
  5. void draw_dial(void);                                //绘制表盘
  6. void draw_time_pointer(RTCTime *time);               //绘制表指针
  7. void draw_time_txt(RTCTime *time);                   //绘制时钟界面显示文本
  8. void draw_cal(RTCTime *time);                        //绘制今日日历
  9. void draw_browse_cal(RTCTime *time);                 //绘制可翻阅日历
复制代码
Arduino 程序结构setup
  1.   // initialize the serial port
  2.   Serial.begin(115200);

  3.   // initialize the TFT Screen
  4.   delay(1);
  5.   TFTscreen.begin();
  6.   Serial.println("TFTscreen init success");

  7.   delay(1);
  8.   // clear the screen with a pretty color
  9.   TFTscreen.background(0, 0, 0);
  10.   TFTscreen.setTextSize(1);
  11.   TFTscreen.stroke(255,255,255);

  12.   // attempt to connect to Wifi network:
  13.   while (status != WL_CONNECTED) {

  14.     Serial.print("Attempting to connect to SSID: ");
  15.     Serial.println(ssid);

  16.     TFTscreen.text("Connecting  ",28,70);
  17.     TFTscreen.text("    ...     ",28,90);
  18.     // Connect to network.
  19.     status = WiFi.begin(ssid, pass);
  20.   }

  21.   Serial.println("Connected to wifi");
  22.   printWifiStatus();
  23.   TFTscreen.fillRect(0,70,128,40,0);

  24.   // initialize UDP
  25.   Serial.println("\nStarting connection to server...");
  26.   Udp.begin(localPort);

  27.   // Init Wire and RTC will use I2C Interface
  28.   Wire1.begin();

  29.   getNtpTimeSuccess = 0;

  30.   // Get NTP time
  31.   ntpTime();

  32.   // if failed ,note user
  33.   if (!getNtpTimeSuccess)
  34.   {
  35.       TFTscreen.stroke(255,0,0);
  36.       TFTscreen.textSize(1);
  37.       TFTscreen.text("get NTP Time",28,70);
  38.       TFTscreen.text("failed",46,80);
  39.       delay(3000);
  40.       TFTscreen.stroke(0,0,0);
  41.       TFTscreen.text("get NTP Time",28,70);
  42.       TFTscreen.text("failed",46,80);
  43.       TFTscreen.stroke(255,255,255);
  44.       TFTscreen.textSize(2);
  45.   }
  46.   else
  47.       RTC.setTime(&time);

  48.   // display the dial
  49.   draw_dial();
复制代码
loop
  1. if(millis() > curr_ms)
  2.     {
  3.         curr_ms = millis() + 250;
  4. //        displaytime();
  5.         display_proc();
  6.     }
  7.     //20ms 检测一次按键状态
  8.     if(millis() > curr_ms_key)
  9.     {
  10.         curr_ms_key = millis() + 20;
  11.         key_sacn();
  12.         key_proc();
  13.         event_proc();

  14.     }
复制代码
示例程序
  1. #include <TFT.h>  // Arduino LCD library
  2. #include "RTC.h"
  3. #include "WiFi.h"
  4. #include <WiFiUdp.h>
  5. #include "Wire.h"

  6. // define for calculate time
  7. #define SECONDS_IN_DAY          86400
  8. #define START_YEAR              1900
  9. #define TIME_ZONE               +8

  10. // status of display
  11. #define MODE_DISPLAY_TIME    0
  12. #define MODE_DISPLAY_CAL    1
  13. #define    MODE_BROWSE_CAL        2
  14. //#define MODE_DGET_NTP_TIME_FAILD    3

  15. // event of key
  16. #define EVENT_MODE            1
  17. #define EVENT_UP            2
  18. #define EVENT_DOWN          3
  19. #define EVENT_MODE_CHANG     4
  20. #define EVENT_MODE_CLICK    5

  21. // Key flag
  22. #define KEY_MODE    0x01
  23. #define KEY_UP        0x02
  24. #define KEY_DOWN    0x04

  25. #define    UP_YEAR                0
  26. #define    DOWN_YEAR            1
  27. #define    UP_MON                2
  28. #define    DOWN_MON            3

  29. // count ms of key press
  30. unsigned int curr_ms;
  31. unsigned int curr_ms_key;

  32. // current status
  33. unsigned char curr_mode;
  34. unsigned char event_key;

  35. // counts of key press
  36. unsigned char mode_count;
  37. unsigned char up_count;
  38. unsigned char down_count;

  39. unsigned char mode_count_i;
  40. unsigned char up_count_i;
  41. unsigned char down_count_i;

  42. // flag of keys
  43. unsigned char key_trg;
  44. unsigned char key_count;

  45. unsigned char modif_bit = 0;

  46. // for display the month
  47. static int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  48. String mon_list[] = {"   ","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

  49. // WIFI information
  50. int status = WL_IDLE_STATUS;
  51. char ssid[] = "Fireduino";  //  your network SSID (name)
  52. char pass[] = "12345678";       // your network password

  53. // Get NTP time status
  54. unsigned char getNtpTimeSuccess;

  55. unsigned int localPort = 2390;      // local port to listen for UDP packets

  56. IPAddress timeServer(128, 138, 140, 44); // time-nw.nist.gov NTP server

  57. const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message

  58. byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

  59. // A UDP instance to let us send and receive packets over UDP
  60. WiFiUDP Udp;

  61. RTCTime time;
  62. RTCTime browseTime;
  63. String cal_char[6][7];
  64. String browse_cal_char[6][7];

  65. TFT TFTscreen = TFT();

  66. // function for WIFI
  67. void printWifiStatus();

  68. // function for NTP Time
  69. unsigned long sendNTPpacket(IPAddress& address);

  70. RTCTime * timeStamp2time(unsigned int timeStamp ,RTCTime *time);

  71. void ntpTime(void);

  72. // function for display
  73. unsigned char Lcd_TimeX(unsigned char circle_x,unsigned char Length,unsigned char Angle);
  74. unsigned char Lcd_TimeY(unsigned char circle_y,unsigned char Length,unsigned char Angle);
  75. void clear_all(void);
  76. void clear_dial(void);
  77. void clear_time_pointer(void);
  78. void clear_time_txt(unsigned char flash_bit);
  79. void draw_dial(void);
  80. void draw_time_pointer(RTCTime *time);
  81. void draw_time_txt(RTCTime *time);
  82. void draw_cal(RTCTime *time);
  83. void draw_browse_cal(RTCTime *time);

  84. // function of key event
  85. void key_sacn(void);
  86. void key_proc(void);
  87. void event_proc(void);
  88. void display_proc(void);

  89. void setup() {

  90.   // initialize the serial port
  91.   Serial.begin(115200);

  92.   // initialize the TFT Screen
  93.   delay(1);
  94.   TFTscreen.begin();
  95.   Serial.println("TFTscreen init success");

  96.   delay(1);
  97.   // clear the screen with a pretty color
  98.   TFTscreen.background(0, 0, 0);
  99.   TFTscreen.setTextSize(1);
  100.   TFTscreen.stroke(255,255,255);

  101.   // attempt to connect to Wifi network:
  102.   while (status != WL_CONNECTED) {

  103.     Serial.print("Attempting to connect to SSID: ");
  104.     Serial.println(ssid);

  105.     TFTscreen.text("Connecting  ",28,70);
  106.     TFTscreen.text("    ...     ",28,90);
  107.     // Connect to network.
  108.     status = WiFi.begin(ssid, pass);
  109.   }

  110.   Serial.println("Connected to wifi");
  111.   printWifiStatus();
  112.   TFTscreen.fillRect(0,70,128,40,0);

  113.   // initialize UDP
  114.   Serial.println("\nStarting connection to server...");
  115.   Udp.begin(localPort);

  116.   // Init Wire and RTC will use I2C Interface
  117.   Wire1.begin();

  118.   getNtpTimeSuccess = 0;

  119.   // Get NTP time
  120.   ntpTime();

  121.   // if failed ,note user
  122.   if (!getNtpTimeSuccess)
  123.   {
  124.       TFTscreen.stroke(255,0,0);
  125.       TFTscreen.textSize(1);
  126.       TFTscreen.text("get NTP Time",28,70);
  127.       TFTscreen.text("failed",46,80);
  128.       delay(3000);
  129.       TFTscreen.stroke(0,0,0);
  130.       TFTscreen.text("get NTP Time",28,70);
  131.       TFTscreen.text("failed",46,80);
  132.       TFTscreen.stroke(255,255,255);
  133.       TFTscreen.textSize(2);
  134.   }
  135.   else
  136.       RTC.setTime(&time);

  137.   // display the dial
  138.   draw_dial();
  139. }

  140. void loop() {

  141.     if(millis() > curr_ms)
  142.     {
  143.         curr_ms = millis() + 250;
  144. //        displaytime();
  145.         display_proc();
  146.     }
  147.     //20ms 检测一次按键状态
  148.     if(millis() > curr_ms_key)
  149.     {
  150.         curr_ms_key = millis() + 20;
  151.         key_sacn();
  152.         key_proc();
  153.         event_proc();

  154.     }


  155. }


  156. void printWifiStatus() {
  157.   // print the SSID of the network you're attached to:
  158.   Serial.print("SSID: ");
  159.   Serial.println(WiFi.SSID());

  160.   // print your WiFi shield's IP address:
  161.   IPAddress ip = WiFi.localIP();
  162.   Serial.print("IP Address: ");
  163.   Serial.println(ip);

  164.   // print the received signal strength:
  165.   long rssi = WiFi.RSSI();
  166.   Serial.print("signal strength (RSSI):");
  167.   Serial.print(rssi);
  168.   Serial.println(" dBm");
  169. }

  170. // send an NTP request to the time server at the given address
  171. unsigned long sendNTPpacket(IPAddress& address) {
  172.   // set all bytes in the buffer to 0
  173.   memset(packetBuffer, 0, NTP_PACKET_SIZE);
  174.   // Initialize values needed to form NTP request
  175.   // (see URL above for details on the packets)
  176.   packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  177.   packetBuffer[1] = 0;     // Stratum, or type of clock
  178.   packetBuffer[2] = 6;     // Polling Interval
  179.   packetBuffer[3] = 0xEC;  // Peer Clock Precision
  180.   // 8 bytes of zero for Root Delay & Root Dispersion
  181.   packetBuffer[12]  = 49;
  182.   packetBuffer[13]  = 0x4E;
  183.   packetBuffer[14]  = 49;
  184.   packetBuffer[15]  = 52;


  185.   // all NTP fields have been given values, now
  186.   // you can send a packet requesting a timestamp:
  187.   Serial.print("Query NTP server ");
  188.   Serial.print(address);
  189.   Serial.print(" at port ");
  190.   Serial.println(123);
  191.   Udp.beginPacket(address, 123); //NTP requests are to port 123
  192.   Udp.write(packetBuffer, NTP_PACKET_SIZE);
  193.   Udp.endPacket();
  194. }

  195. boolean isLeapYear(unsigned int year) {
  196.   return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
  197. }

  198. RTCTime * timeStamp2time(unsigned int timeStamp ,RTCTime *time)
  199. {
  200.       unsigned int week = (((timeStamp / SECONDS_IN_DAY) + 1)% 7);

  201.       unsigned int year = START_YEAR;
  202.       while(1) {
  203.         uint32_t seconds;
  204.         if(isLeapYear(year)) seconds = SECONDS_IN_DAY * 366;
  205.         else seconds = SECONDS_IN_DAY * 365;
  206.         if(timeStamp >= seconds) {
  207.           timeStamp -= seconds;
  208.           year++;
  209.         } else break;
  210.       }

  211.       unsigned int month = 0;
  212.       while(1) {
  213.         uint32_t seconds = SECONDS_IN_DAY * days_in_month[month];
  214.         if(isLeapYear(year) && month == 1) seconds = SECONDS_IN_DAY * 29;
  215.         if(timeStamp >= seconds) {
  216.           timeStamp -= seconds;
  217.           month++;
  218.         } else break;
  219.       }
  220.       month++;

  221.       unsigned int day = 1;
  222.       while(1) {
  223.         if(timeStamp >= SECONDS_IN_DAY) {
  224.           timeStamp -= SECONDS_IN_DAY;
  225.           day++;
  226.         } else break;
  227.       }

  228.       unsigned int hour = timeStamp / 3600;
  229.       unsigned int minute = (timeStamp - (uint32_t)hour * 3600) / 60;
  230.       unsigned int second = (timeStamp - (uint32_t)hour * 3600) - minute * 60;


  231.       time->year = year;//year (1900 ~ 2099)
  232.       time->mon  = month;//month,begin from 1 to 12
  233.       time->week = week;//week (0:Sunday 1:Monday ... 6:Saturday)
  234.       time->day  = day;//day,begin from 1 to 31
  235.       time->hour = hour;//hour,24-hour
  236.       time->min  = minute;//minute
  237.       time->sec  = second;//second

  238.       return time;
  239. }

  240. void upgrade_cal(unsigned int modif_mode,RTCTime *time){
  241. //    static String browse_cal[][];
  242.     switch(modif_mode)
  243.     {
  244.         case    UP_MON    :
  245.             time->mon++;
  246.             if (time->mon > 12)
  247.                 time->mon = 1;
  248.             break;
  249.         case    UP_YEAR    :
  250.             time->year++;
  251.             break;
  252.         case    DOWN_MON    :
  253.             time->mon--;
  254.             if (time->mon < 1 || time->mon > 12)
  255.                 time->mon = 12;
  256.             break;
  257.         case    DOWN_YEAR    :
  258.             time->year--;
  259.             if (time->year < 1583)
  260.                 time->year = 1583;
  261.             break;
  262.         default    :
  263.             break;

  264.     }
  265. }

  266. void ntpTime(){

  267.     sendNTPpacket(timeServer); // send an NTP packet to a time server

  268.     TFTscreen.stroke(255,255,255);
  269.     TFTscreen.textSize(1);
  270.     TFTscreen.text("waitting for get",16,70);
  271.     TFTscreen.text("NTP Time",40,80);
  272.     delay(1000);

  273.     if (Udp.parsePacket()) {
  274.         Serial.println("packet received");
  275.         // We've received a packet, read the data from it
  276.         Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

  277.         //the timestamp starts at byte 40 of the received packet and is four bytes,
  278.         // or two words, long. First, esxtract the two words:
  279.         unsigned long highWord = ((unsigned long)packetBuffer[40] << 8) | (unsigned long)packetBuffer[41];
  280.         unsigned long lowWord = ((unsigned long)packetBuffer[42] << 8) | (unsigned long)packetBuffer[43];
  281.         // combine the four bytes (two words) into a long integer
  282.         // this is NTP time (seconds since Jan 1 1900):
  283.         unsigned long secsSince1900 = (highWord << 16) | lowWord;
  284.         Serial.print("Seconds since Jan 1 1900 = ");
  285.         Serial.println(secsSince1900);

  286.         timeStamp2time(secsSince1900 + (3600 * (TIME_ZONE)) , &time);
  287.         browseTime = time;
  288.         RTC.setTime(&time);
  289.         getNtpTimeSuccess = 1;
  290.     }
  291.     else
  292.         getNtpTimeSuccess = 0;

  293.     RTC.getTime(&time);
  294.     Serial.println();
  295.     Serial.print("Y:");
  296.     Serial.print(time.year,DEC);
  297.     Serial.print(" M:");
  298.     Serial.print(time.mon,DEC);
  299.     Serial.print(" d:");
  300.     Serial.print(time.day,DEC);
  301.     Serial.print(" W:");
  302.     Serial.print(time.week,DEC);
  303.     Serial.print("    h:");
  304.     Serial.print(time.hour,DEC);
  305.     Serial.print(" m:");
  306.     Serial.print(time.min,DEC);
  307.     Serial.print(" s:");
  308.     Serial.print(time.sec,DEC);
  309.     Serial.println();

  310.     TFTscreen.stroke(0,0,0);
  311.     TFTscreen.text("waitting for get",16,70);
  312.     TFTscreen.text("NTP Time",40,80);
  313.     TFTscreen.stroke(255,255,255);
  314.     TFTscreen.textSize(2);

  315. }

  316. unsigned char Lcd_TimeX(unsigned char circle_x,unsigned char Length,unsigned char Angle)
  317. {
  318.    unsigned char x;
  319.    if((Angle>0) && (Angle<=15))
  320.    {
  321.      x = circle_x + Length * (sin(PI * Angle / 30));
  322.    }
  323.    else if(Angle > 15 && Angle <= 30)
  324.    {
  325.       x = circle_x + Length * cos((PI * Angle) / 30 - (PI / 2 ));
  326.    }
  327.    else if(Angle > 30 && Angle <= 45)
  328.    {
  329.        x = circle_x - Length * sin((PI * Angle) / 30- PI);
  330.    }
  331.    else
  332.    {
  333.        x = circle_x-Length * cos((PI * Angle) / 30 - ((3 * PI) / 2));
  334.    }
  335.         return x;
  336. }

  337. unsigned char Lcd_TimeY(unsigned char circle_y,unsigned char Length,unsigned char Angle)
  338. {
  339.    unsigned char y;
  340.    if((Angle>0) && (Angle<=15))
  341.    {
  342.       y = circle_y - Length * (cos(PI * Angle / 30));
  343.    }
  344.    else if(Angle > 15 && Angle <= 30)
  345.    {
  346.       y = circle_y + Length * sin((PI * Angle) / 30 - (PI / 2 ));
  347.    }
  348.    else if(Angle > 30 && Angle <= 45)
  349.    {
  350.        y = circle_y + Length * cos((PI * Angle) / 30- PI);
  351.    }
  352.    else
  353.    {
  354.        y = circle_y - Length * sin((PI * Angle) / 30 - ((3 * PI) / 2));
  355.    }
  356.    return y;
  357. }

  358. void clear_all(void){
  359.     TFTscreen.fillRect(0,0,128,160,0);
  360. }

  361. void clear_dial(void){
  362.     unsigned int i ;

  363.     TFTscreen.circle(64,48,46);
  364.     TFTscreen.circle(64,48,45);

  365.     for(i=0;i<60;i++)
  366.     {
  367.       if((i%5) == 0)
  368.       {
  369.           TFTscreen.line(Lcd_TimeX(64,45,i),Lcd_TimeY(48,45,i),Lcd_TimeX(64,42,i),Lcd_TimeY(48,42,i));
  370.       }

  371.     }

  372. }

  373. void clear_time_pointer(void)
  374. {
  375.     unsigned char i;
  376.     for(i = 0;i<60;i++)
  377.     {
  378.         TFTscreen.line(Lcd_TimeX(64,36,i) ,Lcd_TimeY(48,36,i) ,64,48);
  379.         TFTscreen.line(Lcd_TimeX(64,30,i) ,Lcd_TimeY(48,30,i) ,64,48);
  380.         TFTscreen.line(Lcd_TimeX(64,20,i) ,Lcd_TimeY(48,20,i) ,64,48);
  381.     }
  382. }

  383. void clear_time_txt(unsigned char flash_bit)
  384. {
  385.     switch(flash_bit)
  386.     {
  387.         case 0:
  388.             TFTscreen.fillRect(44,100,33,14,0);
  389.         break;

  390.         case 1:
  391.             TFTscreen.fillRect(6,120,110,14,0);
  392.         break;

  393.         case 2:
  394.             TFTscreen.fillRect(18, 140,94,14,0);
  395.         break;

  396.         case 3:
  397.             TFTscreen.fillRect(0, 100,128,60,0);
  398.         break;

  399.         default:
  400.             TFTscreen.fillRect(18, 140,94,14,0);
  401.         break;
  402.     }
  403. }

  404. void draw_dial(void)
  405. {
  406.     unsigned int i ;

  407.     TFTscreen.circle(64,48,46);
  408.     TFTscreen.circle(64,48,45);

  409.     for(i=0;i<60;i++)
  410.     {
  411.       if((i%5) == 0)
  412.       {
  413.           TFTscreen.line(Lcd_TimeX(64,45,i),Lcd_TimeY(48,45,i),Lcd_TimeX(64,42,i),Lcd_TimeY(48,42,i));
  414.       }

  415.     }
  416. }

  417. void draw_time_pointer(RTCTime *time)
  418. {
  419.     TFTscreen.line(Lcd_TimeX(64,36,time->sec) ,Lcd_TimeY(48,36,time->sec) ,64,48);
  420.     TFTscreen.line(Lcd_TimeX(64,30,time->min) ,Lcd_TimeY(48,30,time->min) ,64,48);
  421.     TFTscreen.line(Lcd_TimeX(64,20,time->min/10 + ((time->hour%12)*5)),Lcd_TimeY(48,20,time->min/10 +((time->hour%12)*5)),64,48);
  422. }

  423. void draw_time_txt(RTCTime *time){

  424.     char temp[9];

  425.     String week[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};

  426.     TFTscreen.text(week[time->week].c_str(), (64-18), 100);

  427.     sprintf(temp,"%04d-%02d-%02d",time->year,time->mon,time->day);
  428.     temp[10] = 0;
  429.     TFTscreen.text(temp, 6, 120);


  430.     sprintf(temp,"%02d:%02d:%02d",time->hour,time->min,time->sec);
  431.     temp[8] = 0;
  432.     TFTscreen.text(temp, 18, 140);
  433. }

  434. unsigned int get_ref_week_for_mon(RTCTime *time){
  435.     // w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
  436. //    unsigned int week;
  437.     int year;
  438.     int century;
  439.     int mon;
  440.     int ref_week;

  441.     year = time->year%100;
  442.     century = time->year/100;
  443.     if (time->mon < 3)
  444.     {
  445.         mon = time->mon + 12;
  446.         year -= 1;
  447.     }
  448.     else
  449.         mon = time->mon;

  450.     ref_week = ((year + (year/4) + (century/4) - 2*century + (26*(mon + 1)/10)) % 7);

  451.     while (ref_week < 0)
  452.         ref_week += 7;

  453.     Serial.print("century : ");
  454.     Serial.println(century);
  455.     Serial.print("year : ");
  456.     Serial.println(year);
  457.     Serial.print("mon : ");
  458.     Serial.println(mon);
  459.     Serial.print("ref_week : ");
  460.     Serial.println(ref_week);


  461.     return (unsigned int)ref_week;
  462. }

  463. unsigned int get_cal_char(RTCTime *time){
  464.     unsigned int ref_week;
  465.     unsigned int last_month;
  466.     unsigned int next_day;
  467.     unsigned int mon_tail;
  468.     unsigned int cnt_x,cnt_y;
  469.     unsigned int cur_x,cur_y;

  470.     ref_week = get_ref_week_for_mon(time);

  471.     cur_x = (time->day-ref_week)/7+1;
  472.     cur_y = time->week - 1;

  473.     if (time->mon == 1 || time->mon == 3 || time->mon == 5 || time->mon == 7 || time->mon == 8 || \
  474.             time->mon == 10 || time->mon == 12)
  475.         mon_tail = 31;
  476.     else if (time->mon == 4 || time->mon == 6 || time->mon == 9 || time->mon == 11)
  477.         mon_tail = 30;
  478.     else if (time->mon == 2 && time->year/4 == 0)
  479.     {
  480.         if (time->year/100 == 0 && time->year/400 != 0)
  481.         mon_tail = 29;
  482.         else
  483.         mon_tail = 28;
  484.     }
  485.     else
  486.         mon_tail = 28;

  487.     Serial.print("mon_tail : ");
  488.     Serial.println(mon_tail);
  489.     for (cnt_y = 0;cnt_y < ref_week;cnt_y++)
  490.         cal_char[0][cnt_y] = " ";
  491.     for (cnt_y = ref_week;cnt_y < 7 ;cnt_y++)
  492.         cal_char[0][cnt_y] = String(cnt_y-ref_week + 1);
  493.     next_day = cnt_y-ref_week + 1;
  494.     for (cnt_x = 1;cnt_x < 6;cnt_x++)
  495.     {
  496.         if ((mon_tail - next_day) > 7)
  497.         {
  498.             for (cnt_y = 0;cnt_y<7;cnt_y++)
  499.                 cal_char[cnt_x][cnt_y] = String(next_day+cnt_y);
  500.             next_day += 7;
  501.         }
  502.         else
  503.         {
  504.             for (cnt_y = 0;cnt_y < (mon_tail - next_day + 1);cnt_y++)
  505.                 cal_char[cnt_x][cnt_y] = String(next_day+cnt_y);
  506.             for (cnt_y = (mon_tail - next_day + 1);cnt_y < 7;cnt_y++)
  507.                 cal_char[cnt_x][cnt_y] = " ";
  508.             cnt_x++;
  509.             while (cnt_x < 6)
  510.             {
  511.                 for (cnt_y = 0;cnt_y < 7;cnt_y++)
  512.                     cal_char[cnt_x][cnt_y] = " ";
  513.                 cnt_x++;
  514.             }
  515.         }
  516.     }
  517.     return ref_week;

  518. }

  519. unsigned int get_browse_cal_char(RTCTime *time){
  520.     unsigned int ref_week;
  521.     unsigned int last_month;
  522.     unsigned int next_day;
  523.     unsigned int mon_tail;
  524.     unsigned int cnt_x,cnt_y;
  525.     unsigned int cur_x,cur_y;

  526.     ref_week = get_ref_week_for_mon(time);

  527.     cur_x = (time->day-ref_week)/7+1;
  528.     cur_y = time->week - 1;

  529.     if (time->mon == 1 || time->mon == 3 || time->mon == 5 || time->mon == 7 || time->mon == 8 || \
  530.             time->mon == 10 || time->mon == 12)
  531.         mon_tail = 31;
  532.     else if (time->mon == 4 || time->mon == 6 || time->mon == 9 || time->mon == 11)
  533.         mon_tail = 30;
  534.     else if (time->mon == 2 && time->year/4 == 0)
  535.     {
  536.         if (time->year/100 == 0 && time->year/400 != 0)
  537.         mon_tail = 29;
  538.         else
  539.         mon_tail = 28;
  540.     }
  541.     else
  542.         mon_tail = 28;

  543.     Serial.print("mon_tail : ");
  544.     Serial.println(mon_tail);
  545.     for (cnt_y = 0;cnt_y < ref_week;cnt_y++)
  546.         browse_cal_char[0][cnt_y] = " ";
  547.     for (cnt_y = ref_week;cnt_y < 7 ;cnt_y++)
  548.         browse_cal_char[0][cnt_y] = String(cnt_y-ref_week + 1);
  549.     next_day = cnt_y-ref_week + 1;
  550.     for (cnt_x = 1;cnt_x < 6;cnt_x++)
  551.     {
  552.         if ((mon_tail - next_day) > 7)
  553.         {
  554.             for (cnt_y = 0;cnt_y<7;cnt_y++)
  555.                 browse_cal_char[cnt_x][cnt_y] = String(next_day+cnt_y);
  556.             next_day += 7;
  557.         }
  558.         else
  559.         {
  560.             for (cnt_y = 0;cnt_y < (mon_tail - next_day + 1);cnt_y++)
  561.                 browse_cal_char[cnt_x][cnt_y] = String(next_day+cnt_y);
  562.             for (cnt_y = (mon_tail - next_day + 1);cnt_y < 7;cnt_y++)
  563.                 browse_cal_char[cnt_x][cnt_y] = " ";
  564.             cnt_x++;
  565.             while (cnt_x < 6)
  566.             {
  567.                 for (cnt_y = 0;cnt_y < 7;cnt_y++)
  568.                     browse_cal_char[cnt_x][cnt_y] = " ";
  569.                 cnt_x++;
  570.             }
  571.         }
  572.     }
  573.     return ref_week;

  574. }


  575. void draw_cal(RTCTime *time){
  576.     //save the cal string to display
  577. //    String cal_char[5][7];
  578.     // cale the week of day 1
  579.     unsigned int ref_week;
  580.     unsigned int cnt_x,cnt_y;
  581.     unsigned int cur_x,cur_y;

  582.     ref_week = get_cal_char(time);

  583.     cur_x = (time->day + 6 - ref_week)/7;
  584.     cur_y = time->week;

  585.     for (cnt_x = 0;cnt_x <6;cnt_x++)
  586.         for (cnt_y = 0;cnt_y < 7;cnt_y++)
  587.         {
  588.             TFTscreen.text(cal_char[cnt_x][cnt_y].c_str(),cnt_y*18+4,cnt_x*18+60);
  589. //            Serial.print("X:");
  590. //            Serial.print(cnt_x);
  591. //            Serial.print("y:");
  592. //            Serial.print(cnt_y);
  593. //            Serial.print("value:");
  594. //            Serial.println(cal_char[cnt_x][cnt_y].c_str());
  595.         }

  596. //    Serial.print("cur_x : ");
  597. //    Serial.print(cur_x);
  598. //    Serial.print("  cur_y : ");
  599. //    Serial.println(cur_y);

  600.     TFTscreen.stroke(0,0,0);
  601.     TFTscreen.fillRect(cur_y*18+1,cur_x*18+57,18,12,0);
  602.     TFTscreen.stroke(255,255,255);
  603.     TFTscreen.fillRect(cur_y*18+1,cur_x*18+57,18,12,255);
  604.     TFTscreen.stroke(0,0,0);
  605.     TFTscreen.text(cal_char[cur_x][cur_y].c_str(),(cur_y)*18+4,((cur_x)*18+60));
  606. }

  607. void draw_browse_cal(RTCTime *time){
  608.     //save the cal string to display
  609. //    String cal_char[5][7];
  610.     // cale the week of day 1
  611.     unsigned int ref_week;
  612.     unsigned int cnt_x,cnt_y;
  613.     unsigned int cur_x,cur_y;

  614.     ref_week = get_browse_cal_char(time);

  615.     for (cnt_x = 0;cnt_x <6;cnt_x++)
  616.         for (cnt_y = 0;cnt_y < 7;cnt_y++)
  617.         {
  618.             TFTscreen.text(browse_cal_char[cnt_x][cnt_y].c_str(),cnt_y*18+4,cnt_x*18+60);
  619. //            Serial.print("X:");
  620. //            Serial.print(cnt_x);
  621. //            Serial.print("y:");
  622. //            Serial.print(cnt_y);
  623. //            Serial.print("value:");
  624. //            Serial.println(cal_char[cnt_x][cnt_y].c_str());
  625.         }
  626. }

  627. void draw_mon(RTCTime *time){
  628.     TFTscreen.text(String(time->year).c_str(),8,15);

  629. }

  630. void draw_year(RTCTime *time){
  631.     TFTscreen.text(mon_list[time->mon].c_str(),80,15);
  632. }

  633. void clear_mon(){
  634.     TFTscreen.fill(0,0,0);
  635.     TFTscreen.fillRect(80,15,33,15,0);
  636. }

  637. void clear_year(){
  638.     TFTscreen.fill(0,0,0);
  639.     TFTscreen.fillRect(8,15,44,15,0);
  640. }

  641. void draw_modif_cal(unsigned char modif_bit){
  642.     static unsigned char modif_flag = 0;
  643.     clear_year();
  644.     clear_mon();
  645.     if (modif_flag)
  646.     {
  647.         if (modif_bit)
  648.         {
  649.             TFTscreen.stroke(0,255,0);
  650.             draw_year(&browseTime);
  651.         }
  652.         else
  653.         {
  654.             TFTscreen.stroke(0,0,255);
  655.             draw_mon(&browseTime);
  656.         }
  657.     }
  658.     else
  659.     {
  660.         TFTscreen.stroke(0,0,255);
  661.         draw_mon(&browseTime);
  662.         TFTscreen.stroke(0,255,0);
  663.         draw_year(&browseTime);
  664.     }
  665.     modif_flag = ~modif_flag;
  666. }

  667. void clear_modif_cal(unsigned char modif_bit){
  668.     clear_year();
  669.     clear_mon();
  670. }

  671. void key_sacn(void)
  672. {
  673.     unsigned char pin_level = 0;
  674.     if(digitalRead(5) == HIGH)
  675.     {
  676.         pin_level |= KEY_MODE;
  677.     }
  678.     if(digitalRead(6) == HIGH)
  679.     {
  680.         pin_level |= KEY_UP;
  681.     }
  682.     if(digitalRead(7) == HIGH)
  683.     {
  684.         pin_level |= KEY_DOWN;
  685.     }

  686.     key_trg = pin_level&(pin_level^key_count);
  687.     key_count = pin_level;
  688. }

  689. void key_proc(void)
  690. {
  691.     if(key_trg & KEY_UP)
  692.     {
  693.         Serial.println("KEY_UP click");
  694.         event_key = EVENT_UP    ;
  695.     }

  696.     if(key_trg & KEY_DOWN)
  697.     {
  698.         Serial.println("KEY_DOWN click");
  699.         event_key = EVENT_DOWN    ;
  700.     }

  701.     if(key_trg & KEY_MODE)
  702.     {
  703.         Serial.println("KEY_MODE click");
  704.         event_key = EVENT_MODE_CLICK;
  705.     }

  706.     if((mode_count > 0 &&  mode_count < 50) && ( ((key_trg & KEY_MODE) == 0) & ((key_count & KEY_MODE) == 0)) )
  707.     {
  708.         Serial.println("KEY_MODE finsh click");
  709.         event_key = EVENT_MODE    ;
  710.     }


  711.     if(key_count & KEY_UP)
  712.     {
  713.         up_count++;
  714.         if(up_count > 100)
  715.         {
  716.             up_count = 80 + up_count_i;
  717.             if(up_count_i++ >100)
  718.             {
  719.                 up_count_i = 100;
  720.             }
  721.             Serial.println("KEY_UP long  click");
  722.             event_key = EVENT_UP;
  723.         }
  724.     }
  725.     else
  726.     {
  727.         up_count = 0;
  728.         up_count_i = 0;
  729.     }

  730.     if(key_count & KEY_DOWN)
  731.     {
  732.         down_count++;
  733.         if(down_count > 100)
  734.         {
  735.             down_count = 80 + down_count_i;
  736.             if(down_count_i++ >100)
  737.             {
  738.                 down_count_i = 100;
  739.             }
  740.             Serial.println("KEY_DOWN long click");
  741.             event_key = EVENT_DOWN;
  742.         }
  743.     }
  744.     else
  745.     {
  746.         down_count = 0;
  747.         down_count_i = 0;
  748.     }

  749.     if(key_count & KEY_MODE)
  750.     {
  751.         mode_count++;
  752.         if(mode_count > 100)
  753.         {
  754.             mode_count = 50;
  755. //            mode_count = 80 + mode_count_i;
  756. //            if(mode_count_i++ >100)
  757. //            {
  758. //                mode_count_i = 100;
  759. //            }
  760.             Serial.println("KEY_MODE  long click");
  761.             event_key = EVENT_MODE_CHANG;
  762.         }
  763.     }
  764.     else
  765.     {
  766.         mode_count = 0;
  767.         mode_count_i = 0;
  768.     }
  769. }

  770. void event_proc(void)
  771. {
  772.     if(event_key)
  773.     {
  774.         switch(event_key)
  775.         {
  776.             case EVENT_MODE_CLICK :
  777.             break;
  778.             case EVENT_MODE :
  779.                 if((curr_mode & 0x03) == MODE_DISPLAY_TIME)
  780.                 {
  781.                     Serial.println("updata NTP time");
  782.                     getNtpTimeSuccess = 0;

  783.                     TFTscreen.stroke(0,0,0);
  784.                     clear_dial();
  785.                     clear_time_pointer();
  786.                     clear_time_txt(3);

  787.                     ntpTime();

  788.                     if (!getNtpTimeSuccess)
  789.                     {
  790.                         TFTscreen.stroke(255,0,0);
  791.                         TFTscreen.textSize(1);
  792.                         TFTscreen.text("get NTP Time",28,70);
  793.                         TFTscreen.text("failed",46,80);
  794.                         delay(3000);
  795.                         TFTscreen.stroke(0,0,0);
  796.                         TFTscreen.text("get NTP Time",28,70);
  797.                         TFTscreen.text("failed",46,80);
  798.                         TFTscreen.stroke(255,255,255);
  799.                         TFTscreen.textSize(2);
  800.                     }

  801.                     TFTscreen.fillRect(0,70,128,10,0);
  802.                 }

  803.                 if ((curr_mode & 0x03) == MODE_BROWSE_CAL)
  804.                     modif_bit = ~ modif_bit;

  805. //                if (curr_mode == MODE_DISPLAY_TIME)
  806. //                    curr_mode = MODE_DISPLAY_CAL;
  807. //                else
  808. //                    curr_mode = MODE_DISPLAY_TIME;
  809. //                break;
  810.                 break;
  811.             case EVENT_UP :
  812.                 if (curr_mode == MODE_BROWSE_CAL)
  813.                 {
  814.                     if (!modif_bit)
  815.                         upgrade_cal(UP_MON,&browseTime);
  816.                     else
  817.                         upgrade_cal(UP_YEAR,&browseTime);
  818.                 }
  819.                 break;
  820.             case EVENT_DOWN :
  821.                 if (curr_mode == MODE_BROWSE_CAL)
  822.                 {
  823.                     if (!modif_bit)
  824.                         upgrade_cal(DOWN_MON,&browseTime);
  825.                     else
  826.                         upgrade_cal(DOWN_YEAR,&browseTime);
  827.                 }
  828.                 break;
  829.             case EVENT_MODE_CHANG :
  830.                 if (curr_mode == MODE_BROWSE_CAL)
  831.                     curr_mode = MODE_DISPLAY_TIME;
  832.                 else
  833.                     curr_mode++;
  834.                 browseTime = time;
  835.                 unsigned char i,j;
  836.                 for (i = 0; i < 6;i++)
  837.                     for (j = 0;j < 7; j++)
  838.                         browse_cal_char[i][j] = cal_char[i][j];
  839.                 break;
  840.                 break;

  841.             default:

  842.                 break;
  843.         }

  844.         event_key = 0;
  845.     }
  846. }

  847. void display_proc(void)
  848. {
  849.     static unsigned char modif_flag = 0;
  850.     switch(curr_mode)
  851.     {
  852.         case MODE_DISPLAY_TIME:
  853.             TFTscreen.stroke(0, 0, 0);
  854.             clear_all();
  855.             RTC.getTime(&time);
  856.             TFTscreen.stroke(255,255,255);
  857.             if (!getNtpTimeSuccess)
  858.             {
  859.                 TFTscreen.stroke(0,255,0);
  860.                 TFTscreen.textSize(1);
  861.                 TFTscreen.text("-_-||",90,100);
  862.                 TFTscreen.stroke(255,255,255);
  863.                 TFTscreen.textSize(2);
  864.             }
  865.             draw_dial();
  866.             draw_time_pointer(&time);
  867.             draw_time_txt(&time);
  868.             break;

  869.         case MODE_DISPLAY_CAL:
  870.             TFTscreen.stroke(0, 0, 0);
  871.             clear_all();
  872.             TFTscreen.stroke(0,0,255);
  873.             TFTscreen.textSize(1);
  874.             TFTscreen.text("Calendar",40,0);
  875.             TFTscreen.textSize(2);
  876.             TFTscreen.stroke(0,255,0);
  877.             draw_year(&time);
  878.             TFTscreen.stroke(0,0,255);
  879.             draw_mon(&time);
  880.             TFTscreen.textSize(1);
  881.             TFTscreen.stroke(0,255,0);
  882.             TFTscreen.text("S  M  T  W  T  F  S ",4,40);
  883.             draw_cal(&time);
  884.             TFTscreen.stroke(255,255,255);
  885.             TFTscreen.textSize(2);

  886.             break;
  887.         case MODE_BROWSE_CAL :
  888.             TFTscreen.stroke(0, 0, 0);
  889.             clear_all();
  890.             TFTscreen.stroke(0,0,255);
  891.             TFTscreen.textSize(1);
  892.             TFTscreen.text("Calendar",40,0);
  893.             TFTscreen.textSize(2);
  894. //            if (modif_flag)
  895. //                clear_modif_cal(modif_bit);
  896. //                clear_mon();
  897. //            else
  898.                 draw_modif_cal(modif_bit);
  899. //                clear_mon();

  900. //            TFTscreen.stroke(0,255,0);
  901. //            TFTscreen.text(String(time.year).c_str(),8,15);
  902. //            TFTscreen.stroke(0,0,255);
  903. //            TFTscreen.text(mon_list[time.mon].c_str(),80,15);
  904.             TFTscreen.textSize(1);
  905.             TFTscreen.stroke(0,255,0);
  906.             TFTscreen.text("S  M  T  W  T  F  S ",4,40);
  907.             draw_browse_cal(&browseTime);
  908.             TFTscreen.stroke(255,255,255);
  909.             TFTscreen.textSize(2);
  910.             modif_flag = ~modif_flag;
  911.             break;
  912.         default :
  913.             break;
  914.     }
  915. }
复制代码
最后编辑410875131@qq.com 最后编辑于 2016-11-18 15:35:05
分享 转发
TOP
2#

楼主,你好,可以给完整的电原理图、接线;完整程序吗?仿制学习。
对万年历、音乐比较兴趣,计划拍一块Fireduino回来玩玩!
谢谢!
TOP
3#

很专业
TOP
4#

回复 2楼yuqingshan@126.的帖子

帖子里已经给出了接线原理图和程序,如有问题可以加官方交流群450340779
TOP
发新话题 回复该主题