Основным контроллером в этой сборке является ESP8266, входящий в состав мини-модуля Wemos D1. Благодаря встроенному Wi-Fi позволяет выполнять многие задачи. Один из них – создание часов с использованием сетевого протокола NTP (Network Time Protocol). NTP можно использовать для синхронизации всех сетевых устройств с временем UTC за несколько миллисекунд. При использовании NTP для создания часов не требуется дополнительный модуль DS1307 для получения данных времени.
Эти часы состоят из 4-х модулей. 2 модуля показывают час, еще 2 модуля – минуты. На секунду указывают 2 светодиода, которые находятся между цифрами часа и минуты. Каждый модуль состоит из 7 сегментов.
Инструменты и материалы:-Wemos D1 Mini;-Разъем штыревой;-Микросхема 74HC595 – 2 шт;-7 сегментный светодиодный цифровой дисплей – 4 шт;-Транзистор TR C1815 – 4 шт;
-Резистор 1кОм -4 шт;-Резистор 100 Ом – 4 шт;-Резистор 330 Ом – 2 шт;-Красный светодиод 5 мм – 2 шт;-Винтовой коннектор;
-3D-принтер;
-Печатная плата;
-Лазерный принтер;
-Емкость;
-Бумага HVS;
-Пластик;
-Гравер;
-Жидкость для травления плат;
-Паяльные принадлежности;
Шаг первый: разработка схемы и платы
Сначала мастер разработал схему и эскиз печатной платы. Файлы можно скачать ниже.
Jam digital 74HC595 + WEmos.brdJam digital 74HC595 + WEmos.brd
Шаг второй: изготовление платы
Дальше распечатывает схему, затем переносит на печатную плату.Помещает плату в травильный раствор. После травления промывает плату, протирает. Сверлит отверстия.
Шаг третий: сборка
Собирает согласно ранее приведенной схемы.Шаг четвертый: программирование
При разработке кода мастер использует программу Visual Studio Code + Platformio. Перед установкой кода нужно установить библиотеку: Time (TimeLib.h)
Загружает код. Показать / Скрыть текст#include <Arduino.h>
/************************************************************** /
Made by : Mr. Sottong
****************************************************************/
#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include "Ticker.h"
Ticker Timer500ms;
//WiFi variables……………………………………………………
const char ssid[] = "xxx"; //your network SSID (name)
const char pass[] = "yyy"; // your network password
// NTP Servers:
static const char ntpServerName[] = "us.pool.ntp.org";
//static const char ntpServerName[] = "time-b.timefreq.bldrdoc.gov";//static const char ntpServerName[] = "time-a.timefreq.bldrdoc.gov";
// static const char ntpServerName[] = "server 0.id.pool.ntp.org";
float timeZone = 7; //+7 GMT
WiFiUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
time_t getNtpTime();
void sendNTPpacket(IPAddress &address);
//OTHER variables……………………………………………………….
//Pin connected to ST_CP / Pin 12 of 74HC595
int latchPin = 0; //D3
//Pin connected to SH_CP / Pin 11 of 74HC595
int clockPin = 5; //D1
////Pin connected to DS / Pin 14 of 74HC595
int dataPin = 4; //D2
//Pin connected to LED
int LEDpin = 2; //D4
//Seven Segment
unsigned long d1[10] = {0x8140,0xcf40,0x9240,0x8640,0xcc40,0xa440,0xa040,0x8f40,0x8040,0x8440};
unsigned long d2[10] = {0x8120,0xcf20,0x9220,0x8620,0xcc20,0xa420,0xa020,0x8f20,0x8020,0x8420};
unsigned long d3[10] = {0x8110,0xcf10,0x9210,0x8610,0xcc10,0xa410,0xa010,0x8f10,0x8010,0x8410};
unsigned long d4[10] = {0x8108,0xcf08,0x9208,0x8608,0xcc08,0xa408,0xa008,0x8f08,0x8008,0x8408};
bool Led = 0;
/*——– NTP code ———-*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime() {
IPAddress ntpServerIP; // NTP server's ip address
while (Udp.parsePacket() > 0) ; // discard any previously received packets
// get a random server from the pool
WiFi.hostByName(ntpServerName, ntpServerIP);
sendNTPpacket(ntpServerIP);
uint32_t beginWait = millis();
while (millis() – beginWait < 1600) {
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();
}
void printDigits(int value) {
int th = value / 1000;
int hun = value / 100;
int tens = value / 10;
// if (th == 0) {
// thByte = 0;
// }
// else {
// thByte = th % 10;
// }
digitalWrite(latchPin, LOW); //THOUSANDS – Ribuan – jam
shiftOut(dataPin, clockPin, LSBFIRST, d4[th]);
shiftOut(dataPin, clockPin, LSBFIRST, d4[th]>>8);
digitalWrite(latchPin, HIGH);
delay(1);
digitalWrite(latchPin, LOW); //HUNDREDS – Ratusan – jam
shiftOut(dataPin, clockPin, LSBFIRST, d3[hun % 10]);
shiftOut(dataPin, clockPin, LSBFIRST, d3[hun % 10]>>8);
digitalWrite(latchPin, HIGH);
delay(1);
digitalWrite(latchPin, LOW); //TENS – Puluhan – menit
shiftOut(dataPin, clockPin, LSBFIRST, d2[tens % 10]);
shiftOut(dataPin, clockPin, LSBFIRST, d2[tens % 10]>>8);
digitalWrite(latchPin, HIGH);
delay(1);
digitalWrite(latchPin, LOW); //ONES – satuan – menit
shiftOut(dataPin, clockPin, LSBFIRST, d1[(value % 10)]);
shiftOut(dataPin, clockPin, LSBFIRST, d1[(value % 10)]>>8);
digitalWrite(latchPin, HIGH);
delay(1);
}
void wifinc(){
//animation when wifi is not connected
int on = 0b0000000001111000;
int off = 0b0000000000000000;
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, on);
shiftOut(dataPin, clockPin, LSBFIRST, on>>8);
digitalWrite(latchPin, HIGH);
delay(100);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, off);
shiftOut(dataPin, clockPin, LSBFIRST, off>>8);
digitalWrite(latchPin, HIGH);
delay(100);
}
void Setiap500ms(){
Led = !Led;
}
void setup() {
//Serial begin
Serial.begin(115200);
//set pins to output so you can control the shift register
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(LEDpin, OUTPUT);
Udp.begin(localPort);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay ( 500 );
Serial.print ( "." );
wifinc();
}
setSyncProvider(getNtpTime);
setSyncInterval(360);
if (hour() == 0 && second() < 3) {
setSyncProvider(getNtpTime);
}
Timer500ms.attach_ms (500,Setiap500ms);
}
void loop() {
printDigits(int(hour() * 100 + minute()));
digitalWrite(LEDpin,Led); //Led Detik
if(Led == 1){
Serial.println(int(hour() * 100 + minute()));
}
}74HC595 Final Skema.rar74HC595_Final_ino.inoШаг пятый: 3D-печать
Для установки часов в горизонтальном положении мастер напечатал подставку. Файлы для печати можно скачать ниже.
base.stl
Все готово.Весь процесс по изготовлению таких часов можно посмотреть на видео.