- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 5 von 5

Thema: 2 Servos mit PWM ansteuern

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    19.01.2006
    Ort
    Aschaffenburg
    Beiträge
    23

    2 Servos mit PWM ansteuern

    Anzeige

    E-Bike
    Hallo Leute,

    ich möchte 2 Servos mittels PWM im "Phase and Frequency Correct"-Modus ansteuern. Mit dem untenstehenden Programm funktioniert allerdings immer nur jeweils ein Servo. Wenn ich beide gleichzeitig aktiviere dann zuckeln sie nur sinnlos herum. Wie kann ich beide Servos gleichzeitig zum Laufen bringen?

    MfG
    Nico

    Code:
    #ifndef F_CPU
    	#define F_CPU 16000000
    #endif 
    
    #include <avr/io.h>
    #include <util/delay.h>
    
    // Servoansteuerung
    #define U_LIMIT 2000
    #define L_LIMIT  1000
    #define TOP      20000
    
    #define SPEED(x) (L_LIMIT + ((( U_LIMIT - L_LIMIT ) / 255.0 )*x))
    #define SETBIT(x,n) ((x)|=1L<<(n))
    #define WAITMS(x)	_delay_loop_2(((F_CPU * 0.001) / 4)*x)	/**< 1 ms delay */
    
    void init(void)
    {
    
        ICR1 = TOP;			// ICR1 as TOP
    	
        SETBIT(DDRD,PIND4); // Port PD4 (OC1B) als Ausgang
        SETBIT(DDRD,PIND5); // Port PD5 (OC1A) als Ausgang
    	
        SETBIT(TCCR1A,COM1A1);	// OCR1A on
        SETBIT(TCCR1A,COM1B1);	// OCR1B on
        SETBIT(TCCR1B,CS11);	        // Prescaler 8
        SETBIT(TCCR1B,WGM13);	// Phase and Frequency Correct PWM
        
        //OCR1A = L_LIMIT + ((U_LIMIT-L_LIMIT)/2); // <-- Problem
        OCR1B = L_LIMIT + ((U_LIMIT-L_LIMIT)/2);
    }
    
    int main(void)
    {
      unsigned char c;
      
      init();
    	
      while(1)
      {
        for(c=0;c<=255;c++)
        {
          //OCR1A = SPEED(c);  // <-- Problem
          OCR1B = SPEED(c);
          WAITMS(10);
        }
      }
    }

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Ich kann deinen Code so auf die Schnelle nicht nachvollziehen aber mich stören in zeitkritischen Anwendungen Warteschleifen unheimlich. Ich habe mir mit diesen Schleifen schon die unmöglichsten Fehler eingehandelt die nur sehr schwer nachzuvollziehen sind. Vieleicht überdenkst du mal das.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    19.01.2006
    Ort
    Aschaffenburg
    Beiträge
    23
    Hallo,

    danke für die Antwort. An dem WAITMS(10) liegt es leider nicht. Auch wenn ich das WAITMS weglasse und einmalig beide Servos in feste Positionen bringen möchte funktioniert dies nicht.

    Ich habe das Programm nochmals etwas modifiziert und diesmal FastPWM genutzt. An dem Problem hat sich jedoch nichts verändert. Es läuft immer nur ein Servo. Der andere muss kommentiert bleiben.

    Code:
    #ifndef F_CPU
    	#define F_CPU 16000000
    #endif
    
    #include <avr/io.h>
    #include <util/delay.h> 
    
    // Werte für OCR1A/OCR1B
    #define U_LIMIT	4000	// oberes Limit
    #define L_LIMIT	2000	// unteres Limit
    
    // Obergrenze Zähler
    #define TOP		40000
    
    // Makro für Normierung auf Werte zwischen 0 und 255
    #define SPEED(x)	(L_LIMIT + ((( U_LIMIT - L_LIMIT ) / 255.0 )*x))
    #define WAITMS(x)   _delay_loop_2(((F_CPU * 0.001) / 4)*x)
    
    void init(void)
    {
    	ICR1 = TOP;				// ICR1 as TOP
    
    	DDRD |= (1 << PIND4); // Port PD4 (OC1B) als Ausgang
    	DDRD |= (1 << PIND5); // Port PD5 (OC1A) als Ausgang
    	
    	// Aktiviere OCR1A und OCR1B und setze Waveform Generation Mode 14
    	TCCR1A = 0x00 | (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);	// OCR1A und OCR1B an
    	TCCR1B = 0x00 | (1 << CS11)   | (1 << WGM12)  | (1 << WGM13);	// Prescaler 8, 16 Bit Fast PWM, TOP ist ICR1
    	
    	// Servos in Mittelstellung
    	OCR1A = SPEED(127);
    	//OCR1B = SPEED(127);			// <- Problem
    }
    
    int main(void)
    {
    	unsigned char c;
    	init();
    	while(1)	// Hauptschleife
    	{
    		for(c=0;c<=255;c++) // Servos von Minimalstellung zu Maximalstellung fahren
    		{
    			// setze Servopositionen
    			OCR1A = SPEED(c);
    			//OCR1B = SPEED(c);		// <- Problem
          
    			// Zeit schinden
    			WAITMS(10);
    		}
    	}
    }
    MfG
    Nico

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Bist du sicher, daß deine Schaltung ok ist? Wenn zB zwei Servos zusammen zu viel Strom saugen und der µC resettet oder spinnt, dann kannst du so nen Effekt bekommen. Geht es, wenn zu die 2 Servos simultan an einem PWM-Kanal betreibst? Also die Soaftware genauso lässt wie sie mit einem Servo geht, aber nur die 2 Dinger an einen Pin anklemmen.
    Disclaimer: none. Sue me.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    19.01.2006
    Ort
    Aschaffenburg
    Beiträge
    23
    Arghh,

    stimmt, das Problem lag in der Schaltung. Die beiden Programme funktionieren wunderbar! Mein fehler war, dass ich Servos und Atmel mit verschiedenen Stromquellen verbunden hatte und vergessen habe die Massen untereinander zu verbinden.

    Grüße,
    Nico

Berechtigungen

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

Labornetzteil AliExpress