Skocz do zawartości

Sterowanie prędkością silnika (enkoder, PID)


faustin

Pomocna odpowiedź

witam wszystkich , chciałabym zrobic tak, aby predkosc mojego silnika z enkoderem była sterowana tak aby była trzymana stała predkosc zadana przezemnie niezaleznie od zakłócen z zewnatrz za pomoca sygnału PWM, który odpowiednio zwiekszałsieby jesli wystapiły by zakłócenia 

oto kod , który mam:

#define ENCA 2

#define ENCB 3 
#define PWM 6
#define IN2 7
#define IN1 8
 
int pos = 0;
long prevT = 0;
float eprev = 0;
float eintegral = 0;
 
void setup() {
  Serial.begin(9600);
  pinMode(ENCA,INPUT);
  pinMode(ENCB,INPUT);
  attachInterrupt(digitalPinToInterrupt(ENCA),readEncoder,RISING);
  Serial.println("target pos");
}
 
void loop() {
 
  // set target position
  int target = 100;
  //target = 250*sin(prevT/1e6);
 
  // PID constants
  float kp = 1;
  float kd = 0.025;
  float ki = 0.0;
 
  // time difference
  long currT = micros();
  float deltaT = ((float) (currT - prevT))/( 1.0e6 );
  prevT = currT;
 
  // error
  int e = pos-target;
 
  // derivative
  float dedt = (e-eprev)/(deltaT);
 
  // integral
  eintegral = eintegral + e*deltaT;
 
  // control signal
  float u = kp*e + kd*dedt + ki*eintegral;
 
  // motor power
  float pwr = fabs(u);
  if( pwr > 255 ){
    pwr = 255;
  }
 
  // motor direction
  int dir = 1;
  if(u<0){
    dir = -1;
  }
 
  // signal the motor
  setMotor(dir,pwr,PWM,IN1,IN2);
 
  // store previous error
  eprev = e;
 
  Serial.print(target);
  Serial.print(" ");
  Serial.print(pos);
  Serial.println();
}
 
void setMotor(int dir, int pwmVal, int pwm, int in1, int in2){
  analogWrite(pwm,pwmVal);
  if(dir == 1){
    digitalWrite(in1,HIGH);
    digitalWrite(in2,LOW);
  }
  else if(dir == -1){
    digitalWrite(in1,LOW);
    digitalWrite(in2,HIGH);
  }
  else{
    digitalWrite(in1,LOW);
    digitalWrite(in2,LOW);
  }  
}
 
void readEncoder(){
  int b = digitalRead(ENCB);
  if(b > 0){
    pos++;
  }
  else{
    pos--;
  }
}

tyle ,ze silnik mój kreci sie przez pewien czas , a pózniej przestaje , po chwili znów sie kreci , a jak sa zakłócenia nie widac aby pwm wzrastało

Link do komentarza
Share on other sites

chodzi o to ze sam kod w sobie jest ok ale ja nie chce miec zadanego sygnału w postaci sygnału prostokątnego tylko chce mieć  na wyjściu predkośc zadana i chce aby była ona utrzymywana , a tam w kodzie jest jakby ustawiona zadana pozycja  a nie prędkość stąd pytanie jak ten kod zmodyfikować, przesyłam link do filmu DC motor PID speed control - Bing video

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Nie jestem pewien, czy dobrze zrozumiałem problem.
Jeżeli chcesz sterować prędkością zamiast pozycją, to musisz:
1. Obliczyć aktualną prędkość – skoro masz pozycję, to prędkość możesz spróbować w najprostszym przypadku oszacować jako różnicę aktualnej pozycji oraz poprzedniej podzielonej przez przyrost czasu (trzeba zapamiętać pozycję z poprzedniego obiegu pętli).
2. Liczyć uchyb układu regulacji jako różnicę prędkości zadanej oraz aktualnej (obliczonej w punkcie 1) zamiast różnicy pozycji.

 

  • Lubię! 1
Link do komentarza
Share on other sites

Generalnie coś takiego w miejscu liczenia uchybu:

float currentSpeed = (pos - prevPos)/deltaT;
// error
float e = targetSpeed - currentSpeed;
prevPos = pos;

Tę zmienną prevPos trzeba gdzieś też wcześniej zadeklarować, najlepiej tam, gdzie pos. Jako targetSpeed można pewnie użyć tej zmiennej, która już tam była w kodzie (zwróć jedynie uwagę na typ, czy potrzeba floatów tak, jak to zrobiłem, czy wystarczą Ci liczby całkowite).
Nie chce mi się analizować całego kodu dokładnie, dziwi mnie, że uchyb liczysz jako różnicę wartości aktualnej i zadanej (zamiast odwrotnie). Ogólnie to dobrze też byłoby, gdyby PID działał ze stałym okresem próbkowania.
 

  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.