idő szinkronizálás

Fórumok

Van 2 (vagy sok, de ez kb mind1) eszköz (perpill konkrétan arduino, de ez kb mind1), amik rádiós linken tudnak beszélgetni egymással. Van még 1 relatív időt mutató számláláóm (konkrétan millis(), de ez kb mind1). Jó lenne nekem egy olyan, hogy minden eszközön ugyanaz legyen a nullpont, hogy tudjam egyes esmények időpontját egymáshoz képest mérni. A dobozokat nem tudom még kb. se egyszerre bekapcsolni, hogy kb hasonló legyen a millis(), de nem is a hasonlóság a cél: pont azt szeretném, hogy a RF link APIjának sebességét mérjem különböző setup-ok mellett.

P.s.: mikor tűnt el a közvetlen beküldés (előnézet nélkül)?

Ötlet?

Hozzászólások

Ha elég pl. a másodperces pontosság, akkor 1 RTC modul adja magát minden csomópontra, ebből pl a DS3231 elég pontos, szóval 1x beállítod aztán X ideig relatív pontos lesz.

A másik ötletem egy dedikált időszinkron eszköz, ami lehetne mondjuk egy ntp-s rpi, amire ráaggatod ezt az rflinket, és ez semmi mást nem csinál, csak pl. 5 másodpercenként küld egy szinkronjelet, amit vesz az összes eszközöd, eltárolja az akkori millis() értéket, és ez a baseline. Minden eszköz bekapcsolás után X ideig csak figyel, és ha megvan a timesync akkor kezd el dolgozni, egyébként pl. 1 perc után felkapcsol egy timesync error LED-et. Ehhez persze kell egy RF szünet a többi adónak is, pl. minden vett timesync után 4995-5005 ms között csendkirályt játszanak és várják a szinkronjelet.

A közvetlen beküldést pár hete okozta trey, valakivel szájkaratéztak valamelyik topic-ban aztán ez lett belőle (a részletekre már nem emlékszem, szerintem nem is fontos).

fejbol, kb. (nincs elmentve)
Par levelezoprogiban volt egy hiba, hogy ha titkositott html darabkakat kuldtel neki, azt o dekodolta, es ezt ki lehetett nyerni beloluk. Erre irta trey, hogy milyen hulyek, hogy html darabkakat csak ugy osszefuz, minden ellenorzes nelkul, - talan - Egmont meg erre irt egy lezaratlan tag-et, demonstralva, hogy ezt a drupal is megteszi. Erre trey besertodott, hogy akkor mostantol kotelezo elonezet, es ellenorizd, hogy nincs-e lezaratlan tag, mert a drupalba beallitani/fixalni/upgrade-elni nagyobb macera lenne.
Ha valaki szeretne, belinkelheti, de kb. ennyi volt a lenyege.

--
When you tear out a man's tongue, you are not proving him a liar, you're only telling the world that you fear what he might say. -George R.R. Martin

Azt hittem ezt az elonezetes dolgot mindenki ugy hasznalja, hogy:
hozzaszolas -> elonezet -> [gepelsz] -> bekuldes

Magyaran az elejen kattintasz kettot. Sokkal jobb, mintha a vegen nem menne el, ha szar a net.

---
Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

"A közvetlen beküldést pár hete okozta trey, valakivel szájkaratéztak valamelyik topic-ban aztán ez lett belőle (a részletekre már nem emlékszem, szerintem nem is fontos)."
- jól ki is maszott ezzel kb a teljes kollektívával...

--
"Nem akkor van baj amikor nincs baj, hanem amikor van!"
Népi bölcsesség

Hát... ezredmásodpercre kellene szinkronizálniuk magukat úgy, hogy az RF link sebessége nem ismert?

De csak relatív időt. Az ezred másodperc azért nem olyan rövid. Két eszköz ezredmásodperc pontossággal össze tudja magát szinkronizálni.

Mindegyik eszköz azzal kezdi, hogy sorban egymás után felveszi a kapcsolatot a többi eszközzel, s mindegyikkel átlagolják a saját relatív idejüket.
Ha már minden eszközzel azonos a relatív ideje, akkor beállítja magánál, hogy az idő szinkronban van.
Majd megnézi, hogy a többi eszköz ideje is szinkronban van-e. Ha igen, kész. Ha nem, kezdi előröl.

Ha tobben vannak, akkor azert ki lehet szurni a random delay-t, ami altalaban nem is annyira random:)

Van 3 csomopontunk: Ászok, Borsodi, Corona

Aszok legyen a fonok o inditja az akciot.
Az egyszeruseg kedveert amikor az Aszok inditja az akciot, akkor a belso oraik:
Aszok = 0sec
Borsodi = 10sec
Corona = 20 sec

Aszok kuld egy idokerest Borsodinak és a valaszt elmenti: Igy az Aszok <-> Borsodi valaszido ismert (Á->B + B->Á)

Amikor Borsodi megkapja a kerest, o is kuld egy kerest Coronanak, igy
Borsodi<->Corona valaszideje is ismert

Amikor Corona megkapja a kerest, akkor elkuldi Aszoknak. Ekkor Aszok rogton visszakuldi, es a kort masik iranybol is bejarjuk (A->C, C->B, C<-B, B->A)

Mindegyik keresbe beleirjak a sajat orajuk allapotat.

Amikor Aszok megkapta mind a ket iranybol a valaszokat, akkor el tudja kuldeni Borsodinak es Coronanak is, hogy mennyit huzzanak az orajukon.

Ebbol ki lehet matekozni, szerintem 100ms-on belul ossze lehet ezt loni.

Update:
Megneztem az NTP protokollt. Hat ez ennel sokkal egyszerubb. Kikialtanak a cuccok egy fonokot (ntp server), es mindenki ohozza allitja az orajat.
A fenti példánál maradva Ászoknál az idő legyen 17:47:02.

Mindenki beállítja 17:47:02-re. Nyilvánvalóan sz*r lesz:
Ászok: 17:47:10
Borsodi: 17:47:12
Corona: 17:47:13

Mostmár, hogy majdnem jó az órájuk, így finoman össze lehet hangolni:
Borsodi(17:47:30-kor) küld egy kérést, megkapja 17:47:31-kor(B), 17:47:29-as(A) értékkel.
Akkor az ő órája: 17:47:29 + roundtrip idő/2, ami 17:47:29 + 0.5 = 17:47:29.5

És ezt ismétli párszor, a hibát mindig beleszámolja (feedback loop).

A lebutitott protokoll meg kb. igy nezne ki:
Ászok küld egy broadcast üzenetet, hogy ennyi az idő.
Majd mindegyik a fenti eljárással finomhangolná a saját óráját.

---
Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

"Két eszköz ezredmásodperc pontossággal össze tudja magát szinkronizálni."

Azért ez nem volt olyan triviális régen. Az SNTP (Simple NTP, Windows server 2000 idején) csak másodperc-pontos időszinkront tudott, ha sub-second precision kellett, használj külső NTP szolgáltatást. Azóta 2003 server már tudja a rendes NTP-t, de a millisecond pontosság attól függ, milyen messze vagy egy valódi stratum 0-tól (atomóra).
--

Ha megvan a rádió típusa, annak az adatlapján esetleg találhatsz infót a késleltetésre.

Amikor össze van rakva a cucc, a következők lehetségesek:
* Drótos óraszinkronizáció induláskor úgy, hogy összekötöd őket. Az AVR csip Input capture-jét felhasználva egy felfutó él időpontját egy órajel pontossággal le lehet olvasni, így kb két órajel pontosságon belül lehet időt szinkronizálni két Arduino között. Órajelre pontosan kiadni élet pedig a számlálóhoz tartozó PWM alrendszerrel lehet például a 0 értéknél felfutó élet kiadni. Én a Timer1-et használnám erre, mert az 16 bites, a csip 16MHz-jával járatva sem lesz túl sűrű az overflow, értelmesen lehet interrupttal kezelni. Nem tudom, hogy van-e hozzá Arduino lib, de a csip tudja az tuti. (Datasheeten: 20.9. 16 Bit Timer/Counter1 - Input Capture)
* Akár drótos a kezdeti sync, akár egyből rádiós, a meglévő óraprotokollokat érdemes tanulmányozni. Időbélyeges üzenetekkel Ping-pong-ozva ki lehet mérni az oda-vissza küldés késleltetését. Ha szerencséd van, összesen is elég kicsi lesz a mért érték. Ha nincs szerencséd, és túl nagy, akkor elvileg nem lehet megmondani, hogy a késleltetésből mennyi hova esik, de azért a gyakorlatban feltételezheted, hogy a két egyforma rádiód késleltetése legalább átlagban ugyanannyi. És így sok méréssel tudod szinkronizálni az órákat.
* A mérésnél számolni kell azzal is, hogy az Arduinok órajelét adó kvarc rezgőkörök sem teljesen egyformák, specifikáció szerint van némi eltérésük, meg hőmérsékletfüggésük is. Ha már csinálsz mérést ezt is kimérheted. Ha kellően kicsi lesz a rádió jitter-je, akkor ezt akár kompenzálni is lehet, ha nagyon nagy pontosság kell.
( * Nem érdemes a millis-t beállítani, hanem egy eltolást kell tárolni)
* Az Arduino millis a Timer0-ra épül, ami csak 8 bites számláló. Az átfordulásokat pedig egy interruptban számolja. Nem tudom mi a prescaler értéke, de ha olyan libet használsz, ami túl sokáig blokkolja az interruptokat, akkor a millis elcsúszhat! Például a SoftwareSerial csinálhat ilyen mókát. (Azért tudom, mert épp ilyet tervezek, hogy XBee rádióval kommunikálok Arduino-k között úgy, hogy SoftwareSerial van az XBee és az Arduino között és ezért utána olvastam.)