mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Regelung eines unstabilen Systems


Autor: Denny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.
Ich habe eine Regelung programmiert, die einen Magneten schweben lässt.
Unter dem Magnet befindet sich ein HAL815.
Je tiefer der Magnet desto höher die Spannung (GetADC; 2,5...5V)

Meine Frage:
Was kann ich an der Regelung verbessern??
'+------------------------------------------------------------------------------+'
'| Titel             :     Endarbeit: "Schwebender Magnet"                      |'
'+------------------------------------------------------------------------------+'
'| Funktion          :     Der Magnet schwebt unter einer Spule.                |'
'| Anschlüsse        :     PB1=PWM, PC0=ADC                                     |'
'+------------------------------------------------------------------------------+'
'| Name              :     Weinberg Denny                                       |'
'| Copyright         :     Copyright © Denny 2009                               |'
'| E-Mail Adresse    :     Denny_Weinberg@hotmail.com                           |'
'+------------------------------------------------------------------------------+'


'|----------------------------------Controller----------------------------------|'
$regfile = "m8def.dat"                                      'ATmega8
$crystal = 3686400                                          'Quarzfrequenz (Extern)
$baud = 9600                                                'Funktionierende Baudrate


'|----------------------------------Variablen-----------------------------------|'
Dim Position As Integer                                     'Analoge Spannung des Hallsensors
Dim Pulsweite As Integer                                    'Die Pulsweite für den Spulenstrom
Dim Alteposition As Integer                                 'Position der letzten Messung
Dim Positionsveraenderung As Integer                        'Die Veränderung der Spannung des Hallsensors während eines Zyklus

Dim Daempfung As Integer                                    'Die Dämpfung des Magneten

Dim Sollwert As Integer                                     'Damit man die Position des Magneten verstellen kann

Dim Nummer As Byte                                          'ASCII-Code die seriell ankommen
Dim Zeichen As String * 5                                   'Seriell ankommende Zeichen

Dim Eingeschaltet As Bit                                    'Um alles auszuschalten

Dim Anfangsbuchstabe As String * 1                          'Hilfsbuchstabe bei Änderungen
Dim Endwert As String * 4                                   'Der wirkliche Wert der benötigt wird

Dim Zeichengroesse As Byte


'|---------------------------------Konfiguration--------------------------------|'
Declare Sub Berechnen()                                     'Unterprogramm um die Variablen zu berechnen
Declare Sub Auswerten()                                     'Unterprogramm um die berechneten Werte auszuwerten

Config Adc = Single , Prescaler = Auto , Reference = Avcc   'Analog-Digital-Wandler
Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down       'Pulsweitenmodulation

On Urxc Serialin                                            'Interrupt der seriellen schnittstelle
Enable Urxc                                                 'Interrupt der seriellen schnittstelle einschalten

Enable Interrupts                                           'Interrupts einschalten


'|------------------------------Eingänge und Ausgänge---------------------------|'
Config Portb.0 = Output                                     'Freier Pin (LED)


'|---------------------------------Einstellungen--------------------------------|'
Set Eingeschaltet                                           'Einschalten

Daempfung = 150                                             'Standartwert

Sollwert = 100

Portb.0 = 1                                                 'LED Einschalten


'|---------------------------------Hauptprogramm--------------------------------|'
Do
    If Eingeschaltet = 1 Then
          Start Adc
                   Position = Getadc(0)                     'Analoge Spannung des Hallsensors messen
          Stop Adc
          Toggle Portb.0                                    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
          Call Berechnen

          Call Auswerten
    Else
          Pulsweite = 0
    End If

    Compare1a = Pulsweite                                   'Spulenstrom regeln
Loop


'|--------------------------------Werte berechnen-------------------------------|'
Sub Berechnen()
          Position = Position - 512                         'Weil der Sensor die halbe Spannung in einer Richtung angibt

          Position = Position / 2                           'Word-->Byte = /4 und Hallsensor = halbe Spannung = *2 => /2 =>0...255

          Pulsweite = Position - Sollwert

          Positionsveraenderung = Position - Alteposition   'Positionsveränderung berechnen
          Positionsveraenderung = Positionsveraenderung * Daempfung       'Dämpfung hinzurechnen

          Pulsweite = Pulsweite + Positionsveraenderung     'Pulsweite berechnen

          'Pulsweite = Pulsweite + Offset                    'Offset hinzurechnen
End Sub


'|-----------------------------------Auswerten----------------------------------|'
Sub Auswerten()
          If Position > 0 Then
                    If Pulsweite > 255 Then Pulsweite = 255 'Begrenzungen der Pulsweite einhalten
                    If Pulsweite < 0 Then Pulsweite = 0     'Begrenzungen der Pulsweite einhalten

                    Alteposition = Position                 'Alteposition setzen
          Else                                              'Wenn der Magnet falsch rum hängt wird er umgedreht
                    Pulsweite = 255
          End If
End Sub


'|---------------------Interrupt der seriellen Schnittstelle--------------------|'
Serialin:
      Nummer = Inkey()                                      'ASCII-Code einlesen

      Select Case Nummer
               Case 13                                      'Nummer 13 ist das Enter, das gesendet wird, wenn alles gesendet ist
                      Select Case Zeichen
                            Case "EiA"
                                Print Eingeschaltet         'Zurücksenden, ob das Gerât eingeschaltet ist
                            Case "OFF"
                                Print Sollwert
                            Case "DAE"
                                Print Daempfung             'Dämpfung zurücksenden
                            Case "Aus"
                                Reset Eingeschaltet         'Ausschalten
                            Case "Ein"
                                Set Eingeschaltet           'Einschalten
                            Case "PB0"
                                Toggle Portb.0              'PortB.0 Ein- /Ausschalten
                            Case Else
                                Zeichengroesse = Len(zeichen) - 1       'Zeichengröße, um den Endwert herauszufinden

                                Anfangsbuchstabe = Left(zeichen , 1)       'Anfangsbuchstabe rausschneiden
                                Endwert = Right(zeichen , Zeichengroesse)       'Endwert rausschneiden

                                Select Case Anfangsbuchstabe
                                     Case "O"
                                          Sollwert = Val(endwert)       'Es wurde das Offset gesenden
                                     Case "D"
                                          Daempfung = Val(endwert)       'Es wurde die Dämpfung gesenden
                                End Select
                      End Select

                      Zeichen = ""                          'Zeichen zurücksetzen
               Case Else
                      Zeichen = Zeichen + Chr(nummer)       'Nächstes zeichen hinzusetzen
      End Select
Return                                                      'Ins Hauptprogramm zurückspringen
'|------------------------------------The End-----------------------------------|'

Da sind noch viele Zusatzsachen drin.
Es geht hauptsächlich um das Unterprogramm "Berechnen".

Danke!
Denny

Autor: Weingut Pfalz (weinbauer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du must den ADC nicht dauernd ein und ausschalten, einmal einschalten 
reicht.

Denny schrieb:
> Position = Position / 2

geht eleganter mit shift Position , right , 1


ansonsten schau mal nach PID-Regler, z.B. hier:

http://www.avr-praxis.de/forum/showthread.php?t=22

oder da:

http://www.mikrocontroller.net/attachment/552/PID.doc

Autor: Alex P. (drdatensalat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da hast du dir eines der kompliziertesten Probleme der Regelungstechnik 
herausgesucht!
Vor allem weil die 1.) Anziehungskraft des Magneten quadratisch(!) mit 
dem Abstand abnimmt - also extem nichtlinear ist und 2.) Der Magnet eine 
Induktivität darstellt die den Strom verzögert; dieser zählt aber für 
die Anziehungskraft.
Außerdem hätte ich statt eines Hallsensors (der ja hauptsächlich deinen 
Schwebemagneten misst) eine Lichtschranke zur Lagemessung erwartet.
Wie soll das überhaupt gehen?

Der vorgeschlagene PID-Regler ist auf jeden Fall die richtige Richtung.
Die benötigten PID-Koeffizienten musst du aber ausprobieren. Außerdem 
muss dein digitaler Regelkreis sehr(!) schnell sein (einschließlich der 
A/D-Wandlung des Signals vom Hallsensor).
Eigentlich würde man für so eine Aufgabe einen analogen Regelkreis (mit 
unterlagerten Regelkreisen) nehmen.

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehr schnell ? Was auch immer das bedeutet. Falls so ein System denn 
schwingen wuerde, was waere denn eine moegliche Resonanzfrequenz ? 1 kHz 
...bmmmmmmmmmm... eher nicht. 100 Hz ... baaaaaaaaa ... eher nicht 
allenfalls 10Hz. Dh ein kilosample sollte genuegen. Allerdings muss man 
die quadratische Kennlinie wegmachen.

Autor: dr.schmock (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anmerkung:
Der PID-Regler ist gut für stabile Systeme, z.B. zur Temperaturregelung.
Wenn dein System instabil ist (es hat einen I-Anteil), sollte der Regler 
keinen I-Anteil haben - sonst wird dein geregeltes System i.A. instabil.
D.h. wenn du den PID-Regler vom Link benutzt, dann I-Koeffizienten auf 0 
setzen. (wird also ein PD-Regler)

Ich denke, dass ein µC schnell genug sein kann, den Magneten zu regeln.

Autor: dr.schmock (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
..aber zu deiner eigentlichen Frage... was verbessern ? ...

dein Regler scheint ja der richtige Typ zu sein. Nun musst du eben 
rausbekommen, was die idealen Koeffizienten sind (welche Dämpfung, 
welche Schnelligkeit).
Das kann dir hier im Forum keiner sagen. Wenn du keine mathematische 
Beschreibung des Systems hast, musst du einfach probieren

Autor: Tueftler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, was meinst du denn mit Dämpfung? Davon habe ich noch nichts gehört?
Ich dachte immer es gibt nur den P I und D Anteil. Oder willst du das 
System aktiv bedämpfen?

Grüße,
Tueftler

Autor: lassativ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
..aber zu deiner eigentlichen Frage... was verbessern ? ...

so lange du standard mit T anstatt D schreibst...
... weigert sich der Magnet mit PID zu schweben.

Autor: Thilo M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tueftler schrieb:
> Oder willst du das
> System aktiv bedämpfen?

Kann z.B. so erfolgen:
ZK = 80;
TG = TG*(1-1/ZK)+T/ZK;
T = TG;

Wobei es sich hier um eine Temperaturregelung handelt.
Gedämpft wird der Istwert, also die gemessene Temperatur.

T = gemessene Temperatur und Variable zur Weiterverrechnung
TG = gedämpfter Temperaturwert (globale Variable, Wert muss erhalten 
bleiben)
ZK = Zeitkonstante, abhängig von der Abtastrate

Autor: dr.schmock (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Tueftler:
hast schon recht.
Aber ich hatte mich auf den Quelltext bezogen, da heißt ein Faktor 
"Daempfung". Das kann man so machen, ist halt nicht wie aus dem 
Lehrbuch.

Autor: Michael von Gersdorff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Denny

Der beste Weg so eine schwierige Strecke zu regeln ist vermutlich ein 
Regler mit sogenanntem Beobachtersystem. Das bedeutet daß Du zunächt 
einen Strom zum Halten des Magneten erzeugst der dem Theoretischen Wert 
oder einer Näherung aus gemessenen Versuchen entspricht (Strom als 
Funktion der Magnetposition). Damit kann Dein Magnet zwar noch nicht auf 
Position gehalten werden aber der Strom ist schon einigermaßen korrekt 
und ändert sich je nach Position des Magneten. Zu diesem Strom addierst 
bzw. subtraierst Du noch einen Korrekturwert falls der Magnet nicht in 
der von Dir gewünschten Position schwebt. Als letzte Verbesserung machst 
Du den Korrekturwert selbst in einer Tabelle auch noch abhängig von der 
Position des Magnetes.
Solch ein Reglekreis ist einem PID Regler weit überlegen und hat nicht 
die Nachteile eines Integralanteils (Destabilisierung)
MfG
Michael

Autor: Denny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Magnet schwebt ja bereits mit den Berechnungen.
Allerdings habe ich diese Berechnungen selbst "erfunden".
Der Magnet Schwebt auch nicht an der Position des Sollwertes.
Aber wie soll ich das machen?

Irgendwie müsste ich schreiben: If Position > Sollwert Then... Else...

Ich bin noch auf der Schule und wir sehen gerade Regelungstechnik.
Aber wir sind noch ganz am Anfang.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.