- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 2 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 11 bis 20 von 31

Thema: PWM Erzeugung 18* Simultan

  1. #11
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Anzeige

    Powerstation Test
    Da können dann schlimmstenfalls 2 Flanken zusammenfallen.
    Bei meiner 18er Version wird jede ISR pro 20ms-Zyklus 10 mal angesprungen. Wenn wirklich zufällig eine ISR warten müsste würde das nur ein paar Takte dauern. Das sollte sich am Servo nicht bemerkbar machen.

    Geschwindigkeitsprobleme bei Servoansteuerungen hatte ich mit C bisher noch nicht.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  2. #12
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Ort
    Preetz
    Alter
    37
    Beiträge
    150
    Es klappt jetzt. ich erzeuge jnun je drei signale parallel und im ungünstigsten fall hat der letzte der drei eine abweichung von 50 takten. kann ich mit leben. aber ich werde die signale natürlch so legen, dass dieser fall eigentlich nie eintritt.
    (c) Rechtschreibfehler sind rechtmäßiges Eigentum des Autors (c)

  3. #13
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Ort
    Preetz
    Alter
    37
    Beiträge
    150
    Hi, nochmal...
    kan mir jemand sagen, warum mein sortieralgorithmus nicht funktioniert?
    Ich habe schon alle hilfvariablen gelöscht, aber der compiler scheint die innere If funktione einfach weg zu kürzen, zumindest komme ich im simulator niemals bis in die innere zuweisung. ich habe schon die suchrichtung umgekehrt, aber es hat nicht geholfen...
    Code:
    for(int8_t j=0;j<18;j++)						// Werte in sorted sortieren und Sortierung in indexbuf merken
    	{
    		sorted[j]=65535;
    		for(int8_t k=j;k<18;k++)
    		{
    			if(sorted[j]>=calibrate[k])
    			{
    				sorted[j]=calibrate[k];
    				indexbuf[j]=k;
    			}
    		}
    	}
    mfg WarChild
    (c) Rechtschreibfehler sind rechtmäßiges Eigentum des Autors (c)

  4. #14
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    20.07.2009
    Ort
    Wien
    Beiträge
    131
    nur so als idee: man hat ja zwischen den servopulsen mengen an zeit, in denen kann man vorberechnen:

    Code:
    struct {
      uint8_t portb, portc, portd;
      uint16_t next_intr;
    } timings[18];
    also für jeden interrupt-zeitpunkt bereits vorberechnet haben, welche bitmuster auf welchen ports ausgegeben gehören, und welcher wert als nächster in den timer gehört.

    damit läßt sich der code in der ISR ziemlich reduzieren:

    Code:
    ISR(TIMER1_COMP_vect) {
      PORTB = timings[cur_timer].portb;
      PORTC = timings[cur_timer].portc;
      PORTD = timings[cur_timer].portd;
      OCR1 = timings[cur_timer++].next_intr;
    }
    da da keine conditionals drin sind, weiß man genau, wieviele zyklen die ISR braucht, und kann beim aufbauen der timer-tabelle berücksichtigen, ob genug zeitabstand zwischen 2 werten ist oder man die besser zusammenfasst.

  5. #15
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Ort
    Preetz
    Alter
    37
    Beiträge
    150
    Gute Idee!
    Aber weiß jemand eine Antwort auf mein sortierproblem?
    das ist eigentlich ne ganz banale sache.
    die außere schleife speichert den durch die innere schleife als minimum bestimmten wert an erster stelle des sort[] arrays. aber das wird einfach übergangen... vlt auch wegoptimiert.

    Lösung: nachdem ich die hilfs arrays global angelegt habe, hat es funktioniert... Fragt mich nicht warum.
    (c) Rechtschreibfehler sind rechtmäßiges Eigentum des Autors (c)

  6. #16
    Benutzer Stammmitglied
    Registriert seit
    07.06.2009
    Alter
    59
    Beiträge
    83
    18x PWM riecht nach Hexabot

    nimm doch pro Bein einen ATtiny25/45/85 Automotive - die sind 8-Pin Dip und stellen 4 PWM-Kanäle zur Verfügung (dann aber nur basierend auf 2 8 Bit Timern - was IMHO genug genau ist)

    8 Pins:

    Vcc
    Gnd
    Reset

    I2C Data
    I2C Clock

    PWM-1
    PWM-2
    PWM-3



    KISS - keep it simple and stupid

    Dann hat der Hauptprozessor auch keine Arbeit mehr.

  7. #17
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Ort
    Preetz
    Alter
    37
    Beiträge
    150
    ich bin jetzt mit meiner Lösung ganz zufrieden.
    Da die werte sortiert sind und immer ein ganz kurzer, ein mittlerer und ein ganz langer impuls gleichzeitig erzeugt werden, kommt es nie zu dem problem, dass die differenzzeit zwischen je drei Impulsen zu gering ist, um den ISR zu durchlaufen. ich habe den Hexapoden jetzt 10 minuten "zufällig" bewegen lassen, und die Fälle, bei denen er vorzeitig beenden musste zählen lassen. ich kann nur soviel sagen... es kam zu keinem überlauf meiner 8-Bit Zählvariablen. bei einem Überlauf wäre ein konrollpin high gestzt worden.(LED). selsbt, wenn ich bei allen 18 Servos den gleichen Winkel eingestllt habe, kam es nicht dazu, da jeder servo anders kalibreirt ist und aufrgrund dieser abweichnungen gibt es anscheinend immer eine Möglichkeit die Signale mit mehr als 100 Takten differenz in dreierpärchen anzuordnen. Deshalb habe ich die sonderbehandlung von eng beieinanderliegenden Signalen herausgenommen. Dank des Simulators konnte ich die Korreturzeiten fürs Vorladen bis auf einen Takt genau bestimmen. Deshalb erreicht der Timer1 effektiv für die relevanten 1,5ms (180°) eine auflösung von über 14-Bit.(außer die signale liegen zu eng beienander, was aber nie vorkommt)

    Ich möchte behaupten, dass die auslastung des controllers größer wäre, wenn er 5 Atinys mit je 8Byte+BLA+BLA 50mal pro sekunde über I²C zu versorgen. Mein I²C Bus soll am ende nur dafür da sein, dass ein master Die Umwelterkennung und die verhaltenssteuerung macht und dem slave, der jetzt die IK und die PWMs macht nur ein paar steuerparameter bekommt, und dann eigenständig arbeitet. dass immer nur wenn sich das verhalten ändern soll ein kurzer steuer befehlkommen muss und dann hat de master wieder ruhe. Durch den ISR gehen mir jetzt alle 20ms 5000 Takte verloren und das sortieren kostet auch nochmal 13000 Takte, aber dafür ist dann alles "On-Board" und ist ein selbstgänger in der ISR.

    Falls jemand von euch auch eine Hexapoden hat.
    Wie hoch löst ihr die Koordinatensysteme auf?
    Ich arbeite jetzt im ganzahligen mm maß. Und Wie immer gibt es ein schwächstes Glied. Die Rotation des Torsos läuft wirklich bis auf 0.0078° genau aufgelöst, aber die translation erfolgt in mm schritten. Sollte ich mir auch dort die arbeit machen die auflösung zu erhöhen, oder sprengt so etwas den rahmen?.

    mfg WarChild
    Code:
    //***************Pulserzeugung + Timer**************//
    
    //**************************************************//
    void startpulse(uint8_t number)
    {
    	  switch (number)
    	  {
    	    case (0):	servo1on;	break;
    	    case (1):	servo2on;	break;
    	    case (2):	servo3on;	break;
    	    case (3):	servo4on;	break;
    	    case (4):	servo5on;	break;
    	    case (5):	servo6on;	break;
    	    case (6):	servo7on;	break;
    	    case (7):	servo8on;	break;
    	    case (8):	servo9on;	break;
    	    case (9):	servo10on;	break;
    	    case (10):	servo11on;	break;
    	    case (11):	servo12on;	break;
    	    case (12):	servo13on;	break;
    	    case (13):	servo14on;	break;
    	    case (14):	servo15on;	break;
    	    case (15):	servo16on;	break;
    	    case (16):	servo17on;	break;
    	    case (17):	servo18on;	break;
    	  }	
    }
    //**************************************************//
    
    //**************************************************//
    void stoppulse(uint8_t number)
    {
    	  switch (number)
    	  {
    	    case (0):	servo1off;	break;
    	    case (1):	servo2off;	break;
    	    case (2):	servo3off;	break;
    	    case (3):	servo4off;	break;
    	    case (4):	servo5off;	break;
    	    case (5):	servo6off;	break;
    	    case (6):	servo7off;	break;
    	    case (7):	servo8off;	break;
    	    case (8):	servo9off;	break;
    	    case (9):	servo10off;	break;
    	    case (10):	servo11off;	break;
    	    case (11):	servo12off;	break;
    	    case (12):	servo13off;	break;
    	    case (13):	servo14off;	break;
    	    case (14):	servo15off;	break;
    	    case (15):	servo16off;	break;
    	    case (16):	servo17off;	break;
    	    case (17):	servo18off;	break;
    	  }	
    }
    //**************************************************//
    
    
    //**************************************************//
    SIGNAL (SIG_OVERFLOW2)								// 1ms Interrrupt
    {
    	TCNT2 = 256 - 250;								//Timer2 mit 6 neu vorladen
    	timer2++;
    	timer3++;
    	if(timer2 == 20)								//je in 3ms Abstand drei Impulse starten
    	{
    		timer2 = 0;									//timer2 endet bei 20ms
    		signal = 0;
    	}
    	if(timer2 == 18)
    	{
    		pulsecalculator();
    		nextIK=1;
    	}
    	else if(timer2%3 == 0)							//alle 3 ms außer 18 s.o. je drei Signale starten
    	{
    		uint8_t a=sortindex[signal],b=sortindex[signal+1],c=sortindex[signal+2];
    		startpulse(a);
    		startpulse(b);
    		startpulse(c);
    		cli(); 
    		TCNT1 = 65536-dtime[signal]+ISRdelay1; 	//Timer1 neu vorladen
    		sei();
    		TIFR |= (1 << TOV1);						//alten Overflow löschen
    		TIMSK |= (1 << TOIE1);
    	}	
    }
    //**************************************************//
    
    
    //**************************************************//
    SIGNAL (SIG_OVERFLOW1)								//Wird von Timer1 freigegeben und beendet die durch Timer2 gestarteten Pulse
    {	
    	stoppulse(sortindex[signal]);					//letzten Impuls beenden
    	signal++;										//nächstes Signal
    	if(signal%3)									//solange signal kein vielfaches von drei ist die nächste zeit vorladen
    	{
    		uint16_t time=dtime[signal];
    		if(time<ISRdelay2)
    			TCNT1 = 65536-time;
    		else
    			TCNT1 = 65536-time+ISRdelay2;
    	}
    	else											//sonst Timer1 beenden
    		TIMSK &= ~(1 << TOIE1);
    }
    //**************************************************//
    (c) Rechtschreibfehler sind rechtmäßiges Eigentum des Autors (c)

  8. #18
    Benutzer Stammmitglied
    Registriert seit
    07.06.2009
    Alter
    59
    Beiträge
    83
    Zitat Zitat von WarChild
    Ich möchte behaupten, dass die auslastung des controllers größer wäre, wenn er 5 Atinys mit je 8Byte+BLA+BLA 50mal pro sekunde über I²C zu versorgen.
    Wie oft du neue Positionen an die Motoren übermitteln musst (ich denke, dir geht es um fliessende Bewegungsabläufe) hängt davon ab, wie du es implementierst.
    du kannst auch zum normalen laufen feste positionen für jedes bein definieren oder auch synchronisierte abläufe und die dann einfach anfordern. der lokale µC übernimmt dann die Beschleunigung, bzw. eine gleichmässige geschwindigkeit.


  9. #19
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.05.2008
    Ort
    Oststeinbek
    Alter
    34
    Beiträge
    607
    Sehr interessantes Programm! Wirklich schön geschrieben!
    Das einzige, was nicht so schön ist, ist dass ständig irgendwelche Interrupts raushüpfen =) Das könnte störend sein, wenn man was über einen Bus übertragen will. Das lässt sich hier aber kaum vermeiden.

    Ich habe gerade meine ASM-Routine fertiggeschrieben. Wenn ich mal Zeit habe und es brauche, werde ich einen ähnlichen Code wie du schreiben.

    Gruß, Yaro

  10. #20
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Ort
    Preetz
    Alter
    37
    Beiträge
    150
    @ Yaro

    Mein Ziel ist es nicht nur primitive festgelegten Bewegungsabläufen zu folgen, sondern dynamisch die beine nachzusetzten, während eine fortlaufende translation und rotation die fußpunkte unter dem bot wegbewegt, und nebenbei kann auchnoch eine statische translation und rotation eingestellt werden. (dann kann Er beim laufen mit drei freiheitsgraden (Vor/Rück,Rechts/Links,Rotation Rechts/Links herum) und nebenbei den Körper frei über den Füßen bewegen und orientieren) Da diese Methoden nur im globalen Koordinatensystem funktionieren müssen alle berechnungen in einem Chip vollbracht werden. Die Datenmenge die da anfällt würde jeden Bus sprengen und dank der Festpunktarithmetik lässt sich das alles in nur 5.3ms bei 16MHz von einem ATMega32 ausrechnen. Die fortlaufenden translation und rotation sowie das dynamische Bein nachsetzen fehlen noch, aber ich denke das sollte ebenfalls in 5ms machbar sein.
    (c) Rechtschreibfehler sind rechtmäßiges Eigentum des Autors (c)

Seite 2 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test