Hallo Forum, ich möchte Daten in einer Richtung von uC zu uC übertragen und möglichst nur eine Leitung dafür verwenden. Der empfangende ATTiny hat keinen Quarz! Die Leitung sollte ein paar (<10) Meter lang sein können und mehrere Attinys sollten dran hängen können (Adressierung kriegen wir später ;-). Was kann man da leicht implementieren (in C)? Grüße, Egberto
nein 1 Leitung mit Quarz ja, 2 Leitungen ohne Quarz ja.
Hallo, mehrere 01 am Anfang schicken zum Syncronisieren, dann eine Präambel um den Anfang zu erkennen, dann die Daten mit Prüfsumme. Wenn es nicht verloren gehen soll, mehrmals schicken. Die Kurzzeitstabilität sollte da ausreichen, wenn die Datenpakete nicht zu groß werden, sonst eben neu syncronisieren. Sollte eigentlich gehen... Gruß aus Berlin Michael
Egberto Gismonti wrote: > ich möchte Daten in einer Richtung von uC zu uC übertragen und möglichst > nur eine Leitung dafür verwenden. Der empfangende ATTiny hat keinen > Quarz! Ja, ist kein Problem. Man kann die Baudrate automatisch ermitteln. Hier ein Beispiel (Anhang 12. Beitrag): Beitrag "LCD über nur einen IO-Pin ansteuern" Peter
Mit einer genugend tiefen Baudrate is das schon moeglich. Denkbar ist eine positive flanke zu detekieren, und eine Zeit danach (zB 100us)das Bit zu sampeln.
Du könntest drei verschiedene Zustände auf der Leitung verwenden. Wenn du dann S0,S1,S2 hast, dann zeigt jeder Zustandswechsel clock an und die Richtung des Wechsels data. Also S1->S0:0 S1->S2:1 S0->S2:0 S0->S1:1 S2->S1:0 S2->S1:1 Jetzt suchst du dir Zustände aus, die du gut implementieren kannst, z.B. -5V,0V,5V oder 0V,5V,hochohmig
@Peter Danneger Hallo Peter, sieht so aus, als wäre es das, was ich brauche (vielen Dank!). Ich habe noch ein Verständnisproblem: lt deiner Doku setzt man mit 0x13 + Zahl die Baudrate - ich dachte, das ist autobaud?? Grüße, Egberto
ok, habs verstanden.. ich muß aber Binärdaten übertragen??
Luther Blissett wrote: > Jetzt suchst du dir Zustände aus, die du gut implementieren kannst, z.B. > -5V,0V,5V oder 0V,5V,hochohmig Und wie soll hochohmig erkannt werden bei? Zumal bei mehreren Empfängern.
Manchester-Code funktioniert auch über eine Leitung ohne Quarz, da sich der Empfänger auf die Flanken synchronisieren kann. Die Fenster können mit einer Toleranz von bis zu 20% sicher ausgewertet werden.
Alexander Schmidt wrote: > Luther Blissett wrote: >> Jetzt suchst du dir Zustände aus, die du gut implementieren kannst, z.B. >> -5V,0V,5V oder 0V,5V,hochohmig > > Und wie soll hochohmig erkannt werden bei? Zumal bei mehreren > Empfängern. Ein Spannungsteiler für den ganzen Bus bringt die hochohmige Leitung auf 2.5V könnte ich mir vorstellen. Wenn man es richtig dimensioniert, dann müssten die slaves eventuell sogar den dritten Zustand detektieren können indem sie ihre internen pullups aktivieren/deaktivieren.
Hat denn jemand einen einfachen Codeschnipsel zur unidirektionalen Übertragung mit Machester-Code (in C)? Schon mal vielen Dank
**nach oben bring** Keiner je sowas programmiert?
Hallo, ich bisher nicht, aber z.B. wohl alle Leute, die einfache Funkmodule benutzen. Da werden üblicherweise die Daten Manchester-codiert in den Sender geschoben und aus dem Empfänger wieder rausgeholt... Man kann durchaus sagen, daß jede Funkstrecke Sender-Empfänger eine 1-Draht Verbindung ist, noch dazu mit dem Nachteil vorkommender Wackelkontakte ;-) Gruß aus Berlin Michael
Wie zeitkritisch ist eigentlich oneWire? Also wieviel % darf das Timing abweichen, damit man noch sicher übertragen kann?
Das Problem bei 1-Wire ist 1. Auf der Empfängersoftware liegt ein Copyright (oder Patent was auch immer) 2. sehr "strammes" Timing Scheint für meinen Zweck ungeeignet. Grüße, Egberto
> Das Problem bei 1-Wire ist > 1. Auf der Empfängersoftware liegt ein Copyright (oder Patent Ist davon auszugehen, dass du deine Schaltung komerziell verwerten willst? Falls nein braucht dich das Patent nicht zu kümmern.
Es gibt Verfahren zur Datenübertragung über eine Leitung, die nicht so taktempfindlich sind. z.B. das Morse-Verfahren: Kurz, Lang, Lang, Kurz, Lang ... Dann kann man sehr gut eine Datenübertragung mit nur 2 Pegeln realisieren. http://www.roboterclub-freiburg.de/AtmelAVR/Software/chEinAnschlussKom_V1.0.c.zip
Egberto Gismonti wrote: > Hat denn jemand einen einfachen Codeschnipsel zur unidirektionalen > Übertragung mit Machester-Code (in C)? > > Schon mal vielen Dank Naja, wenn das Verfahren verstanden hat, sollte es kein Problem sein das zu kodieren. Senden - Du schickst einfach (clock xor data) auf den Draht. Damit sich der Empfänger leichter synchronisieren kann, schickst du am besten am Anfang einer Nachricht noch eine 0 als startbit vorraus. void sendbit(bool b) { put(!b); delay(); put(b); delay(); } Empfänger - Der Empfänger misst einfach die Zeit von Flankenwechsel zu Flankenwechsel. Da der Sender eine Start-0 mitgeschickt hat, bekommt er gleich eine ansteigende Flanke der Länge t (die dem delay() entspricht). Wenn du dir jetzt z.B. das Manchester Code Beispiel auf Wikipedia anschaust, dann siehst du, daß ein Puls der Länge 2*t nur dann vorkommt, wenn sich das Datenbit ändert. Ansonsten bekommst du zwei Pulse der Länge t. Ohne Gewähr hingehackt:
1 | // wartet auf die nächste Flanke (egal welcher Richtung)
|
2 | // gibt zurück wie lange das gedauert hat.
|
3 | unsigned wtf(); |
4 | |
5 | // Aufzurufen, wenn das Startbit sichtbar wird, am Eingang liegt 1 an.
|
6 | void receive() |
7 | {
|
8 | bool bit=0; |
9 | unsigned t = wtf(); // länge des 1-er Puls |
10 | while (1) |
11 | {
|
12 | unsigned tx=wtf(); |
13 | if (eps(tx,t)) |
14 | {
|
15 | tx=wtf(); |
16 | if (eps(t,tx)) |
17 | {
|
18 | output(bit); |
19 | t=(t+tx)/2; // der Drift folgen |
20 | }
|
21 | else
|
22 | error(); |
23 | }
|
24 | else if (eps(tx,2*t)) |
25 | {
|
26 | bit=!bit; |
27 | output(bit); |
28 | t=(2*t+tx)/4; // der Drift folgen |
29 | }
|
30 | else error(); |
31 | }
|
32 | }
|
eps(x,y) ist Vergleich mit akzeptabler Fehlermarge.
Egberto Gismonti wrote: > Das Problem bei 1-Wire ist > 2. sehr "strammes" Timing Das würd ich nicht so sehen: Nach dem kurze Low Impuls sampled der Empfänger in einem recht breiten Zeitfenster. Laut Datenblatt liegt dieses Fenster 15-45µs nach dem vom Master erzeugten Impuls. Selbst mit 50% Taktabweichung sollte Onewire also noch funkionieren.
versuchs doch mal damit, wenn 2 Systeme nicht Absolut genau zueinander sind, is es vl. in einem gewissen Maße Relativ genau. versuchs mal mit: 1/3 LOW + 2/3 HIGH = 1 2/3 LOW + 1/3 HIGH = 0 also du hast einen zähler und zählst einfach wieviele clock pulse high sind und wieviele low sind. dann schaust du welche der beiden größer ist ob hightime oder lowtime. Wenn die Hightime länger war ist eine 1 übertragen worden. und bei Lowtime > Hightime --> 0 Übertragen worden, also mit zb 15~20 Clock zyklen pro Bit funktioniert das schon wirklich sehr gut. Meiner ansicht nach der beste weg um Asnychronität auszugleichen. lg
Gehtdich Nixanduspammbot wrote: > also du hast einen zähler und zählst einfach wieviele clock pulse high > sind und wieviele low sind. dann schaust du welche der beiden größer ist > ob hightime oder lowtime. Wenn die Hightime länger war ist eine 1 > übertragen worden. und bei Lowtime > Hightime --> 0 Übertragen worden, > also mit zb 15~20 Clock zyklen pro Bit funktioniert das schon wirklich > sehr gut. Meiner ansicht nach der beste weg um Asnychronität > auszugleichen. > > lg Das ist auch eine schöne Idee. Wenn man unterschiedliche Pegellängen benutzt, dann kann man auch auf beiden Flanken Daten übertragen. Man sendet zunächst ein Synchronisationszeichen. Wenn der darauffolgende Pegel die gleiche Länge t hat, dann wird 0 kodiert. Hat er eine andere Länge, dann 1. Die andere Länge könnte z.B abwechselnd t*3/2 und t*1/2 sein, so daß die mittlere bitrate erhalten bleibt.
Die Synchonisation-Aktion kann man sich doch sparen, wenn man die Bits über ein bestimmte Periodenlänge verteilt, und die Information ob 1 oder 0 über die Pulslänge realsiert. Dann bräuchte man nur die Puls- und die Periodendauer (per ICP) messen und könnte aus dem Tastgrad den Bitwert feststellen. So ähnlich arbeiten Modellbaufernsteuerungen ja auch.
Hallo. Von den ganzen Einleitungsbussen gibts von TI einen, der sich HDQ nennt. Diesen habe ich mal im wesentlichen kopiert. Der Bus überträgt die Daten bitseriell, mit einem 10us-Low als "1" und 30us-Low als "0", bei einer minimalen Zykluslänge von 80us. Für die Rahmensynchronisation wird dem Ganzen ein 60us-Low vorangestellt, und der Frame mit ACK/NACK bestätigt. Dazu habe ich einen ext. Interrupt auf fallende Flanke getriggert. Im Interrupt wird 80us lang ein Schleifenwert erhöht, solange der PIN low ist. Die Auswertung des Zählerstandes führt zu High/Low/Break. Gemacht habe ich das, weil es auf die Datenrate nicht ankam. Zudem ist der Bus unempfindlich gegenüber Glitches, die nach der fallenden Flanke kommen (war bei mir durch einf. opt. Isolation mit Optokoppler der Fall).
Der Manchester ist ziemlich aufwendig in Software und braucht ne Synchronisation (bekanntes 1.Bit). Wenn man dessen Vorteil der Gleichspannungsfreiheit nicht braucht, sollte man ihn daher nicht benutzen. Wennn man keine Lust hat, ne Software-UART mit automatischer Baudratenerkennung zu verwenden, bietet sich die Impulslängenmodulation an, z.B.: 4*T = Startbit 2*T = 1-Bit 1*T = 0-Bit Vorzugsweise wählt man T so, daß ein 8Bit-Timer im Empfänger nach 3*T überläuft und der Comparator auf 1,5*T vergleicht. Im Flankeninterrupt setzt man ihn zurück auf 0 und wertet diese beiden Flags aus. Peter
Falls jemand HDQ interessiert: http://focus.ti.com/lit/an/slva101/slva101.pdf http://focus.ti.com/lit/ds/symlink/bq2014h.pdf
chris schrieb: > http://www.roboterclub-freiburg.de/AtmelAVR/Softwa... Hallo Chris, in meinem Thread: Beitrag "Re: mehrere MC seriell über Datenbus verbinden (1Draht)" hast Du geschrieben, daß Du 360KBit/s erreichst. Ich habs mir daraufhin mal angesehen. Also ich komme nur auf 1/(2*18,75µs) = 26,7kBit für 0-Bits bzw. 17,8kBit für 1-Bits. Ich verstehe auch nicht, wie sich der Slave auf den Empfang synchronisieren kann, bzw. überhaupt mitkriegt, daß der Master sendet. Es kann doch nicht sein, daß der Slave keine Main-Task machen kann, sondern immer nur auf den Empfang wartet. Und was passiert, wenn der Master schon ein Bit gesendet hat, ehe der Slave auf Empfang geht? Wie erfolgt eine Störerkennung bzw. Resynchronisation? Die Prämisse bei meinem Code liegt nicht auf Geschwindigkeit. Sondern der Slave soll nicht bei seiner Task behindert werden und auch eigene Interrupts ausführen können. Er macht also seine eigenen Aufgabe völlig unabhängig vom Master. Und erst, wenn der Master was will, adressiert er den Slave. Die Kommunikation darf die eigentliche Aufgabe nicht stören oder verzögern. Auch muß die Kommunikation nach einer Störung wieder alleine aufsetzen können. Peter
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.