最終更新日:2023/3/13
インクルードするライブラリですが、Ethernet3を使用します。このライブラリは安定していると思います。
TM1637用のポートは確保します。
/* Udp NTP Client Get the time from a Network Time Protocol (NTP) time server Demonstrates use of UDP sendPacket and ReceivePacket For more on NTP time servers and the messages needed to communicate with them, see http://en.wikipedia.org/wiki/Network_Time_Protocol created 4 Sep 2010 by Michael Margolis modified 9 Apr 2012 by Tom Igoe This code is in the public domain. */ #include <SPI.h> #include <Ethernet3.h> #include <EthernetUdp3.h> // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; unsigned int localPort = 8888; // local port to listen for UDP packets char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets // A UDP instance to let us send and receive packets over UDP EthernetUDP Udp; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } // start Ethernet and UDP if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); // no point in carrying on, so do nothing forevermore: for (;;) ; } Udp.begin(localPort); } void loop() { sendNTPpacket(timeServer); // send an NTP packet to a time server // wait to see if a reply is available delay(1000); if ( Udp.parsePacket() ) { // We've received a packet, read the data from it Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer //the timestamp starts at byte 40 of the received packet and is four bytes, // or two words, long. First, esxtract the two words: unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); // combine the four bytes (two words) into a long integer // this is NTP time (seconds since Jan 1 1900): unsigned long secsSince1900 = highWord << 16 | lowWord; Serial.print("Seconds since Jan 1 1900 = " ); Serial.println(secsSince1900); // now convert NTP time into everyday time: Serial.print("Unix time = "); // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: const unsigned long seventyYears = 2208988800UL; // subtract seventy years: unsigned long epoch = secsSince1900 - seventyYears; // print Unix time: Serial.println(epoch); // print the hour, minute and second: Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day) Serial.print(':'); if ( ((epoch % 3600) / 60) < 10 ) { // In the first 10 minutes of each hour, we'll want a leading '0' Serial.print('0'); } Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) Serial.print(':'); if ( (epoch % 60) < 10 ) { // In the first 10 seconds of each minute, we'll want a leading '0' Serial.print('0'); } Serial.println(epoch % 60); // print the second } // wait ten seconds before asking for the time again delay(10000); } // send an NTP request to the time server at the given address unsigned long sendNTPpacket(char* address) { // set all bytes in the buffer to 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); // 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 // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // all NTP fields have been given values, now // you can send a packet requesting a timestamp: Udp.beginPacket(address, 123); //NTP requests are to port 123 Udp.write(packetBuffer, NTP_PACKET_SIZE); Udp.endPacket(); } |
|
/* * 2023/03/13 T.Wanibe * Udp NTP Client * ネットワーク タイム プロトコル (NTP) タイム サーバーから時刻を取得する * UDP sendPacket および ReceivePacket の使用方法を示します * NTP タイム サーバーとそれらとの通信に必要なメッセージの詳細については、 * http://en.wikipedia.org/wiki/Network_Time_Protocol を参照 * 最大1044480バイトのフラッシュメモリのうち、スケッチが61332バイト(5%)を使っています。 * 最大262144バイトのRAMのうち、グローバル変数が8096バイト(3%)を使っていて、ローカル変数で254048バイト使うことができます。 */ #define TIMER_INTERRUPT_DEBUG 1 #define _TIMERINTERRUPT_LOGLEVEL_ 4 #include "RPi_Pico_TimerInterrupt.h" #include "TM1637.h" #include <SPI.h> #include <Ethernet3.h> #include <EthernetUdp3.h> #define SEG_DP 0x80 #define ON 1 #define OFF 0 #define TIMER0_INTERVAL_MS 1000 #define SPI_SCK 18 #define SPI_RX 16 #define SPI_TX 19 #define SPI_CS 17 #define NICReset 20 #define CLK 28 //pins definitions for TM1637 and can be changed to other ports #define DIO 27 #define HTTPport 80 #define TELNETport 23 #define NTPport 123 #define SerialRate 115200 // コントローラの MAC アドレスと IP アドレスを以下に入力します。 // IP アドレスは、ローカル ネットワークによって異なります。 // ゲートウェイとサブネットはオプションです。 byte mac[] = {0x00,0x08,0xDC,0x54,0x4D,0xE0}; //WIZNET byte ip[] = {192, 168, 0, 210}; byte dns_server[] = {192, 168, 0, 1}; byte gateway[] = {0, 0, 0, 0}; byte subnet[] = {255, 255, 255, 0}; int8_t TimeDisp[] = {0x00, 0x00, 0x00, 0x00}; unsigned char ClockPoint = 1; unsigned char Update; unsigned char halfsecond = 0; unsigned char second; unsigned char minute = 0; unsigned char hour = 12; static int8_t tube_tab[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; //0~9,A,b,C,d,E,F unsigned int localPort = 8888; // local port to listen for UDP packets char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets int timeZone = int(9.0 * 3600); // UDP 経由でパケットを送受信できるようにする UDP インスタンス EthernetUDP Udp; TM1637 tm1637(CLK, DIO); RPI_PICO_Timer ITimer0(0); //-------------- void custom_display(uint8_t bit_addr, uint8_t seg_data) { tm1637.start(); tm1637.writeByte( 0x44 ); tm1637.stop(); tm1637.start(); tm1637.writeByte(bit_addr | 0xc0); tm1637.writeByte(seg_data); tm1637.stop(); tm1637.start(); tm1637.writeByte(tm1637.cmd_disp_ctrl); tm1637.stop(); } //-------------- void TimeUpdate(void) { tm1637.point(POINT_OFF); TimeDisp[0] = hour / 10; TimeDisp[1] = hour % 10; TimeDisp[2] = minute / 10; TimeDisp[3] = minute % 10; if (ClockPoint) { custom_display( 0, tube_tab[TimeDisp[0]]); custom_display( 1, tube_tab[TimeDisp[1]] | SEG_DP); custom_display( 2, tube_tab[TimeDisp[2]]); custom_display( 3, tube_tab[TimeDisp[3]]); } else { custom_display( 0, tube_tab[TimeDisp[0]]); custom_display( 1, tube_tab[TimeDisp[1]]); custom_display( 2, tube_tab[TimeDisp[2]]); custom_display( 3, tube_tab[TimeDisp[3]]); } Update = OFF; } //---------指定されたアドレスのタイム サーバーに NTP 要求を送信します void sendNTPpacket(char* address){ // バッファ内のすべてのバイトを 0 に設定します memset(packetBuffer, 0, NTP_PACKET_SIZE); // NTP リクエストを形成するために必要な値を初期化します (パケットの詳細については、上記の URL を参照してください) 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 // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // すべての NTP フィールドに値が与えられたので、タイムスタンプを要求するパケットを送信できます: Udp.beginPacket(address, NTPport); //NTP requests are to port 123 Udp.write(packetBuffer, NTP_PACKET_SIZE); Udp.endPacket(); } //---------------- void setup(){ tm1637.set(7); //0..7 tm1637.clearDisplay(); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); // シリアル通信を開き、ポートが開くのを待ちます。 Serial.begin(SerialRate); while (!Serial) { ; // シリアルポートが接続されるのを待ちます。 } pinMode(SPI_CS,OUTPUT); pinMode(NICReset,OUTPUT); // イーサネット接続とサーバーを開始します。 SPI.setSCK(SPI_SCK); SPI.setRX(SPI_RX); SPI.setTX(SPI_TX); SPI.setCS(SPI_CS); SPI.begin(); // Ethernet.init(pin)を使用してCSピンを設定できます Ethernet.setCsPin(SPI_CS); Ethernet.setRstPin(NICReset); digitalWrite(NICReset,LOW); delay(10); digitalWrite(NICReset,HIGH); Ethernet.init(SPI_CS); // イーサネットと UDP を開始する Ethernet.begin(mac,ip); Serial.print("server is at "); Serial.println(Ethernet.localIP()); Udp.begin(localPort); } //---------------- void loop(){ sendNTPpacket(timeServer); // NTP パケットをタイム サーバーに送信する delay(1000); // 返信があるかどうかを確認するのを待ちます if ( Udp.parsePacket() ) { // パケットを受信しました。そこからデータを読み取ります Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer //タイムスタンプは受信パケットのバイト 40 から始まり、4 バイトまたは 2 ワードの長さです。 まず、次の 2 つの単語を抽出します。 unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); // 4 バイト (2 ワード) を結合して長整数にします。これは NTP 時間 (1900 年 1 月 1 日からの秒数) です。 unsigned long secsSince1900 = highWord << 16 | lowWord; Serial.print("Seconds since Jan 1 1900 = " ); Serial.println(secsSince1900); // NTP 時間を毎日の時間に変換します。 Serial.print("Unix time = "); // Unix 時間は 1970 年 1 月 1 日から始まります。秒単位では 2208988800 です。 const unsigned long seventyYears = 2208988800UL; // 70年を引く: unsigned long epoch = secsSince1900 - seventyYears; // JST unsigned long JST = epoch + timeZone; // Unix 時間を表示: Serial.println(epoch); // 時、分、秒を出力します。効率の悪い記述です Serial.print("The UTC time is "); // UTC はグリニッジ子午線 (GMT) の時間です。 Serial.print((epoch % 86400L) / 3600); // 時間を出力します (86400 は 1 日あたりの秒に相当します) Serial.print(':'); if ( ((epoch % 3600) / 60) < 10 ) { // 各時間の最初の 10 分間では、先頭に '0' が必要です Serial.print('0'); } Serial.print((epoch % 3600) / 60); // 分を表示します (3600 は 1 時間あたりの秒数) Serial.print(':'); if ( (epoch % 60) < 10 ) { // 毎分の最初の 10 秒には、先頭の '0' が必要です Serial.print('0'); } Serial.println(epoch % 60); // 秒を表示します Serial.print("The JST time is "); // UTC はグリニッジ子午線 (GMT) の時間です。 hour = (JST % 86400L) / 3600; Serial.print(hour); // 時間を出力します (86400 は 1 日あたりの秒に相当します) Serial.print(':'); if ( ((JST % 3600) / 60) < 10 ) { // 各時間の最初の 10 分間では、先頭に '0' が必要です Serial.print('0'); } minute = (JST % 3600) / 60; Serial.print(minute); // 分を表示します (3600 は 1 時間あたりの秒数) Serial.print(':'); if ( (JST % 60) < 10 ) { // 毎分の最初の 10 秒には、先頭の '0' が必要です Serial.print('0'); } Serial.println(JST % 60); // 秒を表示します } TimeUpdate(); // もう一度時間を尋ねる前に 10 秒待ってください delay(10000); } |
本ソフトウエアは、あなたに対して何も保証しません。本ソフトウエアの関係者(他の利用者も含む)は、あなたに対して一切責任を負いません。
あなたが、本ソフトウエアを利用(コンパイル後の再利用など全てを含む)する場合は、自己責任で行う必要があります。本ソフトウエアの著作権はToolsBoxに帰属します。
本ソフトウエアをご利用の結果生じた損害について、ToolsBoxは一切責任を負いません。
ToolsBoxはコンテンツとして提供する全ての文章、画像等について、内容の合法性・正確性・安全性等、において最善の注意をし、作成していますが、保証するものではありません。
ToolsBoxはリンクをしている外部サイトについては、何ら保証しません。
ToolsBoxは事前の予告無く、本ソフトウエアの開発・提供を中止する可能性があります。
Microsoft、Windows、WindowsNTは米国Microsoft Corporationの米国およびその他の国における登録商標です。
Windows Vista、Windows XPは、米国Microsoft Corporation.の商品名称です。
LabVIEW、National Instruments、NI、ni.comはNational Instrumentsの登録商標です。
I2Cは、NXP Semiconductors社の登録商標です。
その他の企業名ならびに製品名は、それぞれの会社の商標もしくは登録商標です。
すべての商標および登録商標は、それぞれの所有者に帰属します。