Forum: Mikrocontroller und Digitale Elektronik PIC: Schrittmotor mit L293D ansteuern


von Sebastian (Gast)


Lesenswert?

Hallo,

emoment versuche ich mit einem PIC16F84A und dem Treiber-IC L293D einen 
bipolaren Schrittmotor anzutreiben. Der Motor bewegt sich beim 
Einschalten auch um ein paar Schritte, doch dann erhitzt sich der PIC 
sehr stark. PORTA habe ich mit dem Treiber-IC L293D verbunden wie im 
Anhang zu sehen ist. Am Treiber-IC lege ich aber statt 12V 5V an.
Mein Quelltext sieht folgendermaßen aus:
1
//Schrittmotorsteuerung:
2
char schleifenschritt = 1;//diese Variable zaehlt immer von 1 bis 4 und //sorgt dafuer das immer der richtige Ausgangszustand an die Statoren //weitergegeben wird
3
4
void schrittefahren(signed char schritte);//dreht den Schrittmotor um eine //bestimmte Anzahl an Schritten
5
6
#define statoren PORTA //an PORTA sind die Statoren ueber den IC verbunden
7
/*PORTA:
8
1.Bit: Stator 1 Anschluss 2
9
2.Bit: Stator 1 Anschluss 1
10
3.Bit: Stator 2 Anschluss 2
11
4.Bit: Stator 2 Anschluss 1
12
*/
13
14
void main(void){
15
     //Initialisierung
16
     TRISA = 0;
17
     PORTA = 0;
18
     schrittefahren(50);//vorwaertsdrehen um 50 Schritte
19
     schrittefahren(-50);//rueckwaertsdrehen ''
20
}
21
void schrittefahren(signed char schritte){
22
     int n; //Zaehlvariable fuer die bisherigen Schritte
23
     if(schritte > 0)//Vorwaerts
24
                 for(n = 0; n < schritte; n++){//Schritte abfahren
25
                    delay_ms(250);
26
                    switch (schleifenschritt) {//je nach Stellung des          //Rotors wird ein anderer Zustand weitergegeben
27
                      case 1: statoren = 0b00000101;  break;
28
                      case 2: statoren = 0b00001001;  break;
29
                      case 3: statoren = 0b00001010;  break;
30
                      case 4: statoren = 0b00000110;
31
                        schleifenschritt = 0;
32
                        break;
33
                    }
34
                  schleifenschritt++;
35
                 }
36
     else//Rueckwaerts
37
                      for(n = 0; n < -schritte; n++){
38
                            delay_ms(250);
39
                            switch (schleifenschritt) {
40
                              case 1: statoren = 0b00001001;  break;
41
                              case 2: statoren = 0b00000101;  break;
42
                              case 3: statoren = 0b00000110;  break;
43
                              case 4: statoren = 0b00001010;
44
                                schleifenschritt = 0;
45
                                break;
46
                            }
47
                      }
48
}
Hat jemand eine Idee warum sich der Mikrocontroller so stark erhitzt?

MfG Sebastian

von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

Der Anhang ist wohl nicht mitgekommen.

von Daniel Reitz (Gast)


Lesenswert?

Also bei starker Erwärmung des PIC würde man am ehesten einen 
Kurzschluss vermuten.

Vielleicht schaust dir die 4 Ausgänge des PORTA einmal an, ob da 
vielleicht irgendwo was falsch verbunden wurde.
Wenn da alles passt, klemm deine PORTA-Ausgänge mal ab und schau, ob der 
µC ohne Anschluss des Treiberbausteins im Betrieb auch warm wird – dann 
weißt zumindest, dass das Problem nicht am Treiberbaustein liegt.
Wird er auch in diesem Fall warm, dürfte ein Fehler in der 
Grundbeschaltung des µC vorhanden sein, oder er ist im schlimmsten Falle 
kaputt.

Ich glaube, dass der Rückwärtslauf nicht funktionieren wird, da dein 
„schleifenschritt“-Zähler nicht inkrementiert wird im else-Zweig!

von Sebastian (Gast)


Lesenswert?

Hallo und vielen Dank für die Hilfe,

den Fehler in dem Skript habe ich repariert. Der PIC wird ohne Treiber 
nicht heiß - mit Leuchtdioden habe ich schon die Funktionalität geprüft. 
Wenn ich die LEDs anschließe wird der PIC ebenfalls nicht heiß (mit 
1k-Widerständen). Wenn ich dann den Treiber-IC dazu schalte, blinken die 
Leds nur mal kurz und hören auf zu leuchten.
Die Schaltung habe ich schon zweimal aufgebaut und bei beiden Malen gab 
es das Problem.
Der Treiber-IC ist auch nicht defekt, den habe ich auch schon überprüft.

MfG Sebastian

von holger (Gast)


Lesenswert?

Du betreibst das komplett ohne Abblockkondensatoren ?

von Jörg (Gast)


Lesenswert?

Habe selbst neulich einen Schrittmotor angesteuert, allerdings über
MSP430, sollte aber keinen unterschied machen.
Dein Code ist etwas kompliziert: Verwende vieleicht eine Variable
Schritt, die je nach Richtung entweder aufwärts oder abwärts zählt,
und zwar von 0 bis 3:

  schritt = (schritt + richtung) & 3;   // richtung = -1,0,1

dann brauchst Du nur noch eine Case-Anweisung und der Code wird
erheblich einfacher zu lesen. Noch einfacher wirds, wenn Du
die Portausgabewerte zur Motoransteuerung in eine Tabelle (mit
vier Werten) ablegst => minimaler Code:

  statoren = table[schritt];

Einen Anschlussfehler habe ich auch nicht gefunden: der L293 ist
richtig angeschlossen.


Gruss

Jörg

von Daniel R. (Gast)


Lesenswert?

Die Ausgänge des PIC halten soweit ich weiß 20mA aus - aber das kann 
eigentlich nicht überschritten werden (da Eingänge des Motortreibers 
TTL-kompatibel).

Deine Versorgungsspannung für die beiden ICs ist ja 5 V - bekommst du 
die von einem Festspannungsregler (7805)? Evtl. ziehst du beim 
Anschließen des Motortreibers und den zwei Schrittmotoren zuviel Strom, 
wodurch die Spannung einbricht und der µC nicht mehr richtig arbeiten 
kann.

von Sebastian (Gast)


Lesenswert?

Hallo und vielen Dank für die Ratschläge,

@ holger: Ja ich betreibe das ohne Abblockkondensatoren.
Wo und was für Abblockkondensatoren sollte ich den einbauen?

@ Jörg: Vielen Dank für die Ratschläge - Ich änder gleich mein Skript. 
Mal eine Frage, hast du bei deiner Schaltung zwischen dem 
Treiber-IC-Anschlüssen für den Mikrokontroller und der Masse Widerstände 
angeschlossen?

@ Daniel R.: An der Spannungsversorgung liegt es nicht - ich verwende 
ein hochwertiges geregeltes Labornetzteil, was mich bis jetzt noch nie 
enttäuscht hat. Es ist übrigens nur ein Schrittmotor angeschlossen.

Ich habe noch eine allgemeine Frage: Könnte es sein, dass der Mic. an 
den Ausgängen Dioden hat, die entweder 5V oder gar nix durchlassen? Dann 
gäbe es dort keine Masse und ich müsste zwischen Ausgang und Masse einen 
Widerstand packen? Richtig oder? Der Mic. würde sich deswegen erhitzen, 
weil ein hoher Strom an den Dioden ist!????


MfG Sebastian

von Jörg (Gast)


Lesenswert?

@Sebastian,

ich habe die Ausgänge direkt mit dem Treiber verbunden, frag aber lieber
eine E-Techniker, wie Du die PIC-Ausgänge mit den TTL-Eingängen des
Treibers verbinden solltest. Meine Testschaltung läuft aber auch nur mit
5 Volt, es ging mir nur um die Funktionalität/Ansteuerung per C-Code.

Gruss,

Jörg

von Zardoz (Gast)


Lesenswert?

PIC-Ausgänge an TTL-Eingänge geht eigentlich problemlos. Schon eher 
könnten die offenen Eingänge 1Y bis 4Y am L293D Probleme bereiten ...

Als Abblockkondensator sollte ein 100nF (Keramik) an VSS und GND des PIC 
ausreichen.

Nice weekend,
Zardoz

von Sebastian (Gast)


Lesenswert?

Hallo - danke für die Informationen,

zunächst erstmal habe ich den Code überarbeitet- statt PORTA nehme ich 
PORTB:
1
//Schrittmotorsteuerung:
2
//Def.
3
#define statoren PORTB
4
//Initial.
5
char statorenstellung = 0;
6
char statoren_stellung[4];
7
void schrittefahren(signed char schritte);
8
9
void main(void){
10
     TRISB = 0;
11
     PORTB = 0;
12
     statoren_stellung[0] = 0b00000101;
13
     statoren_stellung[1] = 0b00001001;
14
     statoren_stellung[2] = 0b00001010;
15
     statoren_stellung[3] = 0b00000110;
16
17
     schrittefahren(50);
18
     schrittefahren(-50);
19
}
20
21
void schrittefahren(signed char schritte){
22
     int richtung = 0; //Richtung des Schrittmotors
23
24
      if(schritte == 0){
25
                  return; //keine Schritte fahren
26
      }else if(schritte > 0){ //vorwaertsfahren
27
           richtung = 1;
28
      }else{ //rueckwaertsfahren
29
          richtung = -1;
30
          schritte = ~schritte;
31
      }
32
      while(schritte > 0){
33
              statoren = statoren_stellung[statorenstellung];
34
              statorenstellung = (statorenstellung + richtung) & 3;
35
              schritte--;
36
              delay_ms(250);
37
        }
38
39
}
Mein Logiktest blinkt in richtigen Abständen ohne Anschluss an den 
Treiber (schon mal ein gutes Zeichen) - aber ich bin mir nicht sicher ob 
das invertieren mit dem Sigmazeichen so klappt (schritte = ~schritte;) ?


Beim Anschluss an den Treiber-IC kamen aber nur für einige Millisekunden 
5V an. Es scheint als würde der Treiber-IC die Spannung von 5V sofort 
auf Low ziehen?
Wie ist so etwas mögl.?


MfG Sebastian

von Olaf (Gast)


Lesenswert?

Hallo,

Du verwendest einen Dopplbrückentreiber. Bei diesen sind 2 Transistoren 
in Reihe geschaltet zwischen Ub und GND. Wenn Du jetzt deine Schaltung 
einschaltest besteht die Möglichkeit (je nach verwendetem IC) dass beide 
Transistoren durchgeschaltet sind und deine Spannung zusammenbricht 
(Kurschluss über die Transistoren). Was wäre eine Lösung? Nun, den 
Baustein erst nach dem "Hochfahren" des PIC mit der Enable-Leitung 
aktivieren (die momentan an Ub hängt). Oder die Eingänge auf definierte 
Pegel legen. Vielleicht helfen am Ausgang des PIC Pull-Down oder 
PUll-Ups. Das sind aber bisher nur Vermutungen die erst noch geprüft 
werden müssen. Also ran ans Messgerät ;-).

Olaf

von Jörg (Gast)


Lesenswert?

@Sebastian,

Der Operator "~" invertiert bitweise, bei 16-Bit-Integer wird aus
50 glaube ich 32718 (oder etwas in der Grösse), bei 32-Bit-Integer
sowas wie 2.147.483.598

D.h. bei 16 bit stört der Fehler bzgl. Laufzeit ein wenig, im
32-Bit-Fall erreichts fast schon das Ende der Motorlebenszeit.


Schreib vieleicht noch

  char statoren_stellung[4] = {0b00000101, ... };

und lass die Initialisierung derstatoren_stellung-Werte in <main> weg.


Gruss

Jörg

von Sebastian (Gast)


Lesenswert?

Vielen Dank für die Ratschläge,

@Olaf: Jo mein Messgerät steht nicht mehr still ;-)
@Jörg:Schade, dass das Sigmazeichen nicht so funktioniert wie ich das 
gerne hätte: Ich wollte eig. folgendes: schritte = (-1)*schritte; - Ich 
dachte das bekäme ich durch das invertieren. Nur mit RISC-Proz. kann man 
nur über bestimmte Algorithmen multiplizieren, die wieder Speicherplatz 
kosten. Gibt es dafür eine andere Mögl. oder muss ich "richtung" als 
Parameter übergeben lassen?

MfG Sebastian

von Jörg (Gast)


Lesenswert?

@Sebastian,

das was ich da mit Invertierung und 32718 als 16-Bit-Ergebnis
geschrieben habe, war natürlich Quatsch (sorry, ist kurzfristig
in einer Werbepause entstanden), bezog sich auf das Invertieren
von 50 statt von -50!!!!!

Beim Negieren hast Du ja das 2er-Komplement, und das erreichst
Du durch

  schritte = -schritte;

statt

  schritte = (-1)*schritte;

Multiplizieren musst Du also nicht.

Gruss

Jörg

von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

es funktioniert!!! Es läuft mit einem anderen Prozessor (PIC16F628). 
Mein 2. PIC16F84A hat wohl Herz-Rhytmusstörungen und kann bald wohl 
wegen Altersschwäche begraben werden. ;-)

Ich hab hier noch mal mein Skript aufgelistet:
1
//Schrittmotorsteuerung:
2
//Def.
3
#define statoren PORTB
4
//Initial.
5
char statorenstellung = 0;
6
char statoren_stellung[4] = { 0b00000101,0b00001001, 0b00001010, 0b00000110};
7
void schrittefahren(signed char schritte);
8
9
void main(void){
10
     TRISB = 0;
11
     PORTB = 0;
12
13
     while(1)
14
     schrittefahren(100);
15
16
}
17
18
void schrittefahren(signed char schritte){
19
     int richtung = 0; //Richtung des Schrittmotors
20
21
      if(schritte == 0){
22
                  return; //keine Schritte fahren
23
      }else if(schritte > 0){ //vorwaertsfahren
24
           richtung = 1;
25
      }else{ //rueckwaertsfahren
26
          richtung = -1;
27
          schritte = -schritte;
28
      }
29
      while(schritte > 0){
30
              statoren = statoren_stellung[statorenstellung];
31
              statorenstellung = (statorenstellung + richtung) & 3;
32
              schritte--;
33
              delay_ms(250);
34
        }
35
36
}

Im Anhang befindet sich der Schaltplan.

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.