Hallo Leute,
ich habe von meinem Lehrer eine Aufgabenstellung bekommen:
ein 12V DC-Motor läuft viel zu schnell UND über einen vorgegebenen ADC
Wert hinaus (Überschiesst sein Ziel)
Ich soll also einen PI Regler nutzen um den Punkt genau anzufahren.
Den Motor steuere ich über einen L298 Motortreiber an mit zwei Ausgängen
vom µC.
PortB,1
PortB,2
Die Freigabe habe ich über PortB,0 gegeben.
mit der Formel :
esum = esum + e
y = Kp * e + Ki Ta esum
aus dem RN-Wissen soll ich den PI Regler Softwaremäßig umsetzen.
Ich habe gerade allerdings noch keinen wirklichen Plan, wie ich mein
Script:
1
voidMotor(uint8_tEingangA)
2
{
3
uint8_tEingangB;
4
EingangB=1-EingangA;
5
6
PORTB&=~(1<<EingangA);// Eingang A am Motortreiber
7
PORTB|=(1<<EingangB);// Eingang B
8
return;
9
}
anpassen muss, um eine PWM mit dem PI Regler einzufügen.
// COM21, COM20 = 0bxx10xxxx: Löschen von OC2 bei Compare Match
34
35
while(1)
36
{
37
adwert=ADC();// Wert des AD-Wandlers aus Unterprogramm "lese" holen
38
OCR2=adwert;// gelesener Wert wird dem PWM-Vergleichswert übergeben.
39
40
intwert;// Dekleration variable wert
41
wert=adwert;// Übergabe des Wertes adwert an wert
42
}
43
}
Also das Problem ist, dass ich nicht weiß wie ich den PI Regler mit der
PWM verknüpfe. Mein Lehrer gab mir die Aufgabe im Zuge eines Projektes
und hat davon leider wenig Ahnung, er meinte nur es geht.
Er sagte, dass Y aus der Formel der Prozentuale Wert ist den die PWM
bekäme.
Kent jemand so eine Funktion?
Gruß Sven
Edit: Sry für die Formatierung der Kommentare, irgendwie ist sieht das
im Editor anders aus!
Ich habe keine Ahnung, wie Dein Motor angesteuert wird. Das geht aus
Deinem Code nicht hervor. Deshalb: Wähle sinnvolle Bezeichner für
Funktionen, Parameter, Variablen und kommentiere, was die Pins bewirken.
Mit diesem Code kann man als Außenstehender absolut nichts anfangen:
1
voidMotor(uint8_tEingangA)
2
{
3
uint8_tEingangB;
4
EingangB=1-EingangA;
5
6
PORTB&=~(1<<EingangA);// Eingang A am Motortreiber
7
PORTB|=(1<<EingangB);// Eingang B
8
return;
9
}
Meine Glaskugel sagt mir allerdings, dass zukünftig mindestens einer der
Pins per PWM angesteuert werden muss. Am besten schließt Du den dann an
den Ausgangs-Pin des Timers an. Ansonsten musst Du den Pin in der
Timer-ISR umschalten.
Der PI-Regler ist dafür da, dem Timer den PWM-Wert vorzugeben, den er
erzeugt. Also statt
sorry für mein unvollständiges script!
also ich habe zwei define angaben mit drin:
einmal für links 0 und rechts 1
wenn ich also dann Motor(links) aufrufe wird im unterprogramm
eine 0 übergeben, womit eingang B automatisch zur 1 wird!
1
voidMotor(uint8_tEingangA)
2
{
3
uint8_tEingangB;
4
EingangB=1-EingangA;
5
6
PORTB&=~(1<<EingangA);// Eingang A am Motortreiber
eine kleine Frage:
wie bekomme ich denn die Parameter für Ki, Kp usw ?
Ich habe ja keinen Sensor o.Ä. den ich nutze. Lediglich einen IST_wert
von der ADC...
irgendwie steh ich da aufm schlauch
wenn ich beispielsweise werte aus einem thread nutze, in dem es um PID
regler ging:
Regler1.Ta=10;
Regler1.I=100;
Regler1.D=0;
Regler1.Kp=1;
Regler1.esum=0;
Regler1.e=0;
Regler1.ealt=0;
erhalte ich bei :
Y = (Kp*e)+(Ki*Ta*esum);
Aktueller ADC_Wert = 524
Fürhungsgröße = 500
folgenden wert: Y = (1*-24) + (100*10*6)
== 5976
was ist denn das für ein Wert? Der macht für mich gar keinen sinn, kann
mir das wer erläutern?
Sven Weinmann schrieb:> wie bekomme ich denn die Parameter für Ki, Kp usw ?
Tja, das ist eine Wissenschaft für sich. Am einfachsten durch
Ausprobieren/Herantasten.
Für einen Regler brauchst Du einen Sollwert (der wird von außen/vom
Benutzer vorgegeben) und einen Istwert (der wird gemessen). Daraus
berechnest Du mit Hilfe von Ki und Kp (und dem gespeicherten
integrierten Wert) den Ausgabewert.
Woher in der Aufgabe Soll- und Istwert kommen weißt aber nur Du bzw.
Dein Lehrer ...
Meiner Meinung nach solltest du fürs erste den Regler erst mal Regler
sein lassen und dich einer ganz anderen Problematik widmen.
Das hier
1
voidMotor(uint8_tEingangA)
2
{
3
uint8_tEingangB;
4
EingangB=1-EingangA;
5
6
PORTB&=~(1<<EingangA);// Eingang A am Motortreiber
7
PORTB|=(1<<EingangB);// Eingang B
8
return;
9
}
kann nicht so bleiben.
Denn mit dieser Funktionn fährt der Motor entweder volle Kanne nach
links oder er fährt volle Kanne nach rechts.
Und genau das kannst du nicht gebrauchen.
Du brauchst erst mal eine PWM Ansteuerung des Motors, mit der du den
Motor mit einer vorgegebenen Geschwindigkeit fahren lassen kannst, nicht
nur volle Kanne.
Dein erstes Ziel sollte IMHO sein:
Da muss eine Steuerung her, die mittels PWM den Motor in (in Grenzen)
jeder beliebigen Geschwindigkeit nach links/rechts fahren lassen kann.
Solange du nur Full-Speed hast, kommst du nicht weiter.
Und dieser Teilaspekt des Problems ist erst mal völlig unabhängig von
irgendwelchen PI Reglern. Er kann also völlig für sich alleine
betrachtet und gelöst werden.
Was du brauchst ist erst mal eine Funktion
1
voidMotor(int8_tSpeed)
2
{
3
....
4
}
mit der du dem Motor nicht nur eine Richtung, sondern auch eine
Geschwindigkeit gibst. Daher auch der int8_t Wert ... also einer mit
Vorzeichen.
0 .... Motor steht
positive Werte .... Motor dreht rechts rum
wobei der Motor umso schneller dreht
je größer der Wert ist
(bei +90 dreht der Motor schneller als
bei +10)
negative Werte .... Motor dreht links rum
wobei der Motor umso schneller dreht
je kleiner der Wert ist
(bei -90 dreht der Motor schneller als
bei -10)
Überleg dir dazu mal was.
Testen kannst du das wieder mit deinem ADC bzw. dem Poti. Ist das Poti
in Mittelstellung muss der Motor stehen. Verdrehst du das Poti aus der
Mittelstellung heraus muss der Motor anfangen zu laufen (Je nachdem in
welcher Richtung du am Poti drehst, dreht dann auch der Motor in eine
richtung). Je mehr du ihn aus der Mittelstellung heraus verdrehst, desto
schneller muss der Motor laufen.
hallo Karl Heinz,
ich hab damit ein kleines problem.
1) ich habe in meiner anlage zwar ein poti welches ich nutzen kann, dies
sollte aber späte rnichtmehr benutzt werden, da das dann durch den PI
regler geschehen soll, beim punktgenauen anfahren.
2) ich hab einen L 298 mit der schaltung vom strippenstrolch ->
http://www.strippenstrolch.de/1-2-9-motortreiber-298.html
auf meinem breadboard gebaut. ich gebe dem treiber also nur ein 1 und
ein 0 signal. + freigabe.
und das zweite zu deiner Funktion:
1
voidMotor(int8_tSpeed)
2
{
3
....
4
}
das bedeutet doch, dass ich den Aufruf über "Motor( zahl +/- 100);"
schreiben muss. vorher hatte ich dort einfach nur "links" und "rechts"
stehen, d.h. ich müsste nun einfach wissen -> + ^rechts und - ^links.
ok UPDATE:
zum Thema PWM:
ich hab also ein Problem:
das erfassen und das anpassen vom Speed funktioniert.
was nicht funktioniert ist die Richtungsumkehr. Grund ->
Das Schema der zwei Pins ist wie folgt (am Treiber)
Eingang 3 ... 1 Vorwärts
Eingang 4 ... 0
Eingang 3 ... 0 Rückwärts
Eingang 4 ... 1
Eingang 3 ... 0 Vollbremsung
Eingang 4 ... 0
Eingang 3 ... 1 Vollbremsung
Eingang 4 ... 1
das problem ist, dass ich nun B1 als PWM Pin (Eingang3) nutze und B2 als
Eingang 4.
Diesen möchte ich in abhängigkeit von B1 invertieren, ist der PWM Wert =
0 dann soll B1 und B2 gleich sein.
Das gilt es nun zu realisieren für die Drehrichtung.
Hallo,
deine "Strippenstrolch-Schaltung" ala L298 hat nicht 2, sondern 3 Pins:
die Freigabe und die beiden Richtungs-Pins. Und die brauchst du auch
alle für die PWM-Steuerung.
Über die 2 Eingänge (3 und 4) stellst du die Drehrichtung ein, und an
den Freigabe-Pin kommt die PWM. Wobei man die Richtung möglichst nur
umschalten sollte, wenn der Freigabe-Pin inaktiv ist; das vermeidet die
Bremseffekte.
Also werden auch 3 Controller-Pins benötigt; einer davon sollte der
PWM-Ausgang von einem Timer sein.
ohje... das ist endlich der tipp gewesen, welchen ich gesucht habe!
der enable -.-
wenn ich den PWM wert eben an diesen setzt und die drehrichtung bestimme
klappt das auch!
nun aber die frage, kann ich denn die PWM auch irgendwie nutzen, die
drehrichtung zu ändern, oder geht das nicht?=
die PWM geht ja vn 0-1023, gibt es sowas wie einen mittelpunkt -> 512
als umschaltpunkt?
oder benötige ich wie in meiner originalfunktion eine drehrichtung und
eben eine geschwindigkeit?
Sven Weinmann schrieb:> die PWM geht ja vn 0-1023, gibt es sowas wie einen mittelpunkt -> 512> als umschaltpunkt?>> oder benötige ich wie in meiner originalfunktion eine drehrichtung und> eben eine geschwindigkeit?
wenn musst du dir eine funktion selber bauen...die PWM stellt nur die
geschwindigkeit des motors ein..die drehrichtung kommt von den pins..
> 1) ich habe in meiner anlage zwar ein poti welches ich nutzen kann,> dies sollte aber späte rnichtmehr benutzt werden
Später ist später. Jetzt ist jetzt.
Und jetzt brauchst du erst mal eine ordentliche Ansteuerfunktion für den
Motor. Und eine Möglichkeit die zu testen.
Später, wenn deine Tests abgeschlossen sind, kannst du ja das Poti
wieder anderweitig benutzen.
> nun aber die frage, kann ich denn die PWM auch> irgendwie nutzen, die drehrichtung zu ändern, oder geht das nicht?=
Genau darum geht es:
Das du eine Funktion brauchst, die BEIDES macht.
Sowohl die Geschwindigkeit ALS AUCH die Richtung einzustellen. Und das
möglichst, indem man ihr EINEN Wert gibt, in dem beides in irgendeiner
Form enthaten ist (denn den Wert wirst du später aus dem PI Regler
bekommen).
> die PWM geht ja vn 0-1023, gibt es sowas wie einen> mittelpunkt -> 512 als umschaltpunkt?
Nein. Denn 'Geschwindigkeit' ist ein in diesem Zusammenhang ein skalarer
Begriff. Deine Motorgeschwindigkeit ist hier etwas absolutes. Die geht
von Stillstand bis Vollgas. 0 bis 100%
Aber: dein µC kann ja rechnen. Es spricht ja nichts dagegen, dass du mit
dem Wert, den die Funktion bekommt, erst mal ein bischen rumrechnest,
ehe du dann die Werte hast mit denen du die Richtungspins einstellst
bzw., den OCR Wert für den PWM-Timer hast. Nicht immer sind die Dinge so
einfach, dass man aus einer Hardware Komponente einen Wert bekommt, den
man unverändert in ein andere Komponente reinsteckt und dann passt das
schon.
Leg deine Abneigung gegen Mathe beiseite und gewöhn dich daran, dass du
auch mal ein paar Formeln 'erfinden' musst. Du wirst sehen: Es geht
selten über die Grundrechenarten hinaus, die meisten Umrechnungen lassen
sich mit ein wenig Phantasie leicht finden und der berühmt/berüchtigte
Dreisatz ist dein Freund.
Du klebst noch viel zu sehr an vorhandenem Code. Es ist nicht verboten,
das man Code, den man schon geschrieben hat, auch mal ändert, wenn es
notwendig ist und sich die Anforderungen geändert haben. Und es ist auch
nicht verboten, sich Zwischenziele zu setzen, in denen man Komponenten
kurzfristig zweckentfremdet, wenn es der Sache das Zwischenziel zu
erreichen dienlich ist. Die Vorstellung: Ich fang heute zu coden an und
dann schreibe ich nur Code, der dann in Zement gemauert auch im fertigen
Programm enthalten sein wird ist eine falsche. Tatsächlich funktioniet
Software-Entwicklung eher wie 'anschleichen an das Ziel'. Die grobe
Richtung kennt man, aber dann hangelt man sich von Busch zu Busch - von
einer sicheren Position zur nächsten.
Bevor man anfängt irgendwas zu programmieren sollte man aber zumindest
mal eine Vorstellung davon haben, wie das Projekt am Ende aussehen soll.
Das scheint bisher nicht der Fall zu sein.
Wir haben also einen Motor, der vorwärts und rückwärts drehen kann.
Bisher aber nur binär, d.h. Vollgas vorwärts oder rückwärts. Außerdem
ein Poti am ADC, das bisher nicht benutzt wird und am Ende auch nicht
benutzt werden soll?
Woher kommen Soll- und Istwert für die Regelung? Was soll geregelt
werden? Die Geschwindigkeit oder vielleicht die Position von etwas, das
der Motor bewegt? Ist vielleicht gar keine Regelung sondern nur eine
Steuerung gefragt?
Vielleicht weiß der TO das alles, dann will ich nichts gesagt haben. Ich
habe aber nicht den Eindruck ...
xfr schrieb:> Vielleicht weiß der TO das alles, dann will ich nichts gesagt haben. Ich> habe aber nicht den Eindruck ...Sven Weinmann schrieb:> Mein Lehrer gab mir die Aufgabe im Zuge eines Projektes> und hat davon leider wenig Ahnung, er meinte nur es geht.
Wer soll es ihm denn auch beibringen?
xfr schrieb:> Woher kommen Soll- und Istwert für die Regelung? Was soll geregelt> werden? Die Geschwindigkeit oder vielleicht die Position von etwas, das> der Motor bewegt? Ist vielleicht gar keine Regelung sondern nur eine> Steuerung gefragt?
Ich hab eine gewisse Vorstellung entwickelt, was eigentlich das Ziel
sein soll. Ob sie stimmt oder nicht, weiß ich nicht.
Aber vor meinem geistigen Auge gibt es da einen 'Schlitten', der über
einen Riemen gezogen auf einer Bahn läuft. Und es gibt einen Motor samt
Poti, die ebenfalls vom Riemen 'umschlungen' sind.
Das ganz ist nicht ganz unähnlich einer Druckkopfmechanik, mit Poti zur
Positionsrückmeldung.
Ziel ist es den Schlitten an eine bestimmte Position zu fahren, wobei
die Position durch die Potistellung (und damit durch eine Spannung)
definiert wird.
Das ist mein mentales Arbeitsmodell.
Vielleicht liege ich völlig falsch, vielleicht auch nicht. Wer weiß das
schon.
Vielleicht gehts auch einfach nur um eine Drehzahlregelung.
hallo leute,
danke für die kommentare, ihr habt natürlich recht.
folgedes zu den werten:
ich habe einen 12v motor mit sehr hoher drehzahl.
dieser ist über zahnräder mit einer "seilsteuerung" verbunden, welche
einen schlitten über eine aluschiene bewegt.
an dem zahnradkonstrukt(, welches ich nicht als getriebe deute!), ist
auch ein poti zur positionierung des schlittens dran.
nun soll später durch ein programm die fahrt von endpunkt zu endpunkt
realisiert werden.
im moment geht das durch vollgas vorwärts/vollgas rückwärts, wie karl
heinz das wunderbar aus meinem code gelesen hat.
stattdessen soll aber keine vollgasfahrt sondern eine PI geregelte fahrt
gemacht werden (aufgabenstellung), welche auch von anfang zum ende
fährt, aber eben auch mal an einem genauen punkt angehalten werden kann.
REAL:
if (position == wunschwert)
{
mnotorstop;
}
vereinfacht dargestellt.
was aber passiert ist folgendes:
er bleibt tatsächlich stehen, aber eben nicht am wunschwert sondern an
einem x-beliebigen wert dahinter. auch die endpositionsanfahrt ist jedes
mal ein anderer wert.
daher die PI regelung -> durch den P anteil wird ja der proportionale
anteil gefahren, ich nenne es mal "den gröbsten teil der strecke" und
mit dem I anteil die "anfahrt an den wunschwert"
dass der PI regler den wunschwert nicht 100% erreicht ist klar, sonst
wärs keine regelung. (regeldifferenz 0 = unsinn!)
was ich also tun muss, ist mir einen schlachtplan zu entwickeln, wie ich
mich dahin programmiere sozusagen.
karl heinz sagte so schön, man muss über umwege gehen. das problem ist
jedoch, dass ich den umweg nicht kenne, oder erst kennen lernen muss,
weil ich nicht weiß wie dieser aussehen könnte.
mitlerweile sind wir soweit, dass ich meinen quellcode so anpassen
möchte,
dass der PWM wert 0-1023 in der mitte (511/512) = 0 ist und bei 0-510
-100%-1% hat und bei 513-1023 1%-100%
diesen dann enthaltenen wert gebe ich auf den enable eingang am L298.
und in abhängigkeit ob der wert positiv oder negativ ist drehrichtung A
oder B.
wie ich damit dann allerdings in richtung PI regler komme weiß ich noch
nicht. vermutlich ist der momentan genutzte PWM wert später mein Y, aber
das ist nur eine vermutung.
später soll an diesem schlitten ein sensor o.Ä. angebracht werden, der
an genauen punkten messwerte ausgibt. aber das ist nicht mein projekt.
ich hoffe mich etwas verständlicher ausgedrückt zu haben.
gruß
sven
Sven Weinmann schrieb:> REAL:> if (position == wunschwert)> {> mnotorstop;> }>> vereinfacht dargestellt.>> was aber passiert ist folgendes:> er bleibt tatsächlich stehen, aber eben nicht am wunschwert sondern an> einem x-beliebigen wert dahinter. auch die endpositionsanfahrt ist jedes> mal ein anderer wert.
Logisch.
Das übliche Problem:
Wenn man nicht rechtzeitig genug bremst (die Geschwindigkeit reduziert),
dann knallt man mit dem Auto unweigerlich in die Rückwand der Garage.
> daher die PI regelung -> durch den P anteil wird ja der proportionale> anteil gefahren, ich nenne es mal "den gröbsten teil der strecke" und> mit dem I anteil die "anfahrt an den wunschwert"> dass der PI regler den wunschwert nicht 100% erreicht ist klar, sonst> wärs keine regelung. (regeldifferenz 0 = unsinn!)
Doch, wenn der gut eingestellt ist, dann macht der das.
Kurz vor dem Ziel wird die Geschwindigkeit zurückgenommen. Der Schlitten
beginnt zu 'bremsen' und kommt im Idealfall mit dem Ende der
Bremsperiode genau an der Wunschposition zum stehen.
> karl heinz sagte so schön, man muss über umwege gehen. das problem ist> jedoch, dass ich den umweg nicht kenne, oder erst kennen lernen muss,> weil ich nicht weiß wie dieser aussehen könnte.
Wie machst du es denn im realen Leben?
Läufst du volle Kanne auf eine Wand zu oder richtest du deine
Geschwindigkeit danach aus, wie weit du noch von der Wand entfernt bist?
Entfernung von der Wand: -> Regelabweichung
Je kleiner die Abweichung, desto kleiner wird die Geschwindigkeit.
Bist du mit dem Fahrrad 300 Meter von der Wand entfernt, dann fährst du
volle Kanne auf die Wand zu. Ab vielleicht 50 Meter ENtfernung beginnst
du zu bremsen und die letzten Zentimeter lässt du es ganz langsam
rollen, bis die Reifen an der Wand anstehen.
Ein 'schärfer eingestellter' Regler (Brain 2.0) hat den Dreh raus, wie
man aus voller Kanne mit quietschenden Bremsen den Reifen exakt an die
Wand einparkt.
>> wie ich damit dann allerdings in richtung PI regler komme weiß ich noch> nicht.
Gar nicht.
Der hat damit ja nichts zu tun.
Der PI-Regler benutzt dann dieses Funktion um die von ihm errechneten
Geschwindigkeitswerte (die sich nach der 'Regeldifferenz', also dem
Abstand zur Zielposition richten) in eine Motorgeschwindigkeit
umzusetzen. Nämlich jene Geschwindikeit mit der er ans Ziel kommt ohne
darüber hinauszuschiessen. Und wenn er mal darüber hinausschiesst, dann
muss er eben zurückfahren - dazu braucht er einen Rückwärtsgang. Für den
Regler ist es am einfachsten, wenn er sich um solche 'Details' nicht
kümmern muss. Er hat einfach eine positive und eine negative
Geschwindigkeit.
Du verwechselst jetzt gerade das Gaspedal (+ Gang-Schaltung) mit dem
Menschen, der aufs Pedal drückt. Jetzt hast du erst mal das Gaspedal
implementiert.
> vermutlich ist der momentan genutzte PWM wert später mein Y, aber> das ist nur eine vermutung.
Das eigentlich traurige ist, dass du so gar keine Ahnung oder
Vorstellung davon hast, wie die Dinge zusammenspielen. Du hast seit den
Tagen als du als Kind Fahrradfahren gelernt hast, genau dasselbe
tausende male gemacht. Hier heißen die Dinge ein wenig anders und sind
technischer beschrieben bzw. in einen Formalismus eingebunden. Aber das
Prinzip und die Einzelkomponenten sind da wie dort genau die gleichen.
Man kann viel davon lernen, wie und aus welchen Komponenten ein Programm
aufgebaut sein könnte, wenn man sich eine ähnliche Aufgabenstellung aus
dem täglichen Leben sucht und sich mal überlegt, wie man da eigentlich
vorgeht. Ich würde mal schätzen, dass mindestens 80% der weniger
ausgeklügelten Algorithmen genau darauf beruhen, dass man sich ansieht,
wie eigentlich das Gehirn aus Erfahrung heraus ein gleichwertiges
Problem löst.
Wir Menschen können viel - nur wissen wir oft gar nicht bewusst, wie wir
das machen. Als Informatiker ist man immer gut beraten, sich selbst mal
bei einer gleichwertigen Problemlösung zu beobachten.
Sven Weinmann schrieb:> ich hoffe mich etwas verständlicher ausgedrückt zu haben.
Ja, damit kann man was anfangen. Du hast allerdings ein ganz
grundlegendes konzeptionelles Problem: Mit dem Aufbau ist keine Regelung
möglich. Für eine Regelung brauchst Du genau das hier:
> später soll an diesem schlitten ein sensor o.Ä. angebracht werden, der> an genauen punkten messwerte ausgibt. aber das ist nicht mein projekt.
Alles was mit Du mit Deinem jetzigen Aufbau machen kannst, ist dem Motor
eine Geschwindigkeit vorgeben, mehr nicht. Du weißt nicht, an welcher
Position er sich befindet. Dieser Code hier
> if (position == wunschwert)> {> mnotorstop;> }
wird also nicht möglich sein. Denn woher soll der Wert "position"
kommen, wenn nicht von einem Sensor?
Das einzige, was Du derzeit machen kannst, ist folgendes:
Du gehst davon aus, dass sich der Aufbau beim Einschalten in einem
definierten Zustand befindet, das heißt der Schlitten ist z.B. ganz
links. Wenn Du an Position x fahren willst, lässt Du den Motor eine
bestimmte Zeit lang mit einer bestimmten Geschwindigkeit nach
rechts/links drehen. Gemäß v = s / t kannst Du das grob ausrechnen.
Das Problem ist: Du weißt nicht, ob der Schlitten danach tatsächlich an
der Stelle ist. Es kommen ja noch Effekte wie Beschleunigung, Abbremsen
und andere Ungenauigkeiten ins Spiel. Mit der Zeit wird also die
geschätzte Position und die tatsächliche Position sich immer weiter
voneinander entfernen.
Um das zu verhindern, macht man eine Regelung. Das heißt, man misst, wo
sich der Schlitten befindet (Ist-Wert) und vergleicht das mit der
Position, an der er sein sollte (Soll-Wert). Wenn die Differenz ungleich
Null ist, lässt man den Motor in die entsprechende Richtung fahren. Wenn
man die Regelung richtig auslegt, erreicht der Schlitten diesen Punkt
dann auch (innerhalb der Messgenauigkeit und Feinheit der
Motoransteuerung). Das geht aber wie gesagt erst, wenn man auch einen
gemessenen Ist-Wert hat.
xfr schrieb:> grundlegendes konzeptionelles Problem: Mit dem Aufbau ist keine Regelung> möglich. Für eine Regelung brauchst Du genau das hier:>>> später soll an diesem schlitten ein sensor o.Ä. angebracht werden, der>> an genauen punkten messwerte ausgibt. aber das ist nicht mein projekt.>> Alles was mit Du mit Deinem jetzigen Aufbau machen kannst, ist dem Motor> eine Geschwindigkeit vorgeben, mehr nicht. Du weißt nicht, an welcher> Position er sich befindet.
Langsam.
Er hat von den Dingen gesprochen, die am Schlitten montiert sind (und
die für uns uninteressant sind). Interessant ist nur, dass sich am
Antrieb ein Poti befindet, welches eine Aussage über die momentane
Schlittenposition erlaubt. Er hat das in einem Nebensatz irgendwo
erwähnt und dafür lieber über Dinge erzählt, die für die Aufgabe
irrelevant sind :-)
Das übliche halt: Vor lauter 'komplexer Aufgabenstellung' verliert man
aus lauter Ehrfurcht vor dem Schwierigkeitsgrad die tatsächlich
wichtigen Dinge aus den Augen. Das Kaninchen sieht aus lauter Angst vor
der Schlange nicht den Adler, der sich gerade auf die Schlange stürzt.
Sven Weinmann schrieb:> an dem zahnradkonstrukt(, welches ich nicht als getriebe deute!), ist> auch ein poti zur positionierung des schlittens dran.
Vielleicht habe ich das aber auch falsch gedeutet. Wenn dieses Poti die
Position des Schlittens erfasst, dann ist das Dein Ist-Wert. Damit ist
dann natürlich eine Regelung der Position möglich.
Die Aufgabe der Regelung ist also grob gesagt: Je größer der Abstand
zwischen Soll- und Ist-Position, desto schneller den Motor in die
Richtung fahren lassen.
Karl Heinz Buchegger schrieb:> Er hat von den Dingen gesprochen, die am Schlitten montiert sind (und> die für uns uninteressant sind). Interessant ist nur, dass sich am> Antrieb ein Poti befindet, welches eine Aussage über die momentane> Schlittenposition erlaubt. Er hat das in einem Nebensatz irgendwo> erwähnt und dafür lieber über Dinge erzählt, die für die Aufgabe> irrelevant sind :-)
Jep, habe es jetzt auch gelesen. Ich war gedanklich die ganze Zeit bei
einem Poti mit Drehknopf, mit dem ein Mensch den Sollwert einstellt ...
1. Potiwert per ADC messen
2. ADC-Wert in absolute IstPosition umrechnen
3. Differenz zwischen IstPosition und SollPosition ausrechnen (mit
Vorzeichen!) -> Regeldifferenz
4. Regelgleichung mit der Differenz berechnen (mit Vorzeichen und gegen
Überläufe abgesichert), ergibt die Stellgröße
5. Stellgröße in PWM umrechnen
6. PWM auf Motor geben
P-Regler:
Die Differenzstrecke zwischen Soll und Ist multipliziert mit einem
festen Faktor ergibt die Motorleistung. Der Schlitten bleibt dann
stehen, wenn er entweder genau am Ziel ist oder die Motorleistung nicht
mehr reicht, um ihn zu bewegen (Reibung).
PI-Regler:
Der I-Anteil gibt sich nicht damit zufrieden, wenn der Schlitten nicht
genau am Ziel ist. Er erhöht die Motorleistung, wenn der Schlitten neben
dem Ziel steht, aber der P-Anteil schon zu gering ist, um die Reibung zu
überwinden.
Sven Weinmann schrieb:> dass der PI regler den wunschwert nicht 100% erreicht ist klar, sonst> wärs keine regelung. (regeldifferenz 0 = unsinn!)
Doch! Der Sinn des I-Anteil ist es, die Regelabweichung zu minimieren!
Zu beachten:
Der Regler kann überschwingen, d.h. der Schlitten fährt über's Ziel
hinaus. Hier ist die Frage, ob bzw. wie weit Deine Maschine das erlaubt.
Als Faustregel gilt: Je schneller der Regler, umso mehr schwingt er
über.
Ist auch logisch: Mit hohem P-Anteil fährt der Schlitten mit voller
Motorleistung nahe ans Ziel und fährt dann wegen seiner Trägheit über's
Ziel hinaus. Mit kleinem P-Anteil schleicht sich der Schlitten an, aber
er braucht auch länger, weil er langsamer fährt.
Hey Leute, danke für die vielen Antworten!
hab mir das nun mal durchgelesen.
den Ansatz den Bronco gegeben hat ist sehr interessant, wobei mir der 2
punkt nicht einleuichtet.
ich lese per ADC den Potiwert, dieser ist zw. 0..1023, also 1024
Schritte.
wenn ich zu Position 500 fahren möchte, wieso muss ich ihn dann noch
vorher umrechnen?
beispiel Istwert = 230 Sollwert = 500 dann ist die Regeldifferenz (e =
w-r => e = 500 - 230 = +270
ich denke der Ansatz ist prima, wobei ich damit natürlich noch nicht mit
der oben genannten Formel arbeiten kann.
Karl Heinz wird wahrscheinlich sagen, "wieso wieder mit der Tür ins Haus
fallen, der junge braucht Grundlagen" und genau da stimme ich ihm an
dieser Stelle zu.
wir waren bei der geschriebenen PWM:
da stand die frage im Raum, durch den pwm wert die geschwindigkeit zu
regeln.
0..1023 umzurechnen in -100 .. 0 .. +100 SPEED
der jetzt genutzte Poti hat allerdings nichts mit der Position zutun,
vom Schlitten!
Dieser ist später erst zu benutzen!
Sven Weinmann schrieb:> ich lese per ADC den Potiwert, dieser ist zw. 0..1023, also 1024> Schritte.>> wenn ich zu Position 500 fahren möchte, wieso muss ich ihn dann noch> vorher umrechnen?
Du musst Dich für eine Einheit für die Position entscheiden. Du kannst
dafür direkt den ADC-Wert nehmen, dann musst Du nichts umrechnen. Du
hast aber ja neben dem Ist-Wert auch noch den Soll-Wert, den der
Benutzer vorgibt. Vielleicht möchte der ja lieber die Position in
Zentimetern angeben statt in "ADC-Spannung". Dann würde es sich
anbieten, den gemessenen ADC-Wert in Zentimeter umzurechnen und dann
erst zu vergleichen.
Sven Weinmann schrieb:> ich denke der Ansatz ist prima, wobei ich damit natürlich noch nicht mit> der oben genannten Formel arbeiten kann.
Mit "oben genannter Formel" meinst Du die im Ausgangspost, für den
PI-Regler? Das ist Schritt 4.
Sven Weinmann schrieb:> wir waren bei der geschriebenen PWM:>> da stand die frage im Raum, durch den pwm wert die geschwindigkeit zu> regeln.> 0..1023 umzurechnen in -100 .. 0 .. +100 SPEED
Die Geschwindigkeit soll nicht geregelt werden, sondern später die
Position. Deine erste Aufgabe (sofern das noch nicht funktioniert) ist,
den Motor mit unterschiedlichen Geschwindigkeiten vor- und rückwärts
fahren zu lassen. Also statt nur Ein und Aus ein PWM-Signal zu erzeugen.
Das ist aber erstmal nur eine reine Steuerung, ohne Messen der
tatsächlichen Geschwindigkeit. Die Regelung kommt später, aber dann
als Positionsregelung, nicht als Geschwindigkeitsregelung.
xfr schrieb:> Vielleicht möchte der ja lieber die Position in> Zentimetern angeben statt in "ADC-Spannung". Dann würde es sich> anbieten, den gemessenen ADC-Wert in Zentimeter umzurechnen und dann> erst zu vergleichen.
Vielleicht noch als Ergänzung:
Hinsichtlich Genauigkeit wäre es hier allerdings sinnvoller, Zentimeter
in "ADC 0-1023" umzurechnen. Die Erklärung war grundsätzlicher gemeint,
also warum man im Allgemeinen den ADC-Wert eventuell nicht 1:1
weiterverwenden kann, sondern in die richtige Einheit umrechnen muss.
Sven Weinmann schrieb:> wenn ich zu Position 500 fahren möchte, wieso muss ich ihn dann noch> vorher umrechnen?
Hat zwei Gründe:
1. Der Mensch versteht physikalische Einheiten besser als Hexwerte,
wodurch das Debuggen einfacher wird. Wenn Du irgendwo in Deiner Rechnung
einen Wert von 0x3354 vorfindest, wird gerade ein ambitionierter
Einsteiger nicht sofort wissen, ob das sinnvoll ist oder total daneben
liegt.
2. Ein Istwert-Sensor (in Deinem Fall der Poti) hat oft keinen linearen
(proportionalen) Zusammenhang von Spannung und physikalischem Meßwert,
sondern irgendeine Kurve. In dem Fall wäre der ADC-Wert dann nicht
proportional zur Position. Um es mit Monthy Python zu sagen: Hast Tu Tas
üperprüft?
Eines noch:
Du mußt wirklich sehr genau darauf achten, die Werte und
Zwischenergebnisse auf ihre erlaubten Werteräume zu begrenzen und
Überläufe zu vermeiden.
Aber das steht auch in der Atmel Appnote drinn.
Das Argument mit der Nichtlinearität ist ok.
Aber das andere ist eine reine Frage der Anzeige.
Ob der Regler jetzt von Position 258 zur Position 876 fahren soll und
beide Zahlen ADC Einheiten sind, oder ob er von Position 12.8 zur
Position 34.2 fahren soll und beides Zentimeter sind, ist ziemlich egal.
Beides sind einfach nur Zahlen. Und mit dem Kp, Ki Werten ist sowieso
keine physikalische Vorstellung verknüpft ausser einer gewissen 'Stärke'
mit der der Regler reagiert.
D.h. Eine Sollvorgabe vom Benutzer gleich mal in ADC Einheiten
umzurechnen und dann innerhalb des Reglers nur mit ADC Einheiten zu
arbeiten ist genauso gut/schlecht wie anders rum. Nur der Rechenaufwand
im Regler ist geringer, weil man sich eine sinnlose
Bereichskonvertierung spart. (und sich hoffentlich dann auch bewusst
ist, dass man auf die Art den überhaupt möglichen Verfahrweg in
lediglich 1024 Teile aufgeteilt hat. D.h. das ist bei 1 Meter ca. 1
Millimeter und selbst die werden nicht wirklich stimmen)
>Den Motor steuere ich über einen L298 Motortreiber
Es handelt sich also um eine Schrittmotorsteuerung. Wozu braucht man
dabei einen PI-regler?
Wenn ich z. B. sage, der Motor soll 200 Schritte nach links machen, dann
bleibt er nach 200 Schritten stehen.
Sollte der Motor durch Trägheit über das Ziel, wie hier angegeben,
hinaus schießen, dann kann man evtl. bei den letzten 10-15 Schritten die
Geschwindigkeit reduzieren. Dann bleibt der Motor genau am gewünschten
Ziel stehen.
Oder habe ich da etwas falsch verstanden?
MfG
Der 298 ist ein motortreiber. Man kann damit in Kombination mit einem
297 auch einen schrittmotor ansteuern. Was ich auch in einen anderen
Projekt schon getan habe. Aber hier geht's nur um einen 12v dc Motor.
ich hätte kurz eine frage:
wie übergebe ich z.b. dem PIN B4 den wert von Y?
PORTB |= (1<<4);
wie übergebe ich den PWM wert an diesen?
oder muss der pin dann der vom OCR1A sein?
Mit PORTB kann man den Pin nur ein- und ausschalten, also auf 0 oder 1
setzen. Du musst einen Timer so einrichten, dass er ein PWM-Signal an
dem Pin erzeugt. Wie das geht steht im Tutorial.
if((y<1023)&&(y>0))// bei Übersteuertem stellglied Integration einfrieren
12
{// (Anti-Windup)
13
esum=esum+e;// Summe der Regelabweichung aktualisieren
14
}
15
16
y=(Kp*e)+(Ki*Ta*esum);// Formel des PI Reglers -> Kp = Proportionalbeiwert, Ki = Integrierbeiwert, Ta = Abtastzeit
17
18
if(y<-5){Motor_X(Links,abs(y));}// Drehrichtung Links und PWM Wert
19
if(y>5){Motor_X(Rechts,abs(y));}// Drehrichtung Rechts und PWM Wert
20
if((y>=-5)&&(y<=5)){Motor_X(Stop,0);}// Drehrichtung "Stop" und PWM = 0
21
22
if(y>1023){y=1023;}// Ist y größer als 1023 dann soll y = 1023 sein
23
if(y<0){y=0;}// Ist y kleiner als 0 dann soll y = 0 sein
24
// 0..1023 = 10bit PWM
// Die Richtungen Links und Rechts sind via define mit 1 und 0 belegt.
folgendes:
ich gebe mit einem poti, wessen wert ich via ADC einlese einen wert vor,
an den der motor fährt. anhand des control centers sehe ich den ist/soll
wert und die sprünge.
ich arbeite mit den werten:
Ta = 2;
esum = 0;
Kp = 10;
Ki = 2;
und das ist mein unterprogram, mit welchem ich den motor ansteuer:
1
voidMotor_X(uint8_tEingangA,int8_tSpeed)
2
{
3
uint8_tEingangB;
4
5
OCR1A=Speed;
6
7
PORTB|=(1<<1);
8
9
if(EingangA==2)// Vollbremsung
10
{
11
PORTB|=(1<<2);// Eingang A = 1
12
PORTB|=(1<<3);// Eingang B = 1
13
}
14
15
if(EingangA==0)// Rechts
16
{
17
PORTB&=~(1<<2);// Eingang A = 0
18
PORTB|=(1<<3);// Eingang B = 1
19
}
20
21
if(EingangA==1)// Links
22
{
23
PORTB|=(1<<2);// Eingang A = 1
24
PORTB&=~(1<<3);// Eingang B = 0
25
}
26
return;
27
}
ich bin mir sicher, dass der P-Regler funktioniert, da ich den Ki Anteil
zunächst auf 0 gesetzt habe, und die Sprünge des Reglers im Control
Center ausgewertet habe.
jedoch der I Anteil fehlt mir.
Im Controlcenter sehe ich lediglich 10er Werte, keine "krummen" Werte,
welche aus der rechnung mit dem Ki-Teil resultieren sollten.
habe ich da noch einen fehler drin, dass der I-Regler nicht
funktionieren könnte?
achja UND :) die bereichseingrenzung > 1023 und <0 ist nicht in der
übergabe an den motor enthalten! d.h. die müsste ich irgendwie noch hier
rein bringen ->
1
if(y<-5){Motor_X(Links,abs(y));}// Drehrichtung Links und PWM Wert
2
if(y>5){Motor_X(Rechts,abs(y));}// Drehrichtung Rechts und PWM Wert
3
if((y>=-5)&&(y<=5)){Motor_X(Stop,0);}// Drehrichtung "Stop" und PWM = 0