Challenge - Výpis času
-
- Příspěvky: 1030
- Registrován: 06 zář 2017, 20:04
- Reputation: 0
- Bydliště: Brno
- Kontaktovat uživatele:
Challenge - Výpis času
Tak malou úlohu nejspíš jen pro tebe. Ve svých aplikacích občas používám zobrazování času od zapnutí - restartu, tedy jakési "motohodiny". Odvozeno je to od millis(), tedy nic přesného a po cca 50 dnech se to vynuluje, ale je to docela užitečné. Člověk získá alespoň představu o výdrži a stabilitě daného systému.
Zadání: pomocí funkce millis() vytvoř funkci, jejíž hodnotou bude String v podobě DD:HH:MM:SS , ukazující dobu od zapnutí systému. Pochopitelně konstantní délky. Vyhni se při tom globálním proměnným
Zadání: pomocí funkce millis() vytvoř funkci, jejíž hodnotou bude String v podobě DD:HH:MM:SS , ukazující dobu od zapnutí systému. Pochopitelně konstantní délky. Vyhni se při tom globálním proměnným
Re: Challenge
Očekával bych asi takovou odpoveď :
Zatím jsem se nevyhnul globálním proměnným. Kód je odzkoušen a je plně funkční na arduino Mega. Napíše to někdo jako lépe ? Třeba jako vnitřně se řídící třídu, která s každým zavoláním .update() sama sebe testne a vyplivne požadované data či vykoná potřebnou činost ?
edit : A když to čtu znovu, nemám ještě splněno, že to bude string
Kód: Vybrat vše
/*
Program co používá millis() pro počítání běhu svého času ... na cca 170let
Schválně nebudu používat millis() pro výpočet času po který program běží, protože vím, že každých cca 50dní přeteče.
Program napíšu proto tak, aby millis() využíval pouze ke generování cca vteřinových "impulzů" (ve skutečnosti to budou odbočky v programu).
Tím mám možnost si celkovou informaci o času běhu programu rozdělit do kolika řádu budu chtít.
Nemám tušení zda je přestupný rok, nebo ne a kolik má dní měsíc ve kterém to funguje. Budu počítat pouze dny.
*/
byte day,hour,minute,sec; // byte 0 - 255 stačí
unsigned long currentTime; // zde si uchovám aktuální počet millis() - mám ho tam i pro jinačí funkce
unsigned long lastLifeTime; // zde si uchovám akutální čas, kdy jsem kontroloval jestli program žije - více časových funkcí = více těhle proměnných
void setup() {
Serial.begin(115200);
}
void loop() {
currentTime = millis(); // zapíšu si aktuální čas -- chceteli si hrát, dejte tu = micros(); a o dva řádky později
//---- Zde porovnávám aktuální a poslední čas
if((unsigned long)(currentTime - lastLifeTime) > 1000){ // výsledek je definován jako unsigned long, nikdy tedy nebude záporný, přeteče-li mi milis dostanu nechutně vysoké číslo ... jinak pokud je vždy větší než 1000ms -- chceteli si hrát nahradit > 1
if(sec < 59){ // vteřin je sice 60, ale kdo kdy viděl 01:60
sec++; // méně jak 59, počítám vteřiny
} else { // přetekly vteřiny
sec = 0; // vynuluji vteřiny
if(minute < 59){ // kdo kdy viděl 00:60:00
minute++; // počítám minuty
} else { // přetekly minuty
minute = 0; // vynuluji minuty
hour++; // počítám hodiny
if(hour < 23){ // všichni známe 00:00:00
hour++; // počítám hodiny
} else { // přetekly hodiny
hour = 0; // vynuluji hodiny
day++; // počítám dny
}
}
}
/*
Vím že zadání bylo 00:00:00:00 - jen pro ukázku modifikace
Vypisuji na sériovou linku, zde je prostor pro odeslání dat kam potřebuješ
*/
Serial.print(day); //dny
Serial.print("d"); //oddělovač dní od hodin ... nahradit : pokud je třeba
if(hour < 10) Serial.print("0"); // méně než 10 a chci tam úvodní nulu
Serial.print(hour); // vypiš hodiny
Serial.print(":"); // oddělovač hodin od minut
if(minute < 10) Serial.print("0"); // méně než 10 a chci tam úvodní nulu
Serial.print(minute); // vypiš minuty
Serial.print(":"); // oddělovač minut od vteřin
if(sec < 10) Serial.print("0"); // méně než 10 a chci tam úvodní nulu
Serial.println(sec); // vypiš vteřiny
lastLifeTime = currentTime; // všechno hotovo, zapiš čas (a uvidíme se příští cca vteřinu)
}
}
edit : A když to čtu znovu, nemám ještě splněno, že to bude string
Re: Challenge
Ale zase na druhou stranu bych rád viděl tvůj počin, jak to tam drtíš ... už v samotném challengi
Re: Challenge
Toto by sa sa vám ako páčilo?
Kód: Vybrat vše
void setup() {
Serial.begin(9600);
}
#define DAY_SEC 86400L
#define HOUR_SEC 3600L
#define MIN_SEC 60L
void print2digit (String& s, uint8_t val, uint8_t pos){
s.setCharAt(pos++, (val/10)|'0' );
s.setCharAt(pos, (val%10)|'0');
}
void toTime(String& s, uint32_t ms){
uint8_t val;
ms /= 1000;
val = ms / DAY_SEC;
print2digit(s, val,0);
ms %= DAY_SEC;
val = ms / HOUR_SEC;
print2digit(s, val,3);
ms %= HOUR_SEC;
val = ms / MIN_SEC;
print2digit(s, val,6);
ms %= MIN_SEC;
print2digit(s, (uint8_t)ms, 9);
}
void loop() {
String s= String(F(" : : : "));
uint32_t ms;
ms = millis();
toTime(s, ms);
Serial.println(s);
}
-
- Příspěvky: 1030
- Registrován: 06 zář 2017, 20:04
- Reputation: 0
- Bydliště: Brno
- Kontaktovat uživatele:
Re: Challenge
Zajímavá je tvoje idea, brát z millis jen sekundové intervaly a mít tedy čítání delší. To asi zkusím v modifikaci zapracovat do svého programu. Ale přináší to některé problémy. Ten tvůj program funguje, vyzkoušel jsem ho, ale zadání úplně nesplňuje. Když budu mít nějaký displej nebo webovou stránku, pak musím celý výstup pracně přepisovat. Je to takové nekompaktní a vyžaduje to každou sekundu nějakou činnost. Moje řešení prostě při zavolání spočítá dobu běhu a basta.
A na tomhle se dobře ladí.
Kód: Vybrat vše
void setup() {
Serial.begin(115200);
Serial.println("");
}
void loop() {
Serial.println(TimeToString());
delay(1000);
}
String TimeToString(void) {
// conversion of millis to time string DD:HH:MM:SS
uint32_t times = millis() / 1000;
uint8_t days = (uint8_t)floor(times / 86400);
uint8_t hours = (uint8_t)floor((times % 86400) / 3600);
uint8_t mins = (uint8_t)floor((times % 3600) / 60);
uint8_t secs = (uint8_t)floor(times % 60);
String uts = (days < 10 ? "0" + String(days) : String(days))
+ ":" + (hours < 10 ? "0" + String(hours) : String(hours))
+ ":" + (mins < 10 ? "0" + String(mins) : String(mins))
+ ":" + (secs < 10 ? "0" + String(secs) : String(secs));
return uts;
}
Naposledy upravil(a) jankop dne 24 lis 2021, 21:16, celkem upraveno 1 x.
-
- Příspěvky: 1030
- Registrován: 06 zář 2017, 20:04
- Reputation: 0
- Bydliště: Brno
- Kontaktovat uživatele:
Re: Challenge
Ten tvůj prográmek zadání nepochybně splňuje, funguje a je v každém případě velmi nekonvenční.
Re: Challenge
Toto funguje ako?
Keď opustíš funkciu tak sa premenná uts na zásobníku nedealokuje?
Kód: Vybrat vše
String TimeToString(void) {
// conversion of millis to time string DD:HH:MM:SS
uint32_t times = millis() / 1000;
uint8_t days = (uint8_t)floor(times / 86400);
uint8_t hours = (uint8_t)floor((times % 86400) / 3600);
uint8_t mins = (uint8_t)floor((times % 3600) / 60);
uint8_t secs = (uint8_t)floor(times % 60);
String uts = (days < 10 ? "0" + String(days) : String(days))
+ ":" + (hours < 10 ? "0" + String(hours) : String(hours))
+ ":" + (mins < 10 ? "0" + String(mins) : String(mins))
+ ":" + (secs < 10 ? "0" + String(secs) : String(secs));
return uts;
}
-
- Příspěvky: 1030
- Registrován: 06 zář 2017, 20:04
- Reputation: 0
- Bydliště: Brno
- Kontaktovat uživatele:
Re: Challenge
uts je lokální ve své funkci a její hodnota se vrací prostřednictvím hodnoty funkce. Globálně neexistuje.
Re: Challenge
aha, takže sa to niekam prekopíruje zase do nejakého iného Stringu. Nie je jednoduchšie a rýchlejšie odovzdávať si referenciu, ako kopírovať celý objekt? A ešte k tomu vnútru, to ti nevadí že tam máš v tej funkcii "tisíc" nových alokácií pre fúru String objektov a pri operátore +. A že sa ti pravdepodobne fragmentuje heap? Moje hodnotenie tej funkcie TimeToString je 3-. Takto si môžem dovoliť programovať v JAVe alebo JavaScripte kde to GCC uprace, ale na AVR ťa to rýchlo dostane do pamäťovej núdze. Na tom ESP či čo to je, asi nebude taká akútna.
-
- Příspěvky: 1030
- Registrován: 06 zář 2017, 20:04
- Reputation: 0
- Bydliště: Brno
- Kontaktovat uživatele:
Re: Challenge
Já jsem netvrdil, že moje řešení je nejlepší. Vracet hodnoty funkcí je ale naprosto přirozené. Předávání referencí je asi lepší metoda. Máš pravdu, že ESP8266 má k dispozici podstatně víc paměti. Na druhé straně jsem spojoval řetězce takhle
i takhle
ale nebyl ve využití paměti rozdíl.
BTW: Nejsem programátor.
Kód: Vybrat vše
void MainPage(void) {
// Authentication is required ?
AuthWeb();
// website layout
String buff = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
buff += "<html><head><meta content=\"text/html; charset=utf-8\"><meta http-equiv=\"refresh\" content=\"" + String(PageRefreshPeriod) + "\">\n";
buff +="<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n";
buff += "<title>ESP8266 Humidity</title></head><body style=\"font-family:Arial,sans-serif\">\n";
buff += "<table frame=\"box\" cellpadding=\"5\" style=\"text-align:left; Font-weight:bold; font-size:large; padding: 0; border-spacing: 0;\">\n";
buff += "<tr style=\"background-color:#f0f0f0\"><td>NAME</td><td colspan=\"2\">" + String(SensorName) + "</td><td>" + String(Version) + "</td></tr>\n";
buff += "<tr style=\"background-color:#ffffff\"><td>MAC</td><td colspan=\"2\">" + StrMacAddr + "</td><td></td></tr>\n";
buff += "<tr style=\"background-color:#f0f0f0\"><td>VALUE</td><td colspan=\"2\">TEMPERATURE</td><td>" + String(temperature, FloatRounding) + " °C</td></tr>\n";
buff += "<tr style=\"background-color:#ffffff\"><td>VALUE</td><td colspan=\"2\">HUMIDITY</td><td>" + String(humidity, FloatRounding) + " %</td></tr>\n";
buff += "<tr style=\"background-color:#f0f0f0\"><td>RESET</td><td colspan=\"2\">" + String(ResetReason) + "</td ><td></td></tr>\n";
buff += "<tr style=\"background-color:#ffffff\"><td>ON</td><td colspan=\"2\">" + TimeString + "</td ><td></td></tr>\n";
buff += "<tr style=\"background-color:#f0f0f0\"><td>WiFi</td><td colspan=\"2\">" + String(rssi) + " dBm</td><td>" + String(PercentRssi, 0) + " %</td ></tr>\n";
buff += "<tr style=\"background-color:#ffffff\"><td>RAM</td><td colspan=\"2\">" + String(FreeHeap) + "</td><td>BYTE</td></tr>\n";
buff += "<tr style=\"background-color:#f0f0f0\"><td>VCC</td><td colspan=\"2\">CHIP VOLTAGE</td><td>" + String(Vcc, 2) + " V</td></tr>\n";
buff += "<tr style=\"background-color:#ffffff\"><td></td><td colspan=\"2\">" + message + "</td><td>" + SymbolRefresh + "</td></tr>\n";
buff += "<tr style=\"background-color:#f0f0f0\"><td></td><td colspan=\"2\">" + response + "</td><td></td></tr>\n";
buff += "</table>\n";
buff += "</body></html>\n";
server.send(200, "text/html", buff);
}
Kód: Vybrat vše
//http main page
void MainPage(void) {
// Authentication is required ?
AuthWeb();
// website layout
String buff = F("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
buff.concat("<html><head><meta content=\"text/html; charset=utf-8\"><meta http-equiv=\"refresh\" content=\"" + String(PageRefreshPeriod) + "\">\n");
buff.concat(F("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n"));
buff.concat(F("<title>ESP8266 Humidity</title></head><body style=\"font-family:Arial,sans-serif\">\n"));
buff.concat(F("<table frame=\"box\" cellpadding=\"5\" style=\"text-align:left; Font-weight:bold; font-size:large; padding: 0; border-spacing: 0;\">\n"));
buff.concat("<tr style=\"background-color:#f0f0f0\"><td>NAME</td><td colspan=\"2\">" + String(SensorName) + "</td><td>" + String(Version) + "</td></tr>\n");
buff.concat("<tr style=\"background-color:#ffffff\"><td>MAC</td><td colspan=\"2\">" + StrMacAddr + "</td><td></td></tr>\n");
buff.concat("<tr style=\"background-color:#f0f0f0\"><td>VALUE</td><td colspan=\"2\">TEMPERATURE</td><td>" + String(temperature, FloatRounding) + " °C</td></tr>\n");
buff.concat("<tr style=\"background-color:#ffffff\"><td>VALUE</td><td colspan=\"2\">HUMIDITY</td><td>" + String(humidity, FloatRounding) + " %</td></tr>\n");
buff.concat("<tr style=\"background-color:#f0f0f0\"><td>RESET</td><td colspan=\"2\">" + String(ResetReason) + "</td ><td></td></tr>\n");
buff.concat("<tr style=\"background-color:#ffffff\"><td>ON</td><td colspan=\"2\">" + TimeString + "</td ><td></td></tr>\n");
buff.concat("<tr style=\"background-color:#f0f0f0\"><td>WiFi</td><td colspan=\"2\">" + String(rssi) + " dBm</td><td>" + String(PercentRssi, 0) + " %</td ></tr>\n");
buff.concat("<tr style=\"background-color:#ffffff\"><td>RAM</td><td colspan=\"2\">" + String(FreeHeap) + "</td><td>BYTE</td></tr>\n");
buff.concat("<tr style=\"background-color:#f0f0f0\"><td>VCC</td><td colspan=\"2\">CHIP VOLTAGE</td><td>" + String(Vcc, 2) + " V</td></tr>\n");
buff.concat("<tr style=\"background-color:#ffffff\"><td></td><td colspan=\"2\">" + message + "</td><td>" + SymbolRefresh + "</td></tr>\n");
buff.concat("<tr style=\"background-color:#f0f0f0\"><td></td><td colspan=\"2\">" + response + "</td><td></td></tr>\n");
buff.concat (F("</table>\n"));
buff.concat (F("</body></html>\n"));
server.send(200, "text/html", buff);
}
BTW: Nejsem programátor.
Kdo je online
Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 39 hostů