Regulace stejnosměrných motoru

Odpovědět
Akrij
Příspěvky: 5
Registrován: 14 pro 2018, 20:02
Reputation: 0

Regulace stejnosměrných motoru

Příspěvek od Akrij » 14 pro 2018, 20:33

Dobrý den,

nemáte někdo nějakou radu jak regulovat stejnosměrné motory? Řeším problematiku koloveho robota, který je vybaven dvojici stejnosměrných motoru. Problém nastane ve chvíli, kdy mají oba motory teoreticky stejne otáčky, ale prakticky se každý točí jinou rychlosti. Podle kódu by se měly točit stejnou rychlosti, ale H můstek asi nedokáže rozdělit stejné proudy mezi oba motory? Lze naprogramovat regulaci, která by vycházela z měřených hodnot za pomoci snímače otáček?

Dekuji

Uživatelský avatar
SkullKeep
Příspěvky: 290
Registrován: 23 srp 2017, 18:51
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: Regulace stejnosměrných motoru

Příspěvek od SkullKeep » 14 pro 2018, 21:39

Já budu řešit podobný problém s regulací stejnosměrného motoru a proto jsem to vyřešil pomocí čipu MX1508 a pomocí desky s tímto čipem a bez snímání otáček.
V tomto pdfku najdeš popis čipu s mým překladem z čínštiny.
mx1208.pdf
Přeložený pdfko k tomuto čipu
(193.02 KiB) Staženo 184 x
:twisted: :?: :arrow: :geek: P. Q. M.

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: Regulace stejnosměrných motoru

Příspěvek od petan » 15 pro 2018, 09:43

Jde o to, jestli se oba motory točí při stejném napětí a proudu stejnou rychlostí - rozdílné motory, rozdílná převodovka, .... Pokud ne, bude se muset použít zpětná vazba. Do regulace by musel zasáhnout nějaký PID regulátor - ty by si zadal jako teď rychlost. On by sepnul výstup a podle otáček by buď přidal, nebo ubral.

Koukni třeba sem: https://playground.arduino.cc/Code/PIDL ... sicExample
Místo analogWrite(pin, setpoint); by si použil tuto funkci. Akorát je nutné pořešit zpětnou vazbu - zde z analogového vstupu. Takže buď rychlost motorku někde externě přepočítat na analogový signál, nebo jednoduchý enkodér (ani by to nemuselo snímat směr, stačil by impulsní vstup připojit na interrupt pin) a počet otáček za sekundu by to přepočítávalo na proměnnou.

Akrij
Příspěvky: 5
Registrován: 14 pro 2018, 20:02
Reputation: 0

Re: Regulace stejnosměrných motoru

Příspěvek od Akrij » 15 pro 2018, 12:24

Děkuji, jen přesně nechápu, jak to přenést na můj kód. V programu pracuji s dvěma konstantami, kterými jsou rychlosti pro oba motory n1, n2 (teoreticky lze nastavit 0-255). Jsou to bezrozmerne konstanty. Dále snimam otáčky podle ncoderu a tyto otáčky převádím na ot/min. Takže mám změřené veličiny rmp_n1 a rpm_n2, které se neustále mění. Můžete mi prosím poradit jak definovat PID regulátor?

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: Regulace stejnosměrných motoru

Příspěvek od jankop » 15 pro 2018, 15:28

Já bych to neviděl zas tak složitě.
Vyzkoušel bych přiložený ideový návrh. Je to vlastně taky regulátor, řekněme regulátor s výrazně "integračním podílem". Je to vcelku jednoduché. Jen je potřeba si uvědomit, že dynamické parametry jsou extrémně závislé především na frekvenci vzorkování-porovnávání požadovaných a naměřených hodnot. Vliv má také dynamika motorů a vlastnosti snímače otáček.Proto jsem aplikoval knihovnu interval, která v případě správného použití v celém programu zajistí alespoň bezvadné časování. Dokáže nahradit funkci delay() a tím zefektivnit program o několik řádů.
Knihovna ve formě zip je dostupnáhttps://github.com/Pablo2048/Interval

Kód: Vybrat vše

#include <interval.h>       // knihovna pro timing
#define PERIODA_REGULACE 10 // [ms]
int MotorPozado1; // pozadovana rychlost motoru 1
int MotorPozado2; // pozadovana rychlost motoru 2
int rpm_n1;      // namerena - skutecna rychlost motoru 1
int rpm_n2;      // namerena - skutecna rychlost motoru 2
int MotorControl1 = 0; // vystupni hodnota pro rizeni H mustku 1
int MotorControl2 = 0; // vystupni hodnota pro rizeni H mustku 2
Interval RegulaceMotor; // definice intervalu regulace motoru
void setup() {
  // put your setup code here, to run once:
  MotorPozado1 = 100;  // nastaveni pozadovane rychlosti
  MotorPozado2 = 100;  // nastaveni pozadovane rychlosti
}
void loop() {
  // put your main code here, to run repeatedly:
  if (RegulaceMotor.expired()) {
    RegulaceMotor.set(PERIODA_REGULACE);
    if (rpm_n1 < MotorPozado1) { // pokud jsou otacky nizsi nez pozadovane, tak pridej
      if (MotorControl1 < 255)MotorControl1++;
    }
    if (rpm_n1 > MotorPozado1) { // pokud jsou otacky vyssi nez pozadovane, tak uber
      if (MotorControl1 > 0)MotorControl1--;
    }
    if (rpm_n2 < MotorPozado2) { // pokud jsou otacky nizsi nez pozadovane, tak pridej
      if (MotorControl2 < 255)MotorControl2++;
    }
    if (rpm_n2 > MotorPozado2) { // pokud jsou otacky vyssi nez pozadovane, tak uber
      if (MotorControl2 > 0)MotorControl2--;
    }
  }
}

Uživatelský avatar
gilhad
Příspěvky: 778
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Regulace stejnosměrných motoru

Příspěvek od gilhad » 17 pro 2018, 05:30

Jen bych podotknul, ze vzhledem ke konstrukci, zejmena kartacku, se stejnosmerne motory muzou pri stejnem napeti/proudu tocit dost jinou rychlosti podle toho, na jakou stranu se toci. Takze i kdyz bys mel mory zcela stejne, tak pri klasicke konstrukci jeden pojede "dopredu", druhy "dozadu" a budou pri stejnem napajeni davat rozdilny vykon a robot bude zatacet.

Akrij
Příspěvky: 5
Registrován: 14 pro 2018, 20:02
Reputation: 0

Re: Regulace stejnosměrných motoru

Příspěvek od Akrij » 17 pro 2018, 05:41

Děkuji

Akrij
Příspěvky: 5
Registrován: 14 pro 2018, 20:02
Reputation: 0

Re: Regulace stejnosměrných motoru

Příspěvek od Akrij » 17 pro 2018, 05:45

gilhad píše:
17 pro 2018, 05:30
Jen bych podotknul, ze vzhledem ke konstrukci, zejmena kartacku, se stejnosmerne motory muzou pri stejnem napeti/proudu tocit dost jinou rychlosti podle toho, na jakou stranu se toci. Takze i kdyz bys mel mory zcela stejne, tak pri klasicke konstrukci jeden pojede "dopredu", druhy "dozadu" a budou pri stejnem napajeni davat rozdilny vykon a robot bude zatacet.
Ano, mě jde o to, aby robot udržel směr. Myslím, že výsledný pohyb se projeví sinusovým pohybem robota vlivem regulace. Další věc je nesymetrické zatížení na obě kola, dynamické účinky apod. Bez regulace není cesta jak ho udržet v přímém směru. Děkuji.

Akrij
Příspěvky: 5
Registrován: 14 pro 2018, 20:02
Reputation: 0

Re: Regulace stejnosměrných motoru

Příspěvek od Akrij » 17 pro 2018, 15:45

jankop píše:
15 pro 2018, 15:28
Já bych to neviděl zas tak složitě.
Vyzkoušel bych přiložený ideový návrh. Je to vlastně taky regulátor, řekněme regulátor s výrazně "integračním podílem". Je to vcelku jednoduché. Jen je potřeba si uvědomit, že dynamické parametry jsou extrémně závislé především na frekvenci vzorkování-porovnávání požadovaných a naměřených hodnot. Vliv má také dynamika motorů a vlastnosti snímače otáček.Proto jsem aplikoval knihovnu interval, která v případě správného použití v celém programu zajistí alespoň bezvadné časování. Dokáže nahradit funkci delay() a tím zefektivnit program o několik řádů.
Knihovna ve formě zip je dostupnáhttps://github.com/Pablo2048/Interval

Kód: Vybrat vše

#include <interval.h>       // knihovna pro timing
#define PERIODA_REGULACE 10 // [ms]
int MotorPozado1; // pozadovana rychlost motoru 1
int MotorPozado2; // pozadovana rychlost motoru 2
int rpm_n1;      // namerena - skutecna rychlost motoru 1
int rpm_n2;      // namerena - skutecna rychlost motoru 2
int MotorControl1 = 0; // vystupni hodnota pro rizeni H mustku 1
int MotorControl2 = 0; // vystupni hodnota pro rizeni H mustku 2
Interval RegulaceMotor; // definice intervalu regulace motoru
void setup() {
  // put your setup code here, to run once:
  MotorPozado1 = 100;  // nastaveni pozadovane rychlosti
  MotorPozado2 = 100;  // nastaveni pozadovane rychlosti
}
void loop() {
  // put your main code here, to run repeatedly:
  if (RegulaceMotor.expired()) {
    RegulaceMotor.set(PERIODA_REGULACE);
    if (rpm_n1 < MotorPozado1) { // pokud jsou otacky nizsi nez pozadovane, tak pridej
      if (MotorControl1 < 255)MotorControl1++;
    }
    if (rpm_n1 > MotorPozado1) { // pokud jsou otacky vyssi nez pozadovane, tak uber
      if (MotorControl1 > 0)MotorControl1--;
    }
    if (rpm_n2 < MotorPozado2) { // pokud jsou otacky nizsi nez pozadovane, tak pridej
      if (MotorControl2 < 255)MotorControl2++;
    }
    if (rpm_n2 > MotorPozado2) { // pokud jsou otacky vyssi nez pozadovane, tak uber
      if (MotorControl2 > 0)MotorControl2--;
    }
  }
}

Bohuzel me Vase regulace nefunguje. Netusite, kde by mohl byt problem.

#include <interval.h>
#define PERIODA_REGULACE 10
#include <AFMotor.h> //import your motor shield library
#define trigPin 4 // define the pins of your sensor
#define echoPin 5
#include <Servo.h>
#include <SoftwareSerial.h>


int encoder_pin_M1 = 2;
int encoder_pin_M2 = 3;

int MotorPozado1;
int MotorPozado2;

int MotorControl1 = 0;
int MotorControl2 = 0;

Interval RegulaceMotor;

unsigned int rpm_M1;
unsigned int rpm_M2;

volatile byte pulses_M1;
volatile byte pulses_M2;

unsigned long timeold_M1;
unsigned long timeold_M2;

unsigned int pulsesperturn = 20;

void counter_M1()
{
pulses_M1++;
}
void counter_M2()
{
pulses_M2++;
}


AF_DCMotor motor1(1,MOTOR12_8KHZ); // set up motors.
AF_DCMotor motor2(2, MOTOR12_8KHZ);

Servo myservo;
int pos = 0;
long duration;
int distance;


void setup()
{
myservo.attach(10);
Serial.begin(9600); // begin serial communitication
Serial.println("Motor test!");
pinMode(trigPin, OUTPUT);// set the trig pin to output (Send sound waves)
pinMode(echoPin, INPUT);// set the echo pin to input (recieve sound waves)
motor1.setSpeed(130); //set the speed of the motors, between 0-255
motor2.setSpeed (130);

pinMode(encoder_pin_M1, INPUT);
pinMode(encoder_pin_M2, INPUT);

attachInterrupt(0, counter_M1, FALLING);
attachInterrupt(1, counter_M2, FALLING);


pulses_M1 = 0;
pulses_M2 = 0;

rpm_M1 = 0;
rpm_M2 = 0;

timeold_M1 = 0;
timeold_M2 = 0;

MotorPozado1 = 300;
MotorPozado2 = 300;

Serial.begin(9600);
}

void loop()

{

if (millis() - timeold_M1 >= 1000)
{
detachInterrupt(0);
rpm_M1 = (60 * 1000 / pulsesperturn )/ (millis() - timeold_M1)* pulses_M1;
//Vypocet snimanych otacek
timeold_M1 = millis();
pulses_M1 = 0;
attachInterrupt(0, counter_M1, FALLING);
}
if (millis() - timeold_M2 >= 1000)
{
detachInterrupt(1);
rpm_M2 = (60 * 1000 / pulsesperturn )/ (millis() - timeold_M2)* pulses_M2;
timeold_M2 = millis();
pulses_M2 = 0;
attachInterrupt(1, counter_M2, FALLING);
}
for (pos = 60; pos <= 120; pos += 5)
{ // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos);
delay(10);
}
for (pos = 120; pos >= 50; pos -= 5)
{ // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10);
}
digitalWrite(trigPin, LOW);
delayMicroseconds(2); // delays are required for a succesful sensor operation.
digitalWrite(trigPin, HIGH);

delayMicroseconds(10); //this delay is required as well!
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;// convert the distance to centimeters.
if (distance < 25)
{
Serial.println ("Close Obstacle detected!" );
Serial.println ("Obstacle Details:");
Serial.print ("Distance From Robot is " );
Serial.print ( distance);
Serial.print ( " CM!");// print out the distance in centimeters.

Serial.println (" The obstacle is declared a threat due to close distance. ");
Serial.println (" Turning !");
motor1.run(FORWARD); // Turn as long as there's an obstacle ahead.
motor2.run (BACKWARD);

Serial.print("\t \t Measured Speed n1 [1/min] = " );
Serial.println((rpm_M1),DEC);
delay(10);
Serial.print("\t \t Measured Speed n2 [1/min] = " );
Serial.println((rpm_M2),DEC);
delay(10);



}
else
{
Serial.println ("No obstacle detected. going forward");
delay (15);
motor1.run(FORWARD); //if there's no obstacle ahead, Go Forward!
motor2.run(FORWARD);
Serial.print("\t \t Measured Speed n1 [1/min] = " );
Serial.println((rpm_M1),DEC);
delay(15);
Serial.print("\t \t Measured Speed n2 [1/min] = " );
Serial.println((rpm_M2),DEC);
delay(15);

}
if (RegulaceMotor.expired()) {
RegulaceMotor.set(PERIODA_REGULACE);
if (rpm_M1 < MotorPozado1) { // pokud jsou otacky nizsi nez pozadovane, tak pridej
if (MotorControl1 < 255)MotorControl1++;
}
if (rpm_M1 > MotorPozado1) { // pokud jsou otacky vyssi nez pozadovane, tak uber
if (MotorControl1 > 0)MotorControl1--;
}
if (rpm_M2 < MotorPozado2) { // pokud jsou otacky nizsi nez pozadovane, tak pridej
if (MotorControl2 < 255)MotorControl2++;
}
if (rpm_M2 > MotorPozado2) { // pokud jsou otacky vyssi nez pozadovane, tak uber
if (MotorControl2 > 0)MotorControl2--;
}
}


}

jankop
Příspěvky: 1029
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: Regulace stejnosměrných motoru

Příspěvek od jankop » 17 pro 2018, 18:11

Tuším... Tys to vložil do svého programu bez jakýchkoliv návazností. Pochopitelně to fungovat nemůže, protože výstupní hodnoty MotorControl nikde nepoužíváš. Psal jsem o ideovém návrhu, protože jsem nikdy tvůj program neviděl. Myslím si, že bys měl asi začít jednoduše rozhýbáním motorů a jejich regulací a ne se hned snažit rozchodit program, který se ti podařilo někde sehnat a ve kterém se nejspíš příliš neorientuješ.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 16 hostů