mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Unidirektionale Datenübertragung, 1 Leitung, kein Quarz


Autor: Egberto Gismonti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Bensch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein

1 Leitung mit Quarz ja, 2 Leitungen ohne Quarz ja.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: 6640 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OneWire Bus.

Autor: Luther Blissett (luther-blissett)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Egberto Gismonti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Egberto Gismonti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, habs verstanden.. ich muß aber Binärdaten übertragen??

Autor: Alexander Schmidt (esko) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Luther Blissett (luther-blissett)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Egberto Gismonti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat denn jemand einen einfachen Codeschnipsel zur unidirektionalen 
Übertragung mit Machester-Code (in C)?

Schon mal vielen Dank

Autor: Egberto Gismonti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
**nach oben bring**

Keiner je sowas programmiert?

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: nixwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie zeitkritisch ist eigentlich oneWire? Also wieviel % darf das Timing 
abweichen, damit man noch sicher übertragen kann?

Autor: Egberto Gismonti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Esko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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/Softwa...

Autor: Luther Blissett (luther-blissett)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
// wartet auf die nächste Flanke (egal welcher Richtung)
// gibt zurück wie lange das gedauert hat. 
unsigned wtf(); 

// Aufzurufen, wenn das Startbit sichtbar wird, am Eingang liegt 1 an.
void receive()
{
 bool bit=0; 
 unsigned t = wtf();  // länge des 1-er Puls
 while (1)  
 {
  unsigned tx=wtf();
  if (eps(tx,t)) 
   { 
     tx=wtf(); 
     if (eps(t,tx)) 
        {
        output(bit);
        t=(t+tx)/2; // der Drift folgen
        } 
     else 
        error();  
   }
  else if (eps(tx,2*t)) 
    {  
      bit=!bit; 
      output(bit);
      t=(2*t+tx)/4; // der Drift folgen
    }
  else error();
 }
} 
eps(x,y) ist Vergleich mit akzeptabler Fehlermarge.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jan Enenkel (Firma: Austriamicrosystems AG) (jankey)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
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

Autor: Luther Blissett (luther-blissett)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Marco S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Winfried (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.