Arduino:Примеры/UdpNtpClient
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Клиент, запрашивающий время через NTP[1]
В этом примере мы воспользуемся Arduino и Ethernet Shield, чтобы делать запросы к серверу Network Time Protocol (NTP). Благодаря этому Arduino сможет получать из интернета информацию о времени.
Необходимое оборудование
- Сетевой модуль Arduino Ethernet Shield;
- Плата Arduino, совместимая с Ethernet Shield;
Цепь
Ethernet Shield позволяет подключить плату Arduino к Ethernet-контроллеру WizNet (через SPI). Это подключение осуществляется при помощи 10-ого, 11-ого, 12-ого и 13-ого контактов. У более поздних моделей Ethernet Shield имеется встроенный слот для SD-карты. В этом примере мы будем управлять SS-контактом этой SD-карты через 4-ый цифровой контакт.
Ethernet Shield должен быть подключен к сети при помощи Ethernet-кабеля. Также вам надо поменять сетевые настройки в скетче, чтобы они соответствовали настройкам вашей сети.
Ethernet Shield устанавливается поверх платы Arduino.
Схема
Код
/*
Клиент, запрашивающий время через NTP
Получает информацию о времени от NTP-сервера времени.
Демонстрирует отправку и передачу пакетов через UDP.
Более подробно о время-серверах NTP и сообщениях,
необходимых для их коммуникации, можно прочесть тут:
http://en.wikipedia.org/wiki/Network_Time_Protocol.
Внимание: NTP-сервера подвержены временным сбоям и имеют склонность менять IP-адреса.
Если время-сервер, используемый для этого примера, не работает,
пожалуйста, пройдите сюда – http://tf.nist.gov/tf-cgi/servers.cgi.
Создан 4 сентября 2010 Майклом Марголисом (Michael Margolis),
модифицирован 9 апреля 2012 Томом Иго (Tom Igoe).
Этот код не защищен авторским правом.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// Ниже введите MAC-адрес вашего контроллера.
// У модулей Ethernet Shield самых последних моделей MAC-адрес напечатан на стикере.
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
unsigned int localPort = 8888; // локальный порт, который будет прослушиваться на предмет UDP-пакетов
IPAddress timeServer(132, 163, 4, 101); // NTP-сервер time-a.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 102); // NTP-сервер time-b.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 103); // NTP-сервер time-c.timefreq.bldrdoc.gov NTP
const int NTP_PACKET_SIZE= 48; // временная отметка NTP находится в первых 48 байтах сообщения
byte packetBuffer[ NTP_PACKET_SIZE]; // буфер, в котором будут храниться входящие и исходящие пакеты
// Создаем экземпляр класса EthernetUDP, который позволит нам отправлять и получать пакеты через UDP:
EthernetUDP Udp;
void setup()
{
// Инициализируем последовательную передачу данных и ждем открытия порта:
Serial.begin(9600);
while (!Serial) {
; // ждем подключения последовательного порта (нужно только для Leonardo)
}
// Запускаем Ethernet и UDP:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP"); // "Не удалось сконфигурировать Ethernet при помощи UDP"
// Продолжать дальше смысла нет, поэтому дальше ничего не делаем:
for(;;)
;
}
Udp.begin(localPort);
}
void loop()
{
sendNTPpacket(timeServer); // Отсылаем время-серверу NTP-пакет
// Ждем, чтобы увидеть, доступен ли ответ:
delay(1000);
if ( Udp.parsePacket() ) {
// Пакет получен, значит считываем данные оттуда:
Udp.read(packetBuffer,NTP_PACKET_SIZE); // считываем содержимое пакета в буфер
// Временная отметка начинается с 40 байта полученного пакета
// и его длина составляет четыре байта или два слова.
// Для начала извлекаем два этих слова:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// Совмещаем четыре байта (два слова) в длинное целое.
// Это и будет NTP-временем (секунды начиная с 1 января 1990 года):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = " ); // "Секунды, прошедшие с 1 января 1990 = "
Serial.println(secsSince1900);
// Теперь конвертируем NTP-время в обычное время:
Serial.print("Unix time = "); // "Unix-время = "
// Время Unix стартует с 1 января 1970 года. В секундах это 2208988800:
const unsigned long seventyYears = 2208988800UL;
// Вычитаем 70 лет:
unsigned long epoch = secsSince1900 - seventyYears;
// Выводим на Serial Monitor Unix-время:
Serial.println(epoch);
// Выводим на Serial Monitor информацию о часах, минутах и секундах:
Serial.print("The UTC time is "); // "Среднее время по Гринвичу = ", // UTC – это среднее время по Гринвичу (GMT):
Serial.print((epoch % 86400L) / 3600); // выводим часы (86400 эквивалентно количеству секунд в день):
Serial.print(':');
if ( ((epoch % 3600) / 60) < 10 ) {
// У первых десяти минут каждого часа должна спереди стоять цифра «0»:
Serial.print('0');
}
Serial.print((epoch % 3600) / 60); // выводим минуты (3600 эквивалентно количеству секунд в минуте):
Serial.print(':');
if ( (epoch % 60) < 10 ) {
// У первых десяти секунд каждой минуты спереди должна стоять цифра «0»:
Serial.print('0');
}
Serial.println(epoch %60); // выводим секунды
}
// Ждем 10 секунд перед новым запросом о времени:
delay(10000);
}
// Отправляем NTP-запрос к время-серверу по указанному адресу:
unsigned long sendNTPpacket(IPAddress& address)
{
// Отправляем все байты (вплоть до 0-ого) в буфер:
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Инициализируем значения, необходимые для формирования NTP-запроса
// (подробнее о пакетах см. в URL выше):
packetBuffer[0] = 0b11100011; // LI (leap indicator, т.е. «индикатор перехода»), версия, режим работы
packetBuffer[1] = 0; // слой (или тип часов)
packetBuffer[2] = 6; // интервал запросов
packetBuffer[3] = 0xEC; // точность
// 8 байтов с нулями, обозначающие базовую задержку и базовую дисперсию
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// После заполнения всех указанных полей
// вы сможете отправлять пакет с запросом о временной метке:
Udp.beginPacket(address, 123); // NTP-запрос идет на порт 123
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
См.также
- Arduino Ethernet Shield
- Getting started with the ethernet shield
- Ethernet library
- ChatServer
- ChatClient
- WebClient
- WebServer
- PachubeClient?
- PachubeClientString?
- BarometricPressureWebServer
- UDPSendReceiveString
- UdpNtpClient
Внешние ссылки
Arduino продукты | |
---|---|
Начальный уровень | Arduino Uno • Arduino Leonardo • Arduino 101 • Arduino Robot • Arduino Esplora • Arduino Micro • Arduino Nano • Arduino Mini • Arduino Starter Kit • Arduino Basic Kit • MKR2UNO • TFT-дисплей Arduino |
Продвинутые функции | Arduino Mega 2560 • Arduino Zero • Arduino Due • Arduino Mega ADK • Arduino Pro • Arduino Motor Shield • Arduino USB Host Shield • Arduino Proto Shield • MKR Proto Shield • MKR Proto Large Shield • Arduino ISP • Arduino USB 2 Serial Micro • Arduino Mini USB Serial Adapter |
Интернет вещей | Arduino Yun • Arduino Ethernet • Arduino MKR1000 • Arduino WiFi 101 Shield • Arduino GSM Shield V2 • Arduino WiFi Shield • Arduino Wireless SD Shield • Arduino Wireless Proto Shield • Arduino Ethernet Shield V2 • Arduino Yun Shield • Arduino MKR1000 Bundle |
Носимые устройства | Arduino Gemma • Lilypad Arduino Simple • Lilypad Arduino Main Board • Lilypad Arduino USB • LilyPad Arduino SimpleSnap |
3D-печать | Arduino Materia 101 |
Устаревшие устройства | - |
Примеры Arduino | |
---|---|
Стандартные функции | |
Основы |
|
Цифровой сигнал |
|
Аналоговый сигнал |
|
Связь |
|
Управляющие структуры |
|
Датчики |
|
Дисплей |
Примеры, объясняющие основы управления дисплеем:
|
Строки |
|
USB (для Leonardo, Micro и Due плат) |
В этой секции имеют место примеры, которые демонстрируют использование библиотек, уникальных для плат Leonardo, Micro и Due.
|
Клавиатура |
|
Мышь |
|
Разное |
- Страницы, использующие повторяющиеся аргументы в вызовах шаблонов
- Справочник языка Arduino
- Arduino
- Перевод от Сubewriter
- Проверка:myagkij
- Оформление:myagkij
- Редактирование:myagkij
- Страницы, где используется шаблон "Навигационная таблица/Телепорт"
- Страницы с телепортом
- Пример
- Примеры
- Пример программирования Arduino
- Примеры программирования Arduino