TWI Master mehrere Slave

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Alle Slaves die selbe Adresse sollte gehen. Aber das blockiert auch den Bus bis der letzte Slave reagiert hat. Vielleicht hilft der Ansatz. Das ist nie geprüft worden (ich bin auf 485 geschwenkt)

      Quellcode

      1. $regfile = "m8def.dat"
      2. $crystal = 8000000
      3. $hwstack = $40
      4. $swstack = $40
      5. $framesize = $100
      6. $eepleave
      7. $baud = 9600
      8. Config Base = 0
      9. '$sim
      10. 'b0=Db4 b1= b2=Bled b3=Mosi b4=Mi/Db5 b5=Sk/Rs b6=nc b7=nc
      11. 'c0= c1= c2= c3=nc c4=Sda c5=Slc c6=/res c7=nu
      12. 'd0=Rx d1=Tx d2=dir d3=nc d4=nc d5=Db7 d6=E d7=Db6
      13. Ddrb = $c4
      14. Ddrd = $f2
      15. Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portb.6 , Rs = Portb.7
      16. Config Lcd = 16 * 2 'Db7 von b1 auf D5 umlöten
      17. Lcd_backlight Alias Portb.2 : Set Lcd_backlight
      18. Initlcd
      19. Cursor Off
      20. Cls
      21. Dim Temp As Byte , Tempi As Integer , Tempw As Word , Tempstr As String * 6
      22. Dim Templ As Byte At Tempw Overlay
      23. Dim Temph As Byte At Tempw + 1 Overlay
      24. Dim I2cinbuf(16) As Byte , I2csendbuf(16) As Byte
      25. Dim I2cinstr As String * 16 At I2cinbuf Overlay
      26. Dim I2csendstr As String * 16 At I2csendbuf Overlay
      27. Dim I2cin As Byte , I2cout As Byte , I2cein As Byte , I2cneu As Byte
      28. Dim I2cstat As Byte , I2c2send As Byte
      29. Const I2cadr = $a0 'At24 eerom adresse
      30. Twsr = 0
      31. Twar = I2cadr
      32. Twcr = $c4
      33. On Twi Twi_isr:
      34. Enable Twi
      35. Enable Interrupts
      36. I2csendstr = "Keine Daten"
      37. Do
      38. Locate 1 , 1
      39. Lcd "Empfangen:"
      40. Lcd I2cein
      41. If I2cneu = 1 Then
      42. Lowerline
      43. Lcd I2cinstr
      44. Print I2cinstr
      45. I2csendstr = I2cinstr '
      46. I2cout = Len(i2csendstr)
      47. End If
      48. Waitms 200
      49. Loop
      50. End
      51. Twi_isr:
      52. I2cstat = Twsr And $f8
      53. Select Case I2cstat
      54. Case Is = 96 'Slave adr empfangen Ack angefordert
      55. I2cein = 0
      56. I2cneu = 0
      57. Case Is = 128 '
      58. I2cinbuf(i2cein) = Twdr
      59. Incr I2cein
      60. Case Is = 160 'Stop
      61. If I2cein > 0 Then I2cneu = 1
      62. Case Is = 168 'Slave Read
      63. I2c2send = 0
      64. Goto Letztes
      65. Case Is = 184 'Ack nach gesendetem Byte
      66. Goto Letztes
      67. 'Case Else
      68. ' Twcr = $c5
      69. End Select
      70. Twcr = $c5 'int,ack,twiEn,intEn
      71. Return
      72. Letztes:
      73. Twdr = I2csendbuf(i2c2send)
      74. Incr I2c2send
      75. If I2c2send >= I2cout Then
      76. Twcr = $85 'ohne Ack
      77. Else
      78. Incr I2c2send
      79. Twcr = $c5
      80. End If
      81. Return
      Alles anzeigen
    • Pino schrieb:

      ich habe auch schon daran gedacht allen Slaves die selbe Adresse zu geben
      Dafür gibt es den "General Call" mit Adresse 0.

      Willst du auf die Slaves eigentlich nur schreiben, oder musst du auch was abfragen?
      Hast du dir da mal Gedanken gemacht?

      Und was ist Clock24 eigentlich? Eine Uhr, die 24Stunden, also rund um die Uhr ablesbar ist?
      Oder werden da mehrere Uhren (in deinem Fall 12?) Uhren benutzt um eine Uhrzeit darzustellen?
    • Moin,
      Das mit der Adresse 0 hab ich auch gelesen, funktionierte aber nicht auf Anhieb. Aber es ist ja kein Problem jedem Slave die gleiche Adresse zum geben und das hat sofort funktioniert.
      Ich schreibe nur zum Slave ohne Abfrage.
      Clock 24 besteht aus 24 analog Uhren ( 3x8 ) wobei die Zeiger quasi die Zeit in Form einer digital Uhr anzeigen. Kostet ca 1000€
      Ob das sinnvoll ist, weiß ich nicht ,aber ich bin Rentner und habe Zeit und mir macht das basteln Spaß.
      Ich habe erst mal nur 6 Uhren , um zu sehen ob ich das hinbekomme , wenn ja werde ich weitere Stepper ordern und weiterbauen.
      Ich habe mal ein Bild angehängt.
      Dateien
      • Clock.jpg

        (151,85 kB, 14 mal heruntergeladen, zuletzt: )
    • Pino schrieb:

      Das mit der Adresse 0 hab ich auch gelesen, funktionierte aber nicht auf Anhieb.
      Das ist ja logisch, vermutlich hast du das Bit 0 im Adress-Register nicht gesetzt und auch die falschen Status-Werte abgefragt.
      Bei General Call gibt es ebenfalls andere Status-Werte.

      Wenn du allen Slaves die gleiche Adresse gibst, ist das in meinen Augen Murks.
      Dafür ist das TWI- bzw. I2C-Bus Konzept nicht gedacht.

      Das ist ja wie wenn du in einem Mehrfamilienhaus jedem einfach den Genealschlüssel gibst und den Salat mit Motoröl anmachst, einfach nur weil es funktioniert.

      Wenn du dein Code veröffentlichst, dass andere was davon haben, werden die mit sowas vermutlich nicht rechnen.

      Wie ist es dir ergangen mit dem Code-Schnipsel aus dem Internet?
      Code aus dem Internet copiert und läuft nicht.

      Für mich ist das Murks mit den gleichen Adressen für mehrere Slaves, aber es ist dein Projekt.

      Ich würde es gleich richtig machen. - Es sind ja nur wenig änderungen notwendig (2x Statuscode für General Code ändern und das Bit 0 im Slave-Adress-Register).

      Wer weis, was du als nächstes noch an den Bus anschließen möchtest, vielleicht ein Uhr-Baustein, oder doch mal was am Clock24-Slave abfragen?
      Was ist, wenn einer der Clocl24-Slaves dann hängt? Wie kriegst du raus welcher es ist?

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Mitch64 ()

    • Hallo Mitch64
      du hast Recht , das mit der gleichen Adresse ist Mist, aber leider bin ich in der TWI Technik nicht so bewandert wie du.
      Englische Datenblätter muss ich mühsam übersetzen und auch dann werden mir manche Sachen nicht richtig klar.
      du schreibst mal einfach
      Ich würde es gleich richtig machen. - Es sind ja nur wenig Änderungen notwendig (2x Statuscode für General Code ändern und das Bit 0 im Slave-Adress-Register).
      das ist für mich nicht mal so einfach, aber ich werde es noch mal versuchen.
      Ich wollte mich mit dem TWI nicht lange aufhalten und aus dem Grund habe ich auf bestehende Routinen zurückgegriffen , das finde ich auch nicht verwerflich .Warum das Rad immer wieder neu erfinden ?
      Aber du hast Recht ich werde über die vorgeschlagene Änderung mal nachdenken.
      Würde es bei der Generaladresse nicht auch Probleme geben wenn alle Bausteine gleichzeig antworten ?
    • Coole Anzeige.
      Wenn ich das richtig verstehe, willst du jedem Slave sagen, dass es 12.34 Uhr ist.
      Aufgrund seiner ihm bekannten Position in der Matrix kann er dann bestimmen, welchen Teil von der Uhrzeit er anzeigen muss.
      Da wüsste ich keinen Grund, warum du jeden einzelnen Slave mit seiner spezifischen Adresse ansprechen solltest.
      Genausogut könntest du RS232, ShiftOut/-In verwenden, um die Uhrzeit an alle zu schicken.
    • Hallo Franz,
      es sollen ja auch Animationen ablaufen dazu schicke ich eine Datentabelle an die Slaves.
      In den Tabellen stehen die Positionen die der Zeiger nacheinander anfährt und am Ende so stehenbleibt wie es die Uhrzeit verlangt .
      nicht so einfach zu erklären.
      Die Tabellen für die Uhrzeit bekommen sie vom Master .
      Es gibt dann 5 Positionen für die Stellung 12 , 3 , 6 und 9 Uhr , die 5. Position zwischen 7 und 8 Uhr wenn der Zeiger nicht gebraucht wird z.B. bei Darstellung der Eins werden ja nur 3 Uhren benötigt.
    • Pino schrieb:

      Warum das Rad immer wieder neu erfinden ?
      Da gebe ich dir recht. Genau dafür gibt es eine I2C-Slave-Lib für Bascom, zu beziehen bei mcselec.com.
      Kostet nicht die Welt und macht vieles einfacher. Das wäre vielleicht eine Alternative, wenn du beim I2C bleiben willst.

      Aber ich muss auch @Franz recht geben, mit den abderen möglichen Schnittstellen.
      RS232 würde ich jetzt nicht nehmen, und anstelle von Shift out und Shift in könnte man auch die SPI-Schnittstelle verwenden.

      Es führen ja immer mehrere Wege nach Rom.

      Man muss sich aber irgend wann festlegen und wissen was man braucht.

      Dann kann man Routinen schreiben.

      Auf der anderen Seite frage ich mich, warum du 12 Slaves brauchst. Nur wegen der Schrittmotor-Steuerung?

      Das kann man doch fast mit einem machen, sofern die Pins reichen. Und auch hier könnte man mit I2C-Expandern oder Shift-Registern die Pins erweitern.

      So gesehen bräuchtest du nur einen Controller und 2 oder 3 Schieberegister mit Latch. Der ganze Code würde sich auf ein Programm beschränken.

      Schrittmotoren an die Schieberegister und am Controller hat du alles frei.

      Wäre doch auch eine Idee, was meinst du?
    • Pino schrieb:

      wenn alle Bausteine gleichzeig antworten ?


      es sollen ja auch Animationen ablaufen
      Sie sollen ja keine Daten ausgeben, nur mit Ack quittieren das sie klar sind.

      Dann wäre eher doch eine Adresse pro Slave sinnvoll sonst müsste ja jeder alle erdenklichen Zustände kennen, heißt 13x brennen wenn eine neue Animation hinzu kommt. Da ist es vermutlich einfacher wenn der Master jedem einzeln sagen kann was er wann zu tun hat.
    • Wenn ich mir jetzt mal so hypothetisch einen einzelnen Slave vorstelle, egal wie der jetzt mit dem master verbinden ist, dann müsste der ja nur wissen, wo der Zeiger (Schrittmototr) gerade steht, und wenn er sich bewegen soll, bekommt er vom Master einfach den Stundenwert (1-12). Und der Slave läuft dann auf Kommando los.

      Die Aktuelleposition ist also 3 Uhr und er soll auf 7 Uhr, dann würde man einfach die 7 an den Slave schicken, und der rechnet dann die Steps für den Schrittmotor von der aktuellen Pos zur neuen aus und los gehts.

      Da du 12 Slaves hast, werden vermutlich pro Analog-Uhr 2 Schrittmotoren gesteuert (2 Zeiger).

      Beim Einschalten bräuchte man noch sowas wie eine Null-Position, auf die der Controler den Schrittmotor bewegt. Hierfür würde sich z.B. 12 Uhr oder 6 Uhr anbieten.

      Wie @Pluto25 schon gesagt hat, ist es doof, wenn man mal einen anderen Effekt haben möchte, 12 Slaves neu zu propgrammieren.

      Mit nur einem Programm wäre das besser zu händeln.
      Und ein Hexenwerk ist das auch nicht.

      Pro Schrittmotor 4 Pins, also Pro Analog-Uhr ein Port. Bei 12 Analog-Uhren sind es also 12 Ports oder einfach 12 schieberegister in Reihe (kaskadiert).

      Zum Bewegen wird einfach eine Tabelle mit den Neuen Positionen für die Motoren geführt, die dann komplett bei jedem Stepp rausgeshiftet wird.
      Der Takt, in dem die Motoren weitersteppen per Interrupt (Timer). Dann läuft die Sache vermutlich schon rund.

      Bei einem neuen Effekt müsste man nur die tabellenwerte für die Schrittmotoren über eine Effekt2-Routine berechnet werden.

      Ach was ich noch vergessen habe.
      Bei General Call antworten die Slaves nicht, dürfen sie auch nicht. Das würde logisch zu falschen Daten beim Empfänger führen. Aber das Ack muss natürlich gemacht werden.
    • Danke für die Anregungen,
      ich brauche pro Uhr 2 Port für die Impulse 2 Port für die Richtung und noch 2 für die Hallsensoren für die Starstellung, als 6 Pin pro Uhr . Also 12 für 2 Uhren . Der ProMini reicht gerade es kommen noch 2 Pin für TWI und 4 Pin um dem Atmega zu sagen an welcher Position er sich befindet, also für welche Uhren er zuständig ist. RXD/TXD möchte ich frei lassen um ew. umzuprogrammieren.
      Alle Slaves bekommen die gleiche Software und der Master bestimmt wohin sich die Zeiger bewegen.
      Die Uhrzeit zum Salve zu schicken würde auch gehen, aber ich möchte ja nicht nur einen Wechsel der Uhrzeit sondern ew. noch Temperaturanzeige ( Ich weiß jetzt brauch TWI für den Sensor :) ) und Animationen . für die Uhrzeit werde ich ein GPS-Modul verwenden der Empfangssicherer als DCF77 und arbeitet mit RXD/TXD .
      12 Slaves ist zwar viel aber ich finde es dann übersichtlicher und einfacher zu programmieren als mit Schieberegister.
      Die Minis sind auch schön klein, es geht ja auch um den mechanischen Aufbau . So muss ich nur 12 mal das gleiche machen.
      Noch mal zu Codeschnipsel aus dem Netz , ich wollte einfach weiterkommen und so klappt es jetzt , aber ich werde mich, wenn ich auf Bauteile warte und Zeit habe mit Master/Slave noch mal auseinandersetzen.
      Ich muss ja auch kein Auto bauen, wenn ich nur fahren will.
      Noch anbei ein Bild der Rückansicht , ist nur der Versuchsaufbau .
      Dateien
      • Clock-r.jpg

        (303,97 kB, 18 mal heruntergeladen, zuletzt: )
    • Mitch64 schrieb:

      Also bei obiger übertragung 4 mal.
      Sorry wenns sein bischen OT ist. Aber ich habs nun mal versucht. Er ist glücklicherweise viel relaxter:
      Ein Int kommt nach passender Adresse ( keine wenn andere Teilnehmer angesprochen werden oder antworten) Dann noch eins wenn ein Byte gesendet wird und noch eins bei Stop (Letzteres auch nur wenn er angesprochen wurde)
      Heißt Start Adresse Stop macht zwei Ints und jedes Datenbyte erzeugt einen weiteren.
      Also glücklicherweise kein Int-Gewitter bei Fremdkommunikation :thumbsup:
    • Pluto25 schrieb:

      Er ist glücklicherweise viel relaxter
      Stimmt.
      Bei einem reinen Slave-Receiver sind es 3 Interrupts, so wie du geschrieben hast.
      Bei anderen Transfer-Modes ist oft auch bei Start-Bedingung ein Interrupt.

      So z.B. bei Master-Transmit und Master-Receive Mode.

      Mal eine Frage zur Adressierung des Slave mit dem Read/Write-Bit.

      Nach der Adressierung des Slave wird ein Interrupt ausgelöst, Statuscode ist dann &h60. Wo steht dann das Bit, ob der Master Lesen oder schreiben will? Ist das Adressbyte mit R/W-Bit im TWDR zu finden?