I2C-Hardcoremagistrale 150m entstoeren :-)

Uwe H.

Neues Mitglied
27. Juli 2011
264
0
0
Hinter die Grenze :-)
Sprachen
  1. BascomAVR
  2. ANSI C
  3. Assembler
Hallo zusammen :)
Vor vier Wochen haben wir mal wieder eine Messanlage in einer Passiv-Sporthalle fertiggestellt. Die Anlage umfasst neben einer Wetterstation ca. 70 Temperatur- und Feuchtigkeitssensoren, die die Energiegewinne und -verluste durch die Bauphysik, Ventilation, etc. erfassen. Da ich mal was Neues testen und ein paar Grenzen ueberwinden wollte, haben wir uns fuer I2C als Hauptmagistrale bei ueber 150m Kabellaenge entschieden. Damit wollte ich mal den "I2C eignet sich nur fuer 30cm-Leuten" mal ein paar Denkansaetze liefern :) Nach anfaenglichen Stoerungen durch die Wechselrichter im Ventilationsraum funktioniert das System sogar hervorragend :) Einziger Knackpunkt ist der, das ab und zu ein Kommunikationsfehler das System aufhaengt. Leider weiss ich nicht, wo genau er sich aufhaengt. Der Fehler macht sich dadurch bemerkbar, dass die SDA auf Null bleibt, SCL ist high (Master wartet auf ACK vom Slave?).

Wie kann man in dem Fall das System wieder stabil bekommen, ohne VCC-Reset? Hab ein I2C-Stop ueber Timer versucht, klappt nicht. Im Moment hilft nur ein kompletter Reset ueber die Netzversorgung, was aber nicht im Sinne des Erfinders ist.


Aufbau des Systems:

- Ein Mastercontroller (Atmega32) + 15 Slave-Stationen (Atmega8) an unterschiedlichen Messpunkten
- Bustreiber P82B96 an jedem uC, Busspannung 12V, 2kHz Geschwindigkeit,
- Ethernetkabel, geschirmt, SCL mit VCC gedrillt, SCA mit GND
- Masterprogramm nutzt die Standard-I2C-Kommandos, Slaves arbeiten direkt mit dem TWI-Statusregister.


Mehrere Oszilloskopmessungen ergaben saubere, klare und steile Flanken, kein nennenswertes Delay zwischen SCL und SDA bei Uebertragung zur entferntesten Slavestation, keine Spikes oder Stoersignale in der Leitung. Bei einer Messung mit dem Logikanalysator hab ich allerdings mehrmals eine "Bitverschiebung" um eine Stelle beobachten koennen, was durchaus die Ursache sein koennte. Hat jemand eine Idee, wie man angemessen auf die Sache reagieren koennte?


Gruesse, Uwe


P.S.: Bitte keine Texte in Form von "Du hast ja nen Schaden, I2C ist fuer 30cm ausgelegt :stupid:". So wie alle kanns ja jeder machen, wo liegt den da der Reiz :victory:
 
Hallo Uwe,

Oszilloskopmessungen decken nicht immer alles auf, siehst du ja am Ergebnis mit deinem Logik-Analysator ;) Bei langen Leitungen musst du mit den Pullup-Widerständen "spielen" und hier macht sich auch der Leitungsabschluss mehr bemerkbar, das ist ziemlich schwierig und problematisch. Selbst wenn es jetzt so funktionieren sollte, wäre es mir zu unsicher.

Schau dir vielleicht einmal folgende Seite an:
http://ics.nxp.com/products/i2chubs/

Dirk :ciao:
 
Gruess Dich Dirk :)

Keiner hat gesagt, dass es einfach wird :) Ich hab gelesen, dass man bei hohen Leitungslaengen die Teilnehmer ueber 330Ohm in Serie zum Bus schalten sollte und die fallende Flanke sollte eher weich ausfallen statt zu schnell. Irgendjemand setzt auch Terminierungswiderstaende wie bei RS485 ein. Was haelst Du davon?
 
Hallo Uwe,

Ich hab gelesen, dass man bei hohen Leitungslaengen die Teilnehmer ueber 330Ohm in Serie zum Bus schalten sollte und die fallende Flanke sollte eher weich ausfallen statt zu schnell. Irgendjemand setzt auch Terminierungswiderstaende wie bei RS485 ein. Was haelst Du davon?

Bei I2C hast du einen Bus der nicht aktiv getrieben wird. Die Chips ziehen die Leitung nur nach GND. Auf High (Vcc) wird die Leitung über die PullUps gezogen die auch gleichzeitig ne Art Abschlußwiderstand sind.

Beim RS485 hast du Treiber die aktiv die Leitung auf +12V oder -12V zwingen. Der Abschlußwiderstand erzeugt einen definierten Stromfluß und soll Reflektionen am Bus-Ende verhindern.

Es sind also zwei verschiedene Arten.

Der 330 Ohm in Reihe soll wohl verhindern das der Bus bei der Länge zu stark belastet wird und auch die SlewRate verändern. Die Flanke soll also weniger steil ausfallen. Damit hat man weniger Oberwellen die dann auch weniger Übersprechen von SDA auf SCL oder umgedreht erzeugen. Damit hat man auf beiden Leitungen sauberere Signale.

Die Leitungslänge bildet auch eine nicht zu unterschätzende Kapazität die mit den PullUp-Widerständen und den bauteilbedingen Widerständen in den Ausgangstreiber einen Tiefpaß bildet.

SCSI ist ähnlich wie RS485 ein aktiv getriebener Bus. Der Abschlußwiederstand wird bei einer größeren Länge lieber aktiv gemacht. Also mit einer Stromquelle pro Leitung die den Pegel sanft etwa auf halben Logikpegel zieht. Damit muß der Treiber nicht mehr so sehr gegen die Leitungskapazität anarbeiten. Ob es sowas jedoch auch für I2C gibt weiß ich aus dem Kopf nicht.

Wie hoch ist denn deine Bitrate/Taktrate auf dem Bus?

Gruß
Dino
 
Hallo Uwe,
Ich hab gelesen, dass man bei hohen Leitungslaengen die Teilnehmer ueber 330Ohm in Serie zum Bus schalten sollte und die fallende Flanke sollte eher weich ausfallen statt zu schnell. Irgendjemand setzt auch Terminierungswiderstaende wie bei RS485 ein. Was haelst Du davon?

es gibt hier unterschiedliche Möglichkeiten, den BUS zu optimieren. Leider geht das bezüglich
- Störimmunität
- Geschwindigkeit
- Treiberfähigkeit
nicht immer in die selbe Richtung und hier wirst du auch sicher viel im Internet lesen können (... du musst halt sehen, was du davon für dich verwerten kannst/solltest :))


Wenn ich von A nach B möchte und dafür die Autobahn nutze, fahre ich nicht mit dem Fahrrad, wobei es damit auch geht, wenn ich gaaaaanz schnell trete und immer ganz rechts bleibe ;)
Meine Meinung: nehme besser ein Auto für die Autobahn

Dirk :ciao:
 
Ich glaube, für diesen UseCase würde ich CAN nehmen, da hat man auch die Ausfallsicherheit geschenkt, wenn man CAN LowSpeed nimmt.

CAN bei 125kBit (als LowSpeed) hat eine Buslänge von 530m. :)
 
Sicher kann man CAN oder irgendwas in der Richtung nehmen, aber gerade das wollte ich ja nicht :) Hier gehts mehr um ein persoenliches Experiment.

@Dino: Taktrate ist 2kHz
 
Hallo Uwe,
also 2 KHz und 150m klingt für mich nicht unlösbar, Reihenwiderstände können unter bestimmten Bedingungen Besserung bringen, halle vor vielen vielen Jahren mal ein Anpassungsproblem (Adapterkarte an einem Z80-Bus).
Da hab ich mir dann einfach einen IC-Sockel dazwischen gelötet und mit verschiedenen Widerstandswerten experimentiert. Die Signale solltest du nicht nur am Anfang und am Ende des Busses prüfen, Probleme können auch mitten drin auftreten. Evtl. bringen Widerstände aber nichts (positives), schau dir mal als Idee die Beschaltung von einem DS1820 (1wire) an, hier gibt es eine Beschaltung mit einem zusätzlichen FET bei langen Leitungen, kannst du sicher nicht 1:1 übernehmen, aber als Idee ...

Gruß
gp177
 
Hallo Uwe!

Ich habe mit den P82B96 zwar auch nicht so viel gearbeitet, aber generell sehe ich in deinen Eckdaten jetzt auch kein Problem.
Weder die Länge der Leitung, noch die Taktfrequenz würden mich jetzt stutzig machen.

Der beste Ansprechpartner dafür wäre aber wohl StevieL, weil er schon einiges mit den P82B96 gemacht hat.


Trotzdem möchte ich dir als Tipp noch einmal das Datenblatt ab Seite 9 ans Herz legen.
Gerade den Bereich mit der Leitungskapazität würde ich noch mal genau beachten.

Außerdem meine ich mal etwas zum Leitungstyp gelesen zu haben und da wurde speziell eine normale JYSTY-Leitung erwähnt.
Von einer Ethernetleitung (geschirmt oder ungeschirmt) wurde abgeraten.

Vielleicht solltest du einfach mal ein oder zwei andere Pärchen in der Leitung verwenden.
Die Verseilung der Paare ist ja bewusst unterschiedlich und hat damit z.B. auch verschiedene Kapazitätswerte.


Ach so......
Hast du softwareseitig einfach mal zur Probe die Delayzeit geändert?
Ich würde die testweise einfach mal über das "Cable-Delay" setzen, ODER
genau das Gegenteil testen.
Laut Datenblatt kannst du bei 250m Leitung den effektiven Bustakt auf 120kHz setzen.


Wie aber oben schon mal erwähnt....
ggf. hat StieveL noch genauere Infos dazu.


Grüße,
Cassio
 
@gp177:

Geht es Dir um sowas wie "aktive Pullups"? Die Variante gibts auch in der Dokumentation vom P82B96 (wenn ich mich nicht irre). In einer anderen Halle haben wir vor zwei Jahren eine Magistrale mit 130 DSen von knapp 500m in Betrieb genommen. Pullup an SQ war glaub ich irgendwas im die 1,8 Ohm. Funktioniert bis heute tadellos ohne FETs. 1wire ist genial, nur gibts zuwenig Chips auf dem Euromarkt und staendig werden gute Chips von Dallas abgekuendigt.

Nochmal zu meinem Problem:

Ich bin mir nicht sicher, ob man mich hier richtig verstanden hat, deshalb moechte nochmal drauf hinweisen, dass das System mit I2C auf 150m zu 99,999% einwandfrei und fehlerfrei laeuft.
Alle Knotenpunkte wurden mehrfach mit dem Oszilloskop auf Stoerungen und Einstreuungen geprueft, Kabel wurden beim Bau der Halle bereits von mir weit weg von etwaigen Stoerquellen verlegt. Es liegt definitiv keine Einstreuung oder aehnliches vor.

Ich denke eher, dass es mit den Pullups zusammenhaengt. Obwohl das merkwuerdig ist, weil wenn sich die Muehle einmal in der Woche aufhaengt, dann meist bei der Slavestation 1. Die ist am Ende vom Bus und hat einen Satz Pullups.


@Cassio

Bei 2kHz Taktung sollte eigentlich die Leitungskapazitaet von 150m keine nennenswerte Rolle mehr spielen. Ein Delay beim Ansprechen des letzten Slaves zwischen gesendetem SCL-Takt und empfangenem SDA-Takt konnte ich mit dem Oszi nicht feststellen, aber scheinbar kommt es ab und zu vor und haengt mein System auf. Schade, dass man die Kommunikation nicht einfach ueber den Logikanalysator mehrere Tage aufzeichnen kann. Dann wuesste ich, was da abgeht. Im Masterprogramm ist I2Cdelay mit 255 deklariert. Fuer die Ethernetleitung hab ich mich aufgrund positiver Erfahrungen mit der frueheren Halle entschieden. Kapazitaet ist gering und der Schirm ist notwendig, weil die Kabel teilweise durch die Ventitatorraeume gehen (Wechselrichter) und streckenweise mit 20cm Abstand neben der Hauptstromleitung (125Amps). Das lies sich leider nicht vermeiden, aber wie gesagt, auf dem Oszi ist das Signal an allen Knotenpunkten glatt wie ein Babyhintern.
 
Hallo Uwe,

wenn du den Fehler in Richtung der Pullups vermutest
kennst du sicher die Beschreibung "Active Termination of I2C"
in der BASCOM-AVR Hilfe:
Reiter Inhalt, BASCOM HARDWARE, Using the I2C protocol.

Gruß
Biker
 

Anhänge

  • Active_Termination_of_I2C.PNG
    Active_Termination_of_I2C.PNG
    23,9 KB · Aufrufe: 18
Hi Uwe,

Schade, dass man die Kommunikation nicht einfach ueber den Logikanalysator mehrere Tage aufzeichnen kann. Dann wuesste ich, was da abgeht.

der LA kann auch auf bestimmte Trigger reagieren. Leider kann er wohl nicht im Ring arbeiten (also mit Ringbuffer). Kannst du dem Atmel nicht auf nem Pin sagen das er bei nem Fehler den Pegel ändern soll? Dann kannst du doch mit dem LA drauf triggern und hast ne Messung.

Mein Hameg-Scope könnte als Ringpuffer laufen und hat dann Bereiche im Puffer für Pre- und Posttrigger damit man auch sieht was vor dem Ereignis war.

Wenn du zB nen Stillstand sehen willst, dann könntest du im Programm nen Port toggeln lassen. Den legst du dann auf einen Tiefpaß (RC-Glied). Wenn der Port dann auf Vcc oder GND stehen bleibt sollten am RC-Glied Vcc oder GND rauskommen und keine halbe Versorgungsspannung. Darauf könnte man doch auch irgendwie mit ner Schaltung triggern (Stichwort Fensterdiskriminator).

Gruß
Dino
 
...der LA kann auch auf bestimmte Trigger reagieren. Leider kann er wohl nicht im Ring arbeiten (also mit Ringbuffer). Kannst du dem Atmel nicht auf nem Pin sagen das er bei nem Fehler den Pegel ändern soll? Dann kannst du doch mit dem LA drauf triggern und hast ne Messung...
reicht denn das, was er (der LA) vor dem Trigger aufgezeichnet hat dazu aus? Kann grad (beim Logic8) nicht nachsehen, wieviel das ist.
 
@biker
Danke fuer den Hinweis, dass Schema kannte ich noch nicht.

@Dino
Man muesste die letzte Transmission vor dem Stillstand einfangen. Genau da liegt das Problem, denn da gibts noch nichts, worauf man triggern koennte. Der einzige Weg, der diesbezueglich fuer mich sinnvoll erscheint, waere, die Standardkommandos wegzulassen und (wie bei den Slaves) direkt ueber die Register steuern und regeln. Wenn das Statusregister dann anfaengt Muell zu registrieren, kann man das als Fehlercode ins EEPROM schicken. Vorausgesetzt, er tritt nicht im kritischen Moment auf. Die Kommunikation sieht folgendermassen aus:

I2Cstart
I2Cwbyte &H10 (Slave Nr. 1)
I2Cwbyte &HCC (Messung starten, jaaaaa genau wie beim Dallas, ich mags gern standardisiert :)) )
I2Cstop

Wartezeit

I2Cstart
I2Cwbyte &H11
I2Crbyte Confirmation, Ack (Hier schickt der Slave seine R-Adresse (&H11) zurueck zur Bestaetigung)
I2Crbyte Data1, Ack
I2Crbyte Data2, Ack
.............

Wenn jetzt beim Haenger SCL auf high und SDA low ist, wo haengt er dann? Ich vermute im zweiten Teil, dem Auslesen. Der erste Teil leitet ja nur die Messung ein. Bascom hackt ja seine Instruktionen eh durch, egal, ob ein Ack kommt oder nicht. Wenn hier schon was falsch laeuft, dann sollte das erstmal ohne Effekt auf das Hauptprogramm sein.
 
Hallo Uwe,
hab mir gerade nochmal deine anfängliche Problembeschreibung durchgelesen - welcher Controller zieht eigentlich die Leitung auf 0 ? Evtl. mal mit einem Digitalvoltmeter die Spannungen an den einzelnen Knoten messen, evtl. hängt sich auch ein ganz anderer Controller auf und du suchst an der falschen Stelle - nur so als Hinweis.

Gruß
gp177
 
...Man muesste die letzte Transmission vor dem Stillstand einfangen. Genau da liegt das Problem, denn da gibts noch nichts...
Deswegen ja meine Frage. Der LA überwacht ja, sobald er auf triggern geschaltet ist zumindest den zu triggernden Kanal, und zeichnet den (wahrscheinlich auch alle anderen) in einem Ring auf. Nach dem Trigger-event wird dann halt der Rest (entsprechend den Einstellungen) aufgezeichnet. Dargestellt wird also nicht nur nach dem Trigger, sondern auch etwas davor. Da ich nicht am Rechner sitze, kann ich aber nicht nachsehen, wie groß dieser "Ring" ist, wieviel vor dem Trigger aufgezeichnet wird. Ich vermute, daß das keine feste Zeit, sondern soundso viele Samples (entsprechend den aktiven Einstellungen) sind.
 
Hi,

beim LA8/LA16 finde ich keine Einstellmöglichkeit für einen Ringbuffer. Müßte man mal probieren wieviel er vor dem Triggerereignis aufzeichnet.

Bei meinem Hameg-DSO weiß ich definitiv das man einstellen kann wie das Triggerereignis im Speicher liegen soll. Zum Beispiel am Anfang, in der Mitte oder am Ende des Ringspeichers. Das kann auch definitiv im Ring arbeiten und hat auch genug Kanäle für nen I2C-Bus. Außerdem würde man damit auch Störungen und Spannungsschwankungen auf dem Bus mitbekommen.

Als letzten Workaround könnte man ja nen Tiny einsetzen der als Watchdog den Bus überwacht und beim Stillstand nen Reset auslöst.

EDIT: Der LA von Saleae kann PreTrigger ...
LA8-PreTrigger.png
Man sollte doch ab und zu mal die Anleitung lesen oder beim rumsuchen die Augen aufmachen :flute:

Gruß
Dino
 
guggst du hier:

www.standardics.nxp.com/support/documents/i2c/xls/buffers.frequency.cable.length.graph.xls

Vllt. hilft dir das weiter. Hab jetzt nicht alles durchgelesen, was bis jetzt geschrieben wurde....
;)


Ich bin gerade an einem ähnlichem Projekt dran, nur sind es bei mir 50m sind. Möchte auch den P82B96 verwenden. Außerdem den ADUM1251 für Potenzialtrennung.

Allerdings möchte ich auch mit 100khz fahrn... ob das klappt?


Danke fuer das Excelsheet, feine Sache :)
50m klappen mit Sicherheit und sogar ohne Potenzialtrennung. Die 150m haben auch auf Anhieb geruckt beim Erststart. 100kHz koennte ich auch fahren, die 2kHz hab ich eigentlich nur testweise eingestellt. Bei mir ist es egal, mit wieviel der Bus getaktet ist, da der Master nur alle 10min die Daten abfragt und im Server aktualisiert. Da reicht sogar 2Hz noch aus.

Das ein anderer Slave dazwischen funkt und SDA auf low haelt, ist theoretisch denkbar. Nur wie kann man das herausfinden.... Jeder Slave ist mit Watchdog programmiert, bei Stillstand sollte er eigentlich reseten. Ein Attiny zur Leitungsueberwachung ist kein dummer Gedanke, nur ist damit das Problem nicht behoben
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)