Hallo Welt & liebe Forengemeinde!
Ich suche im Augenblick nach einer Möglichkeit größere Datenmengen (100
- 200 kb/s pro Slave) von mehreren Slave-Modulen an einen Master zu
senden.
Im Idealfall sollten dabei folgenden Bedingungen erfüllt sein:
- die Kommunikation wird vom Slave Modul eingeleitet (während des
Betriebs kommt es auf den Slave Modulen zu einigen "Wartezeiten" die ich
gerne für die Kommunikation nutzen würde um jeweils kleine Pakete (2-4
Byte) zu versenden)
- die Kommunikation findet einseitig statt (vom Slave zum Master)
Empfangsbestätigungen oder Fehlermeldungen werden nicht benötigt, zum
einen um den Slave nicht zu belasten zum anderen da es sich um
Echtzeitdaten handelt die im nächsten Zyklus bereits erneuert wurden.
- ein Master muss mehrere Slaves betreuen können (im Augenblick 6
später falls möglich auch mehr)
Mir ginge es jetzt vor allem um die Frage ob denn schon etwas existiert
das diese Anforderungen erfüllt?
Vielen Dank schon im Voraus für die Hilfe!
Tom
Hallo Tom,
da gibt es diverse Ansätze.
Ich fürchte um Dir helfen zu können brauchen wir etwas mehr
Informationen.
- Ich gehe davon aus, das Du Kabel verlegen kannst willst!?
- Über welche Längen reden wir?
- Darf es ein Stern oder ein Bus oder ein Ring sein?
Protokolle kann man dan daraus entscheiden
Grüße
Frank
Hallo Jerry und Frank, vielen Dank schon mal für die Antworten!
Das Ganze findet auf relativ kleinem Raum statt, maximale Distanz
zwischen Slave und Master wäre schätzungsweise < 1,5 m, eher noch
deutlich weniger.
Topologie ist völlig frei, ich bin für alle Vorschläge offen!
Hallo Tom,
ok Du machst es also nicht wirklich einfacher ;-)
Da ich nicht sicher bin wie deine Slaves und dein Master aufgebaut sind
und daher nicht sagen kann welche Schnittstellen diese zur Verfügung
haben vermute ich das DU nur eine einfache Serielle hast.
in diesem Fall täte ich einen Stern vorschlagen und die 2 - 4 Bytes beim
Master pro Slave in einem Schieberegister ablegen.
Technisch relativ einfach und Du brauchst kein großes Protokoll um
Kollisionen zu vermeiden..
Der Nachteil dieser Variante ist das Du für jeden weiteren Slave den
Registersatz einfügen musst. Dazu kommt das Du dich festlegst wieviele
Daten ein Slave verschicken darf (muß) damit dein Master nicht
durcheinander kommt.
Sobald Du es variabler brauchst werden Protokolle und damit overhead
benötigt.
Grüße
Frank
Hallo Frank!
Sorry, war wirklich nicht meine Absicht es dir schwerer als nötig zu
machen ;-)
Genau, im Idealfall würde ich einfach einen digitalen Ausgang des Slave
uC mit einem Eingang am Master verbinden und dann die Daten rüber
schaufeln.
Dass es ganz so einfach nicht wird hatte ich schon erwartet, wobei dein
Ansatz mit den Schieberegistern sehr interessant klingt!
Wenn ich dich richtig verstehe dienen die Schieberegister als eine Art
Warteschlange bis der Master den entsprechenden Slave-Kanal ausliest,
korrekt?
Vielen Dank & noch einen schönen sonnigen Tag!
Tom
Jep genau das ist die Idee.
Da gibt es jetzt natürlich 1391 verschiedene Ideen wie man das bauen
kann.
Ich denk mir mal was einfaches zum probieren aus. Das kann man dann zur
Professionellen Nutzung immer noch optimieren ;-)
bis später mal
Frank
Das ist, denke ich, ein typischer Fall für den I2C. Bei Atmel heißt der
SPI. Ich nehme RS485, aber nur weil ich sehr lange Leitungen und große
Störungen habe.
Hallo Hermann,
war auch meine 1. Idee. Aber dann ist mir klar geworden, das bei Tom
Anwendung Master und Slaves vertauscht sind. Dazu das Problem das der
Empfänger (Tom's Master) die Daten von mehreren Sendern quasi parallel
abnehmen muss.
Deswegen meine Idee mit den Schieberegistern als Puffer.
Leider gibt es die link Bausteine aus den alten Transputerzeiten nicht
mehr. Da war das alles ganz einfach ;-)
Wenn Du einen Lösungsansatz mit I2C hast würde mich der interessieren.
Hermann schrieb:> Das ist, denke ich, ein typischer Fall für den I2C.> Bei Atmel heißt der SPI.
Oh nein: der I²C heißt bei Atmel TWI, weil der Name I²C Geld an Philips
kostet. SPI kommt von Motorola und ist ganz was ganz anderes...
Hallo Leute,
da offensichtlich alle was gegen meine etwas verstaubte
Schieberegistervariante haben ;-)
rufe ich hiermit zum vergleich auf welcher der verfügbaren Busse besser
für Tom geeigne ist.
Tom kann uns derweil mal verraten welchen uC er auf dem master und den
Slaves einsetzt. evtl. schränkt das die Auswahl ein.
Nur aus Spass werde ich am Schieberegister basteln ;-)
Grüße
Frank
Man sollte bei der Standard-Master/Slave-Lösung bleiben. Ein Slave hat
sich grundsätzlich nicht unaufgefordert zu melden und den Master gibt es
nur einmal. So wie die Anforderung beschrieben ist, ist das kein
Master/Slave-Prinzip. Wenn sich hier alle Slaves melden, wenn sie gerade
Zeit haben, sind sie definitionsgemäß kein Slave. Das geht nicht auf
einem Bus wegen Kollisionen. Ich denke, das Master/Slave-Prinzip läßt
sich auch hier verwirklichen. Das ist 1000-fach bewährt und dafür gibt
es fertige Protokolle usw. Also der Master gibt ein Kommando mit der
Adresse des Slave. Der hat als einziger zu antworten. Der Master
verwirft das Kommando nach einem Timeout. Bei mir klappt das vorzüglich.
Habe dabei das MODBUS-Protokoll verwendet.
Man muss das Timeout in jedem Fall so lang wählen, dass der Slave
antworten kann. Das ist dann eben so lang bis der Slave Zeit hat.
Schieberegister-Lösung geht natürlich auch, da nimmt man z.B.
Interbus-S. Mit Eigenbau habe ich damit keine Erfahrung.
Hallo zusammen!
Hermann hat recht, nach der klassischen Definition trifft die
Master/Slave Bezeichnung in diesem Fall nicht wirklich zu, da die
"Untereinheiten" von sich aus den Datentransfer einleiten sollen.
Dies wäre mir auch eine sehr wichtige Bedingung, da diese durch den
Prozess des Datensammelns eigentlich schon ausgelastet sind, wobei wie
anfangs erwähnt aber sowieso etwas ungenutzte Zeit anfällt während auf
eine AD Konvertierung gewartet wird.
Diese Zeit nun für die Kommunikation zu nutzen wäre eben ideal.
Für die Entwicklung wurde der ATmega328 genutzt, obwohl das nicht
zwingend die endgültige Entscheidung ist was den uC angeht.
Insofern klingt Franks Schieberegister-Ansatz nach wie vor sehr
interessant.
Die Frage wäre jetzt nur, wie man Schreib- / Lesezugriff auf das
Register synchronisiert, so dass nur dann gelesen wird wenn alle Bits
bereits korrekt gesetzt wurden.
Evtl ließe sich das ja schon durch ein Startbit lösen, nur wenn dieses
auf 1 ist, ist das Register gefüllt, kann gelesen werden und wird danach
komplett auf 0 gesetzt.
Oder hat jemand eine elegantere / effizientere Lösung?
Vielen Dank an alle Beitragenden für eure Hilfe!!
Tom
Moin Moin,
@Herman
Kann man das evtl. als Multimaster lösen?
Wenn der Sender Zeit hat versucht er den Bus zu bekommen und wenn er den
nicht bekommt schickt er halt keine Daten?
@Tom
Genau bei der Datengültigkeit liegt der Hase im Pfeffer.
Nach meiner Meinung gibt es da 2 Lösungsansätze:
1. man schickt ein "Startbit" mit was in der richtigen Position im
Schieberegister anzeigt das Gültige Daten vorliegen.
Das Risiko dabei ist das wenn der Sender schon wieder schickt obwohl der
Empfänger noch nicht gelesen hat es immer noch zu falschen Daten kommen
kann.
2. man gönnt der "Schnittstelle" eine "Daten OK" Leitung mit der der
Sender anzeigt das er gerade nix sendet.
Ich tendiere im Moment zu letzterem. Habe aber das Startbit dafür
genutzt um zu sehen wie viele Bytes übertragen wurden.
Also schaut bei meiner Idee der Leitungssalat derzeit so aus:
TXD
CLK
DataValid
GND
Die Schaltung im Groben:
4 Schieberegister 9 Bit mit Löschen (gibt es das als Baustein?) in Reihe
geschaltet. TXD und CLK Füttern die Schieberegister,DataValid geht auf
nen Port am Empfänger.
Vom Ablauf her denke ich mir das so:
DataValid = 0, Daten werden vom sender geschickt
Daten 1. Bit 1. 8Bit Daten (* Anzahl Bytes) ins Schieberegister tickern
DataValid = 1, Daten im Schieberegister können gelesen werden.
Empfänger prüft jeweils über das 1. Bit wie viele Daten angekommen sind
und liest die Daten aus.
Empfänger löscht das jeweilige Schieberegister (damit das 1. Bit wieder
weg ist)
und so wieter.
Ich werde mal versuchen da nen Plänchen für zu basteln. Dauert aber ein
wenig, weil ich derzeit weit weg und ohne jedes Tool sitze muss also
über meine Wählleitung erst mal saugen ;-)
Evtl. kann jemand mal schauen ob man bei den Sendern den TWI in der
Richtung "verbiegen" kann?
Grüße
Frank
Eine Frage:
Muß der Sammel-uC in der Lage sein, mehrere (im Extremfall alle)
Datenströmen parallel zu empfangen oder gibt es da irgendwelche
Randbedingungen beim Datenaufkommen.
MfG
Ich hab sowas schon mit TWI gemacht, allerdings kommt es da echt auf die
Art der physikalischen Verbindung an.
Mit 0815 Kabeln bin ich da gescheitert, mit STP Kabel und STP
Steck-Verbindungen hab ich es dann auf ca. 1,2m in industriellem Umfeld
gebracht bei fuer mein Projekt ausreichender Geschwindigkeit.
Meine Controller waren unterdshiedliche Atmegas mit 16MHz Cristallen.
Ich muesste mir mal den Code anschauen um zu sagen mit welcher
Geschwindigkeit ich den TWI hab laufen lassen.
Das Problem bei mir war, das ich echtes Multimaster brauchte, so das
jeder im Bus, wann immer, anfangen kann zu erzaehlen.
Es hat mich einiges an Zeit, stundenlanges googeln und lesen, und Nerven
gekostet die Atmegas dazu zu bewegen richtiges Multimaster ueber die
eingebaute Hardware zu machen. Aber wie immer, ist man am Ende schlauer
als zuvor. Und man weiss, dass wenn man alles richtig macht, es auch
funktioniert.
Gruss
Ju
Einen guten Morgen zusammen!
Frank Sander schrieb:> 1. man schickt ein "Startbit" mit was in der richtigen Position im> Schieberegister anzeigt das Gültige Daten vorliegen.> Das Risiko dabei ist das wenn der Sender schon wieder schickt obwohl der> Empfänger noch nicht gelesen hat es immer noch zu falschen Daten kommen> kann.
In letzterem Fall könnte ja der Sender einfach vor jedem neuen Senden
das Register löschen um ungültige Daten zu vermeiden. Allerdings wäre
dann der vorherige Satz natürlich verloren...
> 2. man gönnt der "Schnittstelle" eine "Daten OK" Leitung mit der der> Sender anzeigt das er gerade nix sendet.
Klingt auch nach einer guten Lösung. Könnte es denn hier im schlimmsten
Fall zu einer Race Condition kommen, oder ist das vernachlässigbar?
(Leser prüft Daten Ok Leitung aber bevor er den tatsächlichen
Lesezugriff ausführen kann wurde doch schon wieder das nächste Bit
geschoben)
@ Matthias
>Muß der Sammel-uC in der Lage sein, mehrere (im Extremfall alle)>Datenströmen parallel zu empfangen oder gibt es da irgendwelche>Randbedingungen beim Datenaufkommen.
Da die einzelnen Sender eben genau nicht synchronisiert sind kann es
durchaus zu parallelen Datenströmen kommen.
@ Juergen
>... die Atmegas dazu zu bewegen richtiges Multimaster ueber die> eingebaute Hardware zu machen. Aber wie immer, ist man am Ende schlauer>als zuvor.
Das hört sich sehr interessant an, hast du dazu noch ein paar weitere
Infos wie du das letztlich lösen konntest?
@ Frank
> Kann ich davon ausgehen das jedes übertragene Byte != 0 ist?> Dann kann ich mir das extra Bit sparen ;-)
0 kann durchaus vorkommen, sorry ;-)
Aber da es ja hier erstmal um das Konzept geht, kannst du natürlich auch
ohne Nullen arbeiten.
Vielen Dank an alle, ich weiß euren Input sehr zu schätzen!
Guten Start in den neuen Tag und bis dann!
Tom
Moin Tom,
auch wenn ich es schon gesagt habe:
ok, Du machst es nicht wirklich einfacher ;-)
Ich habe mittlerweile nen Eagle am rennen und bin am Schalten.
Racing habe ich denke ich ausgeschlossen durch Schieberegister mit
Puffer.
Bin derzeit am Stricken wirklich nur die 3 o.g. Signale zu benötigen.
Konzeptschaltung kommt also bald ;-)
(Wenn ich verstanden habe wie ih die "Drucken" kann und dann hier
anhängen)
Gruß
Frank
Hallo Halli,
@Tip:
Super Danke!!
@Tom (und wer immer sonst noch Spass dran hat)
Anbei mal ein erstes Konzept.
Damit kann man bis zu 4 Byte empfangen. IC5B verrät wie viele Byte
gesendet wurden.
Die Puffer und der Zähler werden noch nicht zurück gesetzt, da bastel
ich noch.
Dann muss ich auch noch nen Multiplexer basteln das man die Bytes über
einen Port einlesen kann.
Ich bin für Ideen immer offen ;-)
Ach ja, das ist bitte nur ein Konzept und NICHT ausgetestet. in dem
Plänchen fehlen diverse Spannungsversorgungen, Kapazitäten und so was
alles ;-)
Grüße
Frank
Hallo noch mal ;-)
so nu habe ich auch das mit dem Zurücksetzen im Griff.
Ich habe die Schieberegister getauscht gegen welche mit tri state
Ausgang.
Der Vorteil:
Es können jetzt alle Schieberegister Parallel auf einen Port des
Empfänger uC geschaltet werden. Der zu lesende wird via pin 13 des
Schieberegisters ausgewählt.
Aus diesem Grund auch der 74244 am Zähler (IC5B). auch idese können alle
Parallel auf einen Port des uC geschaltet werden und über das Gate wird
ausgewählt welcher "Byte Anzahl" gelesen wird.
Gesteuert wird alles durch den Sender. Genauer durch die
/Send_Data_Sender Leitung. diese Leitung muss vom Sender während des
senden auf 0 gehalten werden. Wenn alle Bytes durch getickert wurden
muss der Sender diese Leitung auf 1 setzen. Dadurch werden die Daten in
den Puffer der Schieberegister übernommen.
Durch das Zählen der TX Clock Pulse und Teilen dieser durch 8 (IC5A & B)
haben wir die Anzahl der gültigen Bytes.
Gültig ist die Information am Zähler nur bis ein neuer Sendevorgang
beginnt.
Um Kummer zu vermeiden sollte der Empfänger auch nur bis dahin Daten
lesen.
Kurz: Wenn "Send_Data_Sender" auf 1 ist kann, darf, sollte man die
Register auslesen. Ist das Signal 0 lässt man die Finger davon.
Diese Schaltung kann ohne viel Kummer auf 15 Bytes erweitert werden.
Einfach mehr Schieberegister einfügen. Es können beliebig viele Sender
parallel geschaltet werden. Ist eine Frage ob und wie schnell der
Empfänger uC die Dinger auslesen kann.
Theoretisch kann man auf die Steigende Flanke des "Send_Data_Sender"
einen Interrupt auf dem Empfänger auslösen. Ob das nötig ist, ist von
der Anwendung abhängig.
Habe ich was vergessen?
Habe ich was verdreht?
Gibt es Denkfehler in der Schaltung?
Lasst es mich bitte wissen.
Gruß
Frank
P.S. Ich kann das ganze leider nicht testen. Dummerweise habe ich auch
keinen Simulator hier. Wenn jemand einen Simulator auf OSX empfehlen
kann!?
@Frank
Das mit den Shift Registern (SR) und der Logic drumherum ist eine
schoene Fingeruebung, doch besteht weiterhin das Problem, das der
Empfaenger (hier im Thread als Master bezeichnet) die Daten aus den SR's
lesen muss.
Dazu benoetigt er Zeit und eine Unmenge Port Pins in Deinem Beispiel.
Fuer mich sieht das nicht nach einer optimalen Loesung aus.
Die Leute die SPI, I2C & Co entwickelt haben, sind Dir da ein paar
Schritte voraus.
Das was Du da gezeichnet hast, kann man mit dem SPI der AVR's und einem
zusaetzlichem Pin (dem CS zBsp.) direkt machen.
Alle MOSI der Sender gehen auf den MISO des Empfaengers. Die CS sind
alle zusammengeschaltet.
Will ein Sender senden, ueberprueft er den CS, wenn frei dann zieht er
den CS auf den entsprechenden Pegel und legt los seine Daten zu senden.
Erstes Byte ist seine ID, zweites Byte die Menge der Daten die er senden
will, dann die Daten und wenn noetig eine Pruefsumme.
Der Empfaenger laeuft im Interrupt-Betrieb, das heisst wenn ein Byte
komplett ist kommt der Interrupt, er liest das Byte aus, und es kann
weiter gehen.
Eine State Machine macht die Zuordnung der Bytes.
Der SPI des AVR ist gut schnell, und die ISR macht das lesen auch
ausreichend effective.
Alle Leitungen sind einseitig in der Datenrichtung, somit ist es einfach
mit ein paar Optokopplern die Physikalischen Leitungen stoerungsfrei zu
bedienen. In der Industrie ist das eine sehr oft verwendete Schnitstelle
zu Sensoren mit Messwertaufbereitung.
Nachteil des SPI ist, das der SPI des AVR nicht redundant
(doppelgepuffert) ist, damit also Daten verloren gehen koennen wenn der
Empfaenger (die Software darin) das nicht richtig handhabt.
Somit suchen wir ein Protokoll das dieses umgeht, und kommen dabei auf
I2C(TWI). Beim I2C funktioniert der ganze Protokoll Kram und
Identifizierung schon zu grossen Teilen in der Hardware.
Wichtigste Aufgabe des Programmierers ist es da, "alle" I2C Zustaende in
der Software zu behandeln.
Nachteil ist, das die Datenrichtung beidseitig ist, somit die
Implementierung in Hardware ueber laengere Kabel etwas umfangreicher.
Dafuer war I2C aber auch nicht gedacht.
Zur Programmierung des TWI im AVR.
Wie weiter oben schon geschrieben. Wenn man es macht wie es sein soll
funktioniert alles perfekt.
Alle Beispiele zu TWI und I2C die ich gesehen habe, haben Defects, immer
ist irgend etwas was nicht funktioniert was dann den Bus in der Luft
haengen laesst. Es werden die tollsten Erfindungen gemacht um das zu
"korrigieren" meistens wird bei diesen "Korrektionen" der Bus resettet.
Das ware Problem ist aber, das keines der gesehenen Beispiele alle
moeglichen Zustaende des I2C behandelt. Wenn dann ein nicht behandeltes
Ereignis eintritt, bleibt der Bus in der Luft haengen weil nicht darauf
reagiert wird.
Ju
Hallo Jürgen,
ich hoffe doch das es eine bessere Möglichkeit als mein Monster gibt.
Nicht zuletzt aufgrund Hermanns und deiner Kommentare bin ich eifrig am
lesen und lernen.
Bitte sei mir net böse das ich die Chance zu einer Fingerübung genutzt
habe. Es ist fast 20 Jahre her das ich das letzt mal so was gebastelt
habe und es hat mich einfach gereizt mal zu testen ob noch was geht ;-)
Ein bischen widersprechen muss ich allerdings bei den unmengen Port pins
;-)
Es sei den 16 Pins (im Maximum) sind eine Menge. Interruptsteuerung kann
man dem Ding auch noch verpassen :-)
Aber ich gebe zu dann wird es langsam wild.
Ich täte um die Asynchronität zu gewährleisten normal die Daten in einen
Speicher tickern und vom Empfänger über eine 2. Schnittstelle auslesen.
Da ich aber keinerlei Unterlagen hier habe und mir jede Information über
eine gute alte Wählleitung (ja so etwas gebt es noch) zusammen sammeln
muss, konnte ich diesen Entwurf nicht erstellen.
Ich weiß es gibt serielle Speicher, aber gibt es die mit 2
Schnittstellen?
Wäre das ein Denkansatz um die letzten Probleme zu lösen?
Gruß aus der ferne
Frank
@ Frank:
Schon mal ein großes Dankeschön an dich für die Ideen und
Ausarbeitungen, hat mir auf jeden Fall einige neue Denkanstöße und Ideen
gegeben!
@ Juergen:
Auch dir großes Dankeschön für die ausführlichen Infos und Empfehlungen,
auch diese Ansätze werde ich mir noch mal genauer anschauen!
Grüße & einen schönen Abend!
Tom