Forum: Mikrocontroller und Digitale Elektronik Controller mit mehr als 16MHz internem Takt?


von Kuen (Gast)


Lesenswert?

Tag zusammen,

ich arbeite im Moment mit dem Attiny25 und der 16MHz internen Clock. Mit 
dem Controller werte ich Signale im 10-30µs Bereich aus. Im Prinzip 
funktioniert das ganze wie eine Art Servoregelung, nur dass das Signal 
kein typisches Servosignal ist, sondern ein 9-Bit Signal mit diesen µs 
Pegeln. Der Ablauf des Controllers ist folgender:

-Signal einlesen und auswerten (Sollwert)
-A/D Wandlung für die Ist-Position des Motors
-Regelung

und wieder von vorne.

Soweit klappt das ganze schon ganz gut, nur irgendwie hab ich das Gefühl 
das die Regelung dabei zu langsam von statten geht. Der Motor zittert 
ein wenig beim einregeln und dieses Zittern häte ich gerne weg.

Nun ist meine Frage jemand einen Controller von der Größe des Attiny25 
kennt, der mehr als 16MHz interne Clock besitzt? Einen externen Quarz 
kann ich wegen Platzmangel leider nicht verwenden.

Eine andere Frage wäre noch ob es etwas bringen würde, das Programm in 
Assembler anstatt C zu schreiben?

Über ein Paar Tips würd ich mich freuen.

Gruß
Kuen

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Schau mal das du nicht die CHKDIV/8 Fuse gesezt hast (weiß nicht ob der 
Tiny sowas besizt) und lad am besten auch mal die Korrekturwerte des 
internen RC Ozilators.
Achja ASM kann natürlich was bringen gerade wenns Zeitkritisch ist...

von Fly (Gast)


Lesenswert?

Hmm ja, prinzipiell gibt es noch 20 MHz Atmel Controller.
Da das aber nicht viel mehr ist, kann es durch optimieren deines Codes 
möglich sein, dass du mehr raus holst.

Wenn du mit AVR-GCC proggst, stell die Codeoptimierung mal auf "Speed". 
Ansonsten poste mal dein Programm. Grundsätzlich ist es möglich mit ASM 
schnellere Programme zu schreiben -Wenn du weisst wie und es dir antun 
willst.

von Willi W. (williwacker)


Lesenswert?

Wenn der Motor zittert, kann das auch an ungünstig eingestellten 
Regelparametern liegen. Ich denke, dass Deine Regelung schon schnell 
genug ist. Vielleicht auch ein Software-Fehler?

von Blume - konkret Aster (Gast)


Lesenswert?

>Da das aber nicht viel mehr ist

25% mehr ist schon einiges.

von Fly (Gast)


Lesenswert?

Ich denke durch Software-Optimierung kann man vielleicht mehr als die 
25% rausholen. Bis jetzt habe ich es immer geschafft, auch wenn es auf 
den 1. Blick hoffnungslos aussieht.

Poste doch mal deinen Code. Ich denke die Leute werden dir bestimmt 
helfen und Optimierungspotential aufzeigen.

von Kuen (Gast)


Angehängte Dateien:

Lesenswert?

Morgen,

erst eimal vielen Dank für eure Antworten.

Also das CHKDIV/8 Fuse ist nicht gesetzt. Der Controller läuft mit den 
16MHz, das hab ich mir am Oscar angeschaut. Zittern tut der Motor nur, 
wenn er in Position fährt, aber das liegt denke ich am über bzw. unter 
Regeln. Wenn er die Position dann erreicht hat ist das Zittern weg.

Hab den Code mal angehängt, vielleicht habt ihr ja ein paar 
Verbesserungsvorschläge für mich.


Gruß
Kuen

von Falk B. (falk)


Lesenswert?

@ Kuen (Gast)

>Hab den Code mal angehängt, vielleicht habt ihr ja ein paar
>Verbesserungsvorschläge für mich.

Pulsdauer = TCNT0;

Das würde ich als ERSTE Anweisungh in den INterrupt schreiben. Nur so 
hat man einen konstanten Zeitbezug zwischen externer Flanke an INT0 und 
dem Zähler. Bei dir sind noch die Abfragen davor, die je nach Zweig 
unterschiedlich lange dauern. Damit kommt es zu einem Messfehler.

MFG
Falk

von Olaf (Gast)


Lesenswert?

> Wenn der Motor zittert, kann das auch an ungünstig eingestellten
> Regelparametern liegen.

Das wird mit Sicherheit der Fall sein. Das einzige was an so einer 
Regelung schnell sein muss ist die Abtastung des Istwertes von den 
Winkelencodern und auch nur deshalb weil die bei Maximalgeschwindigkeit 
mithalten muss.
Der eigentliche Regler kann sehr langsam sein.

Olaf

von Kuen (Gast)


Lesenswert?

@Falk

Danke für den Tip!

@Olaf
>> Wenn der Motor zittert, kann das auch an ungünstig eingestellten
>> Regelparametern liegen.

> Das wird mit Sicherheit der Fall sein.

Aber in wie fern. Im Prinzip ist die Regelung ja nur ein Soll- Istwert 
Vergleich.

Das ganze läuft ja so ab:
-Sollwert einlesen
-Istwert einlesen
-Vergleichen
-Regeln

Wie kann ich da die Abtastung des Istwertes beschleunigen?

Hab das AD-Wandeln mal etwas beschleunigt indem ich den Wandler etwas 
schneller getaktet hab. Bei 8-Bit Auflösung dürfte es dabei eigentlich 
keine Probleme geben. Bringt aber keine wesentliche Verbeserung. Was 
könnte ich noch optimieren?

von AVR-User (Gast)


Lesenswert?

Was für ne Regelung hast du denn? P, PI, PID oder PD? Spiel einfach mal 
mit den einzelnen Parametern.

von Fly (Gast)


Lesenswert?

Wenn ich es richtig verstehe, Regelst du, wenn c=0.
c wird vom externen Interrupt auf 0 gesetzt. Wann und wieviel Mal pro 
Sekunde wird c=0 ?

Kann es sein das du zu schnell regelst? Vielleicht mal eine Totzeit 
einbauen?
Sehe ich es richtig, dass du keine P(I)(D) Regelung verwendest sondern 
einfach nur auf Schwellwerte schaust und somit eine gewisse Hysterese 
hast?

von Falk B. (falk)


Lesenswert?

@ Kuen (Gast)

>Aber in wie fern. Im Prinzip ist die Regelung ja nur ein Soll- Istwert
>Vergleich.

Wenns soooo einfach wäre . . . ;-) Reglerparametrierung ist eine 
Wissenschaft für sich.

>Das ganze läuft ja so ab:
>-Sollwert einlesen
>-Istwert einlesen
>-Vergleichen

Das ist relativ einfach

>-Regeln

Hinter diesen kleinen Wort steckt eine Wissenschaft!

>Wie kann ich da die Abtastung des Istwertes beschleunigen?

Wozu? Du weisst doch gar nicht wodurch das Ruckeln verursacht wird.

>keine Probleme geben. Bringt aber keine wesentliche Verbeserung. Was
>könnte ich noch optimieren?

Die Parameter. Wobei ich nicht so recht in deinem Code durchsteige.
Deine Stellgrösse ist rein digital in motor(), wenn ich das recht sehe 
ist da reines ON/OFF mit einer Vollbrücke, nicht wahr?
Du hast keinen Filter für deine Istwerte, und der Regelalgorithmus 
erschliesst sich mir auch nicht so wirklich.

MfG
Falk

von Kuen (Gast)


Lesenswert?

Es ist ein Zweipunktregler und hat keine Regelparameter. Es gibt nur den 
Ist- und den Sollwert.

> Wann und wieviel Mal proSekunde wird c=0 ?

Also c wird immer zwischen den Signalpegeln 0. Ein komplettes Signal 
dauert ca. 1,5ms. Zwischen den einzelnen Pulsen des Signals hat der 
Controller ca. 120µs Zeit die AD-Wandlung und die Regelung zu machen. 
Zwischen den Signalen gibt es eine Pause von ca. 60ms in der auch 
gewandelt und geregelt wird.

>Sehe ich es richtig, dass du keine P(I)(D) Regelung verwendest sondern
>einfach nur auf Schwellwerte schaust und somit eine gewisse Hysterese
>hast?

Ist richtig, hab schon überlegt eventuell mal ne PI-Regelung zu 
versuchen. Hatte auch mal irgendwo ne Seite gefunden wo die Regler für 
Mikrocontroller erklärt waren. RC-Wissen oder Kreatives Chaos, find die 
Seite leider nicht mehr wieder.

von AVR-User (Gast)


Lesenswert?

Hier ein sehr ausführlicher Artikel:
http://www.roboternetz.de/wissen/index.php/Regelungstechnik

von Fly (Gast)


Lesenswert?

Ich steige bei deinem Code auch nicht ganz durch.

Ich könnte mir aber vorstellen dass das Zittern von daher kommt:
Du hast ja eine Hyterese von +-3 = 6 von max. 256. Das ist schon 
ziemlich viel und ich denke das verursacht das Zittern.
Wahrscheinlich bist du auch viel zu schnell mit "Regeln", der Motor 
braucht auch seine Zeit, bis er den Sollwert erreicht hat.

von Paul Baumann (Gast)


Lesenswert?

Dann hast Du einen P-Regler gebaut bzw. programmiert und der Kollege 
P-Regler hat eine bleibende Regelabweichung. Das heißt, daß die 
Ausgangsgröße immer um den Sollwert herum schwankt. Darum wird der Motor 
zittern. Ich nehme mal an, daß ein PI-Regler dafür besser wäre, weil der
Motor ja eine gewisse Totzeit hat.

MfG Paul

von Kuen (Gast)


Lesenswert?

>Die Parameter. Wobei ich nicht so recht in deinem Code durchsteige.
>Deine Stellgrösse ist rein digital in motor(), wenn ich das recht sehe
>ist da reines ON/OFF mit einer Vollbrücke, nicht wahr?

Richtig! Also der Motor wird über einen Motortreiber gesteuert. Der 
brauch drei Eingangszustände. Zwei Zustände(Ausgänge PB0 und PB3) sagen 
der Treiber in welche Richtung der Motor drehen soll), der andere ist 
dauerhaft High und sagt Vollgas. Dabei gäbe es eventuell noch die 
Möglichkeit anstatt Vollgas die Geschwindigkeit über PWM zu regeln.


>Du hast keinen Filter für deine Istwerte, und der Regelalgorithmus
>erschliesst sich mir auch nicht so wirklich.

Das mit den Filtern versteh ich nicht ganz? Der Regelalgorithmus ist 
aber Recht einfach. Es wird das Signal über den externen Interrupt 
eingelsen(Sollwert). Die Position des Motors wird vom AD-Wandler 
eingelsen(Istwert).

Dann wird so geregelt:

if((lenkung_ist <= (lenkung_soll +3))&&(lenkung_ist >= (lenkung_soll - 
3)))
{
  PORTB &= ~(1 << PB3);
  PORTB &= ~(1 << PB0);
}

if((lenkung_ist +3) < (lenkung_soll))
{
  PORTB |= (1 << PB3);
  PORTB &= ~(1 << PB0);
}


if((lenkung_ist -3) > (lenkung_soll))
{
  PORTB |= (1 << PB0);
  PORTB &= ~(1 << PB3);
}

es wird also immer der Ist und Sollwert verglichen. In dem einen Fall 
dreht der Motor rechts rum, im anderen links rum. Sind sie 
"gleich"(+-3)" bleibt der Motor stehen. Wenn ich die Hysterese von +-3 
kleiner mache, wird das Zittern stärker.

von Lars Kollros (Gast)


Lesenswert?

Ok, du willst bei 16MHz nen Regelintervall von 10-30µs. hast also pro 
Intervall 160-480 Taktzyklen.
Wenn du wirklich so nen Intervall willst, würde ich mal in Assembler 
schreiben. In C halte ich das für grenzwertig.

Schau mal auf die Atmel-Seite, da gibbet ne AN für nen PID-Regler. Is 
nich das optimale, aber sollte reichen.
nen Tiny zu verwenden halte ich auch für gewagt, weil keinen 
multiplikator...

von Fly (Gast)


Lesenswert?

Also ich würde eine PI-Regelung machen und den Sollwert über PWM, auch 
8-Bit, an den Treiber ausgeben.

von Falk B. (falk)


Lesenswert?

@ Kuen (Gast)

>dauerhaft High und sagt Vollgas. Dabei gäbe es eventuell noch die
>Möglichkeit anstatt Vollgas die Geschwindigkeit über PWM zu regeln.

Das würde ich mal nicht aus den Augen verlieren wollen.

>>Du hast keinen Filter für deine Istwerte, und der Regelalgorithmus
>>erschliesst sich mir auch nicht so wirklich.

>Das mit den Filtern versteh ich nicht ganz?

PID Regler wirken wie ein Filter, dadruch wird die Reglung besser.

> Der Regelalgorithmus ist
>aber Recht einfach. Es wird das Signal über den externen Interrupt
>eingelsen(Sollwert). Die Position des Motors wird vom AD-Wandler
>eingelsen(Istwert).

Du willst also ein Servo nachbauen. OK.

>"gleich"(+-3)" bleibt der Motor stehen. Wenn ich die Hysterese von +-3
>kleiner mache, wird das Zittern stärker.

Scheint so, dass sich Soll und Istwert überholen, durch das harte 
Anfahren vom Motor -> Zittern.

@ Lars Kollros (Gast)

>Ok, du willst bei 16MHz nen Regelintervall von 10-30µs. hast also pro
>Intervall 160-480 Taktzyklen.

Ich glaube kaum, dass für diese Servostuerung 30us Zyklus gebraucht 
werden. Ich tippe mal, dass 1ms locker reicht. Aber dazu muss konstant 
im 1ms Raster geregelt werden! Das sehe ich nicht! Dazu sollte man einen 
Timer verwenden. Allerding würde ich dann die Pulsbreitenmessung besser 
mit ICP machen, das stresst die CPU WESENTLICH weniger.

MFG
Falk

von Kuen (Gast)


Lesenswert?

Also wie würdet ihr denn den Ablauf gestalten?

Nach den ganzen Beiträgen würde ich nun wie folgt vorgehen:

-Timer Compare Interrupt erzeugen welches alle 2ms einen Interrupt 
ausführt.
 In diesem Interrupt würde ich dann die Regelung machen. (Nur welche?
 Zweipunkt PI?) Gut, das kann man ja dann ausprobieren.

-Zwischen diesen 2ms genau einmal das Signal einlesen(Sollwert) und 
einmal
 AD-Wandeln(Istwert).

von Falk B. (falk)


Lesenswert?

Genau.

von Olaf (Gast)


Lesenswert?

> Ich glaube kaum, dass für diese Servostuerung 30us Zyklus gebraucht
> werden. Ich tippe mal, dass 1ms locker reicht.

Diese Einschatzun teile ich. :-)

Uebelege doch mal wie schnell sich die Masse deines Motors ueberhaubt 
bewegen kann.

>  In diesem Interrupt würde ich dann die Regelung machen. (Nur welche?
>  Zweipunkt PI?) Gut, das kann man ja dann ausprobieren.

Das Problem ist nicht der Regler, ein PI-Regler ist da sicher erstmal
ein guter Anfang, das Problem sind die Regelparameter.

Olaf

von Kuen (Gast)


Lesenswert?

Das Signal kommt ja nur alle 60ms. Aber in der Zeit kann ich ja trotzdem 
den Istwert einlesen und Regeln. Dann muss nur das Timing passen, dass 
das Signal auch alle 60ms eingelsen wird und der Interrupt da nicht 
zwischen haut.

von Falk B. (falk)


Lesenswert?

@ Kuen (Gast)

>Das Signal kommt ja nur alle 60ms. Aber in der Zeit kann ich ja trotzdem
>den Istwert einlesen und Regeln. Dann muss nur das Timing passen, dass

Sicher.

>das Signal auch alle 60ms eingelsen wird und der Interrupt da nicht
>zwischen haut.

Lässt sich machen. Wie gesagt, ich würde ICP nehmen.

MFG
Falk

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
Noch kein Account? Hier anmelden.