Forum: Mikrocontroller und Digitale Elektronik Servo Ansteuerung


von Peter K. (Gast)


Lesenswert?

Hallo zusammen,

ich bin gerade dabei, einen Servo anzusteuern.
Dank der Seite "Modellbauservo Ansteuerung" funktioniert das fast 
perfekt.
Mein Code sieht so aus:
1
#define F_CPU 1000000UL
2
3
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
#include <util/delay.h>
7
8
9
ISR(TIMER1_COMPA_vect)
10
{
11
  OCR1A = 2500-OCR1A;
12
}
13
14
int main (void)
15
{
16
  DDRB = 0b00000011;
17
  PORTB = (1<<PB1);
18
    
19
  TCCR1A |= (1<<COM1A0);
20
  TCCR1B |= (1<<WGM12) | (1<<CS11);
21
  TIMSK1 |= (1<<OCIE1A);
22
23
  OCR1A = 2190;
24
25
  sei();
26
27
  while (1)
28
  {
29
    cli();
30
    OCR1A = OCR1A + 5;
31
    sei();
32
    _delay_ms(100);
33
34
    if ( OCR1A == 2420)
35
    {
36
      cli();      
37
      OCR1A = 2190;
38
      sei();
39
      _delay_ms(1000);
40
      _delay_ms(1000);
41
    }
42
    
43
  }
44
45
  return 0;
46
47
}

Der Servo startet an einer Endposition und läuft zur anderen 
Endposition, dort wartet er 2 Sekunden.
Allerdings habe ich nun das Problem, dass er zwischendurch ab und zu 
auch ein paar Schritte wieder Rückwärts macht. Leider kann ich mir das 
nicht erklären.
Kann es sein, dass der Controller durch die delays irgendwie 
durcheinander kommt?
Wie gesagt, er fährt die Strecke ab, nur zwischendurch kommt ein kleiner 
Hüpfer rückwärts. Dies ist auch auf dem Oszi zu sehen, dass sich 
kurzzeitig die PWM wieder ändert.

Hat jemand von euch eine Idee, was hier falsch läuft.

Danke
Peter

von Manno (Gast)


Lesenswert?

ich hatte mal ein ähnliches problem mit zuckenden servos (alle paar 
sekunden, ansonsten lief alles astrein).

das problem war folgendes:
ich hatte noch ein LC-display angeschlossen und daten darüber 
ausgegeben.
die display-routine hat das timing versaut. dadurch wurden hin und 
wieder die pulslängen verzogen.

einzige lösung bei mir:
display-routine entfernen

danach ging alles wunderbar

von Heinz L. (ducttape)


Lesenswert?

Da ich nun selten mit delay arbeite weiss ich es nicht mit Sicherheit, 
meine Vermutung geht aber in die Richtung dass delay sehr anfällig ist 
auf debug code, sprich, dass es alles mögliche aber nicht genau ist 
solang Debug-Info im Code rumspukt.

Mal davon ganz abgesehen, dass hinter delay-Funktionen sehr erhebliche 
Fließkommaoperationen stecken, die insgesamt alles mögliche aber nicht 
schnell sind und damit timings insgesamt gesehen schon recht 
durcheinanderbringen können.

Versuch mal das Ganze als Release-Version zu kompilieren und die 
Optimierung aufzudrehen.

Insgesamt habe ich bei meinen Servoprojekten das Timing überhaupt gleich 
mal selbst in die Hand genommen und die PWM dafür ausgespart. Damit kann 
man dann auch gleich noch einige Servos mehr ansteuern (und verbrät 
keine Rechenzeit in delays).

von Peter K. (Gast)


Lesenswert?

LCD Routine verwende ich ja nicht.
Aber ich werde mal versuche, das Programm so umzuschreiben, dass ich 
keine delays brauche.

von Peter K. (Gast)


Lesenswert?

Jetzt habe ich den Fehler gefunden.
Es waren nicht die delays, die den Fehler verursachten.
Vielmehr war es das Problem, dass ich nicht immer den Wert sauber 
hochgezählt habe. D.h. es wurde nicht immer der Wert zwischen 2190 und 
2420 inkrementiert, sondern auch ab und zu das Ergebnis aus der 
Berechnung aus der Interruptroutine
1
ISR(TIMER1_COMPA_vect)
2
{
3
  OCR1A = 2500-OCR1A;
4
}

Wenn ich das ganze nun abfange, indem ich noch eine Abfrage mach, ob ich 
einen Wert über 2000 momentan im OCR1A Register stehen habe, läuft der 
Servo sauber durch:
1
while (1)
2
  {
3
    if (OCR1A > 2000)
4
    {
5
      cli();
6
      OCR1A = OCR1A + 1;
7
      sei();
8
      _delay_ms(20);
9
10
      if ( OCR1A == 2420)
11
      {
12
        cli();      
13
        OCR1A = 2190;
14
        sei();        
15
             _delay_ms(1000);
16
             _delay_ms(1000);        
17
      }
18
    }
19
  }

Gruß
Peter

von Sven M. (svenm)


Lesenswert?

Hallo,

ich bin ein kompletter Nichtswisser auf dem Gebiet der Mikrocontroller, 
bin aber trotzdem mit einem Projekt beschäftigt, bei dem mir meiner 
Meinung nach nur ein solcher weiterhelfen kann.

Ich möchte zwei RC-Servos parallel mit einem Eingangssignal ansteuern, 
daher poste ich auch in diesem Thread.
Das Eingangssignal kommt von einer Welle, die jeweils 540° in jede 
Richtung drehen kann. In den Winkelbereichen zwischen +120° und -120° 
möchte ich nun linear besagte Servos ansteuern.
Um nun von dieser Welle ein Signal zu bekommen, wollte ich ein 
Mehrgangpotentiometer mit dieser verbinden.

Ist es möglich, dem Widerstandswert, der vom Poti kommt, mithilfe eines 
MCs nun eine Servoposition in Form einer Tabelle oder derartiges 
zuzuordnen? (+120° = Vollausschlag links / -120° = Vollausschlag rechts 
und den Rest in 2°Schritten dazwischen)

Wenn das alles möglich ist, wäre jemand bereit, mir im Ruhrgebiet bei 
der Umsetzung meines Projektes zu helfen?

Mit freundlichem Grüßen

Sven

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.