AMEBA透過網路校時RTC時鐘模組

作者:曹永忠

前文介紹 RTC 時鐘模組具備時間功能,並且為了斷電時仍然可以保留時間,補足Ameba開發板並沒有內置時鐘(Internal Clock)的問題,可以見到 「Tiny RTC I2C 時鐘模組」的外觀圖,模組採用DS1307晶片,若讀者需要更詳盡的資料,請參考「Arduino投幣計時器(網路篇)」,內容關於RTC 時鐘模組。

RTC時鐘模組的介紹與描述

Tiny RTC I2C 時鐘模組

Tiny RTC I2C 時鐘模組

如下圖所示,我們可以參考時鐘模組之電路連接圖,先將電路連接完善後,撰寫與測試下列「Tiny RTC I2C 時鐘模組」測試程式。

時鐘模組電路連接方式

時鐘模組電路連接方式

在完成上圖所示之時鐘模組之電路連接之後,如下圖所示,完成時鐘模組電路實際組裝的工作。

時鐘模組電路實際組裝圖

時鐘模組電路實際組裝圖

RTC模組的校時問題

我們發現,若裝設新的開發板或不同時間點設置新裝置,必須透過使用者重新設定時間,或是修改程式;因為「RTC 時鐘模組」的初始化時間是寫在Ameba開發板的程式內,必須重新編譯程式並上傳,這樣是非常不方便的。

若我們具有自動校時的功能,完全不需使用者手動設定或重新更新系統軟體,就可以達到正確時間校時的機制,這樣才能更簡單的產業化應用,由於目前網路校時非常的方便,所以我們可以透過網路校時的方式來實踐這個機制,或許是一個相當完善的解決方案。

Ameba的WiFi功能

Ameba開發板是一塊「IOT Wi-Fi微型化模組」(RTL8711AF and RTL8195AM),內建 ARM Cortex-M3 CPU、記憶體,同時還配置了完整的無線網路協議,包含:SSL硬體加速電路、UART、 I2C、 SPI、PWM ,以及高速的 SDIO 接口等各式序列介面(如下圖所示)。

Ameba開發板核心晶片「RTL8195AM」規格

Ameba開發板使用「RTL8195AM」為開發板核心晶片,功能強大,其下為晶片的基本規格:

  • 32-bit 166MHz ARM Cortex-M3 CPU
  • 內建 低功耗 802.11 b/g/n 2.4G 無線 Wi-Fi
  • 內建 NFC
  • 介面支援 : GPIO / PWM / SPI / I2C / ADC / DAC / UART
  • Crypto HW engine : 可做硬體加解密, 支援 MD5/ SHA-1 / SHA2-256 / DES / 3DES / AES
  • IC 本身有 512K RAM, 另外模組包含 2M SDRAM / 16M bit flash

Ameba開發板的規格

Ameba開發板具有強大的功能,並內含WiFi上網功能,其下為基本規格:

  • 與Arduino UNO開發板相容,可支援大多數 Arduino 擴充板(Shield),如DfRobot的 LCD Keypad shield…等等
  • 含一個 NXP LPC11U35 cortex-M0 IC,具備下列功能:
  1. 不須使用 JLINK 可直接透過 USB傳入程式image檔
  2. 不須使用USB序列傳輸線,UART即可使用將訊息傳給開發用的電腦

取得網路校時時間資料

將Ameba開發板的驅動程式安裝好之後,我們打開開發工具「Sketch IDE」整合開發軟體撰寫一段程式,如下表所示之網路校時測試程式,就可以透過Ameba WiFi模組取得網路校時時間。

網路校時測試程式(UdpNtpClient)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#include "PMType.h"
#include
#include
#include
uint8_t MacData[6];

char ssid[] = "TSAO";      // your network SSID (name)
char pass[] = "TSAO1234";     // your network password
char server[] = "gpssensor.ddns.net"; // the MQTT server of LASS

#define MAX_CLIENT_ID_LEN 10
#define MAX_TOPIC_LEN     50
char clientId[MAX_CLIENT_ID_LEN];
char outTopic[MAX_TOPIC_LEN];

IPAddress  Meip ,Megateway ,Mesubnet ;
String MacAddress ;
int status = WL_IDLE_STATUS;
WiFiUDP Udp;
const char ntpServer[] = "pool.ntp.org";
const long timeZoneOffset = 28800L;
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
const byte nptSendPacket[ NTP_PACKET_SIZE] = {
  0xE3, 0x00, 0x06, 0xEC, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x31, 0x4E, 0x31, 0x34,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
byte ntpRecvBuffer[ NTP_PACKET_SIZE ];

#define LEAP_YEAR(Y)     ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
static  const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0
uint32_t epochSystem = 0; // timestamp of system boot up
   unsigned long epoch  ;
  int NDPyear, NDPmonth, NDPday, NDPhour, NDPminute, NDPsecond;


void setup() {
  MacAddress = GetWifiMac() ;
    ShowMac() ;
    initializeWiFi();
     delay(1500);
}

void loop() { // run over and over
    ShowNTPDateTime() ;
   delay(6000); // delay 1 minute for next measurement
 

}

void ShowNTPDateTime()
{
      retrieveNtpTime() ;
      getCurrentTime(epoch+timeZoneOffset, &NDPyear, &NDPmonth, &NDPday, &NDPhour, &NDPminute, &NDPsecond);
    //ttt->year = NDPyear ;
    Serial.print("NDP Date is :");
    Serial.print(StringDate(NDPyear,NDPmonth,NDPday));
    Serial.print("and ");
    Serial.print("NDP Time is :");
    Serial.print(StringTime(NDPhour,NDPminute,NDPsecond));
    Serial.print("\n");

}
void ShowMac()
{
 
     Serial.print("MAC:");
     Serial.print(MacAddress);
     Serial.print("\n");

}

void ShowInternetStatus()
{
   
        if (WiFi.status())
          {
               Meip = WiFi.localIP();
               Serial.print("Get IP is:");
               Serial.print(Meip);
               Serial.print("\n");
             
          }
          else
          {
                       Serial.print("DisConnected:");
                       Serial.print("\n");
          }

}


String  StringDate(int yyy,int mmm,int ddd) {
  String ttt ;
//nowT  = now;
 ttt = print4digits(yyy) + "-" + print2digits(mmm) + "-" + print2digits(ddd) ;
  return ttt ;
}


String  StringTime(int hhh,int mmm,int sss) {
  String ttt ;
  ttt = print2digits(hhh) + ":" + print2digits(mmm) + ":" + print2digits(sss) ;
return ttt ;
}

String  print2digits(int number) {
  String ttt ;
  if (number >= 0 && number < 10) { ttt = String("0") + String(number); } else { ttt = String(number); } return ttt ; } String print4digits(int number) { String ttt ; ttt = String(number); return ttt ; } String GetWifiMac() { String tt ; String t1,t2,t3,t4,t5,t6 ; WiFi.status(); //this method must be used for get MAC WiFi.macAddress(MacData); Serial.print("Mac:"); Serial.print(MacData[0],HEX) ; Serial.print("/"); Serial.print(MacData[1],HEX) ; Serial.print("/"); Serial.print(MacData[2],HEX) ; Serial.print("/"); Serial.print(MacData[3],HEX) ; Serial.print("/"); Serial.print(MacData[4],HEX) ; Serial.print("/"); Serial.print(MacData[5],HEX) ; Serial.print("~"); t1 = print2HEX((int)MacData[0]); t2 = print2HEX((int)MacData[1]); t3 = print2HEX((int)MacData[2]); t4 = print2HEX((int)MacData[3]); t5 = print2HEX((int)MacData[4]); t6 = print2HEX((int)MacData[5]); tt = (t1+t2+t3+t4+t5+t6) ; Serial.print(tt); Serial.print("\n"); return tt ; } String print2HEX(int number) { String ttt ; if (number >= 0 && number < 16)
  {
    ttt = String("0") + String(number,HEX);
  }
  else
  {
      ttt = String(number,HEX);
  }
  return ttt ;
}



// send an NTP request to the time server at the given address
void retrieveNtpTime() {
  Serial.println("Send NTP packet");

  Udp.beginPacket(ntpServer, 123); //NTP requests are to port 123
  Udp.write(nptSendPacket, NTP_PACKET_SIZE);
  Udp.endPacket();

  if(Udp.parsePacket()) {
    Serial.println("NTP packet received");
    Udp.read(ntpRecvBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
   
    unsigned long highWord = word(ntpRecvBuffer[40], ntpRecvBuffer[41]);
    unsigned long lowWord = word(ntpRecvBuffer[42], ntpRecvBuffer[43]);
    unsigned long secsSince1900 = highWord << 16 | lowWord; const unsigned long seventyYears = 2208988800UL; // epoch = secsSince1900 - seventyYears + timeZoneOffset ; epoch = secsSince1900 - seventyYears ; epochSystem = epoch - millis() / 1000; } } void getCurrentTime(unsigned long epoch, int *year, int *month, int *day, int *hour, int *minute, int *second) { int tempDay = 0; *hour = (epoch % 86400L) / 3600; *minute = (epoch % 3600) / 60; *second = epoch % 60; *year = 1970; *month = 0; *day = epoch / 86400; for (*year = 1970; ; (*year)++) { if (tempDay + (LEAP_YEAR(*year) ? 366 : 365) > *day) {
      break;
    } else {
      tempDay += (LEAP_YEAR(*year) ? 366 : 365);
    }
  }
  tempDay = *day - tempDay; // the days left in a year
  for ((*month) = 0; (*month) < 12; (*month)++) {
    if ((*month) == 1) {
      if (LEAP_YEAR(*year)) {
        if (tempDay - 29 < 0) {
          break;
        } else {
          tempDay -= 29;
        }
      } else {
        if (tempDay - 28 < 0) {
          break;
        } else {
          tempDay -= 28;
        }
      }
    } else {
      if (tempDay - monthDays[(*month)] < 0) {
        break;
      } else {
        tempDay -= monthDays[(*month)];
      }
    }
  }
  (*month)++;
  *day = tempDay+2; // one for base 1, one for current day
}

void initializeWiFi() {
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
  //   status = WiFi.begin(ssid);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.print("Success to connect AP:") ;
  Serial.print(ssid) ;
  Serial.print("\n") ;
 

  // local port to listen for UDP packets
      Udp.begin(2390);
}

void printWifiData()
{
  // print your WiFi shield's IP address:
  Meip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(Meip);
  Serial.print("\n");

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  Serial.print(mac[5], HEX);
  Serial.print(":");
  Serial.print(mac[4], HEX);
  Serial.print(":");
  Serial.print(mac[3], HEX);
  Serial.print(":");
  Serial.print(mac[2], HEX);
  Serial.print(":");
  Serial.print(mac[1], HEX);
  Serial.print(":");
  Serial.println(mac[0], HEX);

  // print your subnet mask:
  Mesubnet = WiFi.subnetMask();
  Serial.print("NetMask: ");
  Serial.println(Mesubnet);

  // print your gateway address:
  Megateway = WiFi.gatewayIP();
  Serial.print("Gateway: ");
  Serial.println(Megateway);
}

如下圖所示,讀者可以看到本次實驗-網路校時測試程式結果畫面。

透過網路校時設計RTC時鐘模組

整合上述程式,我們可以將RTC時鐘模組的網路校時功能給予實作出來。打開Ameba開發工具「Sketch IDE」整合開發軟體撰寫一段程式,如下表所示之網路校時RTC時鐘模組測試程式,就可以透過Ameba WiFi模組取得網路時間並校正時鐘模組。

網路校時RTC 時鐘模組測試程式(SetTime_fromNet)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#include
#include "RTClib.h"
RTC_DS1307 RTC;
// above is used for RTC
#include "PMType.h"
#include
#include
#include
//    Aboev is used for WIFI
uint8_t MacData[6];

char ssid[] = "linkitone";      // your network SSID (name)
char pass[] = "";     // your network password
char server[] = "gpssensor.ddns.net"; // the MQTT server of LASS

#define MAX_CLIENT_ID_LEN 10
#define MAX_TOPIC_LEN     50
char clientId[MAX_CLIENT_ID_LEN];
char outTopic[MAX_TOPIC_LEN];

IPAddress  Meip , Megateway , Mesubnet ;
String MacAddress ;
int status = WL_IDLE_STATUS;
WiFiUDP Udp;
const char ntpServer[] = "pool.ntp.org";
const long timeZoneOffset = 28800L;
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
const byte nptSendPacket[ NTP_PACKET_SIZE] = {
  0xE3, 0x00, 0x06, 0xEC, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x31, 0x4E, 0x31, 0x34,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
byte ntpRecvBuffer[ NTP_PACKET_SIZE ];

#define LEAP_YEAR(Y)     ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
static  const uint8_t monthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // API starts months from 1, this array starts from 0
uint32_t epochSystem = 0; // timestamp of system boot up
unsigned long epoch  ;
int NDPyear, NDPmonth, NDPday, NDPhour, NDPminute, NDPsecond;
// this is used for WIFI and NTP


void setup() {
  Serial.begin(9600);
  initRTC() ;
  //  init RTC Modules
  MacAddress = GetWifiMac() ;
  ShowMac() ;
  initializeWiFi();
  ShowNTPDateTime() ;
  SetRTCTime(NDPyear, NDPmonth, NDPday, NDPhour, NDPminute, NDPsecond);
  delay(1500);
}

void loop() { // run over and over
  delay(1000); // delay 1 minute for next measurement
  Serial.print("Now RTC Data and Time is :") ;
  Serial.print(ShowDateTime()) ;
  Serial.print("\n") ;
  delay(1000) ;

}

void ShowNTPDateTime()
{
  retrieveNtpTime() ;
  getCurrentTime(epoch + timeZoneOffset, &NDPyear, &NDPmonth, &NDPday, &NDPhour, &NDPminute, &NDPsecond);
  //ttt->year = NDPyear ;
  Serial.print("NDP Date is :");
  Serial.print(StringDate(NDPyear, NDPmonth, NDPday));
  Serial.print("and ");
  Serial.print("NDP Time is :");
  Serial.print(StringTime(NDPhour, NDPminute, NDPsecond));
  Serial.print("\n");

}
void ShowMac()
{

  Serial.print("MAC:");
  Serial.print(MacAddress);
  Serial.print("\n");

}

void ShowInternetStatus()
{

  if (WiFi.status())
  {
    Meip = WiFi.localIP();
    Serial.print("Get IP is:");
    Serial.print(Meip);
    Serial.print("\n");

  }
  else
  {
    Serial.print("DisConnected:");
    Serial.print("\n");
  }

}



void initRTC()
{
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");

  }
}
String ShowDateTime()
{

  return StrDate() + "  " + StrTime() ;
}

String  StrDate() {
  String ttt ;
  //nowT  = now;
  DateTime now = RTC.now();
  ttt = print4digits(now.year()) + "-" + print2digits(now.month()) + "-" + print2digits(now.day()) ;
  //ttt = print4digits(NDPyear) + "/" + print2digits(NDPmonth) + "/" + print2digits(NDPday) ;
  return ttt ;
}

String  StringDate(int yyy, int mmm, int ddd) {
  String ttt ;
  //nowT  = now;
  ttt = print4digits(yyy) + "-" + print2digits(mmm) + "-" + print2digits(ddd) ;
  return ttt ;
}


String  StrTime() {
  String ttt ;
  // nowT  = RTC.now();
  DateTime now = RTC.now();
  ttt = print2digits(now.hour()) + ":" + print2digits(now.minute()) + ":" + print2digits(now.second()) ;
  //  ttt = print2digits(NDPhour) + ":" + print2digits(NDPminute) + ":" + print2digits(NDPsecond) ;
  return ttt ;
}

String  StringTime(int hhh, int mmm, int sss) {
  String ttt ;
  ttt = print2digits(hhh) + ":" + print2digits(mmm) + ":" + print2digits(sss) ;
  return ttt ;
}

String  print2digits(int number) {
  String ttt ;
  if (number >= 0 && number < 10) { ttt = String("0") + String(number); } else { ttt = String(number); } return ttt ; } String print4digits(int number) { String ttt ; ttt = String(number); return ttt ; } String GetWifiMac() { String tt ; String t1, t2, t3, t4, t5, t6 ; WiFi.status(); //this method must be used for get MAC WiFi.macAddress(MacData); Serial.print("Mac:"); Serial.print(MacData[0], HEX) ; Serial.print("/"); Serial.print(MacData[1], HEX) ; Serial.print("/"); Serial.print(MacData[2], HEX) ; Serial.print("/"); Serial.print(MacData[3], HEX) ; Serial.print("/"); Serial.print(MacData[4], HEX) ; Serial.print("/"); Serial.print(MacData[5], HEX) ; Serial.print("~"); t1 = print2HEX((int)MacData[0]); t2 = print2HEX((int)MacData[1]); t3 = print2HEX((int)MacData[2]); t4 = print2HEX((int)MacData[3]); t5 = print2HEX((int)MacData[4]); t6 = print2HEX((int)MacData[5]); tt = (t1 + t2 + t3 + t4 + t5 + t6) ; Serial.print(tt); Serial.print("\n"); return tt ; } String print2HEX(int number) { String ttt ; if (number >= 0 && number < 16)
  {
    ttt = String("0") + String(number, HEX);
  }
  else
  {
    ttt = String(number, HEX);
  }
  return ttt ;
}


// send an NTP request to the time server at the given address
void retrieveNtpTime() {
  Serial.println("Send NTP packet");

  Udp.beginPacket(ntpServer, 123); //NTP requests are to port 123
  Udp.write(nptSendPacket, NTP_PACKET_SIZE);
  Udp.endPacket();

  if (Udp.parsePacket()) {
    Serial.println("NTP packet received");
    Udp.read(ntpRecvBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

    unsigned long highWord = word(ntpRecvBuffer[40], ntpRecvBuffer[41]);
    unsigned long lowWord = word(ntpRecvBuffer[42], ntpRecvBuffer[43]);
    unsigned long secsSince1900 = highWord << 16 | lowWord; const unsigned long seventyYears = 2208988800UL; // epoch = secsSince1900 - seventyYears + timeZoneOffset ; epoch = secsSince1900 - seventyYears ; epochSystem = epoch - millis() / 1000; } } void SetRTCTime( int yr, int mon, int dd, int hr, int mins, int secs) { RTC.adjust(DateTime(yr, mon, dd, hr, mins, secs)); } void getCurrentTime(unsigned long epoch, int *year, int *month, int *day, int *hour, int *minute, int *second) { int tempDay = 0; *hour = (epoch % 86400L) / 3600; *minute = (epoch % 3600) / 60; *second = epoch % 60; *year = 1970; *month = 0; *day = epoch / 86400; for (*year = 1970; ; (*year)++) { if (tempDay + (LEAP_YEAR(*year) ? 366 : 365) > *day) {
      break;
    } else {
      tempDay += (LEAP_YEAR(*year) ? 366 : 365);
    }
  }
  tempDay = *day - tempDay; // the days left in a year
  for ((*month) = 0; (*month) < 12; (*month)++) {
    if ((*month) == 1) {
      if (LEAP_YEAR(*year)) {
        if (tempDay - 29 < 0) {
          break;
        } else {
          tempDay -= 29;
        }
      } else {
        if (tempDay - 28 < 0) {
          break;
        } else {
          tempDay -= 28;
        }
      }
    } else {
      if (tempDay - monthDays[(*month)] < 0) {
        break;
      } else {
        tempDay -= monthDays[(*month)];
      }
    }
  }
  (*month)++;
  *day = tempDay + 2; // one for base 1, one for current day
}

void initializeWiFi() {
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    // status = WiFi.begin(ssid, pass);
    status = WiFi.begin(ssid);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.print("Success to connect AP:") ;
  Serial.print(ssid) ;
  Serial.print("\n") ;


  // local port to listen for UDP packets
  Udp.begin(2390);
}

void printWifiData()
{
  // print your WiFi shield's IP address:
  Meip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(Meip);
  Serial.print("\n");

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  Serial.print(mac[5], HEX);
  Serial.print(":");
  Serial.print(mac[4], HEX);
  Serial.print(":");
  Serial.print(mac[3], HEX);
  Serial.print(":");
  Serial.print(mac[2], HEX);
  Serial.print(":");
  Serial.print(mac[1], HEX);
  Serial.print(":");
  Serial.println(mac[0], HEX);

  // print your subnet mask:
  Mesubnet = WiFi.subnetMask();
  Serial.print("NetMask: ");
  Serial.println(Mesubnet);

  // print your gateway address:
  Megateway = WiFi.gatewayIP();
  Serial.print("Gateway: ");
  Serial.println(Megateway);
}

如下圖所示,可以看到本次實驗「網路校時RTC 時鐘模組」測試程式結果畫面,在下圖第一個紅框中,取得網路校時的時間;在第二個紅框中,已將網路校時的時間寫入RTC時鐘模組,之後就由模組讀出時間,不必浪費網路頻寬,為了取得時間資料,不斷向網路校時伺服器要求時間,不僅加快了系統的速度,也省去了網路不必要的頻寬浪費。

小結

本文主要介紹Ameba開發板如何透過WiFi模組連接上網際網路,去取得網路校正時間,並且成功校正RTC時鐘模組。這樣的功能,可以說是網路化、實務化的核心功能,透過解說,相信讀者更可以應用RTC時鐘模組到商業化產品,進而將本技術應用在物聯網的核心技術。

Author: 曹永忠

目前為自由作家,已有二十多年的開發資訊系統經驗,專長為於軟體工程、軟體開發與設計、物件導向程式設計、Arduino/Ameba/LinkIt 等開發版開發與應用、嵌入式系統開發,同時也喜歡商品攝影及人像攝影,並持續發表作品及相關專業著作。 原始碼網址:https://github.com/brucetsao/

Share This Post On

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *