PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servo ruckel-zuckelt mit meiner ersten PWM



FeuerTobi
28.10.2008, 00:07
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?



/*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

Jojo12
28.10.2008, 15:34
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.


/*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