Morgen erstmal ;-) Nachdem mein Robi nun mehr oder weniger funktioniert bin ich gerade am verbessern von verschiedenen Funktionen. Eine davon ist der Gerade Auslauf. Bisher habe ich die Motoren einfach mit einem PWM angesteuert. Leider ist es aber so das sich der Widerstand des Untergrunds doch relative stark bemerkbar macht. Da die Motoren an der Welle Hallgeber haben könnte ich die auf diese Syncronisieren. Nun habe ich die Hallgeber an einen INT des AT90PMW3B angeschlossen. Der Signalbereich den ich an den Anschlüssen der Hallgeber abgreifen kann ist von ca 10Hz bis ca 140hz. Ich habe nun einen Timer auf 1 sec gestellt und und im INT Register zähle ich die Impulse hoch. Jede sec werden die Impulse dann in ein anderes Register übertragen. Momentan schaut meine alte Regelung so aus. Die Fernsteuerung liefert ein Signal bei dem ich die Pulsweite auslese. In der Mittelstellung habe ich ca 1500 (=1.5ms). Die H-Brückenregelung seht ihr hier. ON_TIME_0=ON_TIME_0_RC_2-1178+dt+dt_range; ON_TIME_1=1950-ON_TIME_0_RC_2-dt-dt_range; Ich schaue das bei 1,5ms beide Register bei ca 300 stehen.Da beide Register gleich sind ist die H-Brücke aus. Je nach dem wie ich den ich den Steuerstick der Fernbdienung bewege steigt der Wert im einen und sinkt im anderen Register. Das dt_range steht immer auf 0. Wird später noch für das ausweichen mit einem Ultraschall Sensor kommen. Nun meine Frage Eine sec ist relative lang für eine Regelung des Gleichlaufes. Wie gehe ich das Problem am besten an, und wie baue ich die Regelung am besten auf. MFG Christoph
Die Anzahl Umdehungen zu zaehlen ist eine Sache, Geradeauslauf eine andere. Abhaengig vom Untergrund braucht man auf beiden Seiten unterschiedliche Anzahl Umdrehungen. Dajer sollte laengerfristig ein Geradeaus sensor rein
schon klar. Das Problem ist das jeder Motor etwas anderst ist aufgrund Toleranzen. So bekomme ich trotz gleicher PWM immer eine etwas andere Geschwindigkeit. Das würde ich gerne schonmal ausgleichen.
Christoph B. schrieb: > Eine sec ist relative lang für eine Regelung des Gleichlaufes. Wie gehe > ich das Problem am besten an, und wie baue ich die Regelung am besten > auf. Da sehe ich auch so. Du hast eine ziemliche Totzeit in deinem System. Besser ist es du mist nicht die Frequenz sondern die Periodendauer. Also die Zeit zwischen 2 Flanken deines Sensor. Das ist das schnellere Signal. Damit baust du erstmal eine Drehzahlregelung fuer jedes Rad separat auf. Dessen Sollwert erzeugst du mit einer uebergeordneten Regelung die die Differenz der Raeder betrachtet. Die bekommt als Eingangswert die Geschwindigkeit und einen Drehzahlunterschied fuer die Raeder.
Üblicherweise macht man für jedes Rad einen DrehzahlREGLER, welche gleiche Sollwerte bekommen. Eine überlagerte Differendrehzahlreglung würde ich nach den beiden Drehzahlregler einkoppeln, zumindest wenn die Differenzausregleung schneller sein soll. In die Sollwerte der einzelen Drehzahlregler eingekoppelt kanns schwingen.... Doch bei deiner einfachen Anwendung sollte eine getrennt Regelung ausreichen. Aber gleiche Drehzahl bedeuted nicht unbedingt geradeaus. Selbst eine Phasenregelung der Räder (Wie in der ULF Straßenbahn) sichert kein Geradeausfahren, wenn Schlupf auftritt. MFG
Mein Roboter hat Odometrie Sensoren, die liefern 40 Impulse pro Radumdrehung. Das dürfte deinem Aufbau sehr ähnlich sein. Zu Neginn einer Fahrt wird berechnet, wie viele Impulse pro 100ms nötig sind, um die Sollgeschwindigkeit zu erreichen und wie viele Impulse absolut nötig sind, um das Ziel (Entfernung) zu erreichen. Bei Kurvenfahrt sind diese Sollwerte links und rechts entsprechend unterschiedlich. Dann werden beide Motoren per PWM beschleunigt, bis sie ihre soll-Drehzahl erreicht haben. Anschließend wird geregelt, um die Soll-Drehzahl zu halten. Das habe ich mit einer PI Regelung realisiert, für links/rechts separat. Variante a) Wenn das Ziel erreicht wurde, stoppen beide Motoren abrupt. Variante b) Fortlaufend während der Fahrt wird der Bremsweg geschätzt (Geschwindigkeit*Geschwindigkeit)/Konstante, wobei ich die Konstante experimentiell ermittelt habe. Wenn der Bremsweg >= Distanz zum Ziel ist, wird gebremst (Motor kurzschließen). Wenn der Bremsweg danach < Distanz zum Ziel ist, wird die Bremse gelöst (Motor im Leerlauf). So kommt der Roboter exakt da zu stehen, wo er soll.
Bei mir gibt es kein Ziel ;-) Die Steuerung soll momentan über einen RC-Fernbedienung gemacht werden. Momentan ist es so das wenn ich gerade aus fahren will ich immer korigieren muss. Das hätte ich gerne automatisch. Momentan zähle ich die Flanken pro sec. Das sind ca 20 bis 135. Mir ist nur noch nicht klar wie ich das am einfachsten Implementiere. Wie vieleicht schon aus dem ersten Post von mir ersichtlich verwende ich den PSC Controller des Atmega AT90PWM3B. Wenn beide Register ( ON_TIME_0 und ON_TIME_1) gleich sind steht der Motor. Je größer der Unterschied zwischen den Registern umso schneller läuft der Motor in die eine oder andere Richtung. Momentan ist es so das die Steuerung auf jedem AT90PWM3B selbst läuft. Das heist er bekommt z.b die Werte für die Entfernung des Ultraschall Sensors über SPI. Auswerten und entscheiden tut jeder AT90PWM3B für sich. Genaus so ist es auch bei der PMW. Er bekommt die Werte der RC Fernbedienung im "Rohformat" und berechnnet anhand einer Formel die Geschwindikeit der PWM. Was mir genau fehlt ist die neue "Formel" wo die Rad Daten eingebunden sind. ;-)
zum testen habe ich einfach aus den 2 Impulswerten die Differenz gebilden und dann dazu addiert ;-). Die Motoren habe sich dann einfach aufgeschaukelt da die 1 sec wohl zu träge ist.
Im Sekundentakt zählen ist zu langsam. Dann kansst Du ja nur im Sekundentakt korrigieren, da ist ein Aufschwingen geradezu zu erwarten. Schwingungen im Regelkreis verhinderst Du, indem Du die Regelung dämpfst. Du darfst die Drehzahl nicht so hefti regeln, sondern schön träge. Miss im 100ms Intervall. Und dann korrigiere die Leistung der Motoren in jedem Intervall maximal ein bisschen (wievie ein bisschen ist, musst du ausprobieren).
das Problem ist das ich bei 100ms zuwenige Signale vom Hallgeber bekomme. ;-) Der Hallgeber gibt pro Umdrehung 2 Impulse aus. Bei Vollgas sind das ca 140Hz.
Christoph B. schrieb: > das Problem ist das ich bei 100ms zuwenige Signale vom Hallgeber > bekomme. ;-) Und warum befolgst Du nicht Helmut Lenzens Vorschlag, eine Messung der Periodendauer durchzuführen, statt die Anzahl der Flanken/Impulse pro fester Zeiteinheit? Das ganze hat der Charme, dass man dann pro Flanke einen Regelzyklus ausführen kann. Man muss jedoch berücksichtigen, dass man dadurch eine reziproke Zeitskala erhält, so dass man dies beim Integrieren und Differenziern berücksichtigen sollte. Natürlich erhält man dann pro Motor jeweils eine eigene reziproke Zeitskala, aber dies ist eigentlich auch kein Problem. Der übergeordnete Differenzregler kann wiederum zeitlich äquidistant aufgerufen werden. Das primäre Ziel muss jedoch erst einmal sein, die richtigen Parameter für jede einzelne Achse zu finden. Erst wenn sich solch ein Regler stabil verhält, d.h. weder bei Lastwechseln noch bei Sprüngen des Sollwertes stärker schwingt als durch den aperiodischen Grenzfall bestimmt, sollte man sich daran machen, den Differenzregler aufzusetzen. Ansonsten sieht man nämlich nicht, welcher Regler Instabilitäten hervorruft.
ich werde die Periodendauer messen. Zuerst muss ich noch die Platinen fix in wasserdichte Boxen verbauen.
So ich muss dieses Thema nochmals ausgraben. Ich habe mich nun an die Periodendauer gewagt. Leider will das nicht ganz wie ich es gerne hätte. Hier der entscheidende Teil des Programms.
1 | void INIT_Pulsdauer(void) |
2 | {
|
3 | TCCR1B |= (1<<WGM12)|(1<<CS10); //prescaler 1 an Timer1 |
4 | TIMSK1 |= (1<<OCIE1A); //overflow Interrupt erlauben |
5 | OCR1A=80; |
6 | }
|
7 | |
8 | void Drehzahl_init(void) |
9 | {
|
10 | PORTD=(1<<PD5)|(1<<PD6); //PULLUPS Aktivieren |
11 | EICRA=(1<<ISC00);// Jede Flanke Interrupt |
12 | EIMSK=(1<<INT0); // INT 0 |
13 | }
|
14 | |
15 | ISR(INT0_vect) //interrupt service routine |
16 | {
|
17 | rpm=count; |
18 | count=0; |
19 | }
|
20 | |
21 | |
22 | ISR(TIMER1_COMPA_vect) |
23 | {
|
24 | count++; |
25 | }
|
Leider ist es so das ich relative oft den Wert 0 rausbekomme. Die Werte die ich sonst bekomme sind zwischen 7000 und 1000. Es scheint als ob sich der die Int in die Quere kommen. PS: Der Takt des Atmega ist 8Mhz. Leider ist es mir nicht möglich einen anderen Pin als den INT0 zu verwenden. Ich weis das es mit dem ICP1A besser gehen würde. MFG Christoph
Christoph B. schrieb: > Leider ist es so das ich relative oft den Wert 0 rausbekomme. > > Die Werte die ich sonst bekomme sind zwischen 7000 und 1000. Dein Sensor prellt. Daher erhältst du Mehrfachauslösungen, sodass mehrmals hintereinander in die ISR(Int0) gesprungen wird und dein aktueller rpm Wert auf 0 gesetzt wird. Lösungsvorschläge: 1. Sensor tiefpassfiltern oder entprellen (selbe wie Tasterentprellung) 2. Softwareseitiger Plausibitätscheck, ob der neue Wert gültig sein kann, z.B. auf Grund zu starker Abweichung vom vorherigen Wert.
Christoph B. schrieb: > Kann ein Hall Sensor überhaupt prellen?? Es prellt nicht der Sensor, sondern das Signal, was am µC ankommt ;-)
Christoph B. schrieb: > mal schauen ob ich es mit einem Tiefpass in den Griff bekomme. Sieht man den da mit dem Skope ueberhaupt ein schwingen?
Toggle in deiner Interruptserviceroutine für den Port doch mal einen Pin. Dann siehst du doch ob da eine Falschtriggerung erfolgt.
So habe mal eine PIN togglen lassen. Das Bild das sich dabei ergibt verwundert mich etwas. Der Gelbe Kanal ist der getoggelte Pin. Der Blaue das Signal was der Atmega vom Sensor bekommt. Wieso ist da getooglete Signal plötzlich so komisch. MFG Christoph
Christoph B. schrieb: > Wieso ist da getooglete Signal plötzlich so komisch. Weil da mehrfach getriggert wird. Du hast da eine Stoerung auf deinem Eingangssignal drauf. Kannst du da ein Signal von einem Funktiongenerator mal drauf geben das wirklich sauber ist? Eventuell mal einen Schmitttrigger vorschalten (74xx14) .
habe leider keinen Schmitttrigger zur hand. ;-( Mit meinen Eigenbau Funktiongenerator geht das togglen bis ca 1.6khz. Welchen Schmitttrigger könntest du empfehlen? Nicht das ich noch den Falsche bestelle. ;-) Ist der SN74AHCT14Q OK?
Der ist zwar schnell sollte aber gehen. Wuerde aber den 74HC14 bevorzugen. Was hast du denn sonst da? Eventuell einen NE555 um damit ein Signal zu erzeugen. Oder einen weiteren uC. Kenn den Inhalt deiner Bastelkiste nicht.
ich würde den Phasenwinkel zwischen den Beiden Hallsensor Impulsen in einer PLL verwursten. Damit hast du die die Wegdifferenz bei jeder Halsensorperiode viermal zu Verfügung mindestens 2 davon sollten sinnvolauswertbare Korrekturwerte an die PWM zu liefern vermögen hier die auswertbaren Fankensignale HLA-HLB HLB-LHA LHA-LHB LHB-HLA diese mit einem Faktorbelegen und der PWM als Korektur hinzufügen und es zittert sich hin. sollte sich das system aufschwingen noch eine Dämpfung (gleitender Mittelwert) für die Korrektur vorsehen so bekommst du unterschiedliche Rollwiderstände ausgeglichen. gegen Kurvenfahrten auf geneigten/gebogenen Flächen benötigst du noch einen Lagesensor wie er auf Schiffen als Krängungsensor eingesetzt wird.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.