Электронные часы термометр без использования модуля/микросхемы точного времени
- Войдите на сайт для отправки комментариев
Ср, 20/03/2013 - 16:04
Доброе время суток.
Позвольте представить мою идею. Электронные часы термометр без использования модуля/микросхемы точного времени.
Идея такова: использовать код из стандартного примера «Udp NTP Client», получу время и выведу его на 7-и сегментную сборку из четырёх цифр. Также использую IR приемник (3-х ногий) буду ловить сигнал всех пультов от бытовой техники и на основании полученного сигнала (неважно какого) буду на 3 секунды выводить температуру с аналогово датчика температуры.
Как думаете получится?
Прошу высказать свои замечания и критику.
Вечером попробую все мои идее воплотить и отписаться тут.
Код для получения времени:
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(192, 43, 244, 18); // 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
EthernetUDP Udp;
void setup()
{
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
for(;;)
;
}
Udp.begin(localPort);
}
void loop()
{
sendNTPpacket(timeServer);
delay(1000);
if ( Udp.parsePacket() ) {
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;
const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 - seventyYears;
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 ) {Serial.print('0');}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ( (epoch % 60) < 10 ) {Serial.print('0');}
Serial.println(epoch %60); // print the second
}
delay(10000);
}
unsigned long sendNTPpacket(IPAddress& address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE);
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;
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();
}
Получится, почему бы и нет.
Только я здесь часов не вижу. Это скорее усовершенствованный радиоприемник, настроенный на станцию "Маяк", с его "Передаем сигналы точного времени. Начало шестого сигнала соответствует .... В Петропавловске-Камчатском полночь".
Ну и индикатор температуры до кучи...
Отлично, :)) буду сегодня тестировать.
под словом часы имелось ввиду индикация текущего точного времени.
протестировал, получилось интересно :)
#include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; unsigned int localPort = 8888; // local port to listen for UDP packets IPAddress timeServer(193, 169, 32, 218); // 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 EthernetUDP Udp; void setup() { Serial.begin(9600); 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 delay(100); if ( Udp.parsePacket() ) { 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; const unsigned long seventyYears = 2208988800UL; unsigned long epoch = secsSince1900 - seventyYears; Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) int Hour = (epoch % 86400L) / 3600; int Min = (epoch % 3600) / 60; int Sec = (epoch % 60); Serial.print(Hour); // print the hour (86400 equals secs per day) Serial.print(':'); if ( ((epoch % 3600) / 60) < 10 ) {Serial.print('0');} Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) Serial.print(':'); if ( (epoch % 60) < 10 ) {Serial.print('0');} Serial.println(epoch %60); // print the second if (Hour >= 0&&Hour < 20){Hour = Hour + 4;} if (Hour == 20){Hour = 00;} if (Hour == 21){Hour = 01;} if (Hour == 22){Hour = 02;} if (Hour == 23){Hour = 03;} Serial.print(Hour); Serial.print("-"); Serial.print(Min); Serial.print("-"); Serial.println(Sec); } // delay(1000); } unsigned long sendNTPpacket(IPAddress& address) { memset(packetBuffer, 0, NTP_PACKET_SIZE); 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; 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(); }подскажите пожайлусто более грамотный способ сделать +4 часа.
Использую пока эту конструкцию. Поздно уже, не думается...
if (Hour >= 0&&Hour < 20){Hour = Hour + 4;} if (Hour == 20){Hour = 00;} if (Hour == 21){Hour = 01;} if (Hour == 22){Hour = 02;} if (Hour == 23){Hour = 03;} Serial.print(Hour); Serial.print("-"); Serial.print(Min); Serial.print("-"); Serial.println(Sec);А не логичней сделать синхронизацию времени при включении, и коррекцию раз в 1, 5 или 15 минут? То есть что бы часы, были часами и шли нормально если инет отвалится?
p/s идея хорошая, возьму на заметку и попытаюсь прикрутить к своей измерялке влажности, температуры, давления .... заодно и графики можно будет по времени строить ...
В цикле считать время без использования "первичных часов" грамотно не получится.
Как то пробовал уже делать подобные часы (только без синхронизации откуда либо) врут сильно. Хотя попробовать можно.
текущий релиз кода.
#include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; unsigned int localPort = 8888; IPAddress timeServer(192, 43, 244, 18); const int NTP_PACKET_SIZE= 48; byte packetBuffer[ NTP_PACKET_SIZE]; EthernetUDP Udp; void setup() { Serial.begin(9600); if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); for(;;) ; } Udp.begin(localPort); } void loop() { sendNTPpacket(timeServer); delay(500); if ( Udp.parsePacket() ) { 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; const unsigned long seventyYears = 2208988800UL; unsigned long epoch = secsSince1900 - seventyYears; int Hour = ((epoch % 86400L) / 3600) + 4 % 24; int Min = (epoch % 3600) / 60; int Sec = epoch % 60; 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 ) {Serial.print('0');} Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) Serial.print(':'); if ( (epoch % 60) < 10 ) {Serial.print('0');} Serial.println(epoch %60); // print the second } } unsigned long sendNTPpacket(IPAddress& address) { memset(packetBuffer, 0, NTP_PACKET_SIZE); 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; 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(); }"В цикле считать время без использования "первичных часов" грамотно не получится."
Не понял ... Яж говорю с синхронизацией через промежутки ... и врут вроде не сильно, тоже где то видел ... несколько секунд в сутки ...
сегодня попробую, отпишусь за точность.
Накидал побыстрому, данный скеч показывает температуру и время на LCD дисплей. Время контроллер считает сам, и раз в минуту синхронизируется с NTP.
Код писал в блокноте на работе (в обед).
#include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h> #include <LiquidCrystal.h> int DateD = 0; int DateW = 0; int DateM = 0; int DateY = 0; int TimeH = 0; int TimeM = 0; int TimeS = 0; long OldMils1 = 0; long OldMils2 = 0; long OldMils3 = 0; long CurMils = 0; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; unsigned int localPort = 8888; // local port to listen for UDP packets IPAddress timeServer(193, 169, 32, 218); // 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 EthernetUDP Udp; void setup() { lcd.begin(16, 2); lcd.print("Temperature: "); Serial.begin(9600); if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); for(;;) ; } Udp.begin(localPort); } void loop() { CurMils = millis(); if (CurMils - OldMils1 > 1000 - 1) { OldMils1 = millis(); Time(); lcd.setCursor(13, 0); lcd.print(analogRead(A0)*500/1024); lcd.print("C"); lcd.setCursor(0, 1); lcd.print(TimeH); lcd.print("h"); lcd.print(":"); lcd.print(TimeM); lcd.print("m"); lcd.print(":"); lcd.print(TimeS); lcd.print("s"); lcd.print(" "); } if (CurMils - OldMils2 > 60000 - 1) { OldMils2 = millis(); sendNTPpacket(timeServer); // send an NTP packet to a time server } if (CurMils - OldMils3 > 1000 - 1) { OldMils2 = millis(); if ( Udp.parsePacket() ) { 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; const unsigned long seventyYears = 2208988800UL; unsigned long epoch = secsSince1900 - seventyYears; Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) int Hour = ((epoch % 86400L) / 3600) + 4 % 24; int Min = (epoch % 3600) / 60; int Sec = (epoch % 60); TimeH = Hour; TimeM = Min; TimeS = Sec; Serial.print(Hour); Serial.print(":"); Serial.print(Min); Serial.print(":"); Serial.println(Sec); } } } unsigned long sendNTPpacket(IPAddress& address) { memset(packetBuffer, 0, NTP_PACKET_SIZE); 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; 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(); } void Time() { TimeS++; if (TimeS > 59) { TimeM++; TimeS = 0; } if (TimeM > 59) { TimeH++; TimeM = 0; } if (TimeH > 23) { DateD++; TimeH = 0; }/* if (DateD > 7 ) { DateW++; DateD = 0; } if (DateW > 30) { DateM++; DateW = 0; } if (DateM > 12) { DateY++; DateM = 0; }*/ }Ух ты ) Быстро ... я с трудом пишу и долго ) Возьму за основу ваш скетчик, себе интегрирую ... как своё доделаю, тоже покажу ... только пока всё на макетке и непрезентабельно совсем ...