macsbug

Just another WordPress.com site

ESP8266 + NTPCliant で時刻を取得し OLED に表示する

leave a comment »

ESP8266 + NTPCliantESP8266 + OLED を組み合わせて NTP時計を作る。   2015.10.19
NTPを使用すると、RCT(リアルタイムクロック) や GSP、電波時計より便利かと思います。
ネットワークがあれば、時刻が取得できる訳です。


基礎知識:不勉強ながら注意が必要と思いました。
NTP (network time protocol)とは、TCP/IPネットワークを通じて正しい現在時刻を取得するため
のプロトコルの一つ。コンピュータの内部時計の時刻を正しく調整するために、ネットワーク上で
時刻情報を配信しているサーバに問い合わせる手順を定義したもの。目的は、時刻合わせの為。
NTPへの短時間の繰り返しアクセスは、ネットワークや自宅回線の負荷になる為、注意が必要です。



準備:
1. ESP8266(ESP-WROOM-02) +  I2C OLED(128 x 64) 。
2. Udp NTP Client:ESP8266WiFi のサンプルを試す:NTPCliant
3. OLED:ESP8266 単体で I2C OLED を動かす
4. Arduino IDE と ESP8266 開発環境。既に習熟済みである事。


配線:ESP8266 と OLED の配線は、信号線2本のみです。
_  ESP8266 IO_14 (14) — OLED (SCL)、ESP8266 IO_13 (13) — OLED (SDA) 。
_  他の IO 端子を使用してもかまいません。
_  ESP8266 の使用する端子は、10kΩ で +3.2V へプルアップしておきましょう。
_  ESP-01 の場合:例:ESP-01  IO_0 — OLED (SDA)、 IO_2 — OLED (SCL) 。
スケッチの設定:SSID、Passwarod は、各自の環境にあわせて入力の事。


謝辞:
NTP Client は、Sandeep Mistry氏の「NTPClient」を使わせて頂きました。
OLED は、Chiang Mai Maker Clubの「ESP_Adafruit_SSD1306」を使わせて頂きました。


参孝:
Network Time Protocol
Network time syncronized clock for Arduino



// ESP8266(ESP-WROOM-02) + OLED(128 x 64) + Udp NTP Client

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Time.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <ESP_Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

char ssid[] = "xxxx";   // your network SSID (name)
char pass[] = "xxxxxx"; // your network password
unsigned int localPort = 2390; // local port to listen for UDP packets
IPAddress timeServerIP(129, 6, 15, 28); // time.nist.gov NTP server
const char* ntpServerName = "time.nist.gov";// time.nist.gov NTP server address
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
WiFiUDP udp; // UDP instance to let us send and receive packets over UDP

void setup(){
 Wire.begin(13,14);      // SDA(GPIO_13), SCL(GPIO_14)
 display.begin(SSD1306_SWITCHCAPVCC, 0x78>>1);
 display.clearDisplay(); // Clear the buffer.
 display.setTextSize(1); // font size 1 ( minnimum )
 display.setTextColor(WHITE);
 display.setCursor(0,0);display.print("Connecting to");
 display.setCursor(0,9);display.print("ssid =");
 display.setCursor(40,9);display.print(ssid);display.display();
 WiFi.begin(ssid, pass);
 int y=5;
 while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  display.setCursor(y,18);display.print(".");display.display();
  y = y + 5;
 }
 display.setCursor(0,27);display.print("WiFi connected");
 display.setCursor(0,36);display.print("IP:");
 display.setCursor(20,36);display.print(WiFi.localIP());display.display();
 display.setCursor(0,45);display.print("Starting UDP");display.display();
 udp.begin(localPort);
 display.setCursor(0,54);display.print("Local port:");
 display.setCursor(68,54);display.print(udp.localPort());display.display();
 delay(3000);
}

void loop(){
WiFi.hostByName(ntpServerName, timeServerIP);//get a random server from the pool
 display.setTextSize(1);display.setCursor(120,0);
 display.print("*");display.display(); // sending NTP packet...on
 sendNTPpacket(timeServerIP); // send an NTP packet to a time server
 delay(1000); // wait to see if a reply is available
 int cb = udp.parsePacket();
 if (!cb) {}
  else { // We've received a packet, read the data from it
  udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
  unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
  unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
  unsigned long secsSince1900 = highWord << 16 | lowWord; // NTP time
  const unsigned long seventyYears = 2208988800UL; // subtract seventy years:
  unsigned long epoch = secsSince1900 - seventyYears; //Unix time:
  setTime(epoch + (9 * 60 * 60)); // JST +‹9 HR

  display.clearDisplay();display.setTextSize(2);
  String ms="";String ds="";
  if (month() < 10){ ms="0";}
  if (day() < 10){ ds="0";}
  String ymd=String(year())+"."+ms+String(month())+"."+ds+String(day());
  display.setCursor(5,10);display.print(ymd);display.display();

  String hs="";String mi="";String ss="";
  if (hour() < 10){ hs="0";}
  if (minute() < 10){ mi="0";}
  if (second() < 10){ ss="0";}
  String hm=hs+String(hour())+":"+mi+String(minute());
  display.setCursor(18,40);display.print(hm);display.display();
 }
 display.setTextSize(1);display.setCursor(120,0);
 display.print(" ");display.display(); // sending NTP packet...off
 delay(10000); // wait ten seconds before asking for the time again
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address){
 memset(packetBuffer, 0, NTP_PACKET_SIZE);// set all bytes in the buffer to 0
 // Initialize values needed to form NTP request
 // (see URL above for details on the packets)
 packetBuffer[0] = 0b11100011; // LI, Version, Mode
 packetBuffer[1] = 0; // Stratum, or type of clock
 packetBuffer[2] = 6; // Polling Interval
 packetBuffer[3] = 0xEC; // Peer Clock Precision
 packetBuffer[12] = 49; // 8 bytes of zero for Root Delay & Root Dispersion
 packetBuffer[13] = 0x4E;
 packetBuffer[14] = 49;
 packetBuffer[15] = 52;
 udp.beginPacket(address, 123); //NTP requests are to port 123
 udp.write(packetBuffer, NTP_PACKET_SIZE);
 udp.endPacket();
}


 

 

Written by macsbug

10月 19, 2015 @ 12:27 pm

カテゴリー: ESP8266

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。