When I try to build this project, I get a lot of messages about undefined stuff:
C:UsersAlexanderDocumentsArduinoesp8266-ledclockesp8266-ledclock.ino: In function ‘void handleRoot()’:
esp8266-ledclock:32: error: ‘hour’ was not declared in this scope
s.replace(«@@hour@@», String(hour()));
esp8266-ledclock:33: error: ‘minute’ was not declared in this scope
s.replace(«@@min@@», String(minute()));
esp8266-ledclock:36: error: ‘timeStatus’ was not declared in this scope
s.replace(«@@SYNCSTATUS@@», timeStatus() == timeSet ? «OK» : «Overdue»);
esp8266-ledclock:36: error: ‘timeSet’ was not declared in this scope
s.replace(«@@SYNCSTATUS@@», timeStatus() == timeSet ? «OK» : «Overdue»);
C:UsersAlexanderDocumentsArduinoesp8266-ledclockesp8266-ledclock.ino: In function ‘void handleForm()’:
esp8266-ledclock:59: error: ‘getNtpTime’ was not declared in this scope
time_t newTime = getNtpTime();
esp8266-ledclock:61: error: ‘setTime’ was not declared in this scope
esp8266-ledclock:77: error: ‘setupWiFi’ was not declared in this scope
C:UsersAlexanderDocumentsArduinoesp8266-ledclockesp8266-ledclock.ino: In function ‘void setup()’:
esp8266-ledclock:82: error: ‘setupDisplay’ was not declared in this scope
setupDisplay();
esp8266-ledclock:85: error: ‘setupWiFi’ was not declared in this scope
setupWiFi();
esp8266-ledclock:86: error: ‘setupTime’ was not declared in this scope
setupTime();
C:UsersAlexanderDocumentsArduinoesp8266-ledclockesp8266-ledclock.ino: In function ‘void loop()’:
esp8266-ledclock:94: error: ‘displayIP’ was not declared in this scope
if (displayIP()) return;
esp8266-ledclock:96: error: ‘timeStatus’ was not declared in this scope
if (timeStatus() != timeNotSet) {
^
esp8266-ledclock:96: error: ‘timeNotSet’ was not declared in this scope
if (timeStatus() != timeNotSet) {
^
esp8266-ledclock:97: error: ‘now’ was not declared in this scope
if (now() != prevDisplay) { //update the display only if time has changed
^
esp8266-ledclock:99: error: ‘displayClock’ was not declared in this scope
C:UsersAlexanderDocumentsArduinoesp8266-ledclockesp8266-ledclock.ino: In function ‘void setupWiFi()’:
esp8266-ledclock:108: error: ‘displayBusy’ was not declared in this scope
displayBusy(0);
esp8266-ledclock:111: error: ‘stopDisplayBusy’ was not declared in this scope
esp8266-ledclock:112: error: ‘setupAP’ was not declared in this scope
esp8266-ledclock:112: error: return-statement with a value, in function returning ‘void’ [-fpermissive]
esp8266-ledclock:116: error: ‘stopDisplayBusy’ was not declared in this scope
stopDisplayBusy();
esp8266-ledclock:117: error: ‘setupSTA’ was not declared in this scope
setupSTA();
C:UsersAlexanderDocumentsArduinoesp8266-ledclockesp8266-ledclock.ino: In function ‘void setupSTA()’:
esp8266-ledclock:126: error: ‘displayBusy’ was not declared in this scope
displayBusy(1);
esp8266-ledclock:141: error: ‘stopDisplayBusy’ was not declared in this scope
stopDisplayBusy();
esp8266-ledclock:142: error: ‘displayDash’ was not declared in this scope
displayDash();
C:UsersAlexanderDocumentsArduinoesp8266-ledclockesp8266-ledclock.ino: In function ‘void setupAP()’:
esp8266-ledclock:149: error: ‘displayAP’ was not declared in this scope
displayAP();
C:UsersAlexanderDocumentsArduinoesp8266-ledclockdisplay.ino: In function ‘void displayBusy(char)’:
display:103: error: ‘_displayBusy’ was not declared in this scope
ticker.attach(0.1, _displayBusy);
C:UsersAlexanderDocumentsArduinoesp8266-ledclockdisplay.ino: In function ‘char displayIP()’:
display:130: error: ‘_displayIP’ was not declared in this scope
ticker.attach(1.0, _displayIP);
C:UsersAlexanderDocumentsArduinoesp8266-ledclockdisplay.ino: In function ‘void _displayIP()’:
display:138: error: ‘displayClock’ was not declared in this scope
clockMode == MODE_CLOCK ? displayClock() : displayAP();
^
C:UsersAlexanderDocumentsArduinoesp8266-ledclockdisplay.ino: In function ‘void displayClock()’:
display:157: error: ‘hour’ was not declared in this scope
int h = hour();
display:158: error: ‘minute’ was not declared in this scope
int m = minute();
display:173: error: ‘second’ was not declared in this scope
if (second() & 0x1) decimals = 0x4;
display:174: error: ‘timeStatus’ was not declared in this scope
if (timeStatus() != timeSet) decimals |= 0x1;
display:174: error: ‘timeSet’ was not declared in this scope
if (timeStatus() != timeSet) decimals |= 0x1;
C:UsersAlexanderDocumentsArduinoesp8266-ledclockntp.ino: In function ‘void setupTime()’:
ntp:13: error: ‘getNtpTime’ was not declared in this scope
setSyncProvider(getNtpTime);
ntp:13: error: ‘setSyncProvider’ was not declared in this scope
setSyncProvider(getNtpTime);
ntp:14: error: ‘setSyncInterval’ was not declared in this scope
setSyncInterval(settings.interval);
C:UsersAlexanderDocumentsArduinoesp8266-ledclockntp.ino: In function ‘time_t getNtpTime()’:
ntp:23: error: ‘sendNTPpacket’ was not declared in this scope
ntp:33: error: ‘SECS_PER_HOUR’ was not declared in this scope
return secSince1900 - 2208988800UL + settings.timezone * SECS_PER_HOUR;
^
exit status 1
‘hour’ was not declared in this scope
spasi_i_sohrani 0 / 0 / 0 Регистрация: 14.12.2020 Сообщений: 6 |
||||
1 |
||||
14.12.2020, 20:24. Показов 7430. Ответов 8 Метки нет (Все метки)
Ошибка [Error] ‘time’ was not declared in this scope
__________________
0 |
Verevkin Нарушитель 8388 / 4391 / 1009 Регистрация: 12.03.2015 Сообщений: 20,566 |
||||
14.12.2020, 21:07 |
2 |
|||
Ошибка [Error] ‘time’ was not declared in this scope
1 |
Yetty 7423 / 5018 / 2890 Регистрация: 18.12.2017 Сообщений: 15,694 |
||||
15.12.2020, 04:33 |
3 |
|||
это не С++
#include <time.h>
0 |
spasi_i_sohrani 0 / 0 / 0 Регистрация: 14.12.2020 Сообщений: 6 |
||||
15.12.2020, 19:43 [ТС] |
4 |
|||
Не сработало
0 |
Нарушитель 8388 / 4391 / 1009 Регистрация: 12.03.2015 Сообщений: 20,566 |
|
15.12.2020, 19:46 |
5 |
Не сработало неужели та же ошибка?
0 |
0 / 0 / 0 Регистрация: 14.12.2020 Сообщений: 6 |
|
15.12.2020, 19:49 [ТС] |
6 |
[Error] сtime: No such file or directory
0 |
Verevkin Нарушитель 8388 / 4391 / 1009 Регистрация: 12.03.2015 Сообщений: 20,566 |
||||
15.12.2020, 19:55 |
7 |
|||
Решение
[Error] сtime: No such file or directory
1 |
0 / 0 / 0 Регистрация: 14.12.2020 Сообщений: 6 |
|
15.12.2020, 20:01 [ТС] |
8 |
Спасибо! После iostream не прописала stdlib, теперь работает
0 |
Нарушитель 8388 / 4391 / 1009 Регистрация: 12.03.2015 Сообщений: 20,566 |
|
15.12.2020, 20:07 |
9 |
После iostream не прописала stdlib
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
15.12.2020, 20:07 |
9 |
-
В программировании я полный ноль.Вчера в первые взял ардуину в руки.Начал как и все с опытов со светодиодами.Даже смог сам написать скетч светофор.Но вот одного не пойму как сделать две независимые друг от друга функции.Например есть простой скетч для 1 светика в него дописал красным для второго светика.Но второй светик не загорится пока первый не выполнит свои действия.Например хочу сделать чтоб 1 светик просто моргал а второй висел на шиме и управлялся переменником.Собрал работает всё но только пока 1 светик не погаснет и снова загорится яркость второго не меняется.
void setup()
{
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
}void loop()
{
digitalWrite(12, HIGH);
delay(100);
digitalWrite(12, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(900);
} -
Для этого надо сделать нечто вроде параллельного исполнения задач, для чего в свою очередь придется перейти на использование millis вместо delay
Что-то вроде.unsigned long last_state_change_time12=0;
unsigned long last_state_change_time13=0;
int laststate12=LOW;
int laststate13=LOW;void setup()
{
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(12, HIGH); // начальное состояние
digitalWrite(13, HIGH); // начальное состояние
laststate12=HIGH;
laststate13=HIGH;
}void loop()
{
if ((laststate12==LOW)&&(millis()-last_state_change_time12>100)) {
digitalWrite(12, HIGH);
last_state_change_time12=millis();
laststate12=HIGH;
} else if ((laststate12==HIGH)&&(millis()-last_state_change_time12>100)) {
digitalWrite(12, LOW);
last_state_change_time12=millis();
laststate12=LOW;
}
if ((laststate13==LOW)&&(millis()-last_state_change_time13>900)) {
digitalWrite(13, HIGH);
last_state_change_time13=millis();
laststate13=HIGH;
} else if ((laststate13==HIGH)&&(millis()-last_state_change_time13>100)) {
digitalWrite(13, LOW);
last_state_change_time13=millis();
laststate13=LOW;
}
}Если второй диод должен управляться шимом, то его надо переключить на пин, поддерживающий шим, например. 11=й. Потенциометр, предположим, подключен к A0.
Код будет примерно такой:unsigned long last_state_change_time13=0;
int laststate13=LOW;void setup()
{
pinMode(11, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(13, HIGH); // начальное состояние
laststate13=HIGH;
}void loop()
{
int val = analogRead(0); // read the input pin
analogWrite(11, val / 4); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255if ((laststate13==LOW)&&(millis()-last_state_change_time13>900)) {
digitalWrite(13, HIGH);
last_state_change_time13=millis();
laststate13=HIGH;
} else if ((laststate13==HIGH)&&(millis()-last_state_change_time13>100)) {
digitalWrite(13, LOW);
last_state_change_time13=millis();
laststate13=LOW;
}
} -
Спасибо большое сам бы не когда до этого не дошел
Выглядит всё очень сложно и совсем не понятно тёмный лес.Буду разбираться может что то пойму.И ещё вопросик есть модуль RTC DS3231 а скетч не заливается пишет ошибку и выделяет строку setSyncProvider(RTC.get);
sketch_aug25a.ino: In function ‘void setup()’:
sketch_aug25a:7: error: ‘class DS1307RTC’ has no member named ‘get’
sketch_aug25a:7: error: ‘setSyncProvider’ was not declared in this scope
sketch_aug25a:10: error: ‘setTime’ was not declared in this scope
sketch_aug25a:12: error: ‘now’ was not declared in this scope
sketch_aug25a.ino: In function ‘void loop()’:
sketch_aug25a:16: error: ‘sleep’ was not declared in this scope#Подключаем библиотеки:
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>void setup() {
setSyncProvider(RTC.get);//Устанавливаем время в формате://Часы, минуты, секунды, день, месяц, год
setTime(14,50,0,12,4,2014);
//Применяем:
RTC.set(now());
}
void loop()
{
sleep(100);
} -
Тут надо разбираться с конкретной библиотекой. Возможно, что она просто другая, с другими функциями.
Компилятор сообщает, что у класса DS1307RTC нет метода get.
Глядя на строку, на которой вылазит это сообщение, видим, что, скорее всего, RTC является переменной класса DS1307RTC (которые, в смысле переменная и класс, объявлены в одном из подключаемых заголовочных файлов, скорее всего DS1307RTC.h). И у этого класса нет метода get. Отсюда следует вывод, что стоит либо поискать библиотеку, соответствующую описанию, согласно которому была написана эта строка, либо ознакомиться с методами класса реально подключенной библиотеки и переписать все согласно ее требованиям.
То же можно сказать относительно следующих трех сообщений, в именно что ни в одной из подключенных библиотек не объявлены функции setSyncProvider, setTime и now, т.е. надо смотреть, на основании чего были написаны эти вызовы, в какой библиотеке они должны быть, и не надо ли посмотреть описание подключенной библиотеки, чтобы заменить эти вызовы на аналоги, в ней имеющиеся.
Более подробно по этому ничего не скажу. поскольку с этой библиотекой (требующей включения DS1307RTC.h) не сталкивался.А с этим предельно понятно. Не sleep, а delay. -
Ясно спасибо за ответы.На сайте где этот скетч взял его тестили на DS3231 и этот скетч к нему подходит.Только у меня он чёт не работает да и много других перепробывал тоже ничего не вышло.Пока оставлю этот rtc и буду изучать опыты на светиках.
-
Наигравшись со светиками решил вновь вернуться к часикам за одно и подключил дисплей)
Библиотеку ds3231 нашел из примеров которые в нём ни чё не работает.Собрал я вот такой скетч всё работает только время при отключении питания сбивается.Батарейка в норме проблема 100% в скетче.#include <Wire.h>
#include <DS3231.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte year, month, date, DoW, hour, minute, second;void setup()
{
Wire.begin();
lcd.begin(20, 4);
lcd.clear();
lcd.setBacklight(HIGH);Clock.setSecond(50);//Set the second
Clock.setMinute(59);//Set the minute
Clock.setHour(10); //Set the hour
Clock.setDoW(7); //Set the day of the week
Clock.setDate(7); //Set the date of the month
Clock.setMonth(10); //Set the month of the year
Clock.setYear(14); //Set the year (Last two digits of the year)
}void loop()
{
int second,minute,hour,date,month,year,temperature;year=Clock.getYear();
month=Clock.getMonth(Century);
date=Clock.getDate();
hour=Clock.getHour(h12,PM);
minute=Clock.getMinute();
second=Clock.getSecond();
temperature=Clock.getTemperature();lcd.print(«Date «);
if (date<10) lcd.print(‘0’);
lcd.print(date,DEC);
lcd.print(‘-‘);
if (month<10) lcd.print(‘0’);
lcd.print(month,DEC);
lcd.print(‘-‘);
lcd.print(«20»);
lcd.print(year,DEC);
lcd.setCursor(11, 3);
lcd.print(» Vcore1.7″);lcd.setCursor(0, 1);
lcd.print(«Time»);
lcd.setCursor(6, 1);
if (hour<10) lcd.print(‘0’);
lcd.print(hour,DEC);
lcd.print(‘:’);
if (minute<10) lcd.print(‘0’);
lcd.print(minute,DEC);
lcd.print(‘:’);
if (second<10) lcd.print(‘0’);
lcd.print(second,DEC);
lcd.print(‘ ‘);
lcd.setCursor(0, 3);
lcd.print(«Temp:»);
lcd.print(temperature);
delay(1);
lcd.setCursor(0,0);
} -
В setup:
Clock.setSecond(50);//Set the second
Clock.setMinute(59);//Set the minute
Clock.setHour(10); //Set the hour
Clock.setDoW(7); //Set the day of the week
Clock.setDate(7); //Set the date of the month
Clock.setMonth(10); //Set the month of the year
Clock.setYear(14); //Set the year (Last two digits of the year)Получается, что время устанавливается на часах при каждых включении и ресете .
-
Спасибо за подсказку.Чёт я сам не догадался.Взял просто удалил со скетча эти строки и теперь время не сбивается
Ещё вопрос есть вот такие функции.Как сделать чтоб от отдельной кнопки управлять сразу 2мя пинами с одной кнопки?buttonState = digitalRead(buttonPin);
if (buttonState == LOW){
digitalWrite(ledPin, HIGH);
}
else{
digitalWrite(ledPin, LOW);
}
{
buttonState = digitalRead(buttonPin1);
if (buttonState == LOW){
digitalWrite(ledPin1, HIGH);
}
else {
digitalWrite(ledPin1, LOW);
}Пробовал так но при нажатии на кнопку диод моргает еле видно
buttonState = digitalRead(buttonPin2);
if (buttonState == LOW){
digitalWrite(ledPin, HIGH), digitalWrite(ledPin1, HIGH);
}
else{
digitalWrite(ledPin, LOW), digitalWrite(ledPin1, LOW);
}
{
buttonState = digitalRead(buttonPin);
if (buttonState == LOW){
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
{
buttonState = digitalRead(buttonPin1);
if (buttonState == LOW){
digitalWrite(ledPin1, HIGH);
}
else {
digitalWrite(ledPin1, LOW);
} -
Есть одиночное, двойное , длительное нажатие кнопки. Вот по этому принципу и управляйте пинами. Например одиночные нажатия — один пин, длительные — второй.
Все давно привыкли, что у каждого электронного устройства есть экран, с помощью которого оно дает человеку всякую полезную информацию. MP3-плеер показывает название играемого трека, пульт квадрокоптера отображает полетную телеметрию, даже стиральная машина выводит на дисплей время до конца стирки, а на смартфоне вообще размещается целый рабочий стол персонального компьютера!
Скорее всего, вашему очередному устройству тоже не помешает какой-нибудь небольшой дисплейчик 🙂 Попробуем сделать простые электронные часы! А в качестве табло используем распространенный и дешевый символьный жидкокристаллический дисплей 1602. Вот прямо такой, как на картинке:
Кроме 16х2, достаточно популярным считается символьный дисплей 20х4 (четыре строки по 20 символов), а также графический дисплей с разрешением 128х64 точек. Вот они на картинках:
У дисплея 1602 есть 16 выводов. Обычно они нумеруются слева-направо, если смотреть на него так как на картинке. Иногда выводы подписываются, типа: DB0, DB1, EN и т.п. А иногда просто указывают номер вывода. В любом случае, список выводов всегда одинаковый:
1 — «GND», земля (минус питания);
2 — «Vcc», питание +5В;
3 — «VEE», контраст;
4 — «RS», выбор регистра;
5 — «R/W», направление передачи данных (запись/чтение);
6 — «EN», синхронизация;
7-14 — «DB0», «DB1», .., «DB7″- шина данных;
15 — анод подсветки (+5В);
16 — катод подсветки (земля).
Линии VEE, RS и четыре линии данных DB4, DB5, DB6, DB7 подключаем к цифровым выводам контроллера. Линию «R/W» подключим к «земле» контроллера (так как нам потребуется только функция записи в память дисплея). Подсветку пока подключать не будем, с этим, я полагаю, вы сами легко разберетесь 🙂
Принципиальная схема подключения дисплея к Ардуино Уно
Внешний вид макета
На всякий случай еще и в виде таблички:
ЖК дисплей 1602 | 1 | 2 | 4 | 6 | 11 | 12 | 13 | 14 | 15 | 16 |
Ардуино Уно | GND | +5V | 4 | 5 | 6 | 7 | 8 | 9 | +5V | GND |
Программируем «Hello, world!»
Для работы с ЖК дисплеями различных размеров и типов, в редакторе Arduino IDE имеется специальная библиотека LiquidCrystal. Чтобы подключить библиотеку, запишем первой строчкой нашей программы следующее выражение:
#include <LiquidCrystal.h>
Далее, нам потребуется указать какие выводы Ардуино мы использовали для подключения дисплея. Эту информацию мы укажем при инициализации модуля:
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
Здесь первые два аргумента — это выводы RS и EN, а оставшиеся четыре — линии шины данных DB4-DB7.
Далее, укажем размер дисплея с помощью команды «begin»:
lcd.begin(16, 2);
Напоминаю, в нашем дисплее имеется две строки, по 16 символов в каждой.
Наконец, для вывода текста нам понадобится простая функция «print». Вывод с помощью этой функции всем известной фразы будет выглядеть следующим образом:
lcd.print( "Hello, world!" );
Полностью программа будет выглядеть так:
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
void setup(){
lcd.begin(16, 2);
lcd.print( "Hello, world!" );
}
void loop(){
}
Загружаем её на Ардуино Уно, и смотрим что творится на дисплее. Может быть три основных ситуации 🙂
1) На дисплее отобразится надпись «Hello, world!». Значит вы все правильно подключили, и контраст каким-то чудесным образом оказался изначально правильно настроен. Радуемся, и переходим к следующей главе.
2) На дисплее отобразится целый ряд черных прямоугольников — требуется настройка контраста! Именно для этого мы добавили в цепь потенциометр с ручкой. Крутим его от одного края, до другого, до момента пока на дисплее не появится четкая надпись.
3) Два ряда черных прямоугольников. Скорее всего, вы что-то напутали при подключении. Проверьте трижды все провода. Если не найдете ошибку — попросите кота проверить!
Программируем часы
Теперь когда дисплей точно работает, попробуем превратить наше нехитрое устройство в настоящие электронные часы.
Внимание! Для вывода времени нам потребуется библиотека «Time». Если она еще не установлена, то можно скачать архив по ссылке. Подключим ее:
#include <Time.h>
Затем установим текущие дату и время с помощью функции «setTime»:
setTime( 23, 59, 59, 12, 31, 2015 );
Здесь все понятно: часы, минуты, секунды, месяц, число, год.
Для вывода даты используем кучу функции:
- year() — вернет нам год;
- month() — месяц;
- day() - день;
- hour() - час;
- minute() — вернет минуту;
- second() - секунду.
Теперь обратим внимание вот на какой факт. Если посчитать количество символов в типовой записи даты: «31.12.2015 23:59:59», получим 19. А у нас всего 16! Не влазит, однако, в одну строчку.
Решить проблему можно еще одной полезной функцией — «setCursor». Эта функция устанавливает курсор в нужную позицию. Например:
lcd.setCursor(0,1);
Установит курсор в начало второй строчки. Курсор — это место символа, с которого начнется вывод текста следующей командой «print». Воспользуемся этой функцией для вывода даты в первой строчке, а времени во второй.
С выводом даты и времени теперь все ясно. Остались рутинные вещи. Например, после каждого заполнения дисплея, мы будем его чистить функцией «clear()»:
lcd.clear();
А еще нам нет смысла выводить данные на дисплей чаще чем раз в секунду, поэтому между двумя итерациями сделаем паузу в 1000 миллисекунд.
Итак, сложив все вместе, получим такую программу:
#include <Time.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
void setup(){
lcd.begin(16, 2);
setTime(7,0,0,1,10,2015); // 7 утра, десятого января 2015 года
}
void loop(){
lcd.clear();
lcd.print( day() );
lcd.print( "." );
lcd.print( month() );
lcd.print( "." );
lcd.print( year() );
lcd.setCursor(0, 1);
lcd.print( hour() );
lcd.print( ":" );
lcd.print( minute() );
lcd.print( ":" );
lcd.print( second() );
delay(1000);
}
Загружаем скетч на Ардуино Уно, и наблюдаем за ходом часиков! 🙂 Для того чтобы закрепить полученные знания, рекомендую прокачать наши часы до полноценного будильника. Всего-то на всего потребуется добавить пару кнопок и зуммер 🙂
Introduction: Arduino Internet Time Client
UPDATE! 11/15/2015
Added a WiFi and rechargeable battery option (step 10).
Step 1: Connecting the Hardware
First, write down the MAC address printed on the bottom of your ethernet shield. You will need it for the next step.
It looks something like 90 A2 DA 00 23 36 but will get inserted into the code as 0x90, 0xA2, 0xDA, 0x00, 0x23, 0x36
Plug the Ethernet Shield on top of the Arduino UNO. Connect it to your internet router with a Ethernet cable.
Step 2: Code
Only one additional library needs to be installed into your Arduino libraries folder. That is the Time Library available at http://www.pjrc.com/teensy/td_libs_Time.html
You will need the mac address from the bottom of your Ethernet Shield, but IP, Gateway and Subnet mask are all obtained throgh DHCP. You will also need the time server address (see next step)
The code that needs to be uploaded to your Arduino is as follows:
//sample code originated at http://www.openreefs.com/ntpServer
//modified by Steve Spence, http://arduinotronics.blogspot.com
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
/* ******** Ethernet Card Settings ******** */
// Set this to your Ethernet Card Mac Address
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x23, 0x36 };
/* ******** NTP Server Settings ******** */
/* us.pool.ntp.org NTP server
(Set to your time server of choice) */
IPAddress timeServer(216, 23, 247, 62);
/* Set this to the offset (in seconds) to your local time
This example is GMT — 4 */
const long timeZoneOffset = -14400L;
/* Syncs to NTP server every 15 seconds for testing,
set to 1 hour or more to be reasonable */
unsigned int ntpSyncTime = 3600;
/* ALTER THESE VARIABLES AT YOUR OWN RISK */
// local port to listen for UDP packets
unsigned int localPort = 8888;
// NTP time stamp is in the first 48 bytes of the message
const int NTP_PACKET_SIZE= 48;
// Buffer to hold incoming and outgoing packets
byte packetBuffer[NTP_PACKET_SIZE];
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// Keeps track of how long ago we updated the NTP server
unsigned long ntpLastUpdate = 0;
// Check last time clock displayed (Not in Production)
time_t prevDisplay = 0;
void setup() {
Serial.begin(9600);
// Ethernet shield and NTP setup
int i = 0;
int DHCP = 0;
DHCP = Ethernet.begin(mac);
//Try to get dhcp settings 30 times before giving up
while( DHCP == 0 && i < 30){
delay(1000);
DHCP = Ethernet.begin(mac);
i++;
}
if(!DHCP){
Serial.println(«DHCP FAILED»);
for(;;); //Infinite loop because DHCP Failed
}
Serial.println(«DHCP Success»);
//Try to get the date and time
int trys=0;
while(!getTimeAndDate() && trys<10) {
trys++;
}
}
// Do not alter this function, it is used by the system
int getTimeAndDate() {
int flag=0;
Udp.begin(localPort);
sendNTPpacket(timeServer);
delay(1000);
if (Udp.parsePacket()){
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord, lowWord, epoch;
highWord = word(packetBuffer[40], packetBuffer[41]);
lowWord = word(packetBuffer[42], packetBuffer[43]);
epoch = highWord << 16 | lowWord;
epoch = epoch — 2208988800 + timeZoneOffset;
flag=1;
setTime(epoch);
ntpLastUpdate = now();
}
return flag;
}
// Do not alter this function, it is used by the system
unsigned long sendNTPpacket(IPAddress& address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011;
packetBuffer[1] = 0;
packetBuffer[2] = 6;
packetBuffer[3] = 0xEC;
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123);
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
// Clock display of the time and date (Basic)
void clockDisplay(){
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(» «);
Serial.print(day());
Serial.print(» «);
Serial.print(month());
Serial.print(» «);
Serial.print(year());
Serial.println();
}
// Utility function for clock display: prints preceding colon and leading 0
void printDigits(int digits){
Serial.print(«:»);
if(digits < 10)
Serial.print(‘0’);
Serial.print(digits);
}
// This is where all the magic happens…
void loop() {
// Update the time via NTP server as often as the time you set at the top
if(now()-ntpLastUpdate > ntpSyncTime) {
int trys=0;
while(!getTimeAndDate() && trys<10){
trys++;
}
if(trys<10){
Serial.println(«ntp server update success»);
}
else{
Serial.println(«ntp server update failed»);
}
}
// Display the time if it has changed by more than a second.
if( now() != prevDisplay){
prevDisplay = now();
clockDisplay();
}
}
Step 3: Time Server Address
If you know the IP address of a working time server, enter it into your code.
Look for this section of your code:
/* ******** NTP Server Settings ******** */
/* us.pool.ntp.org NTP server
(Set to your time server of choice) */
IPAddress timeServer(216, 23, 247, 62);
Otherwise, run this sketch to get a valid time server ip. If you really want to get techy, merge the following code into the main sketch so that it finds a valid time server on every update. Don’t forget to update your MAC address below.
/*
DHCP-based IP printer
This sketch uses the DHCP extensions to the Ethernet library
to get an IP address via DHCP and print the address obtained.
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
created 12 April 2011
by Tom Igoe
*/
#include <SPI.h>
#include <Ethernet.h>
#include <Dns.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[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
void setup() {
// start the serial library:
Serial.begin(9600);
pinMode(4,OUTPUT);
digitalWrite(4,HIGH);
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println(«Failed to configure Ethernet using DHCP»);
// no point in carrying on, so do nothing forevermore:
for(;;)
;
}
// print your local IP address:
Serial.print(«My IP address: «);
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(«.»);
}
Serial.println();
IPAddress testIP;
DNSClient dns;
dns.begin(Ethernet.dnsServerIP());
dns.getHostByName(«pool.ntp.org»,testIP);
Serial.print(«NTP IP from the pool: «);
Serial.println(testIP);
}
void loop() {
}
Step 4: Time Offsets
You need to plug in your time offset for your time zone. As I am currently on East Coast Day Light Savings Time, I used -14400, which is the number of seconds off GMT. Here is a chart to help you determine your offset:
http://www.epochconverter.com/epoch/timezones.php
L
ook for this section in the code:
/* Set this to the offset (in seconds) to your local time
This example is GMT — 4 */
const long timeZoneOffset = -14400L;
Step 5: Is It Working?
At this point, with the hardware connected (UNO and Ethernet Shield), and plugged into your router, with your MAC address and time server address plugged in (and of course uploaded to the Arduino), you should see something similar to the following:
Step 6: Adding the LCD
If you are using the Serial LCD Display, connect it now. There is an additional library you will need, the I2C LCD library. You can find that at http://arduinotronics.blogspot.com/2014/02/sainsmart-i2c-lcd.html
LCD Arduino UNO
SCL A5
SDA A4
VCC +5v
GND Gnd
The preceding NTP code with the LCD additions are below:
//sample code originated at http://www.openreefs.com/ntpServer
//modified by Steve Spence, http://arduinotronics.blogspot.com
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
//LCD Settings
#define I2C_ADDR 0x3F // <<—— Add your address here. Find it from I2C Scanner
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
/* ******** Ethernet Card Settings ******** */
// Set this to your Ethernet Card Mac Address
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x23, 0x36 };
/* ******** NTP Server Settings ******** */
/* us.pool.ntp.org NTP server
(Set to your time server of choice) */
IPAddress timeServer(216, 23, 247, 62);
/* Set this to the offset (in seconds) to your local time
This example is GMT — 4 */
const long timeZoneOffset = -14400L;
/* Syncs to NTP server every 15 seconds for testing,
set to 1 hour or more to be reasonable */
unsigned int ntpSyncTime = 3600;
/* ALTER THESE VARIABLES AT YOUR OWN RISK */
// local port to listen for UDP packets
unsigned int localPort = 8888;
// NTP time stamp is in the first 48 bytes of the message
const int NTP_PACKET_SIZE= 48;
// Buffer to hold incoming and outgoing packets
byte packetBuffer[NTP_PACKET_SIZE];
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// Keeps track of how long ago we updated the NTP server
unsigned long ntpLastUpdate = 0;
// Check last time clock displayed (Not in Production)
time_t prevDisplay = 0;
void setup() {
lcd.begin (16,2);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
Serial.begin(9600);
// Ethernet shield and NTP setup
int i = 0;
int DHCP = 0;
DHCP = Ethernet.begin(mac);
//Try to get dhcp settings 30 times before giving up
while( DHCP == 0 && i < 30){
delay(1000);
DHCP = Ethernet.begin(mac);
i++;
}
if(!DHCP){
Serial.println(«DHCP FAILED»);
for(;;); //Infinite loop because DHCP Failed
}
Serial.println(«DHCP Success»);
//Try to get the date and time
int trys=0;
while(!getTimeAndDate() && trys<10) {
trys++;
}
}
// Do not alter this function, it is used by the system
int getTimeAndDate() {
int flag=0;
Udp.begin(localPort);
sendNTPpacket(timeServer);
delay(1000);
if (Udp.parsePacket()){
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord, lowWord, epoch;
highWord = word(packetBuffer[40], packetBuffer[41]);
lowWord = word(packetBuffer[42], packetBuffer[43]);
epoch = highWord << 16 | lowWord;
epoch = epoch — 2208988800 + timeZoneOffset;
flag=1;
setTime(epoch);
ntpLastUpdate = now();
}
return flag;
}
// Do not alter this function, it is used by the system
unsigned long sendNTPpacket(IPAddress& address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011;
packetBuffer[1] = 0;
packetBuffer[2] = 6;
packetBuffer[3] = 0xEC;
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123);
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
// Clock display of the time and date (Basic)
void clockDisplay(){
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(» «);
Serial.print(day());
Serial.print(» «);
Serial.print(month());
Serial.print(» «);
Serial.print(year());
Serial.println();
lcd.setCursor (0,0);
if (hour() < 10){
lcd.print(«0»); }
if (hour() > 12){
lcd.print(«0»);
lcd.print(hour()-12); } else {
lcd.print(hour()); }
lcd.print(«:»);
if (minute() < 10){
lcd.print(«0»); }
lcd.print(minute());
lcd.print(«:»);
if (second() < 10){
lcd.print(«0»); }
lcd.print(second());
if (hour() > 12){
lcd.print(» PM»); }
else {
lcd.print(» AM»); }
lcd.setCursor (0,1);
if (month() < 10){
lcd.print(«0»); }
lcd.print(month());
lcd.print(«/»);
if (day() < 10){
lcd.print(«0»); }
lcd.print(day());
lcd.print(«/»);
lcd.print(year());
}
// Utility function for clock display: prints preceding colon and leading 0
void printDigits(int digits){
Serial.print(«:»);
if(digits < 10)
Serial.print(‘0’);
Serial.print(digits);
}
// This is where all the magic happens…
void loop() {
// Update the time via NTP server as often as the time you set at the top
if(now()-ntpLastUpdate > ntpSyncTime) {
int trys=0;
while(!getTimeAndDate() && trys<10){
trys++;
}
if(trys<10){
Serial.println(«ntp server update success»);
}
else{
Serial.println(«ntp server update failed»);
}
}
// Display the time if it has changed by more than a second.
if( now() != prevDisplay){
prevDisplay = now();
clockDisplay();
}
}
Step 7: 12h Vs. 24h Time
Originally I built this sketch for 24h time, so 1pm actually displayed as 13. Many folks prefer a 12h clock, with AM/PM, so I modified the final sketch for that instead. Now I’m having second thoughts, so I’m adding a switch to choose which format you prefer to see.
First, we need to read a switch to determine the format, then we need to switch some code based on the results of that read.
We will use pin 5 for the switch, as the Ethernet Shield itself uses pins 4, 10, 11, 12, & 13.
Connect a switch between pin 5 and ground. You don’t need a pullup resistor, as we will use the one built into the arduino using the INPUT_PULLUP command.
Here is the affected code as it currently stands:
lcd.setCursor (0,0);
if (hour() < 10){
lcd.print(«0»); }
if (hour() > 12){
lcd.print(«0»);
lcd.print(hour()-12); } else {
lcd.print(hour()); }
lcd.print(«:»);
if (minute() < 10){
lcd.print(«0»); }
lcd.print(minute());
lcd.print(«:»);
if (second() < 10){
lcd.print(«0»); }
lcd.print(second());
if (hour() > 12){
lcd.print(» PM»); }
else {
lcd.print(» AM»); }
Here is how the new code with the option of switching back and forth would look like:
//12h_24h (at top of sketch before void setup
int timeFormatPin = 5; // switch connected to digital pin 5
int timeFormatVal= 0; // variable to store the read value
//put in void setup replaceing the original code listed above
lcd.setCursor (0,0);
if (hour() < 10){
lcd.print(«0»); }
//12h/24h
pinMode(timeFormatPin, INPUT_PULLUP); // sets the digital pin 5 as input and activates pull up resistor
timeFormatVal= digitalRead(timeFormatPin); // read the input pin
if (timeFormatVal == 1) {
if (hour() < 10){
lcd.print(«0»);}
lcd.print(hour());
} else {
if (hour() > 12){
if (hour()-12 < 10){
lcd.print(«0»);}
lcd.print(hour()-12); } else {
lcd.print(hour()); }
}
lcd.print(«:»);
if (minute() < 10){
lcd.print(«0»); }
lcd.print(minute());
lcd.print(«:»);
if (second() < 10){
lcd.print(«0»); }
lcd.print(second());
if (timeFormatVal == 1){
lcd.print(» 24″);
} else {
if (hour() > 12){
lcd.print(» PM»); }
else {
lcd.print(» AM»); }
}
Step 8: Standard Vs. Daylight Savings Time
Originally I built this sketch for my current time, and we are on Daylight Savings time, which is GMT -4. When we switch back to Standard time (GMT -5), the clock code would have to be edited and re uploaded, so lets add a switch to eliminate that headache.
First, we need to read a switch to determine the format, then we need to switch some code based on the results of that read.
We will use pin 6 for the switch, as the Ethernet Shield itself uses pins 4, 10, 11, 12, & 13.
Connect a switch between pin 6 and ground. You don’t need a pullup resistor, as we will use the one built into the arduino using the INPUT_PULLUP command.
To make this work, you need to RESET or power cycle your Arduino between changes, as the switch code is not in void loop.
Here is the affected code as it currently stands:
/* Set this to the offset (in seconds) to your local time
This example is GMT — 4 */
const long timeZoneOffset = -14400L;
change to /* Set this to the offset (in seconds) to your local time
This example is GMT — 4 */
long timeZoneOffset;
add this before void setup:
//DST Switch
int dstPin = 6; // switch connected to digital pin 5
int dstVal= 0; // variable to store the read value
and change out the whole int getTimeAndDate() function with the code below:
// Do not alter this function, it is used by the system
int getTimeAndDate() {
// Time zone switch
pinMode(dstPin, INPUT_PULLUP); // sets the digital pin 6 as input and activates pull up resistor
dstVal= digitalRead(dstPin); // read the input pin
if (dstVal == 1) {
timeZoneOffset = -14400L;
} else {
timeZoneOffset = -18000L;
}
int flag=0;
Udp.begin(localPort);
sendNTPpacket(timeServer);
delay(1000);
if (Udp.parsePacket()){
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord, lowWord, epoch;
highWord = word(packetBuffer[40], packetBuffer[41]);
lowWord = word(packetBuffer[42], packetBuffer[43]);
epoch = highWord << 16 | lowWord;
epoch = epoch — 2208988800 + timeZoneOffset;
flag=1;
setTime(epoch);
ntpLastUpdate = now();
}
return flag;
}
Step 9: Future Upgrades
Upgrades I’m contemplating are:
- An automatic function for finding a available time server
- Auto switching of Daylight Savings Time
- Alalrm Clock functions with a audible alarm, gradually brightening light, and / or relays.
- RTC for power failure with no network startup
What Would you add?
Step 10: WiFi Rechargeable Version
This version of the Internet Clock uses WiFi instead of Ethernet, and an onboard rechargeable Lithium Ion Battery. There is a power switch that turns the clock off, and it resync’s time with the internet on powerup. It notifies you when the battery is low with a led, and just plug in a USB cable to recharge.
Adafruit RGB I2C LCD Display
Adafruit Powerboost Lipo Shield
Arduino WiFi Shield (retired, there is a newer version out)
Arduino UNO
Code and Libraries
Be the First to Share