Servoprogi läuft net richtig!

Gast #329541
Lesenswert?

Guten Morgen!

Hab mal ein kleines Progi geschriebne welches mir den Servo TS 222
(viell. bekannt) steuern sollte. Leider klappt es nicht richtig. Der
Servo dreht sich LANGSAM bis zum linken(oder rechts -> Sichtweise)
Anschlag,kann dann logischerweise nicht weiter, aber der Motor will
noch immer drehen. Anstatt der 400mA die er sonst entnimmt braucht er
jetzt nur mehr 130mA.
hmm....mein Progi ist im Anhang.Könntet ihr mal rein schauen?
Verwende den Timer 2 vom 89C52.

Mfg Cri
Angehängte Dateien:
Gast #329549
Lesenswert?

OK.Hab die LST Datei mal aufgemacht und da steht die Zeilennummer und
bei der ISR steht auch ne andere Nummer.Muss ich die nebrigen Nummern
einfach addieren? sind das µs oder was bezeichnen die?

LST ist im Anhang.

Mfg Cri
Angehängte Dateien:
Gast #329555
Lesenswert?

sorry wollt ja nur wissen wie es geht da im DATENBLATT nichts von
prescaler drin steht.Das Datenblatt habe ich außerdem gelesen sonst
wüßte ich ja net mal wie ich den Timer initialisiere. Habe schon
Eigeninitiative aber wenns mal nicht klappt braucht man HILFE.
Gast #329556
Lesenswert?

@Peter: es handelt sich um einen 8051er und icht um einen AVR (auch wenn
beide von Atmel sind, haben sie nichts miteinander zutun.)

@Crisitan: Da ich eher im Bereich AVR zuhause bin, stochere ich
eigentlich auch nur rum...
Deine ISR würde ich eher so schreiben:


void T0_int(void) interrupt 5
{
  if(ez ==1)
  {
  Servo_out = 1;
  RCAP2L = 0x23;  // T2 mit 64 035 = 0xFA23 vorladen = 1.5ms
  RCAP2H = 0xFA;
        ez = 0;
  }
  else
  {
         Servo_out = 0;
  RCAP2L = 0xDF;  // T2 mit 45 535 = 0xB1DF vorladen  = 20ms
  RCAP2H = 0xB1;
  ez=1;
  }

Das ist für mich einfach schlüssiger.
Gast #329557
Lesenswert?

hmm...Dein Vorschlag funzt nicht. Ist aber irgendwie klar. EZ wird nie
größer als 1 in deinem Progi da du hier

if(ez ==1)
  {
  Servo_out = 1;
  RCAP2L = 0x23;  // T2 mit 64 035 = 0xFA23 vorladen = 1.5ms
  RCAP2H = 0xFA;
        ez = 0;
  }

EZ immer auf null zurücksetzt.
Das Programm startet ja mit EZ=0.
void main (void)
{
  ez=0;
  Servo_out = 0;
.
.
.
.
.

Aber Danke für deinen Versuch.
Ich hab schon einiges probiert aber leider ohne Erfolg.
Mfg Cri
Gast #329558
Lesenswert?

Wieso sollte es auch grösser als 1 werden?
Man hat doch nur 2 Zustände (und zwei Zeiten):
Wenn ez = 0, wird beim nächsten ISR-Aufruf der Ausgangspin auf H-Pegel
gesetzt und die entsprechende Zeit (1,5ms) für den Timer eingestellt.
Wenn ez = 1, wird beim nächsten ISR-Aufruf (Ende der 1,5ms) der Pin auf
L-Pegel gesetzt und die andere Zeit (20ms) eingestellt.
#329559
Lesenswert?

> EZ wird nie größer als 1 in deinem Progi da du hier
Schau dir den Vorschlag noch mal an.
ez ist eine Flag-Variable. Wenn sie 0 ist, wird der else
Zweig ausgeführt. Im Rahmen des else Zweiges wird ez auf
1 gesetzt. D.h. Beim nächsten Aufruf der Funktion wird
dann der if Teil ausgeführt der u.A. ez wieder auf 0 setzt, woraufhin
beim nächsten Aufruf wieder der else Zweig ausgeführt wird,
der ez wieder umschaltet um im nächsten Aufruf wieder den if Zweig
auszuführen, etc.
Gast #329560
Lesenswert?

Also ich habe mich schlecht ausgedrückt.

void T0_int(void) interrupt 5
{
  ez++;
  if(ez ==1)
  {
  Servo_out = 1;
  RCAP2L = 0x23;  // T2 mit 64 035 = 0xFA23 vorladen = 1.5ms
  RCAP2H = 0xFA;
        ez = 0;
  }
  else
  {
         Servo_out = 0;
  RCAP2L = 0xDF;  // T2 mit 45 535 = 0xB1DF vorladen  = 20ms
  RCAP2H = 0xB1;
  ez=1;
  }

Ich habe ez++; noch dazu geschrieben.
Also,wenn die ISR aufgeruffen wird dann wird ja ez inkrementiert und
auf 1 gesetzt.Dadurch ist die 1.if-Bedingung erfüllt.
Nun wird der If-Zweig abgearbeitet und ez=0 gesetzt.

Nun denke ich,dass else gleichbedeutend mit if(ez !=1) zu sehen
ist,oder?
Wenn ja, würde die else-Bedingung ja ebenfalls erfüllt sein da ja ez =0
ist.somit wird die else_anweisung abgearbeitet und alles ist beim
Alten.

Stimmt das so?

Ahm...das Prgoi funzt aber leider nicht .
Mfg Cri
Gast #329563
Lesenswert?

Vielleicht solltest du dir mal C-Grundlagen antun:

if (Bedingung)
{
  Anweisungen1;
}
else
{
  Anweisungen2;
}

Bedeutet: Wenn Die Bedingung erfüllt ist (z.B. "ez == 1") werden
Anweisungen1 ausgeführt.
Ist die Bedingung nicht erfüllt, werden Anweisungen2 ausgeführt.
Es handelt sich nur um EINE Abfrage mit einer Alternative, die bei
Nichterfüllung ausgeführt wird.
Gast #329567
Lesenswert?

Leder geht es so auch net.
Ist bei mir im timing was falsch??

der interne Takt ist doch fosc (also 12MHz) / 12  => 1MHz

1MHz = 1µs d.f.: jeder Takt dauert eine µs. Bei 65536 wären das ja
65,536ms oder?
Bin ihc schon wieder komplett falsch unterwegs?
Gast #329568
Lesenswert?

seid ihr nun verärgert? Kommt schon :)

Kanns vielleicht daran liegen dass ich den Servo (signalleitung) direkt
am µC hängen hab?
Muss ich da evetuell einen Transistor vorschalten?
#329569
Lesenswert?

Ich kenn den Chip nicht, kann daher nicht entschlüsseln was
du da beim Timer-Setup treibst, aber:

> der interne Takt ist doch fosc (also 12MHz) / 12  => 1MHz

Das kommt mir spanisch vor. Solche Teiler sind normalerweise
2-er Potenzen. Bitte, möglich ist alles, aber glauben tu ich's
nicht.
Gast #329571
Lesenswert?

@Karl Heinz: Das ist beim 8051er aber so... Es handelt sich dabei um
einen unveränderlichen Vorteiler, der den externen Takt (12MHz) durch
12 teilt. Moderne 8051er arbeiten teilweise ohne diese Taktteilung.
Gast #329572
Lesenswert?

Hi,

erstens das wichtigste: umbedingt am Anfang der Routine das
Interrupt-Flag löschen, für Timer2 TF2 = 0. sonst springt er nach
beendigung der Routine direkt wieder in den Interrupt. Dann arbeitest
du Im Reload-Modus, d.h. der Wert aus RCAP2 wird erst bei dem nächsten
Überlauf in den Timer geschrieben. Also muss Servo_out getauscht werden
=1 zu =0 und umgekehrt.
Und um die Sache etwas schöner zu geschtalten, kann man auch statt
einer Integerzahl ein Bit nehmen, wenn man eh nur 2 Zustände haben
will. bei Flag = ~Flag wird das Bit invertiert. Geht schneller, braucht
weniger Platz und ist verständlicher.
Es sieht so aus, als ob du mit Keil arbeitest. Wenn du sowas hast nutze
den Debuger. Bei Keil µVision3 ist auch ein Logicanalyser drin.

Henning
Angehängte Dateien:
#329573
Lesenswert?

Ich habe den Code nur mal kurz überflogen.

Mir ist da aber etwas aufgefallen.

Muß da nicht die Dauer der LowZeit 20ms-HighZeit betragen?

Denn so die es aussieht bekommt man hier 20ms+1,5ms = 21,5ms Pulslänge
zusammen und dass schlucken nicht alle Servos.

mfg Sepp
Gast #329574
Lesenswert?

Nochmal ich,

Servos fressen fast alles. In meinem Wagen betreiber ich die Servos mit
100Hz statt den üblichen 50Hz. Kein analoger oder digitaler Servor hat
sich darüber beschwert. Ob 15 oder 25 ms Pause ist nicht schlimm.
#329575
Lesenswert?

@ Henning

Muesstest du nicht du Polarität des Servo_out-Signals umdrehen?

void T2_int (void) interrupt 5
{
  static bit flag;
  //TF2 = 0;

  if(flag)
  {
    Servo_out = 0;
    RCAP2L = 0x23;  // T2 mit 64 035 = 0xFA23 vorladen = 1.5ms
    RCAP2H = 0xFA;
  }
  else
  {
    Servo_out = 1;
    RCAP2L = 0xDF;  // T2 mit 45 535 = 0xB1DF vorladen  = 20ms
    RCAP2H = 0xB1;
  }
  flag = ~flag;
}

Servos wollen normalerweise einen 1.5ms High-Puls sehen. Wenn
ich mich nicht vertan habe, dann produziert das hier aber ein
invertiertes Signal.
#329576
Lesenswert?

Salve

Bei meinen analiogen Servos mit denen ich's versucht habe, macht schon
eine Abweichung von mehr als 0,5ms bei de Pulsintervalls einen
gewaltigen Unterschied.

Es handelt sich dabei um Servos von Robbe.

Wenn da der Pulsintervall um mehr als 0,5ms abweicht, fängt der Servo
gewaltig an zu vibirieren, was den Verschleiß erhöht und den Verbrauch
um fast das Doppelte anhebt.

Wenn der Pulsintervall um mehr als 1ms abweicht, fängt der Servo an so
richtig zu flattern(+/- 20°).

Dafür schluckt das Servo eine Pulsbreite von 0,2ms bis 3ms.
Dabei hat das Servo einen Schwenkbereich von +/- 90° (von Anschlag zu
Anschlag).
Gast #329580
Lesenswert?

WOW!!!!!!!!  Super!!!!Leute es klappt :)

das ist das Progi:
/* --*******************************************-- */
/* --  Servoansteuerung mittels AT89C52 / T2    -- */
/* --  12MHz Quarz         -- */
/* --*******************************************-- */

#include <AT89x52.h>


sbit Servo_out = P1^0;


void T2_int (void) interrupt 5
{
  static bit flag;

  TF2 = 0;

  if(flag)
  {
    Servo_out = 0;

    RCAP2L = 0x23;  // T2 mit 64 035 = 0xFA23 vorladen = 1.5ms
    RCAP2H = 0xFA;
  }
  else
  {
        Servo_out = 1;

    RCAP2L = 0xDF;  // T2 mit 45 535 = 0xB1DF vorladen  = 20ms
    RCAP2H = 0xB1;
  }
  flag = ~flag;
}


void main (void)
{

  Servo_out = 0;
  RCAP2H = 0xB9;
  RCAP2L = 0xAF;  // T2 mit 45 535 = 0xB1DF vorladen  = 20ms
  //RCAP2H = 0xB1;

//### TIMER initialisieren ###
  RCLK = 0;
  TCLK = 0;
  CP_RL2 =0;
  C_T2 =0;
  TR2 = 1;  // Start
  ET2 =1;         // Timer-Freigabe
  EA = 1;    // Allg. Interrupt-Freigabe

  while(1);
}

Echt toll dass ihr euch so ins Zeug gelegt habt. Vielen Dank!!!
Mfg Cri
Gast #329581
Lesenswert?

Hi. Ich bins nochmal :)

Ist das öfter der Fall dass der Servo bei 0.6ms den Linksanschlag hat
und bei 2.4 den Rechtsanschlag?

Sorry wegen dieser banalen Frage aber ich wollt mal nachfragen.
Mfg Cri

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren