PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Arbeitsteilung zw. 2 µC's - Wie würdet ihr es machen?



Willa
15.02.2009, 19:08
Hi!
Mein Tricopter (https://www.roboternetz.de/phpBB2/viewtopic.php?t=44744&postdays=0&postorder=asc&start=0) fliegt demnächst (wenn es wärmer ist und der Gyrotemperaturdrift nicht mehr so nervt) autostabil. Das eröffnet die Möglichkeit den Copter autonom fliegen zu lassen. Allerdings erfordert das zusätzliche Sensorik die ich meinem ATmega32 nicht mehr zumuten kann. Er ist mittlerweile ziemlich ausgelastet. Also müssen sich wohl zwei µCs die Arbeit teilen. Hinzukommen würde ein GPS Modul und ein Höhenmesser (Ultraschall,Luftdruck oder beides weiss ich noch nicht).
Wie könnte man das nun machen? Ist die Kommunikation per TWI schnell genug (es sollten mit 400 Hz 4 bytes übertragen werden)? Benötigt die einen Timer? Wieviel Rechenaufwand fällt an um Daten zu empfangen? Macht es evtl. Sinn den Empfänger auf einem anderen µC auszuwerten als auf dem der die Motorsignale ausgibt?

Bevor ich mich mit TWI stärker auseinandersetze (ich finde irgendwie wenig verständliche Anleitungen im Netz...) würde ich gerne eure Empfehlungen hören und herausfinden ob das ganze so überhaupt Sinn macht....

So sieht das im Moment aus, neu hinzukommen würden die Komponenten auf der rechten Seite.
http://www.villalachouette.de/william/krims/tricopter/schema%20tricopter.ai.jpg

Volly42
15.02.2009, 20:52
Hut ab! Tolles Projekt.

Ich hatte ähnliche Überlegungen bei einem anderen Projekt. Also die TWI Schnittstelle läuft als Interrupt, aber im Interrupt selbst sind Wartezeiten drin (bis die entsprechenden Bits gesetzt sind usw...), dies kann Dir Ärger machen in den bisher aufgebauten Routinen, der TWI Interrupt steht zwar fast am Schluss, aber ich weiß jetzt nicht, ob der AVR einen Interrupt (in Deinem Fall den Timer 0 für die Antriebsregelung) unterbricht, wenn ein anderer reinkommt. Der TWI kann auch bis 400 kHz, was eigentlich reichen müßte.

Hast Du mal getestet, wie viel Luft Dein AVR noch hat z.B. Togglebit im Timer auf Oszi gemessen? Wenn hier kaum noch Luft ist, sehe ich die Sache als schwierig an. Dann wäre zu überlegen, einige Aufgaben dem zweiten Kontroller zu übergeben, sprich die Funktionen auf beide Kontroller zu verteilen, dies bricht zwar das Konzept mit der Sensortrennung, würde Dir aber wahrscheinlich etwas Luft verschaffen.

Eine andere Lösung wäre es einen 8 Bit Parallelbus aufzubauen zwischen den Kontrollern -- ohne TWI. Du würdest den einen Kontroller die Daten auf die Leitungen legen lassen und den andere würde sie dann nur am Port abholen, dies ließ sich auch dann über ein Bit einfachst steuern lassen, wenn Du mehrere Daten brauchst, verwendest Du einfach mehr Auswahlbits. (z.B. 3 Bit sind 8 verschiedene Datenbytes). Du mußt natürlich die Eingänge am Hauptkontroller noch freihaben.

Gruss
Volly

Willa
15.02.2009, 22:28
Hi Volly!

Hast Du mal getestet, wie viel Luft Dein AVR noch hat z.B. Togglebit im Timer auf Oszi gemessen?
Meine Regelung läuft mittlerweile nur noch mit ca. 200Hz. Ich glaube viel langsamer sollte das nicht mehr werden, sonst wird es instabil bzw. schwingt sich auf.

Eine andere Lösung wäre es einen 8 Bit Parallelbus aufzubauen zwischen den Kontrollern
Das klingt sehr interessant.... 10 Ports um 4 verschiedene bytes zu übertragen.... Das müsste eigentlich noch frei sein... Ich würde dann im zweit µC einfach die Daten aus GPS, Höhe und Heading fertig berechnen lassen und an den Haupt-µC die fertigen Sollwerte für die Motoren und das Heckservo übertragen... Das sollte doch funktionieren? Wenn ich das richtig verstehe kann ich die Werte dann genau so schnell abfragen wie mein µC läuft. Also bei 200 Hz und vier Daten immerhin mit 50 Hz... Vielleicht kriege ich den Haupt-µC aber auch noch schneller, allerdings bringt mir Code-optimieren nicht so viel Spaß wie neue Sachen zu implementieren X-D. Müssten die beiden µCs aber nicht auch synchronisiert werden? Dafür geht dann wahrscheinlich auch noch einiges an Zeit drauf.
Ist auf jeden Fall ein sehr interessanter Ansatz, werde mal darüber nachdenken. Hast du das schonmal ausprobiert bzw. jemand anderes aus dem Forum?

Netzman
15.02.2009, 23:32
theoretisch kannst du deine 4 Byte Telemetriedaten über einen 400Khz TWI Bus mit ~4,76Khz übertragen (wenn ich das jetzt richtig gerechnet habe). Pro 4-Byte Block kommen noch Start- und Stoppbit, Read/Write Bit und 7 Bit Adresse dazu.
Das sollte doch reichen, oder? :)

Den 8-Bit Bus mit den Select Bits kannst du theoretisch mit der halben Taktfrequenz (Ohne Sync) auslesen, das ergäbe max. 8MB/sek, das ist für einen AVR doch etwas viel an Daten.
So ein Bus ist zwar recht einfach zu implementieren, aber doch etwas oversized. Und zum 4-Bit Bus ists auch nicht weit.

Um ein bisschen mehr Luft bei der Verarbeitung zu bekommen, könntest du zb. einen Mega88 einsetzen, der geht bis 20Mhz.

mfg

Manu_91
16.02.2009, 06:57
von wegen 20Mhz - da würd ich dir nen Atmega644 empfehlen, der ist pinkompatibel zum Atmega32 - dann brauchst nicht zu viel an deiner Schaltung ändern :)

ikarus_177
16.02.2009, 08:31
Hi,

bzgl. 8-Bit Parallel Bus: ich würde da noch sowas wie eine Fehlerkorrektur einbauen - ich hab bei meinem Bot die Kommunikation auch so gestaltet, und ohne Korrektur war beinahe jedes dritte Byte fehlerhaft - nicht so wahnsinnig gut ;-) Mit Korrektur ist die Fehlerquote nun bei 0%.


Viele Grüße

Willa
16.02.2009, 08:56
Hi!

theoretisch kannst du deine 4 Byte Telemetriedaten über einen 400Khz TWI Bus mit ~4,76Khz übertragen (wenn ich das jetzt richtig gerechnet habe). Pro 4-Byte Block kommen noch Start- und Stoppbit, Read/Write Bit und 7 Bit Adresse dazu.
Das sollte doch reichen, oder?
Wenn mein µC nichts anderes zu tun hätte würde das reichen... Aber wie es scheint haut einem TWI wohl mit interrupts dazwischen.

Den 8-Bit Bus mit den Select Bits kannst du theoretisch mit der halben Taktfrequenz (Ohne Sync) auslesen, das ergäbe max. 8MB/sek, das ist für einen AVR doch etwas viel an Daten.
Wie soll ich mit 8MHz auslesen...? Dazu brauche ich einen Loop der mit 8Mhz läuft oder? Meiner läuft aber wie gesagt mit 200 Hz...

von wegen 20Mhz - da würd ich dir nen Atmega644 empfehlen
Den hatte ich ursprünglich auch eingeplant, allerdings passen 16Mhz sehr viel schöner für die Timerinterrupts für die Servoansteuerung...

bzgl. 8-Bit Parallel Bus: ich würde da noch sowas wie eine Fehlerkorrektur einbauen
Hast du denn eine synchronisation? Dem Zweit-µC muss doch mitgeteilt werden dass der Erst-µC seine Daten abgeholt hat. Also bräuchte man wohl noch einen zusätzlichen Port den der Erst-µC nur auf high setzt wenn er bereit ist daten zu empfangen... Während der high-zeit sendet µC2 einen konstanten wert, während der low zeit erstellt er den nächsten wert... Oder so ähnlich...
Ich programmiere in Bascom, gibt es hier wohl eine Funktion oder ein Beispiel wie man aus den einzelnen Port-Bits ein Byte zusammenschraubt mit dem sich weiter rechnen lässt?
Danke auf jeden Fall für eure Anregungen @all

ikarus_177
16.02.2009, 09:01
Hi Willa,

ich hab sowohl einen 8 Bit - Bus vom "Master" zum "Slave", als auch wieder zurück. So kann der Slave die Daten zurücksenden, um sie überprüfen zu lassen.

Ich würde mich nicht auf eine Kommunikation ohne Rückmeldung verlassen, denn durch die Motoren ist schnell eine Störung "eingesät", und so ein Tricopter ist schneller am Boden als ein Hexapod ;-)

Viele Grüße

oberallgeier
16.02.2009, 09:17
Hi,


... Wenn mein µC nichts anderes zu tun hätte würde das reichen... Aber wie es scheint haut einem TWI wohl mit interrupts dazwischen ...GENAU mit diesem Problem schlage ich mich seit einiger Zeit herum. Nun habe ich keinen xxCopter - nur einen "popeligen" Zweiräder. Aber der ist auch mit einigen empfindlichen Interrupts gespickt (https://www.roboternetz.de/phpBB2/download.php?id=15412) - Zeitgeber 20kHz, Regelung für zwei Motoren - also 2 x 405 Hz, irDME - 1,22 kHz. Dazu noch zwei extINT für die Drehzahlerfassung der Motoren mit ISR bis jeweils max. 1500 Hz. - normal etwa je 1 kHz.

TWI hatte ich noch nie installiert - die hier vorgelegten Argumente hatte ich schon mal rausgehört - und daher TWI weggelegt/abgehakt. Tatsächlich funktioniert hatte bei mir die Kommunikation zwischen zwei Controllern mit dem seriellen Protokoll "TTL"232. Lief bisher in der Testphase zufriedenstellend und fehlerfrei mit 57600 Bd. Ich hatte es noch nie in der eigentlichen Funktionsumgebung realisiert, da ich mir den zweiten Controller bisher gespart hatte. Das scheint mir als Kommunikation zwischen zwei Kontrollern sinnvoll und ausreichend schnell zu sein - und die Hardware ist ja bei megas praktisch immer vorhanden. Ich hatte auch angedacht einen dritten Controller dranzuhängen, der mir die Kommunikation zum PC ermöglich - der die Steuerbits für die µC-µC-Verbindung ausblendet und nur Daten "nach aussen" durchlässt.

@Willa: Übrigens hast Du mich auf einen weißen Fleck in meiner Auslegung gebracht. Ich hatte zwar alle ISR zeitlich recht genau ausgemessen - aber NIE die Kommunikation :(. Na ja, wie gesagt - das war bisher nur Testphase.

Jedenfalls wünsche ich Dir viel Erfolg

theborg
16.02.2009, 09:23
Hi,

bzgl. 8-Bit Parallel Bus: ich würde da noch sowas wie eine Fehlerkorrektur einbauen - ich hab bei meinem Bot die Kommunikation auch so gestaltet, und ohne Korrektur war beinahe jedes dritte Byte fehlerhaft - nicht so wahnsinnig gut ;-) Mit Korrektur ist die Fehlerquote nun bei 0%.

Viele Grüße

Naja 8bit gehen auch ohne clockleitung ... must nur zwei ports verbinden die interupt on change unterstützen den haste die daten sobald sich was Ändert must nur immer hinungdherschalten wegen senden / entfangen altanativ spi

Willa
16.02.2009, 13:14
SPI, hmmm, das klingt auch interessant. Hatte ich mich noch nie mit auseinandergesetzt (außer beim programmieren...... :-D)
Scheint sich sehr einfach implementieren zu lassen in BASCOM, da werde ich einfach mal RN-Control und Tricopter zusammenhängen, Bytes hin und herschicken und die Frequenz meiner Regelung messen... Oder gibt es hier Erfahrungswerte? Wie sieht das hier aus mit Interrupts/ Timern etc?

Willa
27.02.2009, 07:53
Hi,
ich habe jetzt mal eine SPI Kommunikation zwischen zwei Mega32 aufgebaut. Allerdings bin ich nicht ganz zufrieden: Mein Master überträgt 4 bytes zum Slave. Nur scheint dadurch der Slave total ausgelastet zu sein. Das liegt wohl daran dass ich ein "on SPI" interrupt verwende, aber wie komme ich ohne den aus..?

Hier der Code vom Master:


'MASTER
'===CHIP SETTINGS===
$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 16000000
$baud = 19200

'SPI
Config Spi = Hard , Interrupt = Off , Data Order = Lsb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4

'SPI
Dim A(4) As Byte
Enable Interrupts
Spiinit

'Main Loop soll nur die 4 Bytes verändern
Do
If A(1) < 200 Then
Incr A(1)
Else
A(1) = 16
End If

If A(2) < 250 Then
Incr A(2)
Else
A(2) = 0
End If

If A(3) > 1 Then
Decr A(3)
Else
A(3) = 233
End If

If A(4) > 60 Then
Decr A(4)
Else
A(4) = 160
End If

Spiout A(1) , 4
Waitms 3 '300Hz transfer von 4 bytes ist das ziel
Loop


Der code vom Slave:


'===CHIP SETTINGS===
$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 16000000
$baud = 19200

'SPI
Config Spi = Hard , Interrupt = On , Data Order = Lsb , Master = No , Polarity = High , Phase = 1 , Clockrate = 4
Dim A(4) As Byte

Enable Interrupts
On Spi Wasempfangen
Enable Spi
Spiinit

Do
Toggle Led_gelb
Waitms 3 'wenn die led regelmäßig hell ist -> µC läuft ungestört. Ist aber nicht so
Loop

'SPI
Wasempfangen:
Spiin A(1) , 4
Toggle Led_rot 'diese flackert auch sehr unregelmäßig
Return


Alle Leitungen (MOSI, MISO, SCK, SS) sind direkt 1:1 verbunden. Hatte es zwar erst aus "Sicherheitsgründen" mit 10k Widerständen versucht aber da ging gar nix.

Hat jemand einen Tipp wie ich ohne Interrupts auskomme? Ich dachte mein Haupt-µC soll der Slave sein, da er dann kein SCK erzeugen muss. Ist das sinnvoll? Wie könnte überhaupt ein Master Daten vom Slave empfangen?

Was auch ein bisschen nervt: Zum programmieren (über die ISP Schnittstelle) muss ich jedes mal die SPI Verbindung Master/Slave trennen, sonst werden die µC's nicht erkannt. Gibts da vielleicht nen Trick?

Vielen Dank für eure Hilfe!

Volly42
27.02.2009, 10:19
Hallo.

Ich kenne mich mit Bascom überhaupt nicht aus, aber nach der Dokumentation hast Du eine SPI Clock von 16Mhz/4=4MHz. Dies kommt mir sehr hoch (Störeinflüsse usw.), vielleicht versuchts Du mal den Teiler 128, dies sollte nach Atmega Doku auch gehen. Mal sehen wie sich dann die LEDs verhalten.

Gruss
Volly

Crazy Harry
27.02.2009, 14:21
Hi,

auch ich kenne mich mit Bascom nicht aus, aber ich habe schon öfter 2 Megas per TWI verbunden. Der Master holt sich bei mir die Daten, wenn er sie braucht und Zeit hat :D
Der Slave liest Sensoren, berechnet und legt die Ergebnisse in einem Puffer ab, auf den der Master freien Lese/Schreibzugriff hat.

In einer anderen Schaltung habe ich ein Display (DOG-M132 und 128) mit einem Mega32 bzw Mega644 ausgestattet und dem die ganze Verwaltung/das Zeichnen überlassen. Die Masterschaltung steuert über TWI das Display. Allerdings schickt der Master nur z.b. $11,$00,$00,$7F,$3F,$FF und der Slave zeichnet ein Rechteck (Befehl $11) mit den Eckkoordinaten 0,0,127,63. das $FF am Ende ist das Musterbyte der Umrandung. Ich habe die Datensatzlänge auf 16 Bytes Nutzdaten festgelegt. maximal möglich wären 64k !. Zu den Nutzdaten kommen bei mir noch Start/Stop und eine Prüfsumme. Das macht aber alles mein Compiler bzw. die Library ;)

gruss
Harry

Volly42
27.02.2009, 17:54
Hallo Harry,

dies klingt sehr interessant:



Der Slave liest Sensoren, berechnet und legt die Ergebnisse in einem Puffer ab, auf den der Master freien Lese/Schreibzugriff hat.


Aber was verstehst Du unter einem Puffer (Dual Port Ram?)?

Gruss
Volly

Willa
28.02.2009, 10:32
@Crazy Harry:
Im moment probiere ich noch SPI aus, aber vielleicht ist TWI doch besser geeignet?!?

So, ich habe mal fleißig weiter mit SPI rumprobiert. Auch wenn ich den Teiler auf 128 setze - sobald ich den SPI Interrupt benutze zerhauts mir den Rest meiner Ansteuerung (Servos zucken dann rum etc).
Ich habs jetzt auch mal ohne Interrupt versucht. In diesem Fall wartet der µC dann einfach so lange bis über SPI was reinkommt. Falls nichts kommt wartet er eben ewig und blockiert meine Regelung total. Das ist das gleiche wie der Bascom Befehl "INPUT" bei dem ewig auf Daten per RS232 gewartet wird.
Jetzt komm ich nicht so richtig weiter....


Der Slave liest Sensoren, berechnet und legt die Ergebnisse in einem Puffer ab, auf den der Master freien Lese/Schreibzugriff hat.
Ich glaub so etwas bräuchte ich auch. Und falls der Master mal nichts abholen sollte, dann sollten die Daten im Puffer vom Slave einfach ersetzt werden...

Crazy Harry
01.03.2009, 20:38
Aber was verstehst Du unter einem Puffer (Dual Port Ram?)?
das ist etwas kompliziert zu erklären. ich programmiere nicht mit bascom, c oder assembler, sondern mit pascal (avrco) und dort gibt es eine unit für twinet. ich definiere im slave einen puffer (z.b. 16 byte) der im programm dann TWIrxBuff[] und TWItxBuff[] heißt und auf diese variablen hat sowohl der master als auch der slave zugriff.

aber im endeffekt ist das nichts anderes als RAM im slave.

Volly42
02.03.2009, 19:46
@Harry

Die Idee mit dem Array im Slave ist eine gute Lösung, so bräuchte man keinen Interrupt mehr im Master, sondern der würde sich die Daten einfach dann abholen, wenn er sie braucht. Das Schreiben vom Slave in sein eigenes würde dann zyklisch mit einem Timer erfolgen.

Hardwaretechnisch wäre dies auch mit einem zusätzlichen SRAM mit SPI Schnittstelle lösbar:

http://ww1.microchip.com/downloads/en/DeviceDoc/22100C.pdf

Das Problem beim Teil ist nur, daß die Spannungen mit 3,3 V laufen, ob hier einfach Spannungsteiler einsetzbar sind, kann ich nicht beurteilen.

Gruss
Volly

Willa
28.03.2009, 20:45
Tatsächlich funktioniert hatte bei mir die Kommunikation zwischen zwei Controllern mit dem seriellen Protokoll "TTL"232. Lief bisher in der Testphase zufriedenstellend und fehlerfrei mit 57600 Bd. Ich hatte es noch nie in der eigentlichen Funktionsumgebung realisiert, da ich mir den zweiten Controller bisher gespart hatte. Das scheint mir als Kommunikation zwischen zwei Kontrollern sinnvoll und ausreichend schnell zu sein - und die Hardware ist ja bei megas praktisch immer vorhanden.
Ja da hat Joe wohl wieder recht... Nach gescheiterten Versuchen mit SPI habe ich es doch noch mal mit dieser "so unprofessionell nach Terminal klingenden Schnittstelle" versucht. Und siehe da: Perfekt! Sauschnell, eigentlich unkompliziert und auf die Bedürfnisse anpassbar.
Ich werde drei Bytes (zusätzliche Motor-Sollwerte) von einem Mega8 auf nen Mega32 übertragen. Ohne Übertragung läuft die Regelung mit 359Hz, wenn ich mit 200Hz Daten übertrage läufts noch mit 347 Hz. Also wirklich perfekt für meine Zwecke. Die Sensorwerte können im Mega8 komplett vorverdaut werden, das entlastet den Haupt µC zusätzlich.

Besserwessi
28.03.2009, 22:11
Das Problem scheint ja gelöst zu sei, aber man könnte versuchen weiter mit einer µC auszukommen. Mit dem Mega644 hätte man mehr Speicher und wenn man statt BASCOM die Programmierung in C macht, sollten besonders die Interruptzeiten deutlich schneller werden. Auch sonst ist der Code vermutlich etwas kürzer und schneller.

Wenn man nur 2 µCs koppelt hat die UART tatsächlich ein paar Vorteile, weil es halt kein Bus ist und das Protokoll einfacher ist. An sich sollte aber auch TWI oder SPI gehen ohne das alles andere zu stark ausgebremst wird. Das könnte an den vordefinierten Routinen von BASIC liegen.

thewulf00
29.03.2009, 11:28
@Willa:
Wenn Du -welchen Bus auch immer Du verwendest- auf Interrupts verzichtest, dann musst Du nicht auf die Werte warten.
Du kannst einfach in jedem Schleifendurchlauf nachschauen, ob schon Werte da sind, wenn nicht, dann einfach weitermachen. Wenn sie da sind, dann verarbeiten, und dann weitermachen.
Das ist ein einfacher IF-Zweig, sehe da keine Probleme.