HSG |
|
Quelle: The origin of the Ethernet symbol
nach wikipedia-Artikel 'Manchester-Code':
Der Manchester-Code ist ein Leitungscode, der bei der Kodierung das Taktsignal erhält. Die Flanken des Signals, bezogen auf das Taktsignal, tragen die Information. Eine fallende Flanke bedeutet zum Beispiel eine logische Null, eine steigende Flanke eine logische Eins. Daher gibt es mindestens eine Flanke pro Bit, aus der das Taktsignal abgeleitet werden kann. Der Manchester-Code ist selbstsynchronisierend und unabhängig vom Gleichspannungspegel. Manchester-Code wird zum Beispiel bei 10-Mbit-Ethernet verwendet
Für unsere Zwecke hat der Machestercode zwei wichtige Vorteile. Erstens unterscheidet sich ein 0-Bit von einer 'toten Leitung'. Damit funktioniert die Kollisionserkennung viel sicherer. Zweitens ermöglicht die 'bittragende Flanke' die Rückgewinnung des Taktes. Auf diese Weise sollten auch längere Pakete ohne Synchronisierungsfehler übertragbar werden.
Ein Null-Bit wird durch die Pegelfolge '10', ein Eins-Bit durch die Pegelfolge '01' reräsentiert.
def Manchestercodiert(bitfolge): """ gibt zu bitfolge (str) die Manchester-codierte Pegelfolge zurueck '101011' --> '011001100101' """ t = ['10','01'] return ''.join([t[int(x)] for x in bitfolge])
Tests
>>> Manchestercodiert('101011') '011001100101' >>> Manchestercodiert('01000001') '1001101010101001'
Das Senden soll in einem abbrechbaren Thread erfolgen. Die Zeitsteuerung soll aus der Systemzeit abgeleitet werden. Auf diese Weise wird eine große 'Langzeitkonstanz' erreicht. Zur Kollisionserkennung soll nach jedem Setzen der Leitung auf Null (bei einer Eins gibt es nach Konstruktion des Busses keine Kollision) die Leitung beobachtet werden. Im Kollisionsfall soll ein Callback ausgelöst und die Überwachung der Leitung bis zur nächsten Flanke unterbrochen werden.
import time import platform def zeit(): if platform.system() == 'Windows': return time.clock() else: return time.time() import serial import threading class Model(object): def __init__(self): self.s = serial.Serial('/dev/ttyS0') self.s.setRTS(False) self.stopflag = threading.Event() self.pegelfolge = '' self.pegelzeit = 0.01 self.sendThread = None def send(self,pegelfolge,pegelzeit,setLeitung,getLeitung,stopflag,OnCollision): """ sendet die Pegel aus der pegelfolge (str) mit der pegelzeit (float), benutzt dazu die Funktion setLeitung, die ein boolsches Argument hat, das Senden kann ueber stopflag (threading-event) abgebrochen werden, die Funktion getLeitung gibt einen boolschen Wert zurueck, bei einer Kollision wird der Callback OnCollision aufgerufen """ t0 = zeit() n = len(pegelfolge) i = 0 while (not stopflag.isSet()) and (len(pegelfolge) > 0) : pegel = (pegelfolge[0] == '1') # print(pegel) # DEBUG setLeitung(pegel) pegelfolge = pegelfolge[1:] i = i + 1 # Warten und Kollisionserkennung collisionsflag = False while zeit() - t0 < i*pegelzeit: if (pegel == False) and (not collisionsflag) and (getLeitung() == True): collisionsflag = True if OnCollision != None: OnCollision() if (pegel == True) or collisionsflag: time.sleep(0.0001) if stopflag.isSet(): print('Senden abgebrochen ...') setLeitung(False) def stop(self): self.stopflag.set() def OnColl(self): print('Kollision') # DEBUG def start(self): self.stopflag.clear() self.sendThread = threading.Thread(target=self.send, args=(self.pegelfolge,self.pegelzeit,self.s.setRTS, self.s.getCTS,self.stopflag,self.OnColl)) self.sendThread.start() def __del__(self): # schliesst sicher die Schnittstelle self.s.close()
Test
Zum Test wurde eine Pegelfolge gesendet und das Gesendete auf einem anderen Rechner mit Hilfe des Pegeltransceivers empfangen. Mit dem Pegeltransceiver wurden in die ersten beiden 'Pausen' kurze '1'-Impulse erzeugt, um Kollisionen auszulösen.
>>> m=Model() >>> m.pegelfolge='011001100101' >>> m.pegelzeit=0.5 >>> m.start() >>> Kollision Kollision
Das Bild zeigt die beiden kurzen Impulse in den ersten Pausen. Hinter der eigentlichen Nachricht wurden vier kurze Impulse im Transceiver generiert, die ignoriert werden können.
Auch das Abbrechen einer laufenden Sendung wurde erfolgreich getestet.
>>> m.start() >>> m.stop() >>> Senden abgebrochen ...
Der Transceiver zeigte, dass die Sendung tatsächlich abgebrochen wurde.
aus wikipedia-Artikel 'Ethernet':
Die Präambel besteht aus einer 7 Byte langen, alternierenden Bitfolge (101010...1010), an sie schließt der Start Frame Delimiter (SFD) mit der Bitfolge (10101011) an. Diese Sequenz diente einst der Bit-Synchronisation der Netzwerkgeräte. Sie war für all jene Geräteverbindungen notwendig, die die Bit-Synchronisation nicht durch die Übertragung einer kontinuierlichen Trägerwelle auch in Ruhezeiten aufrecht erhalten konnten, sondern diese mit jedem gesendeten Frame wieder neu aufbauen mussten. Das alternierende Bitmuster erlaubte jedem Empfänger eine korrekte Synchronisation auf die Bit-Abstände. Da bei einer Weiterleitung über Hubs jeweils ein gewisser Teil der Präambel verloren geht, wurde sie in der Spezifikation groß genug gewählt, damit bei maximaler Ausdehnung des Netzwerkes für den Empfänger noch eine minimale Einschwingphase übrig bleibt.
Im MiniEthernet soll die Präambel auf das Byte '10101010' und den SFD '10101011' verkürzt werden.
>>> praeambel '01100110011001100110011001100101' >>> m=Model() >>> m.pegelfolge='01100110011001100110011001100101' >>> m.pegelzeit=0.05 >>> m.start()
ManchesterSender0.zip, Manchesterempfaenger4.zip, NetzHWneu.zip