Forum: Mikrocontroller und Digitale Elektronik Problem Geschwindigkeitserfassung


von Mathias Q. (paolo_pinkel)


Lesenswert?

Hallo Zusammen,

ich bin gerade dabei mit Hilfe des uControllers C167 eine 
Geschwindigkeitsregelung fuer einen DC-Reihenschlussmotor aufzubauen.


Die Nut in der Wellenkupplung wird mit einem Sensor abgetastet. Dieses 
Sensorsignal wird dann aufbereitet (wie weiss ich auch nicht genau, weil 
die entsprechende Elektronik schon vorhanden ist).

Ich greife einen sauberen 3,8 Volt Puls ab. Der Puls wird immer dann 
erzeugt wenn die Nut ueber den Sensorkopf faehrt, also genau einmal pro 
Umdrehung.

Dieses Signal wandle ich mit einem Optokoppler TLP250 so um, dass es 
sich auf das Spannungsniveau meines uControllers bezieht.



Diese Pulse fuehre ich in Pin 3.2 (CAPIN).


Hier beginnt die eigentliche Geschwindigkeitserfassung:

Ich benutze den Hilfstimer T5 (von GPT2). Der Timer befindet sich ganz 
normal im Timer Mode und wird mit
getriggert.

Das CAPREL Register ist im "Capture" mode. Es ist so eingestellt, dass 
bei steigender Flanke an P3.2 der Inhalt von T5 in CAPREL uebernommen 
wird und T5 geloescht wird.

Jetzt kann CAPREL ausgelesen werden (passiert in Interrupt Service 
Routine):

Weiterhin frage ich ab ob es einen Timerueberlauf gibt, fuer diesen Fall 
wird die Geschwindigkeit gleich null gesetzt und das Naechste Ergebniss 
nicht beruecksichtigt.

Funktioniert im stationaeren Zustand ganz gut, aber zu meinem Problem:



Wenn ich den Motor schnell beschleunige, erhalte ich einen sehr hohen 
Wert fuer die Geschwindigkeit, T5 wird bei sehr sehr kleinen Werten 
gecaptured.

Also selbst wenn der Motor mit vielleicht 500 U/Min laeuft werden mir 
uber 10.000 U/Min angezeigt.

Allerdings ist das nur solange er schnell beschleunigt, zum Beispiel mit 
Stromregelung und vorgegebenem Stroll Sollwert (1.4A), wenn ich die 
Versorgungsspannung stark erhoehe (so auf 70V)



Ich weiss echt nicht mehr weiter, fuer jegliche Anregungen bin ich sehr 
dankbar.

Der Code ist angehaengt
1
/* ----- Hier wird der Stromistwert erfasst ----------------------------- */
2
void ad_int (void) interrupt 0x3F
3
{
4
5
 ADST = 1;                   /* Conversion start                */
6
 while(ADBSY) {};                 /* wait of end of conversion  */
7
 current_temp = ADDAT & 0x03FF;      /*read result of conversion         */  
8
 current = (24*current + current_temp)/25; 
9
10
11
if(current > current_desired  ) {
12
P7 = 0x0000;
13
//LED15 = 1;
14
}
15
16
if(current < current_desired ) {
17
 P7 = 0x0002;
18
//LED15 = 0;
19
20
}
21
22
  PWMIR  = 0;            /* delete interrupt request from PWM  */
23
24
}
25
26
27
28
29
30
/* ----- Interrupt from CAPCOM T0: Erfassen des Geschwindigkeitswertes -------------------------------- */
31
void speedcontrol (void) interrupt 0x10
32
{
33
34
35
// Check if Overrun set
36
 
37
 if(overrun == 1) {
38
   speed = 0;
39
   overrun = 0;
40
   }
41
 else if(CAPREL == 0)
42
   {}
43
   else if(CAPREL < 147)
44
     speed = 10000;
45
     else {
46
       speed  = 11718750 / CAPREL;          /* set speed  0 ... 10000   */
47
     }
48
49
 CC0IR  = 0;
50
51
}
52
53
54
55
56
57
58
/* ----- Interrupt from T5 (Overrun): speed very low --------------------------------*/
59
void overr (void) interrupt 0x25
60
{
61
 overrun = 1;
62
 
63
 T5IR  =  0;
64
}
65
66
67
68
69
70
71
/******************************************************************************/
72
/* main program                                                               */
73
/******************************************************************************/
74
75
void main (void)
76
{
77
78
DP71  = 1;                /* Define PWM-Output as Push-/Pull-
79
                                Output, Latch-contents after Reset 0 */
80
81
82
83
   
84
  
85
   PM0   = 1;                /* PWM-Channel 0 Center Aligned Mode    */
86
   PP0   = 2000;             /* Load period register                 */
87
   PIE0  = 1;                /* Interrupt enable */  
88
   PWMIC = 0x005A;           /* interrupt Level 6 Group 2            */
89
90
91
   CCM0    =  0x0006;        /* CAPCOM T0 in Compare mode 2          */
92
   T0REL   =  6241;          /* overrun every 1ms                    */
93
   CC0     =  0xFFFF;
94
   T01CON  =  0x0040;        /* CAPCOM T0 run, f_T0 = f_CPU/8        */
95
   CC0IC   =  0x0061;        /* interrupt Level 8 Group 1            */
96
97
98
   T5CON  =  0xD005;         /*  T5 CAPREL in Capture-mode
99
                                 f_T5 = f_CPU / 128, T5 timer mode
100
                                 T5 counts up, CAPIN (P3.2) triggers
101
                                 at raising edge                        */
102
103
   
104
   T5IC  =   0x0067;          /* T5 overrun Interrupt, Level 9, Group3 */
105
106
107
     IEN = 1;                 /* enable global interrupt   */
108
109
   PWMCON0 = PWMCON0 | 0x0003;                /* Start of PWM-Timer 0 and 1           */
110
  
111
  
112
  ADCON = 0x0000;             /* init AD-Converter in Auto Scan 
113
                                 Continuous Mode for Channel 0       */
114
  
115
   T5R  =  1;                 /* start Timer5 */
116
  
117
         
118
119
120
  while(1)
121
  {}
122
123
}

von Martin (Gast)


Lesenswert?

Das Problem wird sein, dass die vom Motor abgestrahlten Störungen auf 
den Sensor einstrahlen und Fehlimpulse erzeugen. Kannst du dir mal mitm 
Oszi das Sensorsignal anschauen?

von Mathias Q. (paolo_pinkel)


Lesenswert?

Ja klingt plausibel, der Sensor ist auch recht nah am Motor.

Ich werde morgen mal eine Oszi Aufnahme posten und auch den Sensor mal 
unter die Lupe nehmen.

von 6641 (Gast)


Lesenswert?

Ne division im interrupt ? Wuerd ich vermeiden. Zumal sie unnoetig ist. 
Die Regelung wuerd ich im main machen, nicht im interrupt. Die Regelung 
muss nicht auf eine division regeln, sondern auf eine konstante periode. 
Auf den Capture wert.

von Mathias Q. (paolo_pinkel)


Lesenswert?

Ja - das ist wahr. Werde mir morgen auch darüber Gedanken machen und die 
Regelung entsprechend umschreiben, allerdings ist das nur eine kleine 
Schönheitskorrektur und hat so wie ich das einschätze nichts direkt mit 
meinem Problem zu tun.

Wie ich allerdings in main regeln soll ist mir nicht ganz klar. So wie 
ich das realisiere, wird meine Regelalgorithmus (nicht im Code oben) 
periodisch aufgerufen. Die main wird ja permanent bearbeitet, also 
einfach den Algorithmus da rein? Wo ist der Vorteil?

Danke!!

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.