autor: WitekR » 20 maja 2023, 0:52
Mały projekt zegarka, który pobiera dane z serwera NTP po czym wyświetla czas na wyświetlaczu OLED. Używamy WeMos D1 mini do łączenia się z siecią Wi-Fi, uzyskiwania czasu NTP i wyświetlania go na module OLED.
Aby zbudować ten projekt, potrzebujesz WeMos D1 mini lub pochodne która posiadają mikroukład ESP8266 oraz moduł wyświetlacza OLED.
Co nam będzie potrzebne:
– WeMos D1 mini / NodeMcu do nabycia tu
– Moduł wyświetlacza OLED 0.96 cala 128X64 do nabycia tu
– Arduino IDE
– przewody do połączenia całości
Opis połączeń:
Zegarek z NTP
PIN ESP PIN LCD
GND GND
3,3V Vcc
GPIO5 SCL
GPIO4 SDA
Kod programu:
Kod: Zaznacz cały
/********************************************************************************************************************
* Board Settings:
* Board: "WeMos D1 R1 or Mini"
* Upload Speed: "921600"
* CPU Frequency: "80MHz"
* Flash Size: "4MB (FS:@MB OTA:~1019KB)"
* Debug Port: "Disabled"
* Debug Level: "None"
* VTables: "Flash"
* IwIP Variant: "v2 Lower Memory"
* Exception: "Legacy (new can return nullptr)"
* Erase Flash: "Only Sketch"
* SSL Support: "All SSL ciphers (most compatible)"
* COM Port: Depends *On Your System*
*********************************************************************************************************************/
/*
This is an example file for using the time function in ESP8266 or ESP32 tu get NTP time
It offers two functions:
- getNTPtime(struct tm * info, uint32_t ms) where info is a structure which contains time
information and ms is the time the service waits till it gets a response from NTP.
Each time you cann this function it calls NTP over the net.
If you do not want to call an NTP service every second, you can use
- getTimeReducedTraffic(int ms) where ms is the the time between two physical NTP server calls. Betwwn these calls,
the time structure is updated with the (inaccurate) timer. If you call NTP every few minutes you should be ok
The time structure is called tm and has teh following values:
Definition of struct tm:
Member Type Meaning Range
tm_sec int seconds after the minute 0-61*
tm_min int minutes after the hour 0-59
tm_hour int hours since midnight 0-23
tm_mday int day of the month 1-31
tm_mon int months since January 0-11
tm_year int years since 1900
tm_wday int days since Sunday 0-6
tm_yday int days since January 1 0-365
tm_isdst int Daylight Saving Time flag
because the values are somhow akwardly defined, I introduce a function makeHumanreadable() where all values are adjusted according normal numbering.
e.g. January is month 1 and not 0 And Sunday or monday is weekday 1 not 0 (according definition of MONDAYFIRST)
Showtime is an example on how you can use the time in your sketch
The functions are inspired by work of G6EJD ( https://www.youtube.com/channel/UCgtlqH_lkMdIa4jZLItcsTg )
*/
/*
Pobrano z www.tranzystor.pl
Tłumaczenie PL - Wydawnictwo Tranzystor.pl
*/
#ifdef ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
#include <time.h>
#include <U8x8lib.h>
#include "credentials.h"
const char* ssid = mySSID; //zmień w pliku credentials.h
const char* password = myPASSWORD; //zmień w pliku credentials.h
const char* NTP_SERVER = "pl.pool.ntp.org";
const char* TZ_INFO = "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00"; // sprawdz swoją strefę na https://remotemonitoringsystems.ca/time-zone-abbreviations.php
tm timeinfo;
time_t now;
long unsigned lastNTPtime;
unsigned long lastEntryTime;
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
void setup()
{
u8x8.begin();
Serial.begin(115200);
Serial.println("\n\nNTP test czasi\n");
WiFi.begin(ssid, password);
Serial.print("Laczenie z siecia");
int counter = 0;
while (WiFi.status() != WL_CONNECTED)
{
delay(200);
if (++counter > 100)
ESP.restart();
Serial.print( "." );
}
Serial.println("\nWiFi connected\n\n");
configTime(0, 0, NTP_SERVER);
// See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv for Timezone codes for your region
setenv("TZ", TZ_INFO, 1);
if (getNTPtime(10))
{
// wait up to 10sec to sync
}
else
{
Serial.println("Brak czasu");
ESP.restart();
}
showTime(&timeinfo);
lastNTPtime = time(&now);
lastEntryTime = millis();
}
void loop()
{
getNTPtime(10);
showTime(&timeinfo);
delay(1000);
}
bool getNTPtime(int sec)
{
{
uint32_t start = millis();
do
{
time(&now);
localtime_r(&now, &timeinfo);
delay(10);
} while (((millis() - start) <= (1000 * sec)) && (timeinfo.tm_year < (2016 - 1900)));
if (timeinfo.tm_year <= (2016 - 1900))
return false; // the NTP call was not successful
Serial.print("Time Now: ");
Serial.println(now);
}
return true;
}
void showTime(tm *localTime)
{
//print to serial terminal
Serial.print(localTime->tm_mday);
Serial.print('/');
Serial.print(localTime->tm_mon + 1);
Serial.print('/');
Serial.print(localTime->tm_year - 100);
Serial.print('-');
Serial.print(localTime->tm_hour);
Serial.print(':');
Serial.print(localTime->tm_min);
Serial.print(':');
Serial.print(localTime->tm_sec);
Serial.print(" Day of Week ");
Serial.println(localTime->tm_wday);
Serial.println();
//display on OLED
char time_output[30];
u8x8.setFont(u8x8_font_courB18_2x3_f);
u8x8.setCursor(0,0);
sprintf(time_output, "%02d:%02d:%02d", localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
u8x8.print(time_output);
u8x8.setFont(u8x8_font_8x13B_1x2_f);
u8x8.setCursor(4,4);
sprintf(time_output, "%02d/%02d/%02d", localTime->tm_mday, localTime->tm_mon + 1, localTime->tm_year - 100);
u8x8.print(time_output);
u8x8.setCursor(4,6);
u8x8.print(getDOW(localTime->tm_wday));
}
char * getDOW(uint8_t tm_wday)
{
switch(tm_wday)
{
case 1:
return "Poniedzialek";
break;
case 2:
return "Wtorek";
break;
case 3:
return "Sroda";
break;
case 4:
return "Czwartek";
break;
case 5:
return "Piatek";
break;
case 6:
return "Sobota";
break;
case 7:
return "Niedziela";
break;
default:
return "Error";
break;
}
}
Jest parę zmian które musisz dokonać przed wgraniem:
w pliku credentials.h ustawić dane swojej sieci
char mySSID[]="nazwa sieci";
char myPASSWORD[]="hasło do sieci";
w pliku zegarek-ntp.ino ustawić swoją strefę czasową, poniższa dla Polski
const char* TZ_INFO = „CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00”;
Jeszcze przydało by się dodać jedną zmienną, aby ESP nie emitowało WiFi o nazwie „FaryLink-xxxx”. W tym celu dodajemy
WiFi.mode(WIFI_STA);
zaraz przed
WiFi.begin(ssid, password);
- Załączniki
-
Mały projekt zegarka, który pobiera dane z serwera NTP po czym wyświetla czas na wyświetlaczu OLED. Używamy WeMos D1 mini do łączenia się z siecią Wi-Fi, uzyskiwania czasu NTP i wyświetlania go na module OLED.
Aby zbudować ten projekt, potrzebujesz WeMos D1 mini lub pochodne która posiadają mikroukład ESP8266 oraz moduł wyświetlacza OLED.
Co nam będzie potrzebne:
– WeMos D1 mini / NodeMcu do nabycia tu
– Moduł wyświetlacza OLED 0.96 cala 128X64 do nabycia tu
– Arduino IDE
– przewody do połączenia całości
Opis połączeń:
Zegarek z NTP
PIN ESP PIN LCD
GND GND
3,3V Vcc
GPIO5 SCL
GPIO4 SDA
Kod programu:
[code]
/********************************************************************************************************************
* Board Settings:
* Board: "WeMos D1 R1 or Mini"
* Upload Speed: "921600"
* CPU Frequency: "80MHz"
* Flash Size: "4MB (FS:@MB OTA:~1019KB)"
* Debug Port: "Disabled"
* Debug Level: "None"
* VTables: "Flash"
* IwIP Variant: "v2 Lower Memory"
* Exception: "Legacy (new can return nullptr)"
* Erase Flash: "Only Sketch"
* SSL Support: "All SSL ciphers (most compatible)"
* COM Port: Depends *On Your System*
*********************************************************************************************************************/
/*
This is an example file for using the time function in ESP8266 or ESP32 tu get NTP time
It offers two functions:
- getNTPtime(struct tm * info, uint32_t ms) where info is a structure which contains time
information and ms is the time the service waits till it gets a response from NTP.
Each time you cann this function it calls NTP over the net.
If you do not want to call an NTP service every second, you can use
- getTimeReducedTraffic(int ms) where ms is the the time between two physical NTP server calls. Betwwn these calls,
the time structure is updated with the (inaccurate) timer. If you call NTP every few minutes you should be ok
The time structure is called tm and has teh following values:
Definition of struct tm:
Member Type Meaning Range
tm_sec int seconds after the minute 0-61*
tm_min int minutes after the hour 0-59
tm_hour int hours since midnight 0-23
tm_mday int day of the month 1-31
tm_mon int months since January 0-11
tm_year int years since 1900
tm_wday int days since Sunday 0-6
tm_yday int days since January 1 0-365
tm_isdst int Daylight Saving Time flag
because the values are somhow akwardly defined, I introduce a function makeHumanreadable() where all values are adjusted according normal numbering.
e.g. January is month 1 and not 0 And Sunday or monday is weekday 1 not 0 (according definition of MONDAYFIRST)
Showtime is an example on how you can use the time in your sketch
The functions are inspired by work of G6EJD ( https://www.youtube.com/channel/UCgtlqH_lkMdIa4jZLItcsTg )
*/
/*
Pobrano z www.tranzystor.pl
Tłumaczenie PL - Wydawnictwo Tranzystor.pl
*/
#ifdef ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
#include <time.h>
#include <U8x8lib.h>
#include "credentials.h"
const char* ssid = mySSID; //zmień w pliku credentials.h
const char* password = myPASSWORD; //zmień w pliku credentials.h
const char* NTP_SERVER = "pl.pool.ntp.org";
const char* TZ_INFO = "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00"; // sprawdz swoją strefę na https://remotemonitoringsystems.ca/time-zone-abbreviations.php
tm timeinfo;
time_t now;
long unsigned lastNTPtime;
unsigned long lastEntryTime;
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
void setup()
{
u8x8.begin();
Serial.begin(115200);
Serial.println("\n\nNTP test czasi\n");
WiFi.begin(ssid, password);
Serial.print("Laczenie z siecia");
int counter = 0;
while (WiFi.status() != WL_CONNECTED)
{
delay(200);
if (++counter > 100)
ESP.restart();
Serial.print( "." );
}
Serial.println("\nWiFi connected\n\n");
configTime(0, 0, NTP_SERVER);
// See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv for Timezone codes for your region
setenv("TZ", TZ_INFO, 1);
if (getNTPtime(10))
{
// wait up to 10sec to sync
}
else
{
Serial.println("Brak czasu");
ESP.restart();
}
showTime(&timeinfo);
lastNTPtime = time(&now);
lastEntryTime = millis();
}
void loop()
{
getNTPtime(10);
showTime(&timeinfo);
delay(1000);
}
bool getNTPtime(int sec)
{
{
uint32_t start = millis();
do
{
time(&now);
localtime_r(&now, &timeinfo);
delay(10);
} while (((millis() - start) <= (1000 * sec)) && (timeinfo.tm_year < (2016 - 1900)));
if (timeinfo.tm_year <= (2016 - 1900))
return false; // the NTP call was not successful
Serial.print("Time Now: ");
Serial.println(now);
}
return true;
}
void showTime(tm *localTime)
{
//print to serial terminal
Serial.print(localTime->tm_mday);
Serial.print('/');
Serial.print(localTime->tm_mon + 1);
Serial.print('/');
Serial.print(localTime->tm_year - 100);
Serial.print('-');
Serial.print(localTime->tm_hour);
Serial.print(':');
Serial.print(localTime->tm_min);
Serial.print(':');
Serial.print(localTime->tm_sec);
Serial.print(" Day of Week ");
Serial.println(localTime->tm_wday);
Serial.println();
//display on OLED
char time_output[30];
u8x8.setFont(u8x8_font_courB18_2x3_f);
u8x8.setCursor(0,0);
sprintf(time_output, "%02d:%02d:%02d", localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
u8x8.print(time_output);
u8x8.setFont(u8x8_font_8x13B_1x2_f);
u8x8.setCursor(4,4);
sprintf(time_output, "%02d/%02d/%02d", localTime->tm_mday, localTime->tm_mon + 1, localTime->tm_year - 100);
u8x8.print(time_output);
u8x8.setCursor(4,6);
u8x8.print(getDOW(localTime->tm_wday));
}
char * getDOW(uint8_t tm_wday)
{
switch(tm_wday)
{
case 1:
return "Poniedzialek";
break;
case 2:
return "Wtorek";
break;
case 3:
return "Sroda";
break;
case 4:
return "Czwartek";
break;
case 5:
return "Piatek";
break;
case 6:
return "Sobota";
break;
case 7:
return "Niedziela";
break;
default:
return "Error";
break;
}
}
[/code]
Jest parę zmian które musisz dokonać przed wgraniem:
w pliku credentials.h ustawić dane swojej sieci
char mySSID[]="nazwa sieci";
char myPASSWORD[]="hasło do sieci";
w pliku zegarek-ntp.ino ustawić swoją strefę czasową, poniższa dla Polski
const char* TZ_INFO = „CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00”;
Jeszcze przydało by się dodać jedną zmienną, aby ESP nie emitowało WiFi o nazwie „FaryLink-xxxx”. W tym celu dodajemy
WiFi.mode(WIFI_STA);
zaraz przed
WiFi.begin(ssid, password);