极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 29432|回复: 10

Microduino-RTC小应用:网络时钟+OLED显示

[复制链接]
发表于 2013-8-29 00:34:02 | 显示全部楼层 |阅读模式
本帖最后由 wasdpkj 于 2013-8-29 00:41 编辑

[关于microduino上架问题:老张和tiki最近都很忙,过些天应该会陆续上架,需要模块的朋友耐心等等]

------------------------------------------------------------

关于Microduino-RTC模块:
Microduino-RTC模块是基于 PCF8563芯片的时钟模块,模块还附加AT24c32芯片,提供额外的EEPROM功能。I2C接口通信。 采用电容提供了一定的掉电计时能力。PCF8563使用一个外部晶体和电容,并有1个中断输出,可以定时触发中断。
更详细信息:http://wiki.microduino.net/wiki/Microduino-RTC

关于RTC等I2C模块适配Core+:
Core+的IIC接口和Core的不一样,不是A4和A5,而是D20(SDA)和D21(SCL),请注意引出。



先看看如何驱动RTC模块:
首先我们来设置时间,我在源程序“set_clock”的基础上加以修改,时间的两个格式都调用出来。(源程序setup里少了一行串口初始化 Serial.begin(9600);)


  1. #include <Wire.h>
  2. #include <Rtc_Pcf8563.h>

  3. //init the real time clock
  4. Rtc_Pcf8563 rtc;

  5. void setup()
  6. {
  7.   Serial.begin(9600);
  8.   //clear out the registers
  9.   rtc.initClock();
  10.   //set a time to start with.
  11.   //day, weekday, month, century(1=1900, 0=2000), year(0-99)
  12.   rtc.setDate(29, 4, 8, 0, 13);
  13.   //hr, min, sec
  14.   rtc.setTime(00, 21, 0);
  15. }

  16. void loop()
  17. {
  18.   //both format functions call the internal getTime() so that the
  19.   //formatted strings are at the current time/date.
  20.   Serial.println("CODE_1:");
  21.   Serial.print(rtc.formatTime());
  22.   Serial.print("     ");
  23.   Serial.print(rtc.formatDate());
  24.   Serial.print("\r\n");

  25.   Serial.println("CODE_2:");
  26.   Serial.print("20");
  27.   Serial.print(rtc.getYear());
  28.   Serial.print("/");
  29.   Serial.print(rtc.getMonth());
  30.   Serial.print("/");
  31.   Serial.print(rtc.getDay());
  32.   Serial.print("     ");
  33.   Serial.print(rtc.getHour());
  34.   Serial.print(":");
  35.   Serial.print(rtc.getMinute());
  36.   Serial.print(":");
  37.   Serial.print(rtc.getSecond());
  38.   Serial.print("\r\n");

  39.   delay(1000);
  40.   Serial.print("\r\n");
  41. }

  42. }
复制代码


运行效果:


===================================================

接下来简单介绍一下标题所指的应用:
主要功能:开机自动获取DHCP,获取网络NTP时间,如果成功则会将时间同步到Pcf8563里。加以OLED显示。

硬件用到了:
Microduino-Core+、Microduino-FT232R、【Microduino-ENC28J60】 + 【Microduino-RJ45】、Microduino-OLED、Microduino-RTC。



程序如下:
  1. #include "U8glib.h"

  2. U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);        // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
  3. //-------字体设置,大、中、小
  4. #define setFont_L u8g.setFont(u8g_font_7x13)
  5. #define setFont_M u8g.setFont(u8g_font_fixed_v0r)
  6. #define setFont_S u8g.setFont(u8g_font_chikitar)
  7. /*
  8. font:  
  9. u8g.setFont(u8g_font_7x13)
  10. u8g.setFont(u8g_font_fixed_v0r);
  11. u8g.setFont(u8g_font_chikitar);
  12. u8g.setFont(u8g_font_osb21);
  13. */

  14. #include <Wire.h>
  15. #include <Rtc_Pcf8563.h>

  16. Rtc_Pcf8563 rtc;
  17. int time_nian,time_yue,time_ri,time_shi,time_fen,time_miao,time_zhou;

  18. #include <EtherCard.h>

  19. #define SECONDS_IN_DAY          86400
  20. #define START_YEAR              1900
  21. #define TIME_ZONE               +8
  22. static int days_in_month[] = {
  23.   31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

  24. static byte mymac[] = {
  25.   0x00,0x1A,0x4B,0x38,0x0C,0x5C};
  26. byte Ethernet::buffer[700];

  27. static byte ntpServer[] = {
  28.   193,204,114,232};
  29. static byte srcPort = 0;

  30. uint32_t timeStamp;

  31. boolean NET_TIME_reply;

  32. #define NET_TIME_INTERVAL    1000
  33. #define TIME_OUT             10000
  34. #define INTERVAL             100000
  35. unsigned long lastTime = 0,TIME_cache = 0;


  36. void setup () {
  37.   Serial.begin(57600);

  38.   volcdsetup("Load NETWORK",0,15);
  39.   delay(1000);
  40.   if (!ether.begin(sizeof Ethernet::buffer, mymac))
  41.     Serial.println( "Failed to access Ethernet controller");
  42.   else
  43.     Serial.println("Ethernet controller initialized");
  44.   if (!ether.dhcpSetup())
  45.   {
  46.     Serial.println("Failed to get configuration from DHCP");
  47.     volcdsetup("DHCP Error",0,15);
  48.     delay(1000);
  49.   }
  50.   else
  51.   {
  52.     Serial.println("DHCP configuration done");
  53.     volcdsetup("DHCP Succeed",0,15);
  54.     delay(1000);
  55.   }
  56.   ether.printIp("IP Address:\t", ether.myip);
  57.   ether.printIp("Netmask:\t", ether.mymask);
  58.   ether.printIp("Gateway:\t", ether.gwip);

  59.   //-------------------------------------------------------
  60.   volcdsetup("Load Net Time",0,15);
  61.   delay(1000);
  62.   NET_TIME_reply = true;
  63.   vonettime();
  64.   if(NET_TIME_reply)
  65.   {
  66.     volcdsetup("Time Sync. Error",0,15);
  67.     delay(1000);
  68.   }
  69.   else
  70.   {
  71.     vosettime();
  72.     volcdsetup("Time Sync. Succeed",0,15);
  73.     delay(1000);
  74.   }

  75.   //-------------------------------------------------------
  76.   Serial.println();
  77. }

  78. void loop() {
  79.   if(millis() - lastTime > INTERVAL)
  80.   {
  81.     NET_TIME_reply = true;
  82.     vonettime();
  83.     if(!NET_TIME_reply)
  84.     {
  85.       vosettime();
  86.     }
  87.     lastTime = millis();
  88.   }

  89.   volcd();

  90. }

  91. void volcd()
  92. {
  93.   u8g.firstPage();  
  94.   do {
  95.     setFont_M;
  96.     u8g.setPrintPos(0, 9);
  97.     u8g.print("TIME:");
  98.     u8g.print(rtc.formatDate());

  99.     u8g.setPrintPos(0, 20);
  100.     u8g.print(rtc.formatTime());

  101.     //-----------------------------------------
  102.     u8g.setPrintPos(0, 34);
  103.     u8g.print("TIME:");
  104.     u8g.print("20");
  105.     u8g.print(rtc.getYear());
  106.     u8g.print("/");
  107.     u8g.print(rtc.getMonth());
  108.     u8g.print("/");
  109.     u8g.print(rtc.getDay());

  110.     u8g.setPrintPos(0, 45);
  111.     u8g.print(rtc.getHour());
  112.     u8g.print(":");
  113.     u8g.print(rtc.getMinute());
  114.     u8g.print(":");
  115.     u8g.print(rtc.getSecond());

  116.     String WEEK="";
  117.     switch(rtc.getWeekday())
  118.     {
  119.     case 1:
  120.       WEEK="Monday";
  121.       break;
  122.     case 2:
  123.       WEEK="Tuesday";
  124.       break;
  125.     case 3:
  126.       WEEK="Wednesday";
  127.       break;
  128.     case 4:
  129.       WEEK="Thursday";
  130.       break;
  131.     case 5:
  132.       WEEK="Friday";
  133.       break;
  134.     case 6:
  135.       WEEK="Saturday";
  136.       break;
  137.     case 7:
  138.       WEEK="Sunday";
  139.       break;
  140.     }
  141.     u8g.setPrintPos(60, 45);
  142.     u8g.print(WEEK);

  143.     setFont_S;
  144.     u8g.drawFrame(0, 54,128,10);
  145.     u8g.setPrintPos(3, 62);
  146.     u8g.print("Microduino-RTC v1.0  201307");
  147.   }
  148.   while( u8g.nextPage() );
  149. }

  150. void vosettime()
  151. {
  152.   rtc.initClock();  //set a time to start with.
  153.   rtc.setDate(time_ri, time_zhou, time_yue, 0, time_nian%100);  //day, weekday, month, century(1=1900, 0=2000), year(0-99)
  154.   rtc.setTime(time_shi, time_fen, time_miao); //hr, min, sec

  155. }

  156. void volcdsetup(char* zi,unsigned int x,unsigned int y)
  157. {
  158.   u8g.firstPage();  
  159.   do {
  160.     setFont_L;   
  161.     u8g.setPrintPos(x, y);
  162.     u8g.print(zi);
  163.   }
  164.   while( u8g.nextPage() );
  165. }


  166. void vonettime()
  167. {
  168.   uint32_t timeout = millis();    //超时时间
  169.   while(NET_TIME_reply == true && millis() - timeout < TIME_OUT)   //采集到或者超时时跳出
  170.   {
  171.     ether.packetLoop(ether.packetReceive());
  172.     if(millis() - TIME_cache > NET_TIME_INTERVAL)     //发送请求间隔
  173.     {
  174.       ether.ntpRequest(ntpServer, srcPort);
  175.       TIME_cache = millis();
  176.       NET_TIME_reply = true;   //标记发送
  177.     }

  178.     if(NET_TIME_reply && ether.ntpProcessAnswer(&timeStamp, srcPort))    //发送后等待应答
  179.     {
  180.       printDate(timeStamp + 3600 * TIME_ZONE);    //开始计算
  181.       TIME_cache = millis();
  182.       NET_TIME_reply = false;    //接收到了
  183.     }
  184.   }
  185. }


  186. void printDate(uint32_t timeStamp) {

  187.   unsigned long week = (((timeStamp/3600/24)+1)%7);

  188.   Serial.print("Current date and time:");
  189.   Serial.println(timeStamp);

  190.   unsigned int year = START_YEAR;
  191.   while(1) {
  192.     uint32_t seconds;
  193.     if(isLeapYear(year)) seconds = SECONDS_IN_DAY * 366;
  194.     else seconds = SECONDS_IN_DAY * 365;
  195.     if(timeStamp >= seconds) {
  196.       timeStamp -= seconds;
  197.       year++;
  198.     }
  199.     else break;
  200.   }

  201.   unsigned int month = 0;
  202.   while(1) {   
  203.     uint32_t seconds = SECONDS_IN_DAY * days_in_month[month];
  204.     if(isLeapYear(year) && month == 1) seconds = SECONDS_IN_DAY * 29;
  205.     if(timeStamp >= seconds) {
  206.       timeStamp -= seconds;
  207.       month++;
  208.     }
  209.     else break;
  210.   }  
  211.   month++;

  212.   unsigned int day = 1;
  213.   while(1) {
  214.     if(timeStamp >= SECONDS_IN_DAY) {
  215.       timeStamp -= SECONDS_IN_DAY;
  216.       day++;
  217.     }
  218.     else break;
  219.   }  

  220.   unsigned int hour = timeStamp / 3600;
  221.   unsigned int minute = (timeStamp - (uint32_t)hour * 3600) / 60;
  222.   unsigned int second = (timeStamp - (uint32_t)hour * 3600) - minute * 60;


  223.   Serial.print("week: ");
  224.   Serial.println(week);

  225.   if(day < 10) Serial.print("0");
  226.   Serial.print(day);
  227.   Serial.print("/");

  228.   if(month < 10) Serial.print("0");
  229.   Serial.print(month);
  230.   Serial.print("/");  

  231.   Serial.println(year);


  232.   if(hour < 10) Serial.print("0");
  233.   Serial.print(hour);
  234.   Serial.print(":");

  235.   if(minute < 10) Serial.print("0");
  236.   Serial.print(minute);
  237.   Serial.print(":");

  238.   if(second < 10) Serial.print("0");
  239.   Serial.println(second);

  240.   Serial.println();

  241.   time_nian=year;
  242.   time_yue=month;
  243.   time_ri=day;
  244.   time_shi=hour;
  245.   time_fen=minute;
  246.   time_miao=second;
  247.   time_zhou=week;
  248. }

  249. boolean isLeapYear(unsigned int year) {

  250.   return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
  251. }
复制代码


运行效果:


本文用到的库:

更多资料见:http://wiki.microduino.net/

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2013-8-29 00:50:28 | 显示全部楼层
赞 本来就想抽空搞一下,内容几乎一样ntp取时间rtc保存呵呵  这下可以挪用你的了
回复 支持 反对

使用道具 举报

发表于 2013-8-29 04:58:00 | 显示全部楼层
看见了老潘风骚的3d打印板{:soso_e179:} 万事具备就差RTC了。
回复 支持 反对

使用道具 举报

发表于 2013-8-29 09:00:49 | 显示全部楼层
很不错

等上架了,我也搞套microduino玩玩
回复 支持 反对

使用道具 举报

发表于 2013-8-29 11:14:55 | 显示全部楼层
应该可以摞起来吧?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-29 11:36:11 | 显示全部楼层
ogre_c 发表于 2013-8-29 04:58
看见了老潘风骚的3d打印板 万事具备就差RTC了。

偷懒,直接当oled扩展板用了
回复 支持 反对

使用道具 举报

发表于 2013-8-29 13:55:20 | 显示全部楼层
这小板,没得方买呀,哪里购的?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-29 14:30:31 | 显示全部楼层
wyd1520 发表于 2013-8-29 13:55
这小板,没得方买呀,哪里购的?

看文末链接
回复 支持 反对

使用道具 举报

发表于 2013-8-29 15:56:51 | 显示全部楼层
OLCD可以图形吧,可以将时钟显示大些就漂亮了.
回复 支持 反对

使用道具 举报

发表于 2014-10-3 20:24:03 | 显示全部楼层
请问28J60网络模块怎么接线呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-10-7 01:21:11 | 显示全部楼层
504835618 发表于 2014-10-3 20:24
请问28J60网络模块怎么接线呢?

用Microduino模块 直接堆叠就行~不用连线
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-8 10:40 , Processed in 0.038044 second(s), 24 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表