Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Karlitos 17. 12. 2014, 21:11:08
-
Zdravim,
stavim si takovy hudebni budik s R-Pi a 4-mistnym segmentovym displayem. Koupil jsem si na to model od Adafruit ktery se ovlada prez I2C a jede to krasne. Takze sem zacal delat v Pythonu nejakou tridu do ktere bych to ovladani pekne zabalil a narazil jsem na to, ze vlasnte nevim jak blika dvojtecka u digitalnich hodin. Obvykle se tim udavaji sekundy, ale ja nevim jestli ta dvojtecka blika:
* sudou sekundu sviti / lichou nesviti
a nebo treba tak ze prvni 0.5 sekundy sviti a 0.5 sekundy nesviti. To yb ale pak blikala s frekvenci 2Hz ???
Mohl bych to resit tak ze proste udelam nejakou uplne pitomou metodu ktera bude tu dvojtecku stridave rozsvecet a zhaset s tim ze na konci bude nejaky time. sleep(1)
Jenze pak to samozrejme nebude synchroni s hodinami. A vubec, jak casto mam ty hodiny aktualizovat ? Udelal sem nekonecnoun smycku a nakonci dal zase delay time.sleep(0.1) a koukam ze mi jen tento blby process zere 30% CPU na R-Pi
Jak to tady ted sepisuju tak mi dochazi ze resim asi kravovinu. Implementuju BUDIK a ne STOPKY ;) takze na nejakou synchronizaci s hodinami bych se mel asi vykaslat. A udelat update s frekvenci 1Hz kde si prez datetime.datetime.now() vytahnu aktualni cas.
Nebo mi poradi nekdo nejake chytrejsi reseni ? Za pripadne konstruktivni rady budu moc rad, legraci a rypani si prosim odpusste, diky !
-
Proč to neokoukáš od nějakých funkčních digitálek? :)
-
neprogramuji, jen mám před sebou několik displejů s hodinami a každý bliká jinak.
1) dvojtečka svítí trvale
2) dvojtečka se na cca 1/4 sekundy rozsvítí společně se změnou času a pak 3/4 sekundy nesvítí
3) dvojtečka 1/2 sekundy svítí, 1/2 sekundy nesvítí.
-
Já bych to blikání vyřešil takhle:
nová sekunda - zobrazí se dvojtečka
NS + 450 ms - dvojtečka zmizí
NS + 550 ms - opakuj od začátku
-
Udelal sem nekonecnoun smycku a nakonci dal zase delay time.sleep(0.1) a koukam ze mi jen tento blby process zere 30% CPU na R-Pi
Nekonečná smyčka, to je správně ;-).
Na začátku nastavit aktuální čas, to je taky správně.
Zároveň rozsvítit dvojtečku a pak time.sleep( 0.450 ) - přibližně.
Pak zhasnout dvojtečku, zjistit kolik zbývá do konce sekundy a udělat tak dlouhý time.sleep.
-
Hm, nejde na RPi zaridit preruseni od nejakeho HW casovace nebo casovace v jadru? Nejake nekonecne smycky v Pythonu, z toho se asi spousta programatoru z prukopnickych dob obraci v hrobe.
-
Diky vsem za odpovedi. Nemam po ruce nejaky radiobudik nebo digitalky a na radiobudiku co ma moje maminka ani zadna dvojtecka neni.
Zkusil jsem ted ruzne mody blikani a nejlepe vypada frekvence 1Hz, kdy dvojtecka sviti kazdou sudou skeundu. Coz se krasne resi s modulo 2 == 0. Kdyz jsem zkusil frekvenci 2Hz tak me to rychel blikani slo na nervy.
Jinak by me moc-moc zajimalo to co psal JardaP. Uz jsem upustil od toho ze budu mit blikani dvojtecky synchroni s vnitrnim casem, delam budik a ne stopky. Ale take by se mi vic libilo kdybych nemusel aktivne kazdou sekundu zjistovat cas ale vyuzil nejaky hardwarovy timer. Zkusim se na to podivat.
-
Digitálky, co mám teď na ruce, blikají zjevně 0,5s zapnuto, 0,5s vypnuto. Nicméně asi záleží na vlastní spokojenosti, takže to stejně udělej jak uznáš za vhodný ;-)
-
Zkusil jsem ted ruzne mody blikani a nejlepe vypada frekvence 1Hz, kdy dvojtecka sviti kazdou sudou skeundu. Coz se krasne resi s modulo 2 == 0. Kdyz jsem zkusil frekvenci 2Hz tak me to rychel blikani slo na nervy.
Máš v tom hokej ;-)
1 s svícení a 1 s tmy = 2 s celý cyklus = ½ Hz
½ s svícení a ½ s tmy = 1 s celý cyklus = 1 Hz
;-B
-
Hm, nejde na RPi zaridit preruseni od nejakeho HW casovace nebo casovace v jadru? Nejake nekonecne smycky v Pythonu, z toho se asi spousta programatoru z prukopnickych dob obraci v hrobe.
https://docs.python.org/2/library/signal.html
-
A vubec, jak casto mam ty hodiny aktualizovat ? Udelal sem nekonecnoun smycku a nakonci dal zase delay time.sleep(0.1) a koukam ze mi jen tento blby process zere 30% CPU na R-Pi
Aktivní čekání na čas je zbytečné. Moje Turrisem řízené hodiny (http://oskar456.github.io/turrisclock/) to řeší načtením času po každém kroku a následně sleepem do konce sekundy:
https://github.com/oskar456/turrisclock/blob/master/turrisclock.py#L55
Zatížení CPU je téměř nepozorovatelné a nikde se neakumuluje chyba. Myslím, že nemá cenu hnát se za víc low-level řešením, pokud chceš hodiny ovládat z linuxového systému. Pokud bys to programoval pro embedded kontrolér, tam by samozřejmě dávalo smysl použít nějaký vestavěný časovač a překreslení displeje spouštět přerušením.
-
Hm, nejde na RPi zaridit preruseni od nejakeho HW casovace nebo casovace v jadru? Nejake nekonecne smycky v Pythonu, z toho se asi spousta programatoru z prukopnickych dob obraci v hrobe.
Nekonečná smyčka je regulérní programovací technika, až do vynálezu multitaskingu se používala denně.
Problém může nastat s teplotou nebo spotřebou elektřiny, pak je použití přerušení prakticky povinné.
A vubec, jak casto mam ty hodiny aktualizovat ?
Stejně rychle nebo rychleji než jsou změny na displeji. Začít můžeš na hodnotě 3x-5x za sekundu.
-
Hm, nejde na RPi zaridit preruseni od nejakeho HW casovace nebo casovace v jadru? Nejake nekonecne smycky v Pythonu, z toho se asi spousta programatoru z prukopnickych dob obraci v hrobe.
Nekonečná smyčka je regulérní programovací technika, až do vynálezu multitaskingu se používala denně.
Problém může nastat s teplotou nebo spotřebou elektřiny, pak je použití přerušení prakticky povinné.
Tak to sice je, ale kdyz uz, tak snad radsi ne v Pythonu. Kdyz to nazene CPU na takove otacky, ze se tim budikem pak da pritapet, tak je nekde neco asi spatne. To by snad bylo mene narocne i jako shell skript, pokud se z nej lze nejak dostat na HW, aby bylo mozno preklapet segmenty displaye. Zatim jsem si nevsiml, ze by mi sleep v bashi vyhnal CPU na 30 %.
-
Těch 30% CPU zcela jistě negeneruje zmíněný pythoní time.sleep(0.1). Jeho zásluhou je naopak pravděpodobně to, že to žere jen 30 % a nikoli 100 % CPU.
-
Máš v tom hokej ;-)
1 s svícení a 1 s tmy = 2 s celý cyklus = ½ Hz
½ s svícení a ½ s tmy = 1 s celý cyklus = 1 Hz
;-B
Mam a proto se tu tak blbe ptam :-) Kazdopadne s tim modulo 2 == 0 to pro me vypada nejlepe.
Aktivní čekání na čas je zbytečné. Moje Turrisem řízené hodiny (http://oskar456.github.io/turrisclock/) to řeší načtením času po každém kroku a následně sleepem do konce sekundy:
https://github.com/oskar456/turrisclock/blob/master/turrisclock.py#L55
Zatížení CPU je téměř nepozorovatelné a nikde se neakumuluje chyba. Myslím, že nemá cenu hnát se za víc low-level řešením, pokud chceš hodiny ovládat z linuxového systému. Pokud bys to programoval pro embedded kontrolér, tam by samozřejmě dávalo smysl použít nějaký vestavěný časovač a překreslení displeje spouštět přerušením.
Diky za tip, podivam se na ten tvuj kod. Jenom jsem nepochopil jak jsi myslel to "načtením času po každém kroku a následně sleepem do konce sekundy"
Tedy neco jako
while True:
update_time()
sleep(1)
S tim vyhnanim vykonu: to jsem pozoroval kdyz jsem nastavil sleep na desetinu sekundy, takze desetkrat do sekundy se musely prepsat 4 cislice na LCD (ano i to by slo optimalizovat, ale bude s tim dost kodovani) pak zjistit jestli nahodou neni uz budicek ...
Dal jsem jsete vcera dotaz na StackOverflow a uz mi bylo neco doporucene (http://stackoverflow.com/questions/27537301/most-efficient-way-to-implement-clock-with-alarm-clock-in-python), jdu to studovat
-
Jeste neco co jsem pozapomnel doplnit ... a mozna ze je to dulezite, tak jen doufam ze me ted tady vsichni neposlete do #*²¼#½#¼¬³ :D
Krome toho LCD seg,entoveho displaye od Adafruit k tomu mam pripojene jeste RTC hodiny - model PCF8563 RTC Board od firmy WaveShare (http://www.wvshare.com/product/PCF8563-RTC-Board.htm) On si sice Rapsbian po pripojeni na WiFi aktualizuje cas, ale kdyz mi vypadne uprostred noci proud a Malina se nespoji tak mam po hodinach ... Ten kram se mi tu valel v supliku uz nejakou dobu, koupil jsem ho onehda kvuli navodu tady (http://www.raspi.cz/2012/07/pouziti-i2c-sbernice-detailni-postup-hodiny-realneho-casu-pro-rpi/), ale maka dobre a taham z nej pri startu systemu skriptem v rc.local
No a ja si ho ted prohlizim a koukam ze to ma i piny INT a CLK OUT :-[ :-[ :-[
Takze bych nakonec mel o to prerusei postarano ??? Jdu cist datasheet
-
Diky za tip, podivam se na ten tvuj kod. Jenom jsem nepochopil jak jsi myslel to "načtením času po každém kroku a následně sleepem do konce sekundy"
Myslel jsem to takhle
while True:
update_time()
now = time.time()
sleep(1 - now%1)
Tímhle způsobem máš zajištěno, že naplánuješ probuzení právě na začátku každé další sekundy a to bez ohledu na to, jak dlouho bude samotný proces aktualizace času potrvá.
-
Tak teprve ted koukam, jaky poklad mi to lezel v supliku. Ten modul (PCF8563) to na tom pinu CLK OUT umi delat vicero frekvenci
- 128 decimal = 0x80 hex = 10000000 binary for 32.768 kHz;
- 198 decimal = 0x81 hex = 10000001 binary for 1.024 kHz;
- 130 decimal = 0x82 hex = 10000010 binary for 32 kHz;
- 131 decimal = 0x83 hex = 10000011 binary for 1 Hz;
- 0 decimal = 0x0 hex = 0 binary turns the output off and sets it to high impedance.
Pak uz stacilo odebrat modul rtc_pcf8563 a v Pythonu pomoci smbus zapsat 0x83 na adresu 0x51 do registru 0x0D a ejhle ... uz si blikame ledkou s frekvenci 1Hz. Cimz by se jaksi resilo to jak efektivne ridit updaty hodin - na to mame preruseni v RPi.GPIO.
Sic! On ten modul ma i vlastni alarm a pin na kteremm udela preruseni kdyz se alarm spusti! Takze nac resit nejake softwarove hodiny, tohle je prece naprosto supr reseni :D
Vsem diky kteri me na tohle navedli, tady je seznam "literatury" z ktereho jsem cerpal informace:
Velmi podobny modul udelany primo na header R-Pi s knihovnou na GitHub (https://github.com/abelectronicsuk/AlarmPi) Ale 14 liber ... muj stal z ciny bura ... dolaru :)
[url?http://tronixstuff.com/2013/08/13/tutorial-arduino-and-pcf8563-real-time-clock-ic/?utm_source=rss&utm_medium=rss&utm_campaign=tutorial-arduino-and-pcf8563-real-time-clock-ic]Tady je dobry tutorial[/url], sice pro arudino, ale tim lepe, C-cko bych asi lustil mnohem dyl.
-
S tim vyhnanim vykonu: to jsem pozoroval kdyz jsem nastavil sleep na desetinu sekundy, takze desetkrat do sekundy se musely prepsat 4 cislice na LCD (ano i to by slo optimalizovat, ale bude s tim dost kodovani
A to jako proc? To si nemuzete ulozit cas posledniho updatu a display updatovat jen tehdy, kdyz doslo ke zmene?