Tuesday 31 May 2016

[PROJECT] Online clock tanpa RTC dengan Arduino & Ethernet Shield

Kita terkadang punya project yang sudah terhubung dengan Ethernet dan Internet. Kita juga sering membutuhkan data logger sehingga waktu yang akurat dibutuhkan. Banyak orang yang menambah modul RTC. Penambahan modul RTC ini sudah benar menurut fungsinya. Tapi terkadang kita juga malas karena boardnya jadi lebih kompleks. Padahal kita bisa mengambil data waktu di NTP, yang berformat UNIX time.
Apa itu NTP Server Beserta Fungsinya ?

NTP Server - NTP merupakan kepanjangan dari Network Time Protocol adalah sebuah protokol yang berfungsi untuk menyamakan waktu dari setiap komputer yang terhubung dengan jaringan dengan komputer server dalam jaringan tersebut, bisa pada jaringan LAN (Local Area Network) maupun pada jaringan Internet, NTP itu sendiri menggunakan jalur data TCP/IP. NTP Menggunakan komunikasi UDP dengan port 123.

Library yang dibutuhkan :
  1. Ethernet (bawaan Arduino)
  2. TimeLib (https://github.com/PaulStoffregen/Time)
Copy paste program dibawah ini ke Arduino IDE. Asal library benar pasti akan sukses. Pastikan bahwa koneksi internet nya benar (Gateway, DNS, Subnet, dsb..).
Coding:

  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
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <TimeLib.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, 0x12 };

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 5, 198);
IPAddress myDns(140, 0, 223, 250);
IPAddress gateway(192, 168, 5, 9);
IPAddress subnet(255, 255, 255, 0);

unsigned int localPort = 8888;       // local port to listen for UDP packets
unsigned long unixTime, ticker1, ticker2, ticker3, minus;

//char timeServer[] = "ntp.lipi.go.id"; // time.nist.gov NTP server
char timeServer[] = "pool.ntp.org"; // time.nist.gov NTP server
char timeZone = 7, ite = 0;

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

bool DHCP = true, reqTime = false;

// 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(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // start the Ethernet connection:
  //if (Ethernet.begin(mac) == 0)
  {
    Serial.println("Failed to configure Ethernet using DHCP");
    Ethernet.begin(mac, ip, myDns, gateway, subnet);
    DHCP = false;
  }
  setSyncProvider(getNtpTime);
  Udp.begin(localPort);
  ticker2 -= 60000; 
}

void loop() {
  if (millis() - ticker2 >= 60000) {
    ticker2 = millis();
    ticker3 = millis();
    sendNTPpacket(timeServer); // send an NTP packet to a time server
    minus = (millis() - ticker3) / 1000;
    reqTime = true;
    ite = 0;
  }
  if (millis() - ticker3 >= 1000 && reqTime == true) {
    ticker3 = millis();
    ite++;
    if (Udp.parsePacket()) {
      Udp.read(packetBuffer, NTP_PACKET_SIZE);
      unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
      unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
      unsigned long secsSince1900 = highWord << 16 | lowWord;
      if (secsSince1900 != 1145324612) {
        unsigned long epoch = secsSince1900 - 2208988800UL;
        unixTime = epoch;
        setTime(epoch + timeZone * SECS_PER_HOUR + ite);
        reqTime = false;
      }
    }
  }
  if (millis() - ticker1 >= 1000) {
    ticker1 = millis();
    digitalClockDisplay();
  }
  if (DHCP == true)
    Ethernet.maintain();
  delay(10);
}

// send an NTP request to the time server at the given address
void 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] = 10;     // 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();
}

void digitalClockDisplay() {
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}
void printDigits(int digits) {
  // utility for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}
time_t getNtpTime() {
  return unixTime + timeZone * SECS_PER_HOUR;
}



No comments:

Post a Comment

Develop STM32 dengan STM32cubeMx + OpenSTM32 IDE

Banyak temen ² yang masih ngoprek STM32 di Keil, yang harus nyari software crack ²an. Bebas sih, tapi saya sepaham dengan dosen saya saat ...