// Скетч для Arduino. Светодиодные часы с синхронизацией. // Версия 1.0 (29.07.2014) // // Автор: Гладышев Дмитрий (2014) // http://student-proger.ru/2014/07/arduino-svetodiodnye-chasy-s-sinhronizaciej-vremeni/ #include //для Ethernet-shield #include // --//-- #include #include //I2C для RTC #include //RTC #include #include //для задания интервалов времени (аля Cron) //**************************************************************************************** byte mac[] = { 0xDE, 0xAD, 0x00, 0x00, 0x00, 0x00 }; //MAC-адрес Arduino byte clock_addr[] = {0x20, 0x21, 0x22, 0x23}; //адреса PCF8574 IPAddress timeServer(132, 163, 4, 101); // IP-адрес NTP сервера const int timeZone = 8; // TimeZone //**************************************************************************************** unsigned int localPort = 53; Metro TimeSync = Metro(86400000); //Частота синхронизации (1 сутки) char clockbuf[4]; EthernetClient client2; EthernetUDP Udp; unsigned long lastTimeUpdate = 0; bool DotTimeState = false; void setup() { for (int i=0; i<4; i++) { clockbuf[i]='-'; } UpdateClock(); // Ethernet connection: do { delay(1000); } while (Ethernet.begin(mac) == 0); Wire.begin(); Udp.begin(localPort); //Запрашиваем время с NTP сервера setSyncProvider(getNtpTime); //Если время получили успешно, то записываем данные в RTC if (timeStatus() != timeNotSet) { RTC.set(now()); } } //============================== void loop() { tmElements_t tm; if (TimeSync.check() == 1) //Синхронизация по времени { //Запрашиваем время с NTP сервера setSyncProvider(getNtpTime); //Если время получили успешно, то записываем данные в RTC if (timeStatus() != timeNotSet) { RTC.set(now()); } } if (client2.available()) { char c = client2.read(); } if (abs(millis() - lastTimeUpdate) > 500) { lastTimeUpdate = millis(); if (RTC.read(tm)) { DotTimeState=!DotTimeState; clockbuf[0] = (char)(tm.Hour/10)+'0'; if (tm.Hour<10) { clockbuf[0] = ' '; } clockbuf[1] = (char)(tm.Hour%10)+'0'; clockbuf[2] = (char)(tm.Minute/10)+'0'; clockbuf[3] = (char)(tm.Minute%10)+'0'; UpdateClock(); } } } //================================================ void reverse(char s[]) { int i, j; char c; for (i = 0, j = strlen(s)-1; i 0); /* удаляем */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } int len(char *buf) { int i=0; do { i++; } while (buf[i]!='\0'); return i; } void UpdateClock() { for (int i=0; i<4; i++) { Wire.beginTransmission(clock_addr[i]); Wire.write(SegmentValue(clockbuf[i])); Wire.endTransmission(); } } byte SegmentValue(char k) { byte u; switch (k) { case '0': u=B1111110; break; case '1': u=B0110000; break; case '2': u=B1101101; break; case '3': u=B1111001; break; case '4': u=B0110011; break; case '5': u=B1011011; break; case '6': u=B1011111; break; case '7': u=B1110000; break; case '8': u=B1111111; break; case '9': u=B1111011; break; case '-': u=B0000001; break; case ' ': u=B0000000; break; case 'E': u=B1001111; break; case 'U': u=B0111110; break; case 'u': u=B0011100; break; case 'I': u=B0110000; break; case 'i': u=B0010000; break; case 'O': u=B1111110; break; case 'o': u=B0011101; break; case 'P': u=B1100111; break; case 'A': u=B1110111; break; case 'S': u=B1011011; break; case 'F': u=B1000111; break; case 'H': u=B0110111; break; case 'J': u=B0111100; break; case 'L': u=B0001110; break; case 'C': u=B1001110; break; case 'B': u=B1111111; break; case 'b': u=B0011111; break; case 'd': u=B0111101; break; case '°': u=B1100011; break; default: u=B0000000; } byte t=0; //переворачиваем биты for (byte i=0; i<7; i++) { if ((u&(1< 0) ; // discard any previously received packets sendNTPpacket(timeServer); uint32_t beginWait = millis(); while (millis() - beginWait < 1500) { int size = Udp.parsePacket(); if (size >= NTP_PACKET_SIZE) { Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer unsigned long secsSince1900; // convert four bytes starting at location 40 to a long integer secsSince1900 = (unsigned long)packetBuffer[40] << 24; secsSince1900 |= (unsigned long)packetBuffer[41] << 16; secsSince1900 |= (unsigned long)packetBuffer[42] << 8; secsSince1900 |= (unsigned long)packetBuffer[43]; return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; } } return 0; // return 0 if unable to get the time } // send an NTP request to the time server at the given address void sendNTPpacket(IPAddress &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(); } /*-------- NTP code END ----------*/