PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Komunikation zwischen zwei Atmegas



manhunt
28.09.2008, 15:56
Hallo


Ich möchte bei einem zukünftigen Projekt Messwerte auslesen und nach diesen Messwerten 2 Servos ansteuern. bis jetzt habe ich analog servos benutzt die ich mit einem Atmega8 per PWM angesprochen habe. Leider wird wohl die restlich Rechenzeit die nach dem Servo PWM übrig bleibt nicht für die Berechnung und Erfassung der Messwerte Reichen.

Nun würde ich gerne einen Atmega 644 zum erfassen der Messwerte benutzen und mit einem Atmega8 das PWMs für die servos erzeugen.

So wie bekomme ich nun die Information vom einen Atmega in den nächsten oder gibt es einen einfacheren Weg als einen 2ten Atmega?

lg manhunt

Jaecko
28.09.2008, 16:03
Die einfachste Übertragungsart wäre der I2C-Bus. Die Hardware ist bei den ATMegas meistens schon mit drin.

marvin42x
28.09.2008, 16:46
Im Rn-Wissen Bereich gibt es gute Artikel zu I2C
https://www.roboternetz.de/wissen/index.php/TWI_Praxis
https://www.roboternetz.de/wissen/index.php/TWI_Praxis_Multimaster

Für das RNBFRA Board, wo ein Mega32 und ein AT90S2313, oder ersatzweise ein ATtiny2313 als Co- Controller für 10 Servos ihren Dienst tun gibt es auch eine I2C Verbindung der beiden Controller.
Dazu existiert auch ein Multimaster Beispiel.
Also wie Jaecko schon sagte I2C ist eine übliche Art das zu machen.

Netter Gruß

manhunt
28.09.2008, 17:27
Danke für eure Infos, ich habe im netzt jetzt auch von der Möglichkeit per UART erfahren. Kann mir vielleicht jemand dazu etwas sagen? Bzw worauf muss ich achten, gleiche Quarze bei den Prozessoren?

Weiß jemand zufällig wie ein Schaltung per UART aussehen würde?

lg manhunt

Jaecko
28.09.2008, 17:33
Naja gleiche Quarze müssen nicht sein; man kann die Bitrate ja auswählen.
Von der Schaltung her isses genau so einfach wie beim I2C.
Tx vom einen Controller an Rx vom anderen. Nur bei RS232 kann man im Normalfall nur 2 Controller verbinden. Es gehen zwar dort auch mehr, man muss dann aber sicherstellen, dass immer nur einer senden kann, da es sonst Datensalat gibt.
Also wenns nur 2 sein sollen, ginge RS232 auch.

Meine persönliche "Vorliebe" ist aber I2C, da man dort problemlos mal weitere Geräte anstöpseln kann, ohne zusätzliche Pins zu besetzen... also mal kleine Tastaturen oder Displays für Debug-Ausgaben etc.

manhunt
28.09.2008, 17:41
Hallo

Ich habe leider bis heute weder mit dem UART noch mit I2C am uC gearbeitet und würde die leichtere Variante bevorzugen, frage bei welchem von beiden ist weniger Programmieraufwand bzw rechenleistung notwendig?

lg manhunt

Jaecko
28.09.2008, 19:01
Man kann beide Interrupt-gesteuert laufen lassen. Vom Aufwand her kommt mir RS232 einfacher vor; weil man hier keine Zustandsunterscheidung vom TWI braucht (Slave Receiver, Slave Transmitter, Master Receiver, Master Transmitter etc...)

Beim RS232 könnte man noch nen FIFO einbauen (Code gibts glaub ich auch im Wiki hier), so dass man mit einer Funktion entweder einen Ascii-Code vom empfangenen Zeichen bekommt oder eben -1, falls nix neues da ist.

Beim I2C/TWI kann man sich aber mitunter eine Protokollstruktur sparen, da hier keine "Steuerzeichen" benötigt werden, um eine neue Übertragung zu erkennen.

oberallgeier
28.09.2008, 20:05
... 2 Servos ansteuern ... wird ... restlich Rechenzeit ... nicht ... Reichen ... UUUUps - dann hast Du entweder einen etwas langsamen Quarz oder Prozessortakt (1 MHz oder weniger?), oder eine viel zu umständliche Programmiererei.

PWMs macht man möglichst mit Timern und den PWM-Ports. Da gibts was in der Suchfunktion etc.

Wenn nur die PWM-Werte übertragen werden, dann dauert vermutlich die Kommunikation über die Schnittstellen zu einem anderen Controller länger als der PWM-Aufwand - wenn der ordentlich programmiert wurde. Notfalls nimm halt statt dem mega8 - der nur 16 MHz kann - einen m168, der kann 20 MHz. Die 4 MHz mehr sollten für einen ganzen Haufen PWM´s reichen . . .

manhunt
28.09.2008, 21:11
Hallo

Ich benutze den Servo PWM code vom Wiki und wenn der wie im Wiki beschrieben alle 10uS aufgerufen wir geht das ganz schön in die Rechnenzeit.


Hier der "Wiki" code wobei meiner noch auf 2 Servos ausgebohrt wurde.





#define SERVOPIN 7
#define SERVOPORT PORTD
#define DDRSERVO DDRD

volatile unsigned char servopos;

void servo_init()
{
TIMSK|=(1<<OCIE2);
TCCR2 |= (1<<WGM21) | (1<<CS20); //Prescale=1, CTC mode
OCR2 = F_CPU/100000; //alle 10µS ein IRQ
DDRSERVO|=(1<<SERVOPIN);
};

ISR(TIMER2_COMP_vect)
{
static int count;
if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
else SERVOPORT|=(1<<SERVOPIN);
if(count<2000+servopos)count++;
else count=0;
};



lg manhunt

Besserwessi
28.09.2008, 21:56
Gerade bei den etwas größeren Controllern hat man eigentlich genug Hardware PWM Kanäle, auch mit 16 Bit Auflösung. Man ist dann nur in der Wahl der Pins eingeschränkt. Wegen der relativ langen Pausen sollte man schon 16 Bit Auflösung nehmen. Als Nächst beste Alternative auch nur einen 8 Bit timer, dann aber für Pause und Puls getrennt und mit jeweils nur eine ISR Aufruf. Also 1 x warten für lange Pause (ca. 18 ms) 1 x Puls für 1. Servo und 1 x Puls für 2.ten Servo. Das sollte mit weniger Rechenzeit auskommen.

manhunt
28.09.2008, 23:11
Könntest du das vielleicht genauer erklären ich verstehe nemlich nur Bahnhof, ps die 2 servos haben unterschiedliche postionen (immer)

lg manhunt

Dirk
29.09.2008, 11:12
Hallo manhunt,

der ATmega 8 hat 3 Hardware-PWM Optionen.

Für deine Hardware bzw. Platinenentwicklung brauchst du nur darauf achten, dass die beiden Servos an 2 der Pins PB1 (OC1A), PB2 (OC1B) oder PB3 (OC2) angeschlossen werden.

Dein Programm muss diese PWM nur anfangs für beide Servos initialisieren, danach läuft die ganz allein ohne Ressourcen deines Programms zu verbrauchen.

Du must im Programm immer nur dann, wenn das Servo in eine neue Position fahren soll einen Wert übergeben, das sind nur wenige Taktzyklen. Alles andere ist für dein Programm frei.
Also: Du hast über 99% für eigene Dinge frei.

Gruß Dirk

manhunt
29.09.2008, 16:02
Danke für die einfache Antwort mal schauen was ich zum thema hardware pwm finde.

lg manhunt