@ rofo88 : Hatte ich auch erst gedacht, aber dieses System bekomme ich nicht stabil mit nur das P-Anteil. Das erstes Teil von video ist nur P-regelung. Kleine P-factor : fangt langsam an zu oscillieren und nach 3-4 Schwingungen ist das ende von Bahn erreicht. Hohe P-factor : schon nach 1 Schwingung ist schluss !! Grund ist das solange der Stabe nicht in Setpoint is, wird die Bahn in die richtige Richtung gekippt, und der Stabe versnellt immer. Nach die Geschwindigkeit van Stabe wird nicht gesehen/geregelt. Probiers mall !!
Die quellcode ist recht einfach, aber da ist noch ein Fehler in I-anteil derin. Auch bei Atmel (application note 221, PID-code) findts du eine implementierte code für PID.
ADC von draht = zwischen 300 und 700 (von 2 bis 3.5 VDC)
Servoroutine = Zahl zwischen 200 und 550 (von 0.8 bis 2.2 mS)
Das ADC wird jeden 10mS vermessen und dan wird die mittelwert verwendet. Der PID-routine wird jeder 100 mS durchlaufen (stopwatch).
Code:
void Ball_Beam (void)
{
#define SETPOINT 20
#define SAMPLE_TIME 21
#define P_FACTOR 22
#define I_FACTOR 23
#define D_FACTOR 24
#define SERVO_NOM 25
static int16_t last_error = 0;
static int16_t actual_error =0;
uint16_t actual_position = 100;
uint16_t adc4[10];
uint16_t servo_nom = 100; //EEPROM B&B SERVO_NOM
uint16_t setpoint =500; //EEPROM B&B SETPOINT
uint8_t sample_time = 100; //EEPROM B&B SAMPLE_TIME
int8_t P_factor=0; //EEPROM B&B P_FACTOR
int8_t I_factor=0; //EEPROM B&B I_FACTOR
int8_t D_factor=0;
static uint8_t i=0;
static uint8_t j=0;
static int16_t som=0; //EEPROM B&B D_FACTOR
int16_t P_correction=0;
static int16_t I_correction=0;
int16_t D_correction=0;
int16_t servo_position=400;
setpoint=read_buffer[SETPOINT]*5;
if (read_buffer[26]==2) setpoint=625;
if (read_buffer[26]==3) setpoint=375;
sample_time=read_buffer[SAMPLE_TIME];
P_factor=read_buffer[P_FACTOR];
I_factor=read_buffer[I_FACTOR];
D_factor=read_buffer[D_FACTOR];
servo_nom=read_buffer[SERVO_NOM];
if (getStopwatch3()>sample_time/10)
{
setStopwatch3(0);
adc4[i]=readADC(ADC_4);
som=som+adc4[i];
i++;
}
if (i==10)
{
actual_position=(som/10);
som=0;
i=0;
actual_error=actual_position-setpoint;
P_correction=((P_factor*actual_error)/64);//P_correctie delen door 8
I_correction=(I_correction+((I_factor*actual_error*sample_time/100)/64));//I delen door 8
if(I_correction>150) I_correction=150;
if(I_correction<-150) I_correction=-150;
if(I_factor==0)I_correction=0;
D_correction=(10*D_factor/sample_time)*(actual_error-last_error);
last_error=actual_error;
servo_position=((servo_nom*4)+P_correction+I_correction+D_correction);
servo(1,servo_position);
if(j<100)
{
j++;
if (j==1){
writeString_P("Setpoint,");
writeString_P("Actual Pos.,");
writeString_P("Servopos");
writeString_P("P-deel");
writeString_P("I-deel");
writeString_P("D-deel");
writeChar('\n');
}
writeInteger(setpoint,DEC);writeChar(',');
writeInteger(actual_position,DEC);writeChar(',');
writeInteger(servo_position,DEC);writeChar(',');
writeInteger(P_correction,DEC);writeChar(',');
writeInteger(I_correction,DEC);writeChar(',');
writeInteger(D_correction,DEC);writeChar(',');
writeChar('\n');
}
else
if(read_buffer[26]==1) j=0;
}
}
Lesezeichen