Forum: Mikrocontroller und Digitale Elektronik Programm zusammenfügen - DEBUG Messages Fehler


von Dan M. (luizaranha)


Lesenswert?

Hallo Kollegen,

wir haben in der Uni ein Projekt für eine Vorschubregelung einer Turbine 
gemacht. Die Regelung funktioniert auch wunderbar.
Als Zusatz haben wir nun eine Verbindung zu Matlab hergestellt, dass wir 
bis jetzt in einem Extra-Programm implementiert haben. Auch das 
funktioniert wunderbar, wir senden einen Befehl, dann wird der 
Ventilator manuell mit einem gewissen Dutycyle angesteuert. Für die 
manuelle Steuerung setzen wir eine globale auf eins, dass gleiche machen 
wir für die Regelung.

Nun zum Problem: Jetzt wollten wir "nur" noch den Code für den PID 
Regler in das andere Programm einsetzen, so dass das die globale 
Variable für die Regelung entscheidet, ob geregelt wird.
Nach 3h vergeblichen Versuchen konnte wir die Ursache auf Debug Messages 
verkleinern, aber sind nicht sicher obs die wirklich sind....

Die Funktion RS232 liest die Kommandos aus und setzt je nach Kommando 
die globalen Variablen flagPWM und flagCTRL.

Und wie gesagt, der PID Regler an sich funktioniert auch, allerdings nur 
wenn diese Debug Messages mit drin sind........


hier der Code
1
// Predefined compiler symbols:
2
#define LEDgreen 24
3
#define LEDred 25
4
#define LEDyellow 26
5
6
#define RS232 0
7
#define CR 0x0D
8
9
#define PERIOD 492
10
11
// Declaration of global variables:
12
// 100 bytes send + 100 bytes receive RS232Buffer + 6 bytes int.FIFO management
13
byte RS232Buffer[206];         // TxD/RxD buffer RS232
14
byte Linebuffer[101];          // hier wird das gelesene Zeug reingeschrieben
15
byte RxCount;                  // Number of received characters
16
17
18
// Linebuffer will be decoded into this command elements:
19
byte CMD[20];                  // Raw command
20
byte PAR1[20];                 // Command line paramter 1
21
byte PAR2[20];                 // Command line paramter 2
22
byte PAR3[20];                 // Command line paramter 3
23
24
// Test-Message:
25
char rmsg1[5];                 // Message Command
26
27
28
//Globals for Pulse Width Modulation (PWM)
29
byte    flagPWM;               //Schalter für PWM ein oder aus
30
byte    flagCTRL;              //Schalter für Regelung ein oder aus
31
float   RS232output;           //Verhältnis ein zu ausschaltzeit von RS232 vorgeben oder von PID ctrl
32
//float   PIDoutput;             //Verhältnis ein zu ausschaltzeit von PID controller
33
float   PWMwidth;
34
35
36
int period;        //period of the PWM
37
38
float PID_output,pwm_output;
39
word ADC_Value;
40
word ang_ref;
41
float ang_msurd,err,err_prev,err_acc,err_diff;
42
float Kp;
43
float Ki;
44
float Kd;
45
46
// Function of PWM previous version
47
48
void pwm(float PID_output){  //function pwm //////////////////////
49
//help variables///////////////////////////7
50
51
int PWM_Counter_A;  //pulswidth of the PWM in a promille scale
52
//////////////////
53
period=492;
54
PWM_Counter_A=period*PID_output;
55
56
Timer_T1PWM(period,PWM_Counter_A,PS_1);
57
}
58
59
//////////////////////////////////////////////////////////////////
60
float adc2angel(word ADC_Value)
61
{
62
    float ang_tmp;
63
    if(ADC_Value>425)
64
    {
65
        ang_tmp=-0.008*ADC_Value-4.6;
66
    }
67
    if(ADC_Value<=425 && ADC_Value>300)
68
    {
69
        ang_tmp=-0.016*ADC_Value-1.2;
70
    }
71
    if(ADC_Value<=300 && ADC_Value>222)
72
    {
73
        ang_tmp=-0.025*ADC_Value+1.692;
74
    }
75
    if(ADC_Value<=222 && ADC_Value>170)
76
    {
77
        ang_tmp=-0.038*ADC_Value+4.538;
78
    }
79
    if(ADC_Value<=170 && ADC_Value>130)
80
    {
81
        ang_tmp=-0.05*ADC_Value+6.5;
82
    }
83
    if(ADC_Value<=130 && ADC_Value>105)
84
    {
85
        ang_tmp=-0.08*ADC_Value+10.4;
86
    }
87
    if(ADC_Value<=105 && ADC_Value>86)
88
    {
89
        ang_tmp=-0.105*ADC_Value+13.05;
90
    }
91
    if(ADC_Value<=86 && ADC_Value>73)
92
    {
93
        ang_tmp=-0.153*ADC_Value+17.23;
94
    }
95
    if(ADC_Value<=73 && ADC_Value>59)
96
    {
97
        ang_tmp=-0.142*ADC_Value+16.42;
98
    }
99
    if(ADC_Value<=59 && ADC_Value>52)
100
    {
101
        ang_tmp=-0.285*ADC_Value+24.85;
102
    }
103
    if(ADC_Value<=52 && ADC_Value>46)
104
    {
105
        ang_tmp=-0.333*ADC_Value+27.33;
106
    }
107
    if(ADC_Value<=46 && ADC_Value>42)
108
    {
109
        ang_tmp=-0.5*ADC_Value+35;
110
    }
111
    if(ADC_Value<=42)
112
    {
113
        ang_tmp=-1.0*ADC_Value+56;
114
    }
115
     return ang_tmp;
116
117
118
}
119
120
/////////////main//////////////////////////////
121
void main(void)
122
{
123
//****************************
124
//Declaration of variables
125
    int i,PWMwidth;
126
127
//*****************************
128
//Dafault settings of variables
129
    i=0;
130
    PWMwidth=1;
131
    RS232output=1;
132
    flagPWM=0;
133
    flagCTRL=0;
134
135
//************
136
//Initializing
137
    Port_DataDirBit(16,1);    //Define PortD.0 as output
138
    Port_DataDirBit(17,1);      //Define PortD.1 as output
139
    Port_DataDirBit(LEDyellow,1);   //Define PortD.2 as output
140
    Timer_T1PWM(PERIOD,1,PS_1);     //Define PWM with duration of 1 (0 not allowed!!)
141
    Serial_Init_IRQ(RS232,RS232Buffer,100,100,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD19200);
142
    // Initialize RS232: 19200 bps, 8 Bit, 1 Stop, NP
143
    // 100 bytes receive RS232Buffer - 100 bytes send RS232Buffer
144
145
//***************************
146
//Send Test-Message to MATLAB
147
    rmsg1="C-Control PRO ready for receiving\r\n";
148
149
    for(i=0;i<2;i++)
150
        Serial_WriteText(RS232,rmsg1);   // Serielle Schnittstelle Test senden
151
152
153
//*********************************************************************************************
154
155
    PID_output=0.0;
156
    ang_ref=0.0;
157
    err_acc=0;
158
    err_prev=0.0;
159
    ADC_Set(ADC_VREF_VCC, ADC0);
160
    //Kp=0.01;
161
    //Ki=0.005;
162
    //Kd=0.5;
163
    //Zigler Nicolas method
164
    /*Kp=0.0360;
165
    Ki=0.0411;
166
    Kd=0.0079;*/
167
    Kp=0.01;
168
    Ki=0.005;
169
    Kd=0.5;
170
171
    while (1)
172
    {
173
    ////////// PID regler///////////////////////////////////////////////
174
        ADC_Value=ADC_Read();
175
        ang_msurd=adc2angel(ADC_Value);
176
        if(ang_msurd>15) ang_msurd=15;
177
        if(ang_msurd<-10) ang_msurd=-10;
178
        //Msg_WriteHex(ADC_Value);
179
        err=ang_ref+ang_msurd;
180
        err_acc=err_acc+err;
181
        err_diff=err-err_prev;
182
        if(err_acc>20) err_acc= 20.0;
183
        if(err_acc<-20) err_acc= -20.0;
184
        PID_output=Kp*err+Ki*err_acc+Kd*err_diff;
185
        pwm_output=(PID_output+0.5);
186
        //Msg_WriteChar(CR);                    // HIER FEHLER WAHRSCHEINLICH
187
        //Msg_WriteFloat(err_acc);              // HIER FEHLER WAHRSCHEINLICH
188
        if(pwm_output<0.05) pwm_output=0.05;
189
        if(pwm_output>0.95) pwm_output=0.95;
190
191
        //Msg_WriteInt(100);
192
        PWMwidth=PERIOD*pwm_output;   // PWMwidth = hole periode*PIDoutput[0.00-1.00]
193
        //Timer_T1PWA(PWMwidth);       // PWM with value PIDoutput
194
        Timer_T1PWM(PERIOD,PWMwidth,PS_1);
195
196
  //      pwm(pwm_output);            // Previous version
197
        err_prev=err;
198
  //      AbsDelay(10);               // Previous version
199
200
201
   //////////////////////////////////////////////////////////////////////////////
202
203
        readRS232();                     // Read out RS232
204
205
        if(flagPWM & !flagCTRL)                      // PWM switch on/off
206
        {   PWMwidth=RS232output*PERIOD*0.01;
207
            Timer_T1PWA(PWMwidth);     // PWM with value PWMwidth
208
            Port_WriteBit(16,1);
209
        }
210
        else
211
            Port_WriteBit(16,0);
212
213
        if(flagCTRL)                     // Control switch on/off
214
        {   PWMwidth=PERIOD*pwm_output;   // PWMwidth = hole periode*PIDoutput[0.00-1.00]
215
            Timer_T1PWA(PWMwidth);       // PWM with value PIDoutput
216
            Port_WriteBit(17,1);
217
        }
218
        else
219
            Port_WriteBit(17,0);
220
221
        if(!flagCTRL & !flagPWM)         // PWM value --> zero
222
        {
223
            Timer_T1PWA(1);              // (0 not allowed!)
224
        }
225
226
         AbsDelay(10);
227
    }
228
}

Sollte jemand die Lösung finden, würd ich vor Freude in die Luft 
springen!!!!!


gruss Daniel

von Klaus W. (mfgkw)


Lesenswert?

Schwer zu sagen, da ich das Programm etwas, naja, unübersichtlich finde.
Insofern kann es gut sein, daß ich jetzt falsche spekuliere, weil ich
es einfach auch nach 15 min lesen nicht so ganz verstehe.

---

Zumindest ein mittleres Problem sehe ich darin, daß in main()
wohl die PID-Regelung gemacht wird; die ist zeitabhängig:
ob ich die Schleife alle 10 msec oder alle 10 min durchlaufe, ist
relevant für das Zeitverhalten. Insbesondere der I-Anteil
muß ja die Abweichung mit der verstrichenen Zeit multiplizieren.
Ich kann aber kein festes Zeitraster erkennen, in dem die
Schleife durchlaufen wird.

Mehr oder weniger Debugausgaben können also die Regelung
beeinflussen.

Zudem wird ja auch die Regelung angehalten, bis etwas über RS232 kommt.
Soll das so sein?

---

Daniel Mayr schrieb:
> Für die
> manuelle Steuerung setzen wir eine globale auf eins, dass gleiche machen
> wir für die Regelung.

flagPWM und flagCTRL?
Das Programm wäre lesbarer, wenn man am Namen erkennen würde,
welcher Wert welche Bedeutung hat.
Daß das eine irgendwas mit PWM zu tun hat, sieht man, aber wie
wirkt sich welcher Wert aus?
Und was flagCTRL bewirkt, kann ich am Namen auch nicht erkennen.
Das if-Gewurschtel am Ende ist auch nicht gerade durchsichtig.

---

In adc2angel() wird wohl ein ADC-Wert in einen Engel verwandelt;
mit ein paar else könnte man das entlasten - es wird ja immer nur
einer der Zweige genutzt.

---

Daniel Mayr schrieb:
> Die Funktion RS232 liest die Kommandos aus

RS232 ist zu 0 #definiert.

---

Daniel Mayr schrieb:
> Nach 3h vergeblichen Versuchen...

Dann wären 10 min für eine vernünftige Beschreibung und sinnvolle
Kommentare auch noch drin gewesen...

:-)

---

Ich sehe nicht, wo pwm() aufgerufen wird.

---

Was machen Funktionen wie Timer_T1PWA, Timer_T1PWM ?

---

Solche Kommentare sind zwecklos:
    Port_DataDirBit(16,1);    //Define PortD.0 as output
    Port_DataDirBit(17,1);      //Define PortD.1 as output
Interessant wäre ein dürrer Satz dazu, was D.0 und D.1 bewirken
sollen.
Oder rauswerfen, wenn man es hier nicht braucht.

---

0 scheint nicht zu gehen, warum auch immer:
1
    Timer_T1PWM(PERIOD,1,PS_1);     //Define PWM with duration of 1 (0 not allowed!!)

Ist sicher, daß hier dann auch keine 0 gesetzt wird?
1
        PWMwidth=PERIOD*pwm_output;   // PWMwidth = hole periode*PIDoutput[0.00-1.00]
2
        //Timer_T1PWA(PWMwidth);       // PWM with value PIDoutput
3
        Timer_T1PWM(PERIOD,PWMwidth,PS_1);

---

Daniel Mayr schrieb:
> Und wie gesagt, der PID Regler an sich funktioniert auch, allerdings nur
> wenn diese Debug Messages mit drin sind........

"funktionieren" und "nicht funktionieren" heißt für Nichthellseher
wie mich was?

-------------

Das ist das, was mir beim Lesen so auffiel.
Aber wie gesagt finde ich es nicht besonders deutlich programmiert.
Es werden also schon noch ein paar Böcke drin sein.

von Dan M. (luizaranha)


Angehängte Dateien:

Lesenswert?

Hi Klaus,

danke für den "Anschiss". Wir haben leider nicht so viel Erfahrung mit 
Microcontroller geschichten und sind von unserer Uni iwie ins kalte 
Wasser geschmissen worden.
Mein syrischer Kollege hat den PID-Regler gemacht, und wir haben jetzt 
das Programm nochmal kommentiert und unwichtige Stellen draußen 
gelassen.

Das Problem ist immer noch mit den Debug messages:
1
//////////////////////////////////////////////////////////////////
2
        Msg_WriteChar(CR);                //Carry return message
3
        Msg_WriteFloat(err_acc);            //Display of err_acc //
4
// OHNE DIESE DEBUG MESSAGES FUNKTIONIERTS NICHT!!!!
5
///////////////////////////////////////////////////////////////////



Beschreibung im Manual siehe Anhang....

Hier noch der PID-Regler als C-code:
1
#define CR 0x0D
2
3
int period;        //period of the PWM
4
5
float PID_output,pwm_output;            //output value of controller
6
word ADC_Value;                    //ADC value
7
word ang_ref;                    //Reference Angel value
8
float ang_msurd,err,ang_msurd_prev,err_acc,err_diff;    //Controller variables
9
float Kp;                      //Propotional Coefficient
10
float Ki;                      //Integrater Coefficient
11
float Kd;                      //Diffirential Coefficient
12
void pwm(float PID_output){  //function pwm //////////////////////
13
//help variables///////////////////////////7
14
int PWM_Counter_A;  //pulswidth of the PWM in a promille scale
15
//////////////////
16
period=492;
17
PWM_Counter_A=period*PID_output;
18
19
Timer_T1PWM(period,PWM_Counter_A,PS_1);
20
}
21
//////////////////////////////////////////////////////////////////
22
float adc2angle(word ADC_Value)
23
{
24
    float ang_tmp;
25
    if(ADC_Value>425)
26
    {
27
        ang_tmp=-0.008*ADC_Value-4.6;        //1st interval equation
28
    }
29
    if(ADC_Value<=425 && ADC_Value>300)
30
    {
31
        ang_tmp=-0.016*ADC_Value-1.2;        //2nd interval equation
32
    }
33
    if(ADC_Value<=300 && ADC_Value>222)
34
    {
35
        ang_tmp=-0.025*ADC_Value+1.692;        //3rd interval equation
36
    }
37
    if(ADC_Value<=222 && ADC_Value>170)
38
    {
39
        ang_tmp=-0.038*ADC_Value+4.538;        //4th interval equation
40
    }
41
    if(ADC_Value<=170 && ADC_Value>130)
42
    {
43
        ang_tmp=-0.05*ADC_Value+6.5;        //5th interval equation
44
    }
45
    if(ADC_Value<=130 && ADC_Value>105)
46
    {
47
        ang_tmp=-0.08*ADC_Value+10.4;        //6th interval equation
48
    }
49
    if(ADC_Value<=105 && ADC_Value>86)
50
    {
51
        ang_tmp=-0.105*ADC_Value+13.05;        //7th interval equation
52
    }
53
    if(ADC_Value<=86 && ADC_Value>73)
54
    {
55
        ang_tmp=-0.153*ADC_Value+17.23;        //8th interval equation
56
    }
57
    if(ADC_Value<=73 && ADC_Value>59)
58
    {
59
        ang_tmp=-0.142*ADC_Value+16.42;        //9th interval equation
60
    }
61
    if(ADC_Value<=59 && ADC_Value>52)
62
    {
63
        ang_tmp=-0.285*ADC_Value+24.85;        //10th interval equation
64
    }
65
    if(ADC_Value<=52 && ADC_Value>46)
66
    {
67
        ang_tmp=-0.333*ADC_Value+27.33;        //11th interval equation
68
    }
69
    if(ADC_Value<=46 && ADC_Value>42)
70
    {
71
        ang_tmp=-0.5*ADC_Value+35;          //12th interval equation
72
    }
73
    if(ADC_Value<=42)
74
    {
75
        ang_tmp=-1.0*ADC_Value+56;          //13th interval equation
76
    }
77
     return ang_tmp;
78
79
80
}
81
82
/////////////main//////////////////////////////
83
void main(void)
84
{
85
    PID_output=0.0;              //Initialization
86
    ang_ref=0.0;              //Assigning Reference angel value
87
    err_acc=0;                //Initialization of error value
88
    ang_msurd_prev=ang_ref;              //Initialization of previous error value
89
    ADC_Set(ADC_VREF_VCC, ADC0);      //Setting ADC Configurations
90
    //Kp=0.01;
91
    //Ki=0.005;
92
    //Kd=0.5;
93
    //Zigler Nicolas method
94
    /*Kp=0.0360;
95
    Ki=0.0411;
96
    Kd=0.0079;*/
97
    Kp=0.01;                //Propotional Coefficient value
98
    Ki=0.005;                //Integrater Coefficient value
99
    Kd=0.5;                  ////Diffirential Coefficient value
100
101
    while (1)
102
    {
103
        ADC_Value=ADC_Read();        //Reading ADC value
104
        ang_msurd=adc2angle(ADC_Value);    //Calculating Angel value
105
        if(ang_msurd>15) ang_msurd=15;    //Limiting Angel value
106
        if(ang_msurd<-10) ang_msurd=-10;
107
        //Msg_WriteHex(ADC_Value);
108
        err=ang_ref+ang_msurd;        //Computing the error
109
        err_acc=err_acc+err;        //Accumlating the error
110
        err_diff=ang_msurd-ang_msurd_prev;        //computing the diffirential error
111
        if(err_acc>20) err_acc= 20.0;          //Limitting Accumulation error
112
        if(err_acc<-20) err_acc= -20.0;
113
        PID_output=Kp*err+Ki*err_acc+Kd*err_diff;    //PID equation
114
        pwm_output=(PID_output+0.5);          //Nolmalizing PID Output
115
        //////////////////////////////////////////////////////////////////
116
        Msg_WriteChar(CR);                //Carry return message
117
        Msg_WriteFloat(err_acc);            //Display of err_acc
118
        //// OHNE DIESE DEBUG MESSAGES FUNKTIONIERTS NICHT!!!!
119
        ///////////////////////////////////////////////////////////////////
120
        if(pwm_output<0.05) pwm_output=0.05;      //Limitting PWM Output
121
        if(pwm_output>0.95) pwm_output=0.95;
122
123
        pwm(pwm_output);                //Transfering PWM to Motor
124
        ang_msurd_prev=ang_msurd;            //Assigning current angle value to the previous angel value
125
        AbsDelay(10);                  //10 ms Interval Time
126
    }
127
}

Zur Beschreibung des Problems:
Wenn wir den Regler aus dem Compiler starten, dann funktioniert er, aber 
nur wenn die Debug messages drin sind.

Wenn wir nun die REset Taste drücken, dann funktioniert der Regler nicht 
(was ich komisch finde, da bei REset das Programm doch wieder bei void 
main (void) beginnt.

Danke schon im Vorraus für eure Hilfe!!

Gruss Luiz

von Karl H. (kbuchegg)


Lesenswert?

Klingt für mich alles noch dem Problem, welches Klaus schon angesprochen 
hat: Ihr habt im Regler keinen definierten Zeittakt. Die Durchlaufzeit 
durch 1 Regelschleife ist mehr oder weniger von irgendwelchen 
Umgebungsbedingungen abhängig. Und wenn ihr die Umgebung entsprechend 
langsam genug macht, dann kommen die Regelparameter in einen Bereich in 
dem der Regler dann auch tatsächlich regelt. Lässt ihr aber alles mit 
'Full-Speed' laufen, funktionieren diese Parameter nicht mehr.


Den ganzen PID Regler in eine Timer ISR verschieben und so für einen 
regelmässigen immer gleichen Zeittakt sorgen. Die Regelparameter müssen 
dann natürlich wieder neu abgeglichen werden.

von Dan M. (luizaranha)


Lesenswert?

Hallo Karl Heinz,

danke für den Tip. Haben den Regler jetzt in eine ISR geschoben und 
jetzt funktioniert die Sache (fast) perfekt.

Unser Projekt ist zwar jetzt schon abgegeben, aber eine weitere Frage zu 
unserer ISR:

1. Wir haben die Zeitdauer dieser ISR gemessen, und kommen auf knappe 
2ms.
  (Einen Ausgang auf High geschaltet, wenn die ISR läuft )
   ist das nicht ein bisschen lang?

Wir haben zwei Programme, eins, in dem nur der PID regler läuft ohne 
Schnick Schnack. Der Sollwert wird fast perfekt erreicht und gehalten.

Das andere Programm beinhaltet eine interrupt getriebene Auslesung der 
seriellen Schnittstelle, um zwischen Regelbetrieb und Manueller 
Ansteuerung zu unterscheiden. In jedem Durchlauf der while schleife wird 
die serielle SS gelesen... wenn keine Bytes im Puffer sind, kehrt die 
Funktion direkt wieder aus dem interrupt zurück.

Hier jedoch mussten wir für den Sollwert 5 Grad mehr einstellen, um auf 
0 Grad sollwert zu regeln.

Liegt das an mehr Rechenaufwand wg. der seriellen SS?

Wahrscheinlich könnt ihr das ohne programm nicht sagen, das programm ist 
glaub ich zu groß, ums hier reinzustellen. Hab auch keine Ahnung, was 
jetzt wirklich diesen kleinen Schönheitsfehler ausmacht, deswegen müsst 
ich alles reinstellen

Gruss und danke für die super tipps!

daniel

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Der Interrupt darf auch 10 Sekunden dauern wenn dieser nur alle 10 
Minuten auftritt und keine andere Funktionalität eine Unterbrechnung von 
10 Sek nicht Tolerieren kann.

Wegen Serielle Schnittstelle: Die würde ich nicht im Interrupt auslesen, 
sondern in der Hauptschleife, weil sonst je nachdem (Daten da/nicht da) 
das Zeitverhalten möglicherweise negativ beeinflusst wird.

@auszug_manual.jpg  Sowas nächstmal besser als PNG jpeg eignet sich 
nicht wirklich für Text.

von Dan M. (luizaranha)


Angehängte Dateien:

Lesenswert?

Hi Läubi,

danke für deinen Antwort.
Ich glaube jedoch, dass ich den interrupt Betrieb brauch, da ich in 
Matlab eine GUI geschrieben habe, und ich ja nicht beeinflussen kann, 
wann welcher Schalter gedrückt wird... Deswegen muss ich immer lesen, 
wenn nix da is, kehr ich wieder zurück.
im anhängsel noch der auszug aus dem Manual......für entweder interrupt 
betrieb oder ohne.

Aber das auslesen oder besser gesagt hören auf die serielle SS kann doch 
nicht so zeitkritisch sein, dass mein Regler im Interruptbetrieb ( 
Schleife alle 10 ms beeinflusst wird).


Gruss daniel

von Karl H. (kbuchegg)


Lesenswert?

Für die Serielle selbst wieder einen Interrupt Betrieb zu benutzen ist 
schon ok.

Was gemeint ist:
Du sollst zb nicht eine Serielle AUsgabe aus einer ISR heraus machen.
Deine Berechnung des PID Reglers in der ISR soll tatsächlich nur das 
machen: einen Durchgang durch die Reglergleichungen und den Ausgang 
ansteuern. Mehr nicht.

Dann dauert deine ISR auch keine 2ms mehr.

Grundsätzlich: In einer ISR willst du
  * nicht warten
  * nichts machen, was länger dauert
  * nur das Allernotwendigste durchführen

Das heißt jetzt nicht, das man in einer ISR gar nichts tun darf, sondern 
dass man ein wenig überlegen soll, was man alles in eine ISR steckt und 
was nicht.

Grundsätzlich hätte man gerne, dass man aus einer ISR möglichst schnell 
seine Arbeit erledigt und wieder aus der ISR rauskommt. Eine Ausgabe 
über eine serielle Schnittstelle ist da kontraproduktiv.

von Vlad T. (vlad_tepesch)


Lesenswert?

Das ist böse:

Daniel Mayr schrieb:
> // Test-Message:
> char rmsg1[5];                 // Message Command
>
> ...
>
>     rmsg1="C-Control PRO ready for receiving\r\n";
>
>     for(i=0;i<2;i++)
>         Serial_WriteText(RS232,rmsg1);   // Serielle Schnittstelle Test senden
>
>
>

von Dan M. (luizaranha)


Lesenswert?

Vlad Tepesch schrieb:
> Das ist böse:
>
> Daniel Mayr schrieb:
>> // Test-Message:
>> char rmsg1[5];                 // Message Command
>>
>> ...
>>
>>     rmsg1="C-Control PRO ready for receiving\r\n";
>>
>>     for(i=0;i<2;i++)
>>         Serial_WriteText(RS232,rmsg1);   // Serielle Schnittstelle Test senden
>>
>>
>>

Ja, dass ist schon länger behoben..... unser feld hat ist jetzt char 
rmsg1[50].

Aber das Programm ging trotzdem!!!,

von Klaus W. (mfgkw)


Lesenswert?

Daniel Mayr schrieb:
> unser feld hat ist jetzt char rmsg1[50].
> Aber das Programm ging trotzdem!!!,

Rubrik "spekulatives Programmieren", soweit es nur um die Feldlänge 
geht.

So wie es da steht, ist es aber nicht mal kompilierbar.

von Karl H. (kbuchegg)


Lesenswert?

Daniel Mayr schrieb:

> Aber das Programm ging trotzdem!!!,

Falsch.
Es sah nur so aus als ob.

Nur weil ein Fehler nicht unmittelbar Unheil anrichtet, heißt das noch 
lange nicht, dass es in Ordnung ist.

von Dan M. (luizaranha)


Lesenswert?

aha,

und warum ist das nicht kompilierbar??
mein Compiler meckert nicht bei
1
char rmsg1[50];         // Message Command

von Klaus W. (mfgkw)


Lesenswert?

aber dann hoffentlich bei:
1
  rmsg1="C-Control PRO ready for receiving\r\n";

Grund: ein Feld ist ein konstanter Zeiger auf die Elemente, und
kann durch eine Zuweisung nicht mehr geändert werden.
Einen String ins Feld bekommt man entweder durch Initialisierung,
oder strcpy().

von Dan M. (luizaranha)


Angehängte Dateien:

Lesenswert?

Hallo Klaus,

Ich möcht hier nicht mein Kopf aus der Schlinge ziehn, jedoch ein paar 
Anmerkungen.
Meine Unerfahrenheit at mich ins Manual schauen lassen und den 
angehängten Ausschnitt hab ich  somit angewendet.

Die Sache mit String copy steht schon drin.... aber auch das meine 
Deklaration nicht falsch ist.
DIe Programmiersprache CompactC hat vllt etwas damit zu tun?!.

Gruss

p.s. der verwendete string ist constant wird nicht geändert, und nur 
einmal verwendet.

von Klaus W. (mfgkw)


Lesenswert?

Daniel Mayr schrieb:
> Meine Unerfahrenheit at mich ins Manual schauen lassen und den
> angehängten Ausschnitt hab ich  somit angewendet.
>
> Die Sache mit String copy steht schon drin.... aber auch das meine
> Deklaration nicht falsch ist.
> DIe Programmiersprache CompactC hat vllt etwas damit zu tun?!.

Wenn deine Anleitung stimmt, dann ist das kein Standard-C.
Weder nach C89 noch nach C99 noch nach irgendwelchen C++ ist das
erlaubt.

Da du den String ja nur einmal setzen willst, gibt es eine kleine
Änderung, die wieder standardkonform ist, nämlich eine saubere
Initialisierung:
1
char rmsg1[50]="C-Control PRO ready for receiving\r\n"; // Message Command
So ist es mit jedem Compiler richtig.

von Dan M. (luizaranha)


Lesenswert?

>
> Wenn deine Anleitung stimmt, dann ist das kein Standard-C.
> Weder nach C89 noch nach C99 noch nach irgendwelchen C++ ist das
> erlaubt.

wie gesagt CompactC ( siehe Projectboard MEGA32 von Conrad)
>

> Da du den String ja nur einmal setzen willst, gibt es eine kleine
> Änderung, die wieder standardkonform ist, nämlich eine saubere
> Initialisierung:
>
1
> char rmsg1[50]="C-Control PRO ready for receiving\r\n"; // Message 
2
>
> So ist es mit jedem Compiler richtig.

Und genau das unterstützt der Compiler nicht.......habs gerade 
durchlaufen lassen... es geht wirklich nur der eine Weg...
>
1
> char rmsg1[50];
2
rmsg="C-Control PRO ready for receiving\r\n"; // Message
3
4
>

Der Compiler übrigens heisst "C Control Pro IDE".

Das hat mit C wohl schon noch Ähnlichkeit, aber nicht mehr 100%....
Was an dem Compiler auch komisch ist, dass ich im Ausgabefenster nur 
globale Variablen anschauen kann...

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.