Arduino:Примеры/UdpNTPClient
Перейти к навигации
Перейти к поиску
Поддержать проект | Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.
Содержание
Получение времени от NTP-сервера при помощи WiFi-модуля[1]
Этот пример показывает, как при помощи WiFi-модуля и платы Arduino/Genuino сделать запрос к серверу Network Time Protocol (NTP). Благодаря этому ваша плата сможет узнавать время через интернет.
Необходимое оборудование
- WiFi-модуль Arduino
- Плата Arduino/Genuino, совместимая с WiFi-модулем
Цепь
Чтобы выполнить SPI-соединение с модулем HDG104, WiFi-модуль использует 10-ый, 11-ый, 12-ый и 13-ый контакты. Для управления SS-контактом SD-карты используется 4-ый цифровой контакт.
Кроме того, для этого скетча нужен доступ к беспроводной сети типа 802.11b/g, подключенной к интернету. Также в скетче нужно будет поменять сетевые настройки, чтобы они соответствовали настройкам вашей SSID.
На картинке выше плата Arduino находится под WiFi-модулем Arduino.
Код
1 /*
2
3 Клиент, запрашивающий время через NTP с помощью WiFi
4
5 Получает информацию о времени через время-сервер Network Time
6 Protocol (NTP). Показывает, как получать и отправлять пакеты через
7 UDP. Более подробно о время-серверах NTP и сообщениях для
8 коммуникации с ними читайте на https://ru.wikipedia.org/wiki/NTP.
9
10 Создан 4 сентября 2010 года Майклом Маргулисом (Michael Margolis),
11 модифицирован 9 апреля 2012 года Томом Иго (Tom Igoe).
12
13 Этот код не защищен авторским правом.
14
15 */
16
17 #include <SPI.h>
18 #include <WiFi.h>
19 #include <WiFiUdp.h>
20
21 int status = WL_IDLE_STATUS;
22 char ssid[] = "mynetwork"; // ваш SSID (название точки доступа)
23 char pass[] = "mypassword"; // пароль к точке доступа
24 int keyIndex = 0; // номер ключа (нужно только для WEP)
25
26 unsigned int localPort = 2390; // локальный порт, который нужно прослушивать на предмет прихода UDP-пакетов
27
28 IPAddress timeServer(129, 6, 15, 28); // NTP-сервер time.nist.gov
29
30 const int NTP_PACKET_SIZE = 48; // временная отметка NTP находится в первых 48 байтах сообщения
31
32 byte packetBuffer[ NTP_PACKET_SIZE]; // буфер для хранения входящих и исходящих пакетов
33
34 // экземпляр класса UDP, который позволит отправлять и получать пакеты через UDP:
35 WiFiUDP Udp;
36
37 void setup() {
38 // запускаем последовательную коммуникацию и ждем открытия порта:
39 Serial.begin(9600);
40 while (!Serial) {
41 ; // ждем подключения последовательного порта (нужно только для плат со штатным USB-портом)
42 }
43
44 // проверяем наличие WiFi-модуля:
45 if (WiFi.status() == WL_NO_SHIELD) {
46 Serial.println("WiFi shield not present"); // "WiFi-модуль не подключен"
47 // дальше не продолжаем:
48 while (true);
49 }
50
51 String fv = WiFi.firmwareVersion();
52 if (fv != "1.1.0") {
53 Serial.println("Please upgrade the firmware"); // "Пожалуйста, обновите прошивку"
54 }
55
56 // пытаемся подключиться к WiFi-сети:
57 while (status != WL_CONNECTED) {
58 Serial.print("Attempting to connect to SSID: "); // "Пытаемся подключиться к SSID: "
59 Serial.println(ssid);
60 // подключаемся к сети с шифрованием WPA/WPA2. Если используете открытую сеть или WEP, поменяйте эту строчку:
61 status = WiFi.begin(ssid, pass);
62
63 // 10 секунд ждем подключения:
64 delay(10000);
65 }
66
67 Serial.println("Connected to wifi"); // "Подключение к WiFi-точке установлено"
68 printWifiStatus();
69
70 Serial.println("\nStarting connection to server..."); // "\nНачинаем подключаться к серверу..."
71 Udp.begin(localPort);
72 }
73
74 void loop() {
75 sendNTPpacket(timeServer); // отправляем NTP-пакет на время-сервер
76 // ждем, пока придет ответ:
77 delay(1000);
78 if (Udp.parsePacket()) {
79 Serial.println("packet received"); // "Пакет получен"
80 // Пакет получен, считываем данные из него:
81 Udp.read(packetBuffer, NTP_PACKET_SIZE); // считываем пакет в буфер
82
83 // временная отметка начинается на 40-ом байте полученного пакета, и это 4 байта
84 // или 2 слова (тип данных – long). Сначала извлекаем 2 слова:
85
86 unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
87 unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
88 // совмещаем 4 байта (2 слова) в long integer;
89 // это будет NTP-время (секунды, прошедшие с 1 января 1900 года):
90 unsigned long secsSince1900 = highWord << 16 | lowWord;
91 Serial.print("Seconds since Jan 1 1900 = "); // "Секунды, прошедшие с 1 января 1900 года = "
92 Serial.println(secsSince1900);
93
94 // теперь конвертируем NTP-время в обычное время:
95 Serial.print("Unix time = "); // "Unix-время = "
96 // Unix-время стартует с 1 января 1970 года. В секундах это «2208988800»:
97 const unsigned long seventyYears = 2208988800UL;
98 // вычитаем 70 лет:
99 unsigned long epoch = secsSince1900 - seventyYears;
100 // показываем Unix-время:
101 Serial.println(epoch);
102
103
104 // показываем час, минуту и секунду:
105 Serial.print("The UTC time is "); // "UTC-время: " UTC – это время по Гринвичу (GMT)
106 Serial.print((epoch % 86400L) / 3600); // показываем час (86400 - это количество секунд в сутках)
107 Serial.print(':');
108 if (((epoch % 3600) / 60) < 10) {
109 // у первых 10 минут каждого часа впереди должна стоять цифра «0»:
110 Serial.print('0');
111 }
112 Serial.print((epoch % 3600) / 60); // показываем минуту (3600 – это количество секунд в минуту)
113 Serial.print(':');
114 if ((epoch % 60) < 10) {
115 // у первых 10 секунд каждой минуты впереди должна стоять цифра «0»:
116 Serial.print('0');
117 }
118 Serial.println(epoch % 60); // показываем секунду
119 }
120 // перед тем, как спрашивать время еще раз, ждем 10 секунд:
121 delay(10000);
122 }
123
124 // отправляем NTP-запрос на время-сервер по указанному адресу:
125 unsigned long sendNTPpacket(IPAddress& address) {
126 //Serial.println("1");
127 // делаем все байты в буфере нулями:
128 memset(packetBuffer, 0, NTP_PACKET_SIZE);
129 // инициализируем значения, необходимые для NTP-запроса:
130 // (более подробно о пакетах читайте по ссылке выше)
131 //Serial.println("2");
132 packetBuffer[0] = 0b11100011; // LI (leap indicator, т.е. «индикатор перехода»), версия, режим работы
133 packetBuffer[1] = 0; // слой (или тип часов)
134 packetBuffer[2] = 6; // интервал запросов
135 packetBuffer[3] = 0xEC; // точность
136 // 8 байт с нулями, обозначающие базовую задержку и базовую дисперсию
137 packetBuffer[12] = 49;
138 packetBuffer[13] = 0x4E;
139 packetBuffer[14] = 49;
140 packetBuffer[15] = 52;
141
142 //Serial.println("3");
143
144 // после заполнения всех указанных полей
145 // вы сможете отправлять пакет с запросом о временной метке:
146 Udp.beginPacket(address, 123); // NTP-запросы на порт 123
147 //Serial.println("4");
148 Udp.write(packetBuffer, NTP_PACKET_SIZE);
149 //Serial.println("5");
150 Udp.endPacket();
151 //Serial.println("6");
152 }
153
154
155 void printWifiStatus() {
156 // показываем SSID сети, к которой подключились:
157 Serial.print("SSID: ");
158 Serial.println(WiFi.SSID());
159
160 // показываем IP-адрес WiFi-модуля:
161 IPAddress ip = WiFi.localIP();
162 Serial.print("IP Address: "); // "IP-адрес: "
163 Serial.println(ip);
164
165 // показываем мощность приемного сигнала:
166 long rssi = WiFi.RSSI();
167 Serial.print("signal strength (RSSI):"); // "Мощность сигнала (RSSI):"
168 Serial.print(rssi);
169 Serial.println(" dBm"); // "дБм"
170 }
См.также
- WiFi library – Your reference for the WiFi Library.
- WiFi Shield – Product details for the retired WiFi Shield.
- Getting started – Getting started with the retired WiFi Shield.
- Connect No Encryption - Demonstrates how to connect to an open network.
- Connect With WEP - Demonstrates how to connect to a network that is encrypted with WEP.
- Connect With WPA - Demonstrates how to connect to a network that is encrypted with WPA2 Personal.
- Scan Networks - Displays all WiFi networks in range.
- Simple Web Server WiFi – Turn on and off an LED accessing this simple Web Server.
- WiFi Chat Server - Set up a simple chat server.
- WiFi Web Client - Connect to a remote webserver.
- WiFi Web Client Repeating - Repeatedly make HTTP calls to a server.
- WiFi Web Server - Serve a webpage from the WiFi shield with Analog Input values.
- WiFi Send Receive UDP String - Send and receive a UDP string.
Внешние ссылки