www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem Geschwindigkeitserfassung


Autor: Mathias Quetschlich (paolo_pinkel)
Datum:

Bewertung
0 lesenswert
nicht 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
/* ----- Hier wird der Stromistwert erfasst ----------------------------- */
void ad_int (void) interrupt 0x3F
{

 ADST = 1;                   /* Conversion start                */
 while(ADBSY) {};                 /* wait of end of conversion  */
 current_temp = ADDAT & 0x03FF;      /*read result of conversion         */  
 current = (24*current + current_temp)/25; 


if(current > current_desired  ) {
P7 = 0x0000;
//LED15 = 1;
}

if(current < current_desired ) {
 P7 = 0x0002;
//LED15 = 0;

}

  PWMIR  = 0;            /* delete interrupt request from PWM  */

}





/* ----- Interrupt from CAPCOM T0: Erfassen des Geschwindigkeitswertes -------------------------------- */
void speedcontrol (void) interrupt 0x10
{


// Check if Overrun set
 
 if(overrun == 1) {
   speed = 0;
   overrun = 0;
   }
 else if(CAPREL == 0)
   {}
   else if(CAPREL < 147)
     speed = 10000;
     else {
       speed  = 11718750 / CAPREL;          /* set speed  0 ... 10000   */
     }

 CC0IR  = 0;

}






/* ----- Interrupt from T5 (Overrun): speed very low --------------------------------*/
void overr (void) interrupt 0x25
{
 overrun = 1;
 
 T5IR  =  0;
}






/******************************************************************************/
/* main program                                                               */
/******************************************************************************/

void main (void)
{

DP71  = 1;                /* Define PWM-Output as Push-/Pull-
                                Output, Latch-contents after Reset 0 */



   
  
   PM0   = 1;                /* PWM-Channel 0 Center Aligned Mode    */
   PP0   = 2000;             /* Load period register                 */
   PIE0  = 1;                /* Interrupt enable */  
   PWMIC = 0x005A;           /* interrupt Level 6 Group 2            */


   CCM0    =  0x0006;        /* CAPCOM T0 in Compare mode 2          */
   T0REL   =  6241;          /* overrun every 1ms                    */
   CC0     =  0xFFFF;
   T01CON  =  0x0040;        /* CAPCOM T0 run, f_T0 = f_CPU/8        */
   CC0IC   =  0x0061;        /* interrupt Level 8 Group 1            */


   T5CON  =  0xD005;         /*  T5 CAPREL in Capture-mode
                                 f_T5 = f_CPU / 128, T5 timer mode
                                 T5 counts up, CAPIN (P3.2) triggers
                                 at raising edge                        */

   
   T5IC  =   0x0067;          /* T5 overrun Interrupt, Level 9, Group3 */


     IEN = 1;                 /* enable global interrupt   */

   PWMCON0 = PWMCON0 | 0x0003;                /* Start of PWM-Timer 0 and 1           */
  
  
  ADCON = 0x0000;             /* init AD-Converter in Auto Scan 
                                 Continuous Mode for Channel 0       */
  
   T5R  =  1;                 /* start Timer5 */
  
         


  while(1)
  {}

}

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Mathias Quetschlich (paolo_pinkel)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: 6641 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Mathias Quetschlich (paolo_pinkel)
Datum:

Bewertung
0 lesenswert
nicht 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!!

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.