-
        

Ergebnis 1 bis 2 von 2

Thema: Servo ruckel-zuckelt mit meiner ersten PWM

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    24.08.2007
    Ort
    Pforzheim/ Nürnberg
    Alter
    35
    Beiträge
    14

    Servo ruckel-zuckelt mit meiner ersten PWM

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Hallo!

    Ich hab mich jetz doch tatsächlich an die µC Programmierung gewagt und muss sagen: Ihr habt recht! Soo schwer is es nicht. Man muss sich nur rantrauen.
    Der Elektriker in unserer Werkstatt hat mich mit Testboard und einem Pic ausgerüstet hat und der Software zum C programmieren. Es kann losgehen!

    Ich möchte jetz gern einen Servo schwenken lassen, je nachdem wie weit ich an einem Poti (steuerknüppel aus einer alten Fernbedienung) schiebe.

    Das bestehende Grundprogramm hab ich soweit geändert/ ergänzt, dass es mir passt. Allerdings reagiert der Servo nicht so schnell auf eine Potiänderung. Außerdem ruckelt/korrigiert er auch in Ruheposition manchmal rum.

    Woran liegt das, bzw. wie kann ich es besser machen?

    Code:
    /*Grundprogramm für PIC 12F629/675
      zum Einlesen eines Analogwertes mit Anzeige auf dem LC-Display
     
      belegt min.4 max.5 Ausgänge
        825 Codewords
         30 Bytes RAM
    
    //Pinbelegung des 12F629:            Funktion:
    //Pin1    VPP    +5V                +5V
    //Pin2    GP5     IOP    INT on Ch./T1CKI/OSC1    in out Funktion5    SI    Serielle Daten
    //Pin3    GP4    AIOP    INT on Ch./T1G/OSC2        in out Funktion4    CLK      Serieller Takt
    //Pin4    GP3     I        INT on Ch./MCLR\        in     Funktion3   
    //Pin5    GP2    AIOP    INT on Ch./Cout/INT/T0CIin out Funktion2    RS    Daten(1)/Steuerzeichen(0)
    //Pin6    GP1    AIOP    INT on Ch./Cin-/Vref+    in out Funktion1    Servo
    //Pin7    GP0    AIOP    INT on Ch./Cin+            in out Funktion0    AD-Kanal 0
    //Pin8    Gnd    0V                GND
    */
    
    #pragma config |=0b000.1.1.1.0.0.0.100
    //                   ||| | | | | | | +++----Oscillator Selection Bits    (100=intern)
    //                   ||| | | | | | |+-------Watchdog timer             (1=enable)
    //                   ||| | | | | +----------Power up timer             (0=enable)
    //                   ||| | | | +------------MCLR\ select *)            (0:RA5=IO; 1:RA5=MCLR\)
    //                   ||| | | +--------------Brown out reset         (1=enable)
    //                   ||| | +----------------Flash-Programm memory protection(0=enable)
    //                   ||| +------------------EE-Prom memory code protected    (0=enable)          
    //                   +++--------------------nicht implementiert
    
    
    //   Konstanten        Portzuweisung    I/O Funktionsbeschreibung
    
    bit    SI             @ GPIO.5;    //I/O     Serial Input
    bit    CLK            @ GPIO.4;    //I/O     Clock
    //bit Taste_3    @ GPIO.3;    //I    
    bit    RS            @ GPIO.2;    //I/O     Daten/Steuerzeichen (Da=1; St=0)
    bit Servo        @ GPIO.1;    //I/O     Hintergrundbeleuchtung         (Option)
    //bit CSB         @ GPIO.0;    //I/O     Analogkanal
    
    
    #include "delay4.c"            //Timer0 wird verwendet
    #include "LC_Display.c"        //LC-Display Hilfsprogramme
    #include "AD_Wandler.c"        //AD-Wandler Hilfsprogramme
    //#include "MATH24F.H"         //Mathematikroutinen
    
    
    //    Variablen                Funktionsbeschreibung
    
    uns16    Z;            //Zählervariable
    uns16    i;
    uns16 AD_wert;        //eingelesener AD-Wert
    uns16 Wert;
    //float24 U;
    //-------------------Hauptprogramm-------------------------------------------------------------
    
    void main(void)
    {
    //-------------------Konfiguration des PIC
    //Anm.: Erst Ausgänge setzen, dann Konfigurieren (wg. Spikes)
    
    GPIO=    0b.00.00.0.000;        //Port Grundeinstellungen Statusregister
    TRISIO=    0b.00.00.1.001;        //Port Eingänge definieren (1=Eingang; 0=Ausgang)
    
    //--------------------AD-Wandler, nicht relevant für 12F629
    
    ADCON0=0b.10.00.0001;        //AD-Wandler konfigurieren
    ANSEL=0b.0.001.0001;        //Bit 0..3: GPIO 0..3=Analog(=1) / Digital(=0) Bit4..6:AD Clock
    
    //--------------------Komperator
    
    CMCON=0b.0.0.0.00111;        //Komperator aus
    
    //-------------------Timer 0 (8bit)
    
    T0CS=0;                    //Timer0 externen/internen Takt verwenden (1=extern; 0=intern)
    PSA=0;                    //Vorteiler: 1=WDT zuordnen; 0=Timer0 zuordnen
    PS2=0;                    //Vorteiler: Teilerwert PS2..PS0; Tabelle gilt für Timer0,
    PS1=0;                    //000=1:2;  001=1:4;  010=1:8;   011=1:16;
    PS0=1;                    //100=1:32; 101=1:64; 110=1:128; 111=1:256;
    T0IE=0;                    //Timer0 Interrupt erlauben (1=ja; 0=nein)
    
    //--------------------Konfiguration der Variablen
    
    //Z=0;
    Servo=0;
    
    //CSB=0;                //Chipselect ein                            (Option)
    //LCD_Init();                //LCD Anzeige initialisieren
    //LCD_Back=1;            //LCD Hintergrundbeleuchtung einschalten    (Option)
    
    ruecksprung:
    
    //Hauptprogramm
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
    //U=AD_wert/10.23;
    //U=U*25;
    //Wert=U;
    //ZahlString(' ',AD_wert,"mm",5,0,',',0,0,0);
    //ZahlString(' ',Z," km/h",4,2,',',0,0,6);   
    //Vorz.,Zahl,Einheit,Stellen[1..5],Vorkommastellen,Trennzeichen,V.Nullen[0=nein,1=ja],Zeile,Position
    
    
    Delay1ms(14);
    AD_wert=Analogwert(0);        //Kanal 0 einlesen
    AD_wert=AD_wert/12;
    
    Servo=1;                      //Servo bekommt Signal
    i=0;                               
    for (i=0; i<95; i++)        //Signal soll gehalten werden bis i zu 60 hochgezählt hat: 60 ist starker Linksausschlag
        {;}                        //für einen SchleifenDurchgang braucht er 12µs. 1000µs:12=85,3 also i gleich 85 setzten um 1 ms zu bekommen
           
    //nop();                    //No operation lässt µC genau 1 µs warten       
    //i=0;a
    //while (i<AD_wert) {i++;}
    
    for (i=0; i<AD_wert; i++) // Er braucht 85 Schleifen um 1ms zu warten. Der AD_Wert vom Poti kann 0 bis 1024 betragen. --> 1024/85
        {;}
    
    
    
    Servo=0;                    //Signal wird abgesetzt. Servo hat also 1 PWM Signal bekommen
    
    
    
    //Z++;                        //Zählervariable inkrementieren
    LCDPos(1,2);
    LCDWriteByte ('+');            //Einzelzeichen darstellen
    LCDWriteString ("Systemdynamik");    //Text ausgeben
    //Delay1ms(50);
    
    goto ruecksprung;
    }
    Bin für eure Hilfe dankbar,

    Tobi

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    15.09.2007
    Alter
    25
    Beiträge
    15
    Hallo,
    ich habe in deinem Code mal ein bisschen was verändert.Das Servo hat eine Wartezeit von 20ms das hast du vergessen und du hattest die Werte bei der Einschaltzeit konstant auf 1,1 ms gesetzt. Guck dir den Code mal an, ich hoffe er funktioniert. ich bin nämlich noch nicht so gut in C.
    Code:
    /*Grundprogramm für PIC 12F629/675 
      zum Einlesen eines Analogwertes mit Anzeige auf dem LC-Display 
      
      belegt min.4 max.5 Ausgänge 
        825 Codewords 
         30 Bytes RAM 
    
    //Pinbelegung des 12F629:            Funktion: 
    //Pin1    VPP    +5V                +5V 
    //Pin2    GP5     IOP    INT on Ch./T1CKI/OSC1    in out Funktion5    SI    Serielle Daten 
    //Pin3    GP4    AIOP    INT on Ch./T1G/OSC2        in out Funktion4    CLK      Serieller Takt 
    //Pin4    GP3     I        INT on Ch./MCLR\        in     Funktion3    
    //Pin5    GP2    AIOP    INT on Ch./Cout/INT/T0CIin out Funktion2    RS    Daten(1)/Steuerzeichen(0) 
    //Pin6    GP1    AIOP    INT on Ch./Cin-/Vref+    in out Funktion1    Servo 
    //Pin7    GP0    AIOP    INT on Ch./Cin+            in out Funktion0    AD-Kanal 0 
    //Pin8    Gnd    0V                GND 
    */ 
    
    #pragma config |=0b000.1.1.1.0.0.0.100 
    //                   ||| | | | | | | +++----Oscillator Selection Bits    (100=intern) 
    //                   ||| | | | | | |+-------Watchdog timer             (1=enable) 
    //                   ||| | | | | +----------Power up timer             (0=enable) 
    //                   ||| | | | +------------MCLR\ select *)            (0:RA5=IO; 1:RA5=MCLR\) 
    //                   ||| | | +--------------Brown out reset         (1=enable) 
    //                   ||| | +----------------Flash-Programm memory protection(0=enable) 
    //                   ||| +------------------EE-Prom memory code protected    (0=enable)          
    //                   +++--------------------nicht implementiert 
    
    
    //   Konstanten        Portzuweisung    I/O Funktionsbeschreibung 
    
    bit    RS            @ GPIO.2;    //I/O     Daten/Steuerzeichen (Da=1; St=0) 
    bit Servo        @ GPIO.1;    //I/O     Hintergrundbeleuchtung         (Option) 
    //bit CSB         @ GPIO.0;    //I/O     Analogkanal 
    
    #include "AD_Wandler.c"        //AD-Wandler Hilfsprogramme 
    //#include "MATH24F.H"         //Mathematikroutinen 
    
    
    //    Variablen                Funktionsbeschreibung 
    
    
    uns16    i; 
    uns16 AD_wert;        //eingelesener AD-Wert 
    //-------------------Hauptprogramm------------------------------------------------------------- 
    
    void main(void) 
    { 
    //-------------------Konfiguration des PIC 
    //Anm.: Erst Ausgänge setzen, dann Konfigurieren (wg. Spikes) 
    
    GPIO=    0b.00.00.0.000;        //Port Grundeinstellungen Statusregister 
    TRISIO=    0b.00.00.1.001;        //Port Eingänge definieren (1=Eingang; 0=Ausgang) 
    
    //--------------------AD-Wandler, nicht relevant für 12F629 
    
    ADCON0=0b.10.00.0001;        //AD-Wandler konfigurieren 
    ANSEL=0b.0.001.0001;        //Bit 0..3: GPIO 0..3=Analog(=1) / Digital(=0) Bit4..6:AD Clock 
    
    //--------------------Komperator 
    
    CMCON=0b.0.0.0.00111;        //Komperator aus 
    
    //--------------------Konfiguration der Variablen 
    
    Servo=0; 
    
    ruecksprung: 
    
    //Hauptprogramm 
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
    
    
    AD_wert=Analogwert(0);        //Kanal 0 einlesen 
    AD_wert=AD_wert/12; 
    AD_wert=AD_wert + 85;  //  1ms dazuaddieren
    
    Servo=1;                      //Servo bekommt Signal 
    
    for (i=0; i<AD_wert; i++) // Er braucht 85 Schleifen um 1ms zu warten. Der AD_Wert vom Poti kann 0 bis 1024 betragen. --> 1024/85 
        {;} 
    
    Servo=0;                    //Signal wird abgesetzt. Servo hat also 1 PWM Signal bekommen 
    
    for (i=0; i<1700; i++) // Er braucht 85 Schleifen um 1ms zu warten. Also 85*20 um 20ms zu warten. 
        {;} 
    
    
    
    
    goto ruecksprung; 
    }
    Gruß,
    Jojo12

Berechtigungen

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