7.7 Budilica
Ovaj projekt je prava budilica. Pločica se pridružuje tvojoj Wi-Fi mreži, pita vremenski server na internetu koliko je sati, i prikazuje to na LCD-u. Dvije tipke postavljaju alarm, a kada sat dođe do njega, buzzer se oglasi.
To je najveći sklop u kitu, i gotovo ništa u njemu nije novo. LCD je spojen točno kao u 4.1 Ispis poruke, tipke se čitaju točno kao u 2.2 Debounce tipke, buzzer se pobuđuje točno kao u 2.4 Piskanje buzzera, a mrežna veza je ona iz 6.1 Povezivanje i dohvat podataka. Novo je to što sva četiri rade u isto vrijeme.
U ovoj dokumentaciji naučit ćeš:
- Kako pločica bez vlastitog sata nauči koliko je sati, pomoću NTP-a
- Zašto vrijeme na tvom ekranu ovisi o pomaku vremenske zone koji moraš sam postaviti
- Kako na istoj pločici pokrenuti Qwiic ekran i krug na breadboardu
- Kako dvije varijable sprječavaju alarm da se oglašava iznova cijelu minutu
Potreban hardver:
- 1x Soldered NULA MINI pločica
- 1x Breadboard
- 1x Soldered Qwiic 16x2 LCD ekran
- 2x Tipke
- 1x Pasivni buzzer
- 10x Jumper žice
- 1x Qwiic kabel
- 1x USB-C kabel
INPUT_PULLUP, a pin buzzera se uvijek kreće samo između 0 V i 3.3 V pa ga nema od čega štititi. Ako si vidio krug budilice nacrtan s dva otpornika od 10 kΩ, to je drugačiji način spajanja tipki i nije ono što ova skica očekuje.tone() ispravno radi samo na pasivnom buzzeru, koji svira onu frekvenciju koja mu se pošalje. Aktivni buzzer sadrži vlastiti oscilator i piska na jednoj fiksnoj visini bez obzira što kod traži.Spajanje komponenti
Ovaj sklop koristi tri pina plus masu, i sva četiri su na f–j strani pločice:
| Pin | Red | Strana | Što radi |
|---|---|---|---|
IO2 | 25 | f–j | Tipka za sate |
IO3 | 26 | f–j | Tipka za minute |
IO4 | 27 | f–j | Buzzer |
GND | 30 | f–j | Masa za sve |
LCD-u ne trebaju pinovi uopće. Spaja se preko Qwiic utičnice pločice, koja je interno spojena na IO6 i IO7.
IO4, buzzer. Na a–e strani red 27 je IO19, koji ovaj projekt ne koristi. Sjede na suprotnim krajevima istog broja reda i nisu spojeni međusobno. Čitaj ime ispisano duž ruba pločice, nikada broj reda sam.Tijelo pločice prekriva srednje stupce, pa su uz nju slobodni samo stupac a na a–e strani i stupac j na f–j strani. Svaka žica koja dotiče pločicu ide zato u a… ili j… rupicu.
Prati jedanaest koraka ispod. Svaka fotografija snimljena je s istog položaja, pa svaku možeš usporediti s onom prije nje i vidjeti točno što se promijenilo.
1. Umetni NULA MINI pločicu na breadboard
Utisni pločicu u jedan kraj breadboarda tako da njezina dva reda pinova sjednu s obje strane središnjeg kanala, s čipom okrenutim prema dolje. Pritisni je ravnomjerno dok svi pinovi ne sjednu.

Na fotografijama koje slijede pločica zauzima redove 25 do 30.
2. Sagradi jednu dijeljenu masu
Masa je najzaposleniji spoj u ovom projektu: trebaju je i obje tipke i buzzer. Zato je prvi posao pretvoriti dvije plave − vodilice u jednu liniju mase do koje obje strane pločice mogu doći.
Za to treba četiri kratke jumper žice:
| Iz | U | Što radi |
|---|---|---|
j30 (GND) | f–j plava − vodilica | Izvodi masu s pločice |
j1 | f–j plava − vodilica | Vraća masu na red 1 |
e1 | f1 | Prenosi je preko središnjeg kanala |
a1 | a–e plava − vodilica | Dovodi je u drugu vodilicu |

3. Postavi dvije tipke
Utisni dvije tipke u sredinu breadboarda tako da svaka premosti središnji kanal, nekoliko redova dalje od pločice. Svaka tipka obuhvaća dva reda.
Na fotografijama sjede u redovima 17 i 19 za tipku sati, najbliža pločici, i redovima 13 i 15 za tipku minuta.

4. Spoji obje tipke na masu
Dvije kratke jumper žice, jedna po tipki, s a–e strane tipke do plave − vodilice na tom rubu: a19 za tipku sati i a15 za tipku minuta.

GND izveden s pločice na f–j strani. Bez tih žica preko reda 1 ta vodilica ne bi bila spojena ni na što, i obje tipke bile bi mrtve.5. Spoji svaku tipku na svoj pin
Sada dvije signalne žice, obje na f–j strani. Svaka ide od pina pločice do nižeg reda para jedne tipke:
| Iz | U | Tipka | Boja na fotografiji |
|---|---|---|---|
j25 (IO2) | j17 | Sati | Narančasta |
j26 (IO3) | j13 | Minute | Bijela |

Primijeti da dvije žice idu paralelno i nikada se ne križaju. IO2, pin najbliži tipkama, ide na najbližu tipku. Njihova zamjena zamjenjuje što tipke rade: tipka sati postavljala bi minute a tipka minuta sate.
6. Postavi buzzer
Buzzer ide na f–j stranu na daleki kraj breadboarda, s nožicama u dva susjedna reda, na fotografiji redovi 7 i 8.
Pogledaj vrh njegovog kućišta prije nego ga utisneš. Uz utisnuta slova nalazi se mali + unutar kružića, i nožica na toj strani kućišta je pozitivna. Ta nožica ide u red 8, red bliži tipkama.

7. Spoji buzzer na IO4
Jedna jumper žica iz j27, a to je IO4, do j8, reda u kojem je + nožica buzzera. To je žica koja nosi pravokutni signal.

8. Spoji buzzer na masu
Još jedna jumper žica, iz j7 (druga nožica buzzera) dolje do plave − vodilice na istom rubu.

Krug je sada zatvoren: IO4 → buzzer → GND. Kućište od 12 mm skriva nožice kada je buzzer utisnut, pa ako ikada budeš morao provjeriti ovo spajanje, čitaj umjesto toga dvije jumper žice.
Breadboard je gotov. Sve odsad se jednostavno utiskuje.
9. Spoji Qwiic kabel na pločicu
LCD uopće ne dotiče breadboard. Spaja se preko jednog jedinog Qwiic kabela, koji u jednom utikaču nosi napajanje i oba I2C signala.
Nađi bijelu Qwiic utičnicu na NULA MINI i utisni jedan kraj kabela u nju. Ulazi samo na jedan način.


10. Spoji drugi kraj na LCD
Okreni ekran. Ljubičasta pločica na njegovoj pozadini je I2C LCD ADAPTER, i nosi dvije Qwiic utičnice, po jednu na svakom kraju. Bilo koja radi: to je isto spojište s dva utikača.

I2C ADDR 0X20 ispisan na adapteru je adresa ekrana na sabirnici. Skica je nikada ne spominje jer je biblioteka već zna: LCD lcd(16, 2) ispuni 0x20 za tebe. Kontakti A0, A1 i A2 uz nju mogu tu adresu pomaknuti, a to bi koristio ako bi ikada htio dva ekrana na jednoj pločici.11. Spoji pločicu na računalo
Utisni USB-C kabel u pločicu. PWR LED-ica se upali, a s njom i pozadinsko svjetlo ekrana.

Kako pločica zna koliko je sati
NULA MINI nema vlastiti sat. Iskopčaj je i zaboravi koliko je sati. Nema baterije koja drži sat da otkucava kako je ima u ručnom satu ili u računalu.
Zato pita. Kada je na mreži, pošalje kratak zahtjev vremenskom serveru i dobije natrag trenutno vrijeme. Protokol za to je NTP, Network Time Protocol, i tako gotovo svaki povezani uređaj na zemlji drži svoj sat ispravnim.
Skica koristi pool.ntp.org, besplatan svjetski servis koji tvoj zahtjev predaje serveru koji ti je najbliži. configTime() to pokreće, i od tog trenutka pločica vodi vlastito brojanje sekundi, provjeravajući ponovno svake minute tako da nikada ne odluta daleko.
Vremenske zone su tvoj posao
NTP server uvijek odgovara u UTC, svjetskom referentnom vremenu. Nema pojma gdje si, pa ne može znati koliko je sati za tebe. Pretvaranje UTC-a u lokalno vrijeme ostavljeno je dvama brojevima na vrhu skice:
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 0;
Oba su u sekundama, pa je jedan sat 3600. Prvi je koliko je tvoja vremenska zona daleko od UTC-a. Drugi je dodatni sat za ljetno računanje vremena, ako ga tvoja zemlja koristi.
gmtOffset_sec = 3600 cijele godine a daylightOffset_sec = 3600 od kraja ožujka do kraja listopada. Skica dolazi s oba postavljena na 0, i zato ekran na fotografijama niže pokazuje 10:29 kada je sat na zidu pokazivao 12:29. Ako ti je sat pogrešan za cijeli broj sati, to je razlog. Nije ništa pokvareno.Zašto alarmu treba pamćenje
Pločica prolazi kroz loop() oko deset puta u sekundi, a alarm se oglašava kada se sat poklopi s vremenom alarma. Ali minuta traje šezdeset sekundi, pa bi se obična usporedba poklopila oko šest stotina puta u nizu i buzzer nikada ne bi prestao.
To sprječavaju dvije varijable. alarmTriggered postavlja se onog trenutka kada se alarm oglasi i blokira svako daljnje oglašavanje dok ne pritisneš tipku. lastAlarmMinute pamti u kojoj se minuti oglasio, tako da pritisak tipke za brisanje ekrana ne može odmah ponovno pokrenuti alarm dok ta ista minuta još traje.
Kod
Ovdje je cijela skica. Postavi pločicu na Soldered NULA Mini ESP32C6 prije prijenosa, i upiši svoje ime mreže i lozinku u WIFI_SSID i WIFI_PASS.
/**
**************************************************
*
* @file 7.7_Alarm_Clock.ino
* @brief Projekt koji gradi budilicu povezanu na Wi-Fi. Pločica se pridružuje tvojoj mreži, pita NTP server na
* internetu koliko je sati, i prikazuje trenutno vrijeme na LCD ekranu. Dvije tipke postavljaju sat i minutu
* alarma, a kada se dosegne vrijeme alarma, buzzer se oglasi nizom pisaka.
* Spaja LCD iz sekcije 4, debounce tipke iz sekcije 2.2, buzzer iz
* sekcije 2.4 i Wi-Fi vezu iz sekcije 6.
* Za detalje, shemu spajanja i više, pogledaj dokumentaciju primjera na: <link placeholder>
* @author Soldered
***************************************************
*/
/*
Soldered biblioteka za LCD ekran.
*/
#include "LCD-SOLDERED.h"
/*
Biblioteka WiFi sadrži sve što je potrebno za pridruživanje Wi-Fi mreži.
*/
#include <WiFi.h>
/*
Biblioteka time daje nam funkcije za rad s datumima i vremenima, i za pitanje NTP servera koliko je sati.
NTP je skraćeno od Network Time Protocol, i tako gotovo svaki uređaj na internetu drži svoj sat ispravnim.
*/
#include <time.h>
/*
Ove dvije varijable drže ime tvoje Wi-Fi mreže (SSID) i njezinu lozinku. Zamijeni tekst između
navodnika svojim mrežnim podacima.
*/
const char* WIFI_SSID = "your ssid";
const char* WIFI_PASS = "your password";
/*
Ovo je adresa NTP servera kojeg pitamo koliko je sati. pool.ntp.org je besplatan, svjetski servis koji tvoj
zahtjev predaje onom vremenskom serveru koji ti je najbliži, pa je dobra zadana vrijednost koju treba ostaviti kakva je.
*/
const char* ntpServer = "pool.ntp.org";
/*
NTP serveri uvijek odgovaraju u UTC-u, svjetskom referentnom vremenu, pa pločici moramo reći koliko je naša vremenska zona
daleko od njega. Pomak se zadaje u sekundama, pa je jedan sat 3600. Hrvatska je zimi jedan sat ispred UTC-a, što bi
ovdje bilo 3600.
Druga vrijednost je dodatni pomak za ljetno računanje vremena. Postavi ga na 3600 tijekom ljetnog vremena u zemlji koja
ga koristi, a inače ga ostavi na 0.
*/
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 0;
/*
Ovdje stvaramo naš objekt ekrana, koji smo nazvali "lcd". Objekt je naš način razgovora s ekranom: svaku funkciju
koju na njemu pozovemo, pozivamo preko ovog imena. Ne trebaju mu brojevi pinova jer koristi easyC, a to je Soldered ime za
I2C vezu preko jednog kabela, a I2C uvijek koristi ista dva pina na pločici (IO6 i IO7 na NULA pločici).
*/
LCD lcd(16, 2); // Qwiic 16x2 LCD
/*
Ovo su varijable kojima predajemo brojeve pinova na koje smo spojili dvije TIPKE i buzzer.
Jedna tipka nabraja sat alarma gore, druga nabraja minutu alarma gore.
NULA pločica ima logiku imenovanja pinova ovako: IO2, gdje je 2 broj koji dajemo varijabli.
*/
const int BUTTON_HOUR = 2;
const int BUTTON_MIN = 3;
const int BUZZER_PIN = 4;
/*
Ove varijable drže vrijeme alarma prema kojem brojimo, počevši od 07:00, i pamte je li se alarm
već oglasio, tako da se oglasi jednom a ne iznova tijekom iste minute.
*/
int alarmHour = 7;
int alarmMinute = 0;
bool alarmTriggered = false;
/*
Ova varijabla pamti u kojoj se minuti alarm posljednji put oglasio. Bez nje bi zaustavljanje alarma pritiskom tipke
unutar same minute u kojoj se oglasio dopustilo da se oglasi ponovno odmah, iznova dok minuta ne prođe. Počinjemo
na -1, vrijednosti koju nijedna prava minuta ne može imati, tako da prvi alarm nikada nije blokiran.
*/
int lastAlarmMinute = -1;
/*
Ovo su varijable koje se koriste za debounce tipki, ista tehnika objašnjena u primjeru 2.2. Budući da ovdje imamo dvije
tipke, svakoj treba vlastiti par varijabli: jedna koja pamti njezino prethodno stanje i jedna koja pamti kada
se to stanje posljednji put promijenilo.
*/
bool lastHourState = HIGH;
bool lastMinState = HIGH;
unsigned long lastHourChangeMs = 0;
unsigned long lastMinChangeMs = 0;
const unsigned long debounceMs = 25;
/*
Ove dvije varijable upravljaju koliko često ponovno pitamo NTP server koliko je sati. Vlastiti sat pločice polako odlutava, pa
provjeravanje s vremena na vrijeme drži njegovu točnost.
*/
unsigned long lastSync = 0;
const unsigned long syncInterval = 60000;
/*
Ovo je funkcija koju smo napisali sami. Pita za trenutno vrijeme i prijavljuje je li uspjela.
getLocalTime() ispunjava strukturu koju mu predamo i vraća true pri uspjehu ili false pri neuspjehu. Pri neuspjehu je
struktura ostavljena točno kakva je bila, a to bi bilo puno besmislenih vrijednosti, pa taj odgovor predajemo
onome koji poziva i puštamo ga da odluči što će, umjesto da koristimo brojeve kojima ne možemo vjerovati.
"*" u parametru znači da predajemo lokaciju strukture a ne njezinu kopiju, a to je ono što
funkciji dopušta da ispuni našu vlastitu varijablu umjesto neke svoje.
*/
bool getLocalTimeData(struct tm *timeinfo) {
if (!getLocalTime(timeinfo)) {
Serial.println("Failed to obtain time from NTP");
return false;
}
return true;
}
/*
Ova funkcija oglašava alarm. tone() tjera buzzer da proizvede zvuk zadane frekvencije, u ovom slučaju 1000 Hz,
a noTone() ga ponovno zaustavlja. Ponavljanje toga pet puta u nizu je ono što jedan dugi zvuk pretvara u niz pisaka.
Slobodno eksperimentiraj s frekvencijom, brojem ponavljanja i dvjema pauzama.
*/
void beepAlarm() {
for (int i = 0; i < 5; i++) {
tone(BUZZER_PIN, 1000);
delay(300);
noTone(BUZZER_PIN);
delay(100);
}
}
void setup() {
/*
Serial.begin() uspostavlja serijsku komunikaciju između tvoje pločice i tvog računala preko USB kabela. Ovdje ga koristimo
da pratimo povezivanje na mrežu i na vremenski server.
*/
Serial.begin(115200);
/*
Ovdje pripremamo ekran. begin() pokreće komunikaciju s njim a backlight() pali njegovo svjetlo da tekst
bude čitljiv.
*/
lcd.begin();
lcd.backlight();
/*
pinMode() je funkcija koja konfigurira zadani pin da se ponaša ili kao ulaz ili kao izlaz.
Buzzer je nešto u što pišemo, pa ide u OUTPUT mod, dok su dvije tipke stvari koje čitamo, pa
idu u INPUT_PULLUP mod. INPUT_PULLUP uključuje mali otpornik unutar čipa koji svaki pin veže na 3.3V,
što znači da pin sjedi na HIGH dok je njegova tipka otpuštena a ide na LOW dok je pritisnuta.
*/
pinMode(BUZZER_PIN, OUTPUT);
pinMode(BUTTON_HOUR, INPUT_PULLUP);
pinMode(BUTTON_MIN, INPUT_PULLUP);
/*
clear() briše sve što je ostalo na ekranu od prije, a setCursor() odabire gdje će se sljedeći tekst pojaviti:
prvi broj je stupac a drugi je red, oba brojeći od nule.
*/
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Connecting WiFi");
/*
WiFi.begin() pokreće pokušaj povezivanja. Funkcija samo pokreće proces, ne čeka da se dovrši,
pa na to čekamo sami u petlji ispod. WiFi.status() nam kaže trenutno stanje a WL_CONNECTED je vrijednost
koju prijavljuje kada smo na mreži.
*/
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected!");
lcd.clear();
lcd.print("WiFi connected");
delay(1000);
/*
configTime() govori pločici koji NTP server koristiti i koliko je naša vremenska zona daleko od UTC-a, i pokreće prvi
zahtjev za vremenom u pozadini. Vraća se odmah, prije nego je ikakav odgovor došao.
*/
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
/*
Zato ovdje čekamo taj prvi odgovor, jer dok ne dođe pločica nema pojma koliko je sati i na ekranu bi
prikazivala besmislice. Dajemo joj do deset sekundi i onda nastavljamo u svakom slučaju, tako da je nedostatak
veze s internetom ne može ostaviti zaglavljenu ovdje zauvijek.
*/
lcd.clear();
lcd.print("Syncing time...");
struct tm startupTime;
unsigned long syncStart = millis();
bool timeReady = false;
while (!timeReady && millis() - syncStart < 10000) {
timeReady = getLocalTime(&startupTime);
delay(200);
}
lcd.clear();
if (timeReady) {
Serial.println("Time synced!");
lcd.print("Time synced!");
lastSync = millis();
} else {
Serial.println("Time sync failed, the clock will keep trying.");
lcd.print("Sync failed!");
}
delay(1000);
lcd.clear();
}
void loop() {
/*
Ovdje pitamo za trenutno vrijeme preko naše funkcije iznad. Struct tm drži cijeli datum i vrijeme razdvojeno u
odvojena polja, od kojih koristimo samo dva: tm_hour i tm_min.
*/
struct tm timeinfo;
/*
Ako nismo mogli pročitati vrijeme, nema ničega smislenog za prikazati i sigurno ničega s čime bismo alarm usporedili,
pa počekamo trenutak i probamo ponovno u sljedećem prolazu. return rano završava ovaj prolaz kroz loop(), a budući da
pločica loop() poziva odmah ponovno, pravo smo natrag na sljedećem pokušaju.
*/
if (!getLocalTimeData(&timeinfo)) {
delay(1000);
return;
}
/*
sprintf() gradi komad teksta iz nekoliko vrijednosti, prema uzorku koji mu damo. "%02d" znači "cijeli broj
napisan s najmanje dvije cifre, dopunjen nulom ako treba", a to je ono što 7 minuta nakon punog sata pretvara u "07" umjesto
u "7". Rezultat se sprema u polje timeStr i onda se ispisuje na ekran.
*/
char timeStr[6];
sprintf(timeStr, "%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min);
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.print(timeStr);
/*
U drugoj liniji prikazujemo vrijeme alarma. Ovdje brojeve dopunjavamo ručno umjesto pomoću sprintf(): ako je vrijednost
manja od 10, prvo pred nju ispišemo nulu.
*/
lcd.setCursor(0, 1);
lcd.print("Alarm ");
if (alarmHour < 10) lcd.print("0");
lcd.print(alarmHour);
lcd.print(":");
if (alarmMinute < 10) lcd.print("0");
lcd.print(alarmMinute);
/*
Ovo je logika debouncea za tipku sati, ista ona objašnjena u primjeru 2.2. digitalRead() čita vrijednost
s pina, millis() vraća broj milisekundi koje su prošle od kada je pločica počela izvršavati trenutni program,
i zajedno nam dopuštaju da ignoriramo svaku promjenu koja dođe prerano nakon prethodne da bi bila stvarni pritisak.
Budući da tipke koriste pull-up otpornike, vrijednosti su obrnute od onoga što bi mogao očekivati: pritisak
je trenutak kada vrijednost ide s HIGH na LOW, a to je točno trenutak kada sat nabrajamo gore. Nakon 23
počinjemo iznova od 0, jer sata 24 nema.
*/
bool hourReading = digitalRead(BUTTON_HOUR);
unsigned long now = millis();
if (hourReading != lastHourState && (now - lastHourChangeMs) > debounceMs) {
lastHourChangeMs = now;
if (lastHourState == HIGH && hourReading == LOW) {
alarmHour++;
if (alarmHour > 23) alarmHour = 0;
}
lastHourState = hourReading;
}
/*
Ta ista logika za tipku minuta, nabrajajući do 59 prije nego počne iznova.
*/
bool minReading = digitalRead(BUTTON_MIN);
if (minReading != lastMinState && (now - lastMinChangeMs) > debounceMs) {
lastMinChangeMs = now;
if (lastMinState == HIGH && minReading == LOW) {
alarmMinute++;
if (alarmMinute > 59) alarmMinute = 0;
}
lastMinState = minReading;
}
/*
Ovdje provjeravamo je li vrijeme za alarm. Sva tri uvjeta moraju biti istinita odjednom: sat se mora poklopiti,
minuta se mora poklopiti, i alarm se ne smije već oglasiti. Ta posljednja provjera je ono za što varijabla
alarmTriggered služi, jer bi se bez nje alarm oglašavao iznova i iznova cijelu minutu.
*/
if (timeinfo.tm_hour == alarmHour && timeinfo.tm_min == alarmMinute && !alarmTriggered
&& timeinfo.tm_min != lastAlarmMinute) {
alarmTriggered = true;
lastAlarmMinute = timeinfo.tm_min;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ALARM!");
Serial.println("Alarm Triggered!");
beepAlarm();
}
/*
Pritisak bilo koje tipke nakon što se alarm oglasio briše upozorenje s ekrana i ponovno naoružava alarm za
sljedeći dan.
*/
if (alarmTriggered && (hourReading == LOW || minReading == LOW)) {
alarmTriggered = false;
lcd.clear();
}
/*
A ovdje s vremena na vrijeme ponovno pitamo NTP server koliko je sati, tako da sat ne odluta.
*/
if (millis() - lastSync > syncInterval) {
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
lastSync = millis();
}
/*
Kratka pauza da se ekran ne prepisuje tisućama puta u sekundi. Držanje kratke također drži tipke
odzivnima.
*/
delay(100);
}
Što bi trebao vidjeti
Pokretanje
Skica svoje pokretanje pripovijeda na ekranu, jedan ekran po ekran. Prvo najavljuje da se pridružuje mreži:

WIFI_SSID i WIFI_PASS za tipfelere, a ne spajanje.Kada je na mreži, dobiješ sekundu potvrde:

Zatim pločica pita vremenski server koliko je sati. configTime() se vraća odmah, prije nego je ikakav odgovor došao, pa skica ovdje čeka do deset sekundi:

Ako odgovor dođe, vidiš Time synced! na sekundu i sat počinje. Ako ne, dobiješ Sync failed!, a sat ipak nastavlja, pokušavajući svake minute, pa spora mreža odgađa prvu vrijednost ali ne zaglavljuje projekt.
U Serial Monitoru
Otvori Serial Monitor na 115200 bauda i resetiraj pločicu. Cijelo pokretanje ulazi u nekoliko linija:
ESP-ROM:esp32c6-..., SPIWP, load: i entry ispisuje ugrađeni bootloader čipa pri svakom resetu, prije nego se tvoj program pokrene. Izgledaju uznemirujuće a znače da ništa nije u krivu.4 nisu iz skice. Dolaze iz same LCD biblioteke: lcd.begin() ekranu pošalje tri poruke za postavljanje i ispiše rezultat svake od njih. Nisi ih vidio u 4.1 ni u 4.2 jer te skice nikada ne pozivaju Serial.begin(), pa brojevi nisu imali kamo otići. Ova ga poziva, pa se pojavljuju. Ignoriraj ih. Ekran radi, kako fotografije na ovoj stranici pokazuju.Svaka točka je jedan krug petlje čekanja, a svaki krug traje 500 ms. Njihovo brojanje govori ti točno koliko je pločici trebalo da se pridruži mreži: dvanaest točaka ovdje, dakle šest sekundi. Ako ikada budeš htio znati je li tvoja mreža spora u dodjeljivanju adresa, taj red točaka je mjerenje.
Sat u radu
Nakon što se ekrani pokretanja očiste, ekran se smjesti u dvije linije koje će odsad prikazivati: trenutno vrijeme gore, vrijeme alarma ispod:

Oba su dopunjena na dvije cifre, pa sedam minuta nakon punog sata pokazuje 07 a ne 7. Gornji red to radi pomoću sprintf() i %02d; donji red isti posao radi ručno, ispisujući 0 prvo kad god je broj ispod deset. Dva načina do istog rezultata, jedan uz drugi na jednom ekranu.
10:29 jer skica dolazi s gmtOffset_sec = 0 i zato prikazuje UTC. U prostoriji je bilo 12:29. Postavi pomak i gornji red postaje tvoje lokalno vrijeme.Postavljanje i slušanje alarma
Alarm počinje na 07:00. Pritisni tipku na IO2 da nabrajaš sate gore i onu na IO3 da nabrajaš minute, i gledaj kako se donji red mijenja. Oba obilaze: 23 ide natrag na 0, a 59 natrag na 0.
Da alarm čuješ bez cjelodnevnog čekanja, postavi ga na minutu koja upravo dolazi. Kada ga sat sustigne, gornji red se zamjenjuje:

beepAlarm() svira pet pisaka od 300 ms sa 100 ms tišine između njih, a ekran se ne dira ponovno dok ne završi. Onog trenutka kada piskanje prestane, loop() se izvrši još jednom i preko ALARM! upisuje vrijeme. Ako to želiš fotografirati, imaš jedan pokušaj kada piskanje počne.Serial Monitor u istom trenutku ispisuje Alarm Triggered!, što je korisno ako si propustio ekran.
ALARM! s ekrana i ponovno naoružava alarm za sljedeći put.Ako nešto nije u redu
Ekran je upaljen ali prazan. To ima tri različita uzroka, a Serial Monitor ih razlikuje u nekoliko sekundi, pa ga otvori prije nego diraš spajanje.
- Ničega uopće nakon boot poruka, ili red punih blokova. Skica ne dolazi do ekrana. Provjeri je li Qwiic kabel propisno na mjestu na oba kraja, i je li pločica odabrana u IDE-u Soldered NULA Mini ESP32C6. Druga ESP32 varijanta stavlja I2C na druge pinove, a skica će se savršeno prevesti i prenijeti a da nikada ne dođe do ekrana.
- Monitor pokazuje točke i
Time synced!, ali ekran ostaje taman. Pločica razgovara s ekranom a ekran je jednostavno previše blijed da bi se čitao. OkreniCONTRASTtrimpot na ljubičastoj adapterskoj pločici. - Monitor ponavlja
Failed to obtain time from NTP. Pločica je na mreži ali ne može dobiti vrijeme, paloop()odustaje prije nego bilo što ispiše. Ekran je prazan jer nema što prikazati. Neke gostinske i korporativne mreže blokiraju vremenske servere.
Sat je pogrešan za cijeli broj sati. To je pomak vremenske zone, a ne greška. Vidi iznad.
Jedna tipka ne radi ništa. Provjeri koristi li jednu nožicu s obje strane središnjeg kanala. Tipka spojena s obje žice na istoj strani čita se kao trajno pritisnuta, a ona s žicom mase u pogrešnom redu ne radi ništa uopće.
Buzzer je tih ali se ALARM! pojavljuje. Kod je u redu a greška je u posljednje dvije žice. Provjeri da su nožice buzzera stvarno u dva različita reda, i da je IO4 pin u j27. S druge strane pločice, a27 je IO19.
Cijeli primjer
Pogledaj cijeli kod primjera na linku ispod:
7.7_Alarm_Clock.ino
Budilica povezana na Wi-Fi: pločica vrijeme dobiva s NTP servera, prikazuje ga na Qwiic LCD-u i oglašava buzzer u vrijeme alarma postavljeno dvjema tipkama.