TWI Master mehrere Slave

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • TWI Master mehrere Slave

      Hallo User,
      ich beschäftige mich seit Tagen mit TWI und komme nicht weiter
      Ich baue gerade eine Clock24 , dazu wollte ich 12 Atmega 328 als Slave und einen als Master einsetzen.
      Verbunden über TWI .
      Das Problem , wenn ich den ersten Slave anspreche und diesen beschäftige ( also er ist nicht mehr im Abfragemodus, z.b in einer Zeitschleife )
      kann ich keinen weiteren Slave mehr ansprechen. Sobald ich einen weiteren Slave anspreche blockiert der Erste den Bus
      Erst wenn der erste Slave zurück ist in der Abfrage geht es auf dem Bus weiter.
      Ich habe SCL und SDA also Port PC5 und PC4 benutzt als über Hardware TWI.
      Also der erste Slave blockiert den Bus , sobald ich einen anderen Slave anspreche.
      Die Frage, kann ich beim Atmega 328 über Software-TWI mit der TWI-Slave.lib arbeiten und währe das Problem damit erledigt?
      Hat schon mal Jemand mehr als 2 Atmega über TWI erfolgreich verbunden und wenn währe ich für jeden Tip dankbar.
      Gruß Pino
    • Ich habe schon mal 4 Slaves betrieben, die an einem Master hängen.

      Dein Problem wirst du nicht lösen, wenn du einen SoftTWI dazu nimmt. Dann blockiert dieser, wenn du auf den nächsten Slave zugreifen willst und der noch in einer Zeitschleife steckt.

      Dein Problem ist aller wahrscheinlichkeit nach dein Programm bzw. der Code.

      Du darfst nicht einen Slave um etwas bitten und auf Empfang gehen und der Slave braucht eine Weile, bis er antwortet. Das blokoert logisch das Programm im Master.

      Du brauchst eine andere Vorgehensweise.

      Anweisung an Spave 1 schicken und Übertragung beenden. Dann an Slave 2 ein Befehl senden und Übertragung abschließen.

      So können alle Slaves abarbeiten.

      Später fragt dann der Master ab, ob Slave 1 Fertig ist, wenn nicht frägt er Slave 2 usw.
      Der Slave, der Fertig ist, kann nun zum Lesen des Ergebnisses angesprochen werden.

      Stichwort Asynchrone Abarbeitung.

      Um aber genau zu sagen, wo es bei dir hakt, müsste man den Code sehen - von Master und Slave.

      Ich vermute mal, dass dein Slave so programmiert ist, dass er die Anfrage sofort versucht abzuarbeiten und dann das Ergebnis liefert.
      Das wäre dann synchrone Abarbeitung.
    • Hallo Mitch64
      Vielen Dank für die Antwort.
      Aber eigentlich wartet der Master nicht auf ein Ergebnis , ich lade die Slave mit Tabellen nacheinander ,
      das klappt noch und dann, wenn alle Slaves die Tabellen haben sollen sie die Tabellen abarbeiten dazu möchte ich an alle Slaves
      hintereinander den Startbefehl schicken , dass sie quasi gleichzeitig starten.
      Aber dann nach dem Startbefehl zum ersten Slave hängt der Bus, weil diese ja jetzt anfängt die Tabelle abzuarbeiten.
      Der Master fragt die Slave nicht ab .
      Also der Master geht nicht auf Empfang.
    • Hallo Mitch64
      vielen Dank für deine Geduld und deine Mühe.
      Ich bin mir auch sicher, dass ich etwas falsch mache, leider weis ich nicht was .
      Ich habe mal beide Programme angehängt , so abgespeckt um nur den Fehler zu erkennen.
      Also der Master schickt Adresse 12 , dann Datenbyte 1 , Slave geht in die Zeitschleife von 10 Sekunden.
      Jetzt kann ich keinen weiteren Slave ansprechen , erst wieder wenn die Zeitschleife beendet ist.
      Die TWI Rutinen habe ich irgendwo im Netz gefunden und sie funktionieren ja auch soweit ganz gut
      Files
    • Hallo Pluto25 ich bin davon ausgegangen das ich quittiert habe , warum meinst du ich habe nicht quittiert ?

      würdest du das mit dem INT mir vielleicht genauer erklären ?
      Wie meinst du das ?
      Einen INT benutze ich für die Stepperimpulse
      Ich benutze ja das Hardware TWI und bin mir nicht sicher ob die Softwarelösung auch funktioniert wenn der Atmega Hardware TWI hat und brauch ich dann doch die .lib ?
      Würde mich über eine Antwort freuen
    • Weil er hängt. Der Slave kann das Ganze bremsen um das Empfangene Byte ab zu holen bevor das nächste kommt.

      Das Bit7 von Controlregister würde einer Isr aufrufen wenn bit 0 gesetzt ist.
      Damit wird die nach jedem eingegangenen Byte aufgerufen? So müsste der Eingang nicht gepollt werden.
      Im Gegensatz zu anderen Ints muß das Bit 7 zurückgesetzt (durch 1 reinschreiben) werden.
      In Software würde ich das nur als "Notlösung" betreiben. Oder wenn es nötig wäre zwei unabhängige I2C zu haben. (Warum auch immer das nötig sein könnte)
      Durch Deine Lösung wird die lib ja nicht benötigt. Sie ist erstaunlich kurz. Ich hatte mich vor längerer Zeit damit beschäftigt , da war die Lösung erheblich länger. Vermutlich weil ich alle Stausmeldungen bearbeitet hatte ?)
    • Richtig verstanden hab ich das noch nicht, in der Abfrageroutine wird doch TWINT wieder auf 1 gesetzt , und Bit 6 also TWEA als Ack
      doch auch?????
      Ich werde mich noch mal mit dem TWCR beschäftigen vielleicht geht mir ja ein Licht auf.
      vielen Dank für die Hilfe
      Files
    • @Pino
      Ich glaube ich weis jetzt warum dein Slave blockiert.

      Wenn der Master etwas weg schicken will, muss er die Start-Kontition setzen, dann den Slave adressieren und dann das DatenByte schicken, zuletzt die Übertragung mit der Stop-Kondition beenden.

      Bei jedem dieser Events wird ein Interrupt ausgelöst. In deinem Fall das TWINT-Flag mehrfach gesetzt.
      Also bei obiger übertragung 4 mal.

      In deiner Routine setzt du das TWINT-Flag ja auch immer zurück. Nur dann nicht, wenn die Routine nicht aufgerufen wird und etwas am Bus passiert.

      Angenommen der Master hat nun dem 1. Slave das obige Frame gesendet und die Hauptschleife wartet nun wegen dem Kommandobyte die 10 Sekunden und in der Zeit versucht der Master den 2. Slave anzusprechen. Nur es lauschen ja immer alle Slaves am bus. Also auch der 1. Slave.
      Der kann aber den Bus nicht freigeben, da er das TWINT-Flag nicht löscht - er steckt ja in dem Waitms 10000 fest.

      Ich denke es gibt 2 Ansätze, wie du das hinbekommen kannst.

      Die Routine twiData vom TWI-Interrupt aufzurufen. Dazu aber den Loop innerhalb der Routine weg machen, und das Datenbyte in der Hauptschleife verarbeiten.

      Der andere Ansatz ist, kein Wait zu verwenden. Dazu musst du aber die Zeit mittels Timer messen, ob die Zeit vergangen ist. Und währenddessen musst du regelmäßig die Routine twidata aufrufen, also Pollen.

      Der 1. Ansatz dürfte für dich der einfachere sein.
    • Das wär ja blöd ;(
      Dann haut jeder Slave unzählige Ints raus obwohl gar nicht mit Ihm gesprochen wird? :(
      Würde der Master noch ein Display bedienen drehen die Slaves total ab a_217_27b18bee :D
      da gibts doch bestimmt eine gute Lösung für?
      Da stellt sich noch die Frage wenn er per Adresse geweckt werden soll , müssen die Ints ausgeschaltet sein?
    • Pluto25 wrote:

      da gibts doch bestimmt eine gute Lösung für?
      Ja, TWI-INT verwenden. Man muss aber nicht auf alle Status-Werrt reagieren,
      Aber immer das TWINT-Flag löschen!

      Pluto25 wrote:

      Da stellt sich noch die Frage wenn er per Adresse geweckt werden soll , müssen die Ints ausgeschaltet sein?
      Der Auszug der Tabelle bezieht sich jetzt nur auf den Slave im Receiver-Mode.
      Der Slave kann ja auch im Transmit-Mode betrieben werden.

      Selbiges gilt für Master, der ja auch Senden und Empfangen kann.

      Multimaster gibt es ja auch noch.

      Ich denke, wenn der TW-INT den Slave wecken sollte, dann muss man einen Sleepmode wählen, der auch diesen Imterrupt bzw. den TWI überwacht.
      Dazu im Datenblatt lesen.

      Es ging hier ja nur um die Problemlösung des hängenden Programms.

      Und ich vermute hier ist der Hund begraben.
    • Hallo Leute, ich bin dabei die Lösungsvorschläge durchzuarbeite.
      ich habe auch schon daran gedacht allen Slaves die selbe Adresse zu geben und jeder Slave lädt die für ihn bestimmten Tabellen,
      anschließend kann ich den Startbefehl an Alle senden.