Microduino-RTC小应用:网络时钟+OLED显示
本帖最后由 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);)
#include <Wire.h>
#include <Rtc_Pcf8563.h>
//init the real time clock
Rtc_Pcf8563 rtc;
void setup()
{
Serial.begin(9600);
//clear out the registers
rtc.initClock();
//set a time to start with.
//day, weekday, month, century(1=1900, 0=2000), year(0-99)
rtc.setDate(29, 4, 8, 0, 13);
//hr, min, sec
rtc.setTime(00, 21, 0);
}
void loop()
{
//both format functions call the internal getTime() so that the
//formatted strings are at the current time/date.
Serial.println("CODE_1:");
Serial.print(rtc.formatTime());
Serial.print(" ");
Serial.print(rtc.formatDate());
Serial.print("\r\n");
Serial.println("CODE_2:");
Serial.print("20");
Serial.print(rtc.getYear());
Serial.print("/");
Serial.print(rtc.getMonth());
Serial.print("/");
Serial.print(rtc.getDay());
Serial.print(" ");
Serial.print(rtc.getHour());
Serial.print(":");
Serial.print(rtc.getMinute());
Serial.print(":");
Serial.print(rtc.getSecond());
Serial.print("\r\n");
delay(1000);
Serial.print("\r\n");
}
}
运行效果:
===================================================
接下来简单介绍一下标题所指的应用:
主要功能:开机自动获取DHCP,获取网络NTP时间,如果成功则会将时间同步到Pcf8563里。加以OLED显示。
硬件用到了:
Microduino-Core+、Microduino-FT232R、【Microduino-ENC28J60】 + 【Microduino-RJ45】、Microduino-OLED、Microduino-RTC。
程序如下:
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins areSCK = 13 and MOSI = 11)
//-------字体设置,大、中、小
#define setFont_L u8g.setFont(u8g_font_7x13)
#define setFont_M u8g.setFont(u8g_font_fixed_v0r)
#define setFont_S u8g.setFont(u8g_font_chikitar)
/*
font:
u8g.setFont(u8g_font_7x13)
u8g.setFont(u8g_font_fixed_v0r);
u8g.setFont(u8g_font_chikitar);
u8g.setFont(u8g_font_osb21);
*/
#include <Wire.h>
#include <Rtc_Pcf8563.h>
Rtc_Pcf8563 rtc;
int time_nian,time_yue,time_ri,time_shi,time_fen,time_miao,time_zhou;
#include <EtherCard.h>
#define SECONDS_IN_DAY 86400
#define START_YEAR 1900
#define TIME_ZONE +8
static int days_in_month[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static byte mymac[] = {
0x00,0x1A,0x4B,0x38,0x0C,0x5C};
byte Ethernet::buffer;
static byte ntpServer[] = {
193,204,114,232};
static byte srcPort = 0;
uint32_t timeStamp;
boolean NET_TIME_reply;
#define NET_TIME_INTERVAL 1000
#define TIME_OUT 10000
#define INTERVAL 100000
unsigned long lastTime = 0,TIME_cache = 0;
void setup () {
Serial.begin(57600);
volcdsetup("Load NETWORK",0,15);
delay(1000);
if (!ether.begin(sizeof Ethernet::buffer, mymac))
Serial.println( "Failed to access Ethernet controller");
else
Serial.println("Ethernet controller initialized");
if (!ether.dhcpSetup())
{
Serial.println("Failed to get configuration from DHCP");
volcdsetup("DHCP Error",0,15);
delay(1000);
}
else
{
Serial.println("DHCP configuration done");
volcdsetup("DHCP Succeed",0,15);
delay(1000);
}
ether.printIp("IP Address:\t", ether.myip);
ether.printIp("Netmask:\t", ether.mymask);
ether.printIp("Gateway:\t", ether.gwip);
//-------------------------------------------------------
volcdsetup("Load Net Time",0,15);
delay(1000);
NET_TIME_reply = true;
vonettime();
if(NET_TIME_reply)
{
volcdsetup("Time Sync. Error",0,15);
delay(1000);
}
else
{
vosettime();
volcdsetup("Time Sync. Succeed",0,15);
delay(1000);
}
//-------------------------------------------------------
Serial.println();
}
void loop() {
if(millis() - lastTime > INTERVAL)
{
NET_TIME_reply = true;
vonettime();
if(!NET_TIME_reply)
{
vosettime();
}
lastTime = millis();
}
volcd();
}
void volcd()
{
u8g.firstPage();
do {
setFont_M;
u8g.setPrintPos(0, 9);
u8g.print("TIME:");
u8g.print(rtc.formatDate());
u8g.setPrintPos(0, 20);
u8g.print(rtc.formatTime());
//-----------------------------------------
u8g.setPrintPos(0, 34);
u8g.print("TIME:");
u8g.print("20");
u8g.print(rtc.getYear());
u8g.print("/");
u8g.print(rtc.getMonth());
u8g.print("/");
u8g.print(rtc.getDay());
u8g.setPrintPos(0, 45);
u8g.print(rtc.getHour());
u8g.print(":");
u8g.print(rtc.getMinute());
u8g.print(":");
u8g.print(rtc.getSecond());
String WEEK="";
switch(rtc.getWeekday())
{
case 1:
WEEK="Monday";
break;
case 2:
WEEK="Tuesday";
break;
case 3:
WEEK="Wednesday";
break;
case 4:
WEEK="Thursday";
break;
case 5:
WEEK="Friday";
break;
case 6:
WEEK="Saturday";
break;
case 7:
WEEK="Sunday";
break;
}
u8g.setPrintPos(60, 45);
u8g.print(WEEK);
setFont_S;
u8g.drawFrame(0, 54,128,10);
u8g.setPrintPos(3, 62);
u8g.print("Microduino-RTC v1.0201307");
}
while( u8g.nextPage() );
}
void vosettime()
{
rtc.initClock();//set a time to start with.
rtc.setDate(time_ri, time_zhou, time_yue, 0, time_nian%100);//day, weekday, month, century(1=1900, 0=2000), year(0-99)
rtc.setTime(time_shi, time_fen, time_miao); //hr, min, sec
}
void volcdsetup(char* zi,unsigned int x,unsigned int y)
{
u8g.firstPage();
do {
setFont_L;
u8g.setPrintPos(x, y);
u8g.print(zi);
}
while( u8g.nextPage() );
}
void vonettime()
{
uint32_t timeout = millis(); //超时时间
while(NET_TIME_reply == true && millis() - timeout < TIME_OUT) //采集到或者超时时跳出
{
ether.packetLoop(ether.packetReceive());
if(millis() - TIME_cache > NET_TIME_INTERVAL) //发送请求间隔
{
ether.ntpRequest(ntpServer, srcPort);
TIME_cache = millis();
NET_TIME_reply = true; //标记发送
}
if(NET_TIME_reply && ether.ntpProcessAnswer(&timeStamp, srcPort)) //发送后等待应答
{
printDate(timeStamp + 3600 * TIME_ZONE); //开始计算
TIME_cache = millis();
NET_TIME_reply = false; //接收到了
}
}
}
void printDate(uint32_t timeStamp) {
unsigned long week = (((timeStamp/3600/24)+1)%7);
Serial.print("Current date and time:");
Serial.println(timeStamp);
unsigned int year = START_YEAR;
while(1) {
uint32_t seconds;
if(isLeapYear(year)) seconds = SECONDS_IN_DAY * 366;
else seconds = SECONDS_IN_DAY * 365;
if(timeStamp >= seconds) {
timeStamp -= seconds;
year++;
}
else break;
}
unsigned int month = 0;
while(1) {
uint32_t seconds = SECONDS_IN_DAY * days_in_month;
if(isLeapYear(year) && month == 1) seconds = SECONDS_IN_DAY * 29;
if(timeStamp >= seconds) {
timeStamp -= seconds;
month++;
}
else break;
}
month++;
unsigned int day = 1;
while(1) {
if(timeStamp >= SECONDS_IN_DAY) {
timeStamp -= SECONDS_IN_DAY;
day++;
}
else break;
}
unsigned int hour = timeStamp / 3600;
unsigned int minute = (timeStamp - (uint32_t)hour * 3600) / 60;
unsigned int second = (timeStamp - (uint32_t)hour * 3600) - minute * 60;
Serial.print("week: ");
Serial.println(week);
if(day < 10) Serial.print("0");
Serial.print(day);
Serial.print("/");
if(month < 10) Serial.print("0");
Serial.print(month);
Serial.print("/");
Serial.println(year);
if(hour < 10) Serial.print("0");
Serial.print(hour);
Serial.print(":");
if(minute < 10) Serial.print("0");
Serial.print(minute);
Serial.print(":");
if(second < 10) Serial.print("0");
Serial.println(second);
Serial.println();
time_nian=year;
time_yue=month;
time_ri=day;
time_shi=hour;
time_fen=minute;
time_miao=second;
time_zhou=week;
}
boolean isLeapYear(unsigned int year) {
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
运行效果:
本文用到的库:
更多资料见:http://wiki.microduino.net/ 赞 本来就想抽空搞一下,内容几乎一样ntp取时间rtc保存呵呵这下可以挪用你的了 看见了老潘风骚的3d打印板{:soso_e179:} 万事具备就差RTC了。 很不错
等上架了,我也搞套microduino玩玩:lol 应该可以摞起来吧? ogre_c 发表于 2013-8-29 04:58 static/image/common/back.gif
看见了老潘风骚的3d打印板 万事具备就差RTC了。
:lol偷懒,直接当oled扩展板用了 :Q这小板,没得方买呀,哪里购的? wyd1520 发表于 2013-8-29 13:55 static/image/common/back.gif
这小板,没得方买呀,哪里购的?
看文末链接 OLCD可以图形吧,可以将时钟显示大些就漂亮了. 请问28J60网络模块怎么接线呢? 504835618 发表于 2014-10-3 20:24 static/image/common/back.gif
请问28J60网络模块怎么接线呢?
用Microduino模块 直接堆叠就行~不用连线
页:
[1]