- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: Servo in Mittelstellung Bring

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.02.2007
    Beiträge
    139

    Servo in Mittelstellung Bring

    Anzeige

    E-Bike
    Hallo

    Ich hätte eine Frage wie schaffe ich es einen Servo der Make HiTec Hs-311 in die Mittelpostition zu bringen.

    Ich habe es schon mit Folgendem Code Probiert. Wobei mein Servo auf dem PORT D Pin 3 liegt.


    Ist es möglich das Folgender Code mit meinem Atmega8 nicht möglich ist?

    Denn code habe ich von https://www.roboternetz.de/wissen/index.php/Servos
    Code:
    #define F_CPU 3686400
    #include <avr/io.h>
    #include <avr/delay.h>
    #include <avr/interrupt.h> 
    #define SERVOPIN 3
    #define SERVOPORT PORTD
    #define DDRSERVO DDRD
    
    volatile unsigned char servopos;
    
    void servo_init()
    {
    	TIMSK|=(1<<OCIE2);
    	TCCR2 |= (1<<WGM21) | (1<<CS20);	
    	OCR2 = F_CPU/100000;			
    	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;
    };
    
    
    int main(void) {
    	
            servo_init();
    	sei();
    	
    	
    	servopos = 150;
    	while(1);
    	
    	
    	cli();
    	
    	return 0;
    }
    Hoffe ihr könnt mir helfen.

    lg manhunt

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

    Mein asuro (mit 8MHz-Mega kann es mit deinem minimal veränderten Code:

    Code:
    #include <avr/io.h>
    //#include <avr/delay.h>
    #include <avr/interrupt.h>
    
    #define SERVOPIN 4 // Pin6
    #define SERVOPORT PORTD
    #define DDRSERVO DDRD
    
    uint8_t servopos=150;
    volatile uint16_t p=0;
    
    void pause(uint16_t p_dauer)
    {
    	p=p_dauer;
    	while(p);
    }
    
    int main(void)
    {
       TIMSK|=(1<<OCIE2);
       TCCR2 = (1<<WGM21) | (1<<CS20);
       OCR2 = 80; // Für 8MHz-Takt, 37 für 3686400Hz
    	DDRSERVO|=(1<<SERVOPIN);
    	sei();
    
       while(1)
       {
          pause(100);
          servopos=100;
          pause(50);
          servopos=200;
          pause(50);
          servopos=150;
    	}
       return(0);
    }
    
    ISR(TIMER2_COMP_vect)
    {
    	static uint16_t count=1;
    	if(count>servopos) SERVOPORT&=~(1<<SERVOPIN); else SERVOPORT|=(1<<SERVOPIN);
    	if(count<2000)count++; else { count=1; if(p) p--; }
    }
    Das hat bei mir erst funktioniert nachdem ich das TCCR2-Register direkt gesetzt hatte (ohne |) (Es kann aber auch sein, das bei meinen ersten Tests die asuro-Lib störte)

    Die Positionen stimmen nicht wirklich, aber immerhin bewegt sich was:

    Bild hier  
    http://www.youtube.com/watch?v=VNbpkGiD-YI

    Hinweis für asuro-Besitzer: Der verwendete Pin6 (PORTD4) ist beim orginalen asuro belegt, also nicht ohne Anpassung verwenden!

    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!

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.02.2007
    Beiträge
    139
    Hallo

    Danke, dein Programm bewegt meinen Servo.

    EDIT:

    Ich bin ein id**t, mein Programm funktioniert auch aber, ich habe vergessen Servo_init aufzurufen!!!

    irgendwie könnte ich mich dafür selbst eine runter hauen.

    Ich habe jetzt herum Probiert und festgestellt das der Servo ab 15 zuckt das heißt 16 ist der Linkeanschlag und Rechts zuckt er ab 79 das heißt dann wohl 78 ist der Rechteanschlag.

    Ist nun 48 genau die Mitte des Servos?

    Und warum ist es nicht 150 == 1.5ms wie im Wiki zu Servo beschrieben?



    lg manhunt

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    irgendwie könnte ich mich dafür selbst eine runter hauen.
    *lol* (Das hatte ich auch übersehen weil ich mich gleich auf die Timerinitialisierung gestürzt hatte)

    Ist nun 48 genau die Mitte des Servos?
    Mit den üblichen Angaben für die Impulslängen komme ich auch nicht zurecht. Das liegt an der Frequenz mit der die ISR aufgerufen wird. Welchen Wert lädst du nun in OCR2?
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.02.2007
    Beiträge
    139
    Hallo

    Am code selber habe ich nichts verändert. Das heißt "OCR2 = F_CPU/100000;"

    lg manhunt

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

    Möglicherweise ist die ISR zu lang und die Interrupts laufen über. Ich habe die Ausführungszeit noch nicht genau berechnet, aber so grob über den Daumen gepeilt dürfte das knapp werden. Es sind 24 Befehle in der ISR + je 9 fürs sichern und restaurieren der Register. Selbst wenn jeder Befehl nur einen Takt benötigen würde, es würde nicht reichen. Die Interrupts kommen bei prescaler=1 alle 36 Takte:

    Code:
      45               	.global	__vector_4
      47               	__vector_4:
      48               	.LFB3:
      49               	.LM6:
      50               	/* prologue: frame size=0 */
      51 0014 1F92      		push __zero_reg__
      52 0016 0F92      		push __tmp_reg__
      53 0018 0FB6      		in __tmp_reg__,__SREG__
      54 001a 0F92      		push __tmp_reg__
      55 001c 1124      		clr __zero_reg__
      56 001e 2F93      		push r18
      57 0020 3F93      		push r19
      58 0022 8F93      		push r24
      59 0024 9F93      		push r25
      60               	/* prologue end (size=9) */
      61               	.LM7:
      62 0026 8091 0000 		lds r24,servopos
      63 002a 9927      		clr r25
      64 002c 2091 0000 		lds r18,count.0
      65 0030 3091 0000 		lds r19,(count.0)+1
      66 0034 8217      		cp r24,r18
      67 0036 9307      		cpc r25,r19
      68 0038 14F4      		brge .L3
      69               	.LM8:
      70 003a 9398      		cbi 50-0x20,3
      71 003c 01C0      		rjmp .L4
      72               	.L3:
      73               	.LM9:
      74 003e 939A      		sbi 50-0x20,3
      75               	.L4:
      76               	.LM10:
      77 0040 8091 0000 		lds r24,servopos
      78 0044 9927      		clr r25
      79 0046 8053      		subi r24,lo8(-(2000))
      80 0048 984F      		sbci r25,hi8(-(2000))
      81 004a 2817      		cp r18,r24
      82 004c 3907      		cpc r19,r25
      83 004e 3CF4      		brge .L5
      84 0050 2F5F      		subi r18,lo8(-(1))
      85 0052 3F4F      		sbci r19,hi8(-(1))
      86 0054 3093 0000 		sts (count.0)+1,r19
      87 0058 2093 0000 		sts count.0,r18
      88 005c 04C0      		rjmp .L2
      89               	.L5:
      90               	.LM11:
      91 005e 1092 0000 		sts (count.0)+1,__zero_reg__
      92 0062 1092 0000 		sts count.0,__zero_reg__
      93               	.L2:
      94               	/* epilogue: frame size=0 */
      95 0066 9F91      		pop r25
      96 0068 8F91      		pop r24
      97 006a 3F91      		pop r19
      98 006c 2F91      		pop r18
      99 006e 0F90      		pop __tmp_reg__
     100 0070 0FBE      		out __SREG__,__tmp_reg__
     101 0072 0F90      		pop __tmp_reg__
     102 0074 1F90      		pop __zero_reg__
     103 0076 1895      		reti
     104               	/* epilogue end (size=9) */
     105               	/* function __vector_4 size 50 (32) */
    Mögliche Lösungen: Schnellerer Kontrollertakt, ISR in Assembler schreiben oder weniger Interrupts pro Zeit (z.B.: OCR2 = F_CPU/50000 Dann wird zwar die Auflösung geringer und die Werte für die Positionen müssen halbiert werden, aber dafür stimmen dann die Wiederholungen.

    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!

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.02.2007
    Beiträge
    139
    Hallo

    Trotz verringerter OCR2 = F_CPU/50000 verändern sich die Start und END Werte von 16 bis 78 nicht am Servo.

    Mittlerweile habe ich einen zweiten Servo der Marke Zebra ZS-S2113 benutzt und dort auch die selben Werte minimal verändert erhalten (17 bis 77)

    Gibts noch andere Ideen oder ist das doch normal?

    lg manhunt

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

    Bist du sicher dass dein Mega8 mit 3686400Hz rennt?

    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!

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.02.2007
    Beiträge
    139
    Hallo

    Sicher bin ich mir nicht auf jedenfall ist ein Quarz mit der Aufschrift 3.6864 drann.

    Allerdings weiß ich net ob der Aktiv ist.

    gibts da irgend nen Test?

    lg manhunt

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

    Mit den externen Takten habe ich noch keine Erfahrungen gemacht. Im Datenblatt des Mega8 steht:
    The device is
    shipped with CKSEL = “0001” and SUT = “10” (1 MHz Internal RC Oscillator, slowly rising
    power).
    Also taktet er defaultmässig mit 1MHz. Wenn er nicht den "Quarz" beachtet müsste der Teiler für OCR2 10 sein (1000000/100000). Dann wären die Servo-Werte im Bereich von ca. 50-200, aber nur 10 Takte Zeit für die ISR. Bei OCR2=100 (10kHz) müssten die Werte von ca. 5-20 sein mit 100 Takten für die ISR. Das könnte funktionieren, wenigsten testweise um festzustellen, welcher Takt verwendet wird. Man könnte natürlich auch die Parametrierung des Takts überprüfen wenn man das kann. btw. muss der Überlauf für count bei 10kHz auf 200 geändert werden.

    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!

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests