Forum: Mikrocontroller und Digitale Elektronik BASCOM AVR PID-Regler


von Franz Vida (Gast)


Lesenswert?

Hallo,
hat jemand Erfahrung mit PID-Regler unter BASCOM AVR? Kann mir jemand
einen Tip geben, wo ich suche soll oder gar ein Programmbespiel?
Habe bis jetzt nur das Buch Büttner, digitale Regelungen gefunden

von HansHans (Gast)


Lesenswert?

www.mcselec.com/an_109.htm

Aber nicht von mir getestet
Gruß HH

von Leszek Cielecki (Gast)


Lesenswert?

I am looking for some exampl of software for PID regulator on 
microcntroller AVR  for motor or temperatur.

von déjà vu (Gast)


Lesenswert?


von M.A.N (Gast)


Lesenswert?

$regfile = "m8535.dat"

' -----[ Program Description 
]--------------------------------------------------
'
' This program implements an PID algorithm in BASCOM
'
' This File is partialy based on a program from ?????? and
' I do not intent to touch any of his rights !!!
' So for correct use of his copyrights please inform as marked below!
' ?????????
'
'
' -----[ Disclaimer 
]-----------------------------------------------------------
'
' This example is offered on an "AS IS" basis, no warranty expressed or 
implied.
' The programers disclaim liability of any damages associated with the 
use of
' the hardware or software described herein. You use it on your own 
risk.
' I'm not able to provide any free support.
'
' Copyright (c) 2001 Mike Eitel all rights reserved
'
' -----[ Revision History 
]-----------------------------------------------------
'
' 060529 - Version AVRPID Ver .95    Basic PID functionality   Mike 
Eitel
'
' -----[ Aliases 
]--------------------------------------------------------------
$sim                                                        ' Helps 
testing in a simulation
' -----[ Constant 
]-------------------------------------------------------------

' -----[ Variables 
]------------------------------------------------------------
   Dim Auto_mode As Bit                                     ' Regulator 
on ?
   Dim Manual_value As Single                               ' Output if 
not regulating

   Dim Sp As Single                                         ' Setpoint
   Dim Pv As Single                                         ' Process 
Value
   Dim Cv As Single                                         ' PID output

   Dim First_execution As Byte                              ' First 
start recognition
   Dim Initial_error As Single                              ' Startup 
difference

   Dim A As Byte                                            ' Tmp for 
random
   Dim B As Single                                          ' Tmp for 
random


' -----[ Start of program 
]-----------------------------------------------------
' -----[ Start of program 
]-----------------------------------------------------
' -----[ Start of program 
]-----------------------------------------------------

   Auto_mode = 1                                            ' Permanent 
running choosen
   First_execution = 0                                      ' Set 
permanent running algorithm
   Manual_value = 40                                        ' Output if 
not regulating = on
   Sp = 37                                                  ' Value to 
aim to

Cyclic:
' -----[ Start of endless running program 
]-------------------------------------
   Waitms 50                                                ' PID must 
run deterministic
                                                  ' time slices
   Gosub Regulator                                          ' Call the 
PID allgorithm
   Gosub Object                                             ' Call the 
simulated outer loop
Goto Cyclic

   ' -----[ End of endless running program 
]------------------------------------
   ' -----[ End of endless running program 
]------------------------------------
   ' -----[ End of endless running program 
]------------------------------------


   ' 
------------------------------------------------------------------------ 
---
   ' -----------------------------[ Subroutines 
]-------------------------------
   ' 
------------------------------------------------------------------------ 
---
Object:
   ' -----[ Start of simulated regulation loop 
]--------------------------------
    Pv = Pv + Cv                                            ' linear 
function used

    If Pv = Sp Then                                         ' When PV=SP 
then make a
       A = Rnd(100)                                         ' random SP 
jump
       Sp = 1 * A
    End If
Return

Regulator:
   ' -----[ Start of PID 
Regulator]---------------------------------------------
   ' -----[ Constant 
]----------------------------------------------------------
   Const Kp = .85                                           ' 
Proportional factor
   Const Ki = .67                                           ' 
Integration factor
   Const Kd = .15                                           ' Derivation 
factor
   ' -----[ Variables 
]---------------------------------------------------------
   'Dim Sp As Single                               ' Setpoint
   'Dim Pv As Single                               ' Process Value
   'Dim Cv As Single                               ' PID output
   '
   'Dim First_execution As Byte                    ' First start 
recognition
   'Dim Initial_error As Single                    ' Startup difference
   Dim Last_pv As Single                                    ' Last PV
   Dim Last_sp As Single                                    ' Last SP
   Dim Sum_error As Single                                  ' Summed 
error value
   Dim D_pv As Single                                       ' Derrivated 
delta PV

   Dim Error As Single                                      ' Difference 
between SP and PV
   Dim Pterm As Single                                      ' 
Proportional calculated part
   Dim Iterm As Single                                      ' Integrated 
calculated part
   Dim Dterm As Single                                      ' Derivated 
calculated part
   ' -----[ Code 
]--------------------------------------------------------------

   If Auto_mode = 1 Then
      ' -------- Regulating modus
      Error = Sp - Pv
      Sum_error = Sum_error + Error
      Iterm = Ki * Sum_error                                ' Integrated 
CV part

      ' -------- First time startup
      If First_execution < 2 Then
         If First_execution = 0 Then
            Sum_error = Manual_value / Ki
            First_execution = 1
            Initial_error = Error
         End If
         Pterm = 0
         Dterm = 0
         If Initial_error > 0 And Error < 0 Then
            First_execution = 2
            Last_pv = Pv
         End If
         If Initial_error < 0 And Error > 0 Then
            First_execution = 2
            Last_pv = Pv
         End If
         Last_sp = Sp

      ' -------- Normal calculation loop
      Else
         D_pv = Last_pv - Pv
         Last_pv = Pv
         Dterm = Kd * D_pv                                  ' Derivated 
CV part
         If Sp = Last_sp Then
            ' -------- Normal loop when setpoint not changed
            Pterm = Kp * Error                              ' 
Proportional CV part
            ' -------- Loop when setpoint changed
            Else
            Pterm = 0
            Dterm = 0
            If Sp > Last_sp And Pv > Sp Then
               Last_sp = Sp
               Last_pv = Pv
            End If
            If Sp < Last_sp And Pv < Sp Then
               Last_sp = Sp
               Last_pv = Pv
            End If
         End If                                             ' Enf of SP 
change seperation                                   '
      End If                                                ' Enf of 
first time running seperation                                  '

      Cv = Pterm + Iterm                                    ' Summing of 
the tree
      Cv = Cv + Dterm                                       ' calculated 
terms

   ' -------- Forced modus
   Else                                                     ' When 
running in non regulationg modus
      Cv = Manual_value                                     ' Set output 
to predefined value
      First_execution = 0                                   ' restart 
bumpless
   End If
Return

von MARIO (Gast)


Lesenswert?

Ich hab vor Kurzem einen PID Regler mit Atmega8 + L293 aufgebaut. Ich 
wollte damit einen DC-Motor mit selbst gebastelten Encoder regeln.
Der Encoder besteht aus einer auf Overheadfolie bedruckten Codescheibe 
und einer Gabellichtschranke. Das Programm funktionier bisher ganz gut. 
Ich kann die Parameter Kp, Ki, und Kd verstellen und mir die Drehzahl 
via Uart/RS232 anzeigen lassen. Die Impulse werden mittels Interrupt an 
INT0 gezählt. Die Regelung erfolgt in 40ms Abstand mittels 
Timerinterrupt.

Dummerweise habe ich nun aber keine Idee, wie der Regler abgeändert 
werden muss um eine Positionsregelung zu erhalten. Ich möchte sagen, 
dass sich der Motor z.B. 20 Umdrehungen nach rechts drehen und dort 
stoppen soll. Ich möchte gerne eine Linearführung damit antreiben bzw. 
so etwas wie eine Servomotorsteuerung aufbauen. Ich hab zwar immer 
wieder etwas mit Kaskadenregelung gelesen, aber wie das nun in Bascom 
gehen soll, ist mir noch nocht ganz klar. Wenn ich recht verstanden habe 
brauche ich quasi noch einen äußeren Regelkreis, der mir aus den 
Umdrehungen pro Sekunde noch irgendwie eine Position verrät und diese 
dann Regelt.
Vielleicht hätte da jemand den Einen oder Anderen Codebrocken für mich?

Mein PID Drehzahlregler:
1
'------------------------------------------------------------------------------
2
'name                     : PID Drehzahlregelung
3
'copyright                : (c) 2009 by Türk Mario
4
'purpose                  : Drehzahlregelung von DC-Motoren
5
'
6
'micro                    : Mega8
7
'------------------------------------------------------------------------------
8
$regfile = "m8def.dat"
9
$crystal = 8000000
10
$hwstack = 32
11
$swstack = 8
12
$framesize = 24
13
$baud = 38400
14
15
Config Pinb.0 = Output                                      'LED
16
Config Pinb.3 = Output                                      'PWM
17
Config Pinc.0 = Output                                      'Richtung
18
Config Pinc.1 = Output                                      'Richtung
19
Config Pind.2 = Input
20
Portd.2 = 1                                                 'Pullup einschalten
21
Config Portd.0 = Input                                      'Uart Eingang
22
Portd.0 = 1
23
24
Dim E As Single
25
Dim Esum As Single
26
Dim Ealt As Single
27
Dim Kp As Single
28
Dim Ki As Single
29
Dim Kd As Single
30
Dim Ta As Single
31
Dim Proportionalteil As Single
32
Dim Integralteil As Single
33
Dim Differentialteil As Single
34
Dim Cv As Single
35
Dim Gv As Single
36
37
Dim Flanken As Integer                                      'Gezählte Flanken
38
Dim Flankenperturn As Integer                               'Anzahl der Flanken pro Umdrehung
39
Dim Umdrehungen As Single
40
Dim Solldrehzahl As Single
41
Dim Maxdrehzahl As Single
42
43
Dim Befehl As String * 9
44
Dim Bcount As Integer
45
Dim Ar(5) As String * 5
46
47
Kp = 30
48
Ki = 8
49
Kd = 0.2
50
Ta = 0.04
51
Solldrehzahl = 20
52
Maxdrehzahl = 80
53
Flankenperturn = 30
54
55
E = 0
56
Esum = 0
57
Ealt = 0
58
59
Config Int0 = Falling                                       'Fallende Flanke löst den Interupt aus
60
Enable Interrupts
61
Enable Int0
62
On Int0 Encoder_zaehlen                                     'Encoder_zaehlen wird im Falle des Interrupts ausgelöst
63
64
65
Config Timer1 = Timer , Prescale = 256                      'Timer1 führt alle 40ms die Regelung durch
66
On Timer1 Regler
67
Timer1 = 64285                                              ' 65535 - (8000000/256/Ta)   Ta = 25
68
Enable Timer1
69
Start Timer1
70
                                                             'Timer 2 ist für die Motor PWM zuständig
71
Config Timer2 = Pwm , Compare Pwm = Clear Up , Pwm = On , Prescale = 64
72
   Ocr2 = 30
73
   'Richtung Vorgeben:
74
   Portc.0 = 1
75
   Portc.1 = 0
76
   'Motor PWM Starten
77
   Enable Timer2
78
   Start Timer2
79
$sim
80
81
Do                                                          'Hauptprogramm
82
83
Input "" , Befehl
84
Bcount = Split(befehl , Ar(1) , ": ")
85
   If Ar(1) = "Kp" Then                                     'Einstell- und Infomöglichkeiten
86
          Kp = Val(ar(2))
87
   End If
88
    If Ar(1) = "Ki" Then
89
          Ki = Val(ar(2))
90
   End If
91
    If Ar(1) = "Kd" Then
92
          Kd = Val(ar(2) )
93
   End If
94
   If Ar(1) = "soll" Then
95
   Solldrehzahl = Val(ar(2))
96
   End If
97
    If Ar(1) = "max" Then
98
   Maxdrehzahl = Val(ar(2))
99
   End If
100
   If Ar(1) = "rps" Then
101
        Print Umdrehungen
102
   End If
103
    If Ar(1) = "pid" Then
104
        Print "Kp=" ; Kp
105
        Print "Ki=" ; Ki
106
        Print "Kd=" ; Kd
107
   End If
108
    If Ar(1) = "pwm" Then
109
        Print Ocr2
110
    End If
111
Loop
112
113
Encoder_zaehlen:                                            'Hier werden alle Flanken gezählt
114
Incr Flanken
115
Return
116
117
118
119
Regler:                                                     'Der PID Regler Algorithmus
120
Timer1 = 64285
121
Umdrehungen = Flanken / Ta                                  'Ermittlung der Umdrehungen pro Sekunde
122
Umdrehungen = Umdrehungen / Flankenperturn
123
Flanken = 0                                                 'Flankenzähler auf null setzen
124
125
E = Solldrehzahl - Umdrehungen                              'Regelabweichung berechnen
126
Esum = Esum + E                                             'Fehler aufsummieren
127
128
Proportionalteil = Kp * E                                   'Proportionalglied berechnen
129
130
Integralteil = Ki * Ta                                      'Integralglied berechnen
131
Integralteil = Integralteil * Esum
132
133
Differentialteil = E - Ealt                                 'Differentialglied berechnen
134
Differentialteil = Differentialteil / Ta
135
Differentialteil = Differentialteil * Kd
136
137
Cv = Proportionalteil + Integralteil                        'Alle Gliede zusammenfassen
138
Cv = Cv + Differentialteil
139
140
Gv = Maxdrehzahl / 255                                      'Übertragen auf PWM Duty Cycle
141
Gv = Gv * Cv
142
143
If Gv < 0 Then Gv = 0
144
If Gv > 255 Then Gv = 255
145
Ocr2 = Gv                                    'Motor PWM wird entsprechend angepasst
146
147
148
149
Ealt = E                                                    'Regelfehler merken für den nächsten Durchlauf
150
151
152
Return

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.