mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mikroschrittmotor mit L293 oder PBM3960 + PBL3771: Wie programmieren?


Autor: Christian Kl (dxrz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche, einen bipolaren Schrittmotor zum Laufen zu bringen und 
komme da nicht so wirklich weiter.

Der Schrittmotor (1,8° Step) soll eine Masse von ca. 300g bewegen. Als 
Auflösung reichen viertelschritte. Allerdings soll die Bewegung ruhig 
und ruckelfrei sein. Das Problem ist die Programmierung. Ich 
programmiere – oder versuche es zumindest ;-) - mit Bascom avr.

Als erstes habe ich es mit dem Treiber L293D für den Schrittmotor 
versucht. Im Vollschrittmodus lief er gut. Jedoch sprang der Motor immer 
nur ruckhaft einen Schritt weiter und drehte sich nicht gleichmäßig. 
Nächster Versuch war, 4 Software PWM-Ports zu erstellen, um den Motor im 
Mikroschrittmodus zu betreiben. Allerdings vibrierter der Motor sehr 
stark und drehte sich nicht, der Motor musste hierbei keine Last 
bewegen. (Wenn ich anstatt des Motors 4 LED’s anschließe, dimmen die 
LED‘s genauso wie erwartet.)

Eine Weitere Idee ist jetzt, das Ganze mit der Treiberkombination PBM 
3960 + PBL 3771 bzw. NJU 39610 + NJM 3771 zu versuchen. Hier verstehe 
ich jedoch die Vorgehensweise nicht so ganz. An die Inputregister D0 bis 
D6 gebe ich über den Mikrocontroller ein Bitmuster aus, mit D7 bestimme 
ich die Richtung, in welcher der Motor sich drehen soll und dann 
generiere ich einen WR-Puls damit sich der Motor dreht? Funktioniert das 
so? Was mache ich dann mit A0, A1 und CS? Im Datenblatt steht ja, dass 
es nicht sinnvoll ist, alle theoretisch möglichen Mikroschritte aus zu 
nutzen. Heißt dass, das ich das Register nicht immer um binär 1 erhöhe 
sondern um binär 10 oder binär 100? In welcher Frequenz müssen die 
Mikroschritte generiert werden, damit eine saubere Drehung entsteht?

Datenblatt PBM 3960:
 http://pdf1.alldatasheet.com/datasheet-pdf/view/60...

Am liebsten würde ich beide Varianten zum Laufen bekommen.
Hat jemand vielleicht ein paar Tipps für mich?

Gruß
Christian

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian Kl schrieb:
> bewegen. (Wenn ich anstatt des Motors 4 LED’s anschließe, dimmen die
> LED‘s genauso wie erwartet.)

Vielleicht sind deine Erwartungen fehlerhaft?

Poste mal den Code.

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian Kl schrieb:
> Allerdings vibrierter der Motor sehr
> stark und drehte sich nicht, der Motor musste hierbei keine Last
> bewegen. (Wenn ich anstatt des Motors 4 LED’s anschließe, dimmen die
> LED‘s genauso wie erwartet.

Nur um Missverständnissen vorzubeugen: Schliesst du die 4 PWM Signale 
direkt an die Motorphasen an, oder über 4 Transistoren?

Zur Variante mit dem L293D gibt es mehr als genügend Beispiele für Soft- 
und Hardware hier im forum und im Internet. Mit etwas Suchen lässt sich 
da leicht ein gutes Beispiel finden.

Autor: Christian Kl (dxrz)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Zum L293D
 Beschaltung:  Die 4 „Soft-PWM – Portpins“  habe ich an den L293D 
angeschlossen und zwar an 1A, 2A, 3A und 4A. Weiterhin habe ich noch 1-2 
EN und 2-3 EN an den Mikrocontroller angeschlossen um eventuell später 
mal mehrere Motoren betreiben zu können. Außerdem habe ich gelesen, dass 
man hiermit den Strom begrenzen, bzw. erhöhen kann falls mehr Drehmoment 
erforderlich ist. Das wollte ich aber erst mal beiseite lassen. Y1 bis 
Y4 des L293D gehen dann an die beiden Motorphasen. Wozu brauche ich 
jetzt noch Transistoren? (Der L293D hat eingebaute Freilaufdioden)
Da ich programmiertechnisch nicht ganz so bewandert bin, habe ich einen 
anderen Code adaptiert. Es ging mir zunächst nur um eine saubere 
Drehung:
 ' ------ Soft PWM für Mikroschrittmotor -------------




$crystal = 8000000                                          
$regfile "m16def.dat"                                      
$programmer = 7 'STK 500
$hwstack = 8
$swstack = 6
$framesize = 10


Dim M1_w1afreq As Integer , M1_w1bfreq As Integer , M1_w2afreq As Integer , M1_w2bfreq As Integer
Dim Updn As Byte
Dim Wartems As Integer
Dim Zeit As Integer
Dim N As Integer
Dim Flimit As Integer


'-------- Bitmuster für Vollschrittbetrieb --------
' Mit dem hier auskommentiere Bitmuster funktioniert der Schrittmotor im
' Vollschrittbetrieb deshalb habe ich es aus dem Code erstaml nicht 
'rausgelöscht.

'Portb.0 = 1  ' 1-2 EN
'Portb.5 = 1  ' 2-3 EN

'Portb.1 = 1
'Portb.2 = 0
'Portb.3 = 0
'Portb.4 = 1
'Waitms 500

'Portb.1 = 1
'Portb.2 = 0
'Portb.3 = 1
'Portb.4 = 0

'Waitms 500

'Portb.1 = 0
'Portb.2 = 1
'Portb.3 = 1
'Portb.4 = 0

'Waitms 500

'Portb.1 = 0
'Portb.2 = 1
'Portb.3 = 0
'Portb.4 = 1


' Waitms 500

'Portb.1 = 1
'Portb.2 = 0
'Portb.3 = 0
'Portb.4 = 1
'Waitms 500

'------- Ende Bitmuster für Vollschrittbetrieb ------




Const Timerstartwert = 10                                   'Wert ab dem bis 256 bzw. 1024 gezählt wird.
Config Timer0 = Timer , Prescale = 1                        'Prescale: Bei Ausgabe des Bitmusters an LED's ist alles andere außer 1 zu schnell.
Timer0 = Timerstartwert
On Timer0 Ontimer0
Enable Timer0
Enable Interrupts

Motor1_w1a Alias Portb.1                                    'Motorwicklung 1 Ende "a" der ersten Spule. PortB.1 geht zum L293 1A
Motor1_w1b Alias Portb.2                                    'Motorwicklung 1 Ende "b" der ersten Spule. PortB.2 geht zum L293 2A
Motor1_w2a Alias Portb.3                                    'Motorwicklung 2 Ende "a" der zweiten Spule. PortB.3 geht zum L293 3A
Motor1_w2b Alias Portb.4                                    'Motorwicklung 2 Ende "b" der zweiten Spule. PortB.4 geht zum L293 4A



Config Motor1_w1a = Output                                  ' PortB.1 bis PortB.4 als
Config Motor1_w1b = Output                                  ' Ausgang setzen
Config Motor1_w2a = Output
Config Motor1_w2b = Output



 Motor1_w1a = 0                                             ' Werte initialisieren für den ersten Start
 Motor1_w1a = 0
 Motor1_w1a = 0
 Motor1_w1a = 0



Flimit = 400              'Zählerbegrenzer
Zeit = 3                  'Vergleichszaehler für Pulsweite im Interrupt
Wartems = 1               'Wartevariable fuer waitms.
Updn = 1                  'Toggle fuer Hoch/Runter-Zaehlen der Intervalle.
                          'Bei Wert groesser 1 wird Wartems nicht hoch/runtergezaehlt

M1_w1afreq = 0
M1_w1bfreq = 0
M1_w2afreq = 0
M1_w2bfreq = 0



Portb.1 = 1
Portb.2 = 0
Portb.3 = 0
Portb.4 = 1

Macro Motor 1 Schritt 1                                     '1001-->1010
 M1_w1afreq = Flimit
 M1_w1bfreq = 0
 M1_w2afreq = 0
 M1_w2bfreq = Flimit


   Waitms Wartems
   For N = 1 To Flimit

      Incr M1_w2afreq
      Decr M1_w2bfreq

      Waitms Wartems

   Next N
   M1_w1afreq = Flimit



End Macro



Macro Motor 1 Schritt 2                                     '--> 0110
 M1_w1afreq = Flimit
 M1_w1bfreq = 0
 M1_w2afreq = Flimit
 M1_w2bfreq = 0


   Waitms Wartems
   For N = 1 To Flimit

     Decr M1_w1afreq
      Incr M1_w1bfreq

      Waitms Wartems

   Next N
   M1_w1afreq = Flimit





End Macro

Macro Motor 1 Schritt 3                                     '--> 0101
 M1_w1afreq = 0
 M1_w1bfreq = Flimit
 M1_w2afreq = Flimit
 M1_w2bfreq = 0


   Waitms Wartems
   For N = 1 To Flimit


      Decr M1_w2afreq
      Incr M1_w2bfreq

      Waitms Wartems

   Next N
   M1_w1afreq = Flimit


End Macro

Macro Motor 1 Schritt 4                                     '--> 1001
 M1_w1afreq = 0
 M1_w1bfreq = Flimit
 M1_w2afreq = 0
 M1_w2bfreq = Flimit


   Waitms Wartems
   For N = 1 To Flimit

     Incr M1_w1afreq
      Decr M1_w1bfreq


      Waitms Wartems

   Next N
   M1_w1afreq = Flimit


End Macro



Do                                                          'Hauptschleife
Portb.0 = 1                                                 ' 1-2 EN  gibt am L 293 die Wicklung 1 frei
Portb.5 = 1                                                 ' 2-3 EN  gibt am L 293 die Wicklung 2 frei
Motor 1 Schritt 1
Motor 1 Schritt 2
Motor 1 Schritt 3
Motor 1 Schritt 4


   If Updn = 1 Then
      Wartems = Wartems + 3
      If Wartems >= 100 Then Updn = 0
   Elseif Updn = 0 Then
      Wartems = Wartems - 3
      If Wartems = 0 Then Updn = 1
   End If
Loop

End

Ontimer0:
   Incr Zeit                                                'Bei jedem Interruptueberlauf Zeit um 1 erhöhen
   If Zeit < M1_w1afreq Then Motor1_w1a = 0 Else Motor1_w1a = 1
   If Zeit < M1_w1bfreq Then Motor1_w1b = 0 Else Motor1_w1b = 1
   If Zeit < M1_w2afreq Then Motor1_w2a = 0 Else Motor1_w2a = 1
   If Zeit < M1_w2bfreq Then Motor1_w2b = 0 Else Motor1_w2b = 1
   If Zeit >= Flimit Then Zeit = 0                          'Bei erreichen von Flimit zurücksetzen
   Timer0 = Timerstartwert
Return

Im Internet habe ich bis jetzt immer nur tolle Abhandelungen gefunden, 
wie so ein Schrittmotor in der Theorie funktioniert, welche Kräfte 
wirken usw... Aber einen schönen, auskommentierten Quellcode in Basic 
leider nicht. Da ich Assembler und C nicht kann, helfen mir die Codes 
auch nicht viel weiter und ich denke ein verständlicher Quelltext in 
BASCOM würde auch vielen anderen Anfängern helfen. Falls jemand dazu 
einen Link hat würde ich mich freuen.

Gruß
Christian

Autor: Thorsten Ostermann (Firma: mechapro GmbH) (ostermann) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Christian!

> Zum L293D
>  Beschaltung:  Die 4 „Soft-PWM – Portpins“  habe ich an den L293D
> angeschlossen und zwar an 1A, 2A, 3A und 4A. Weiterhin habe ich noch 1-2
> EN und 2-3 EN an den Mikrocontroller angeschlossen um eventuell später
> mal mehrere Motoren betreiben zu können. Außerdem habe ich gelesen, dass
> man hiermit den Strom begrenzen, bzw. erhöhen kann falls mehr Drehmoment
> erforderlich ist. Das wollte ich aber erst mal beiseite lassen.

Was hat denn dein Motor für eine Nennspannung, und mit welcher Spannung 
betreibst du deinen L293? Ich habe so das Gefühl, dass schon die 
Hardware nicht optimal ist.

Was es die Software angeht:
> Als erstes habe ich es mit dem Treiber L293D für den Schrittmotor
> versucht. Im Vollschrittmodus lief er gut. Jedoch sprang der Motor
> immer nur ruckhaft einen Schritt weiter und drehte sich nicht
> gleichmäßig.

Bei welcher Geschwindigkeit bzw. Steprate war das? Bei niedrigen 
Geschwindigkeiten "steppt" der Schrittmotor nur, deswegen heißt er so. 
Wenn du auch bei niedrigen Geschwindigkeiten auf einen möglichst 
gleichmäßigen Lauf wert legst, wirst du um Mikroschritt nicht 
herumkommen. Da setzt man in der Regel aber Treiber mit Stromregelung 
ein. Reine gesteuerte PWM ist dafür zu ungenau. Ausserdem gibt es das 
alles schon fertig auf einem Chip, z.B. Allegro A3977 oder A3979.

Mit freundlichen Grüßen
Thorsten Ostermann

Autor: Christian Kl (dxrz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Thorsten,
für den µC beträgt die Spannung 5V (über 7805 wie im Tutorial) der L293D 
bekommt 12V aus einem alten PC-Netzteil. Am 12V Eingang des L293 habe 
ich noch ein Stützkondensator von 1000µF gesetzt  Der Schrittmotor ist 
ein „Reserve-Schrittmotor“ für ein gerät, an dem er auch mit 12V 
betrieben wird. Allerdings wird dort der PBL 3771 benutzt. Da ich 
hiervon auch noch Ersatztreiber habe, wollte ich es dann damit versuchen 
wie oben geschrieben. Nur verstehe ich nicht, wie der funktioniert.

Im professionellen Bereich macht man es aber auch so. Die nehmen zwar 
einen L6204D aber das ist im Prinzip auch nur eine Brücke und somit 
nichts anderes als der L293.

Es muss also an der Programmierung liegen.  Nur finde ich kein konkretes 
Beispiel, an dem man sehen kann, wie man sowas in Bascom macht. Falls 
jemand ein funktionierendes Beispiel hat oder einen Link dazu würde ich 
mich sehr freuen.

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Jedoch sprang der Motor immer nur ruckhaft einen Schritt
> weiter und drehte sich nicht gleichmäßig.

Deswegen bekommen Schrittmotore eine Bremsresonatorplatte,
also Gewicht.

> PBM3960 + PBL3771

Veraltet.
Nimm TB6560.
Dann klappt's auch mit der Mikroschrittprogrammierung.


Ich versteh übrigens deinen Code kein Stück:

   If Zeit < M1_w1afreq Then Motor1_w1a = 0 Else Motor1_w1a = 1
   If Zeit < M1_w1bfreq Then Motor1_w1b = 0 Else Motor1_w1b = 1
   If Zeit < M1_w2afreq Then Motor1_w2a = 0 Else Motor1_w2a = 1
   If Zeit < M1_w2bfreq Then Motor1_w2b = 0 Else Motor1_w2b = 1

Du möchtest die Spannung PWM-Mässig einen Teil der Zeit einschalten und 
einen Teil der Zeit ausschalten ? Schrittmotore interessieren sich nicht 
für die Spannung, sondern für den Strom.

Deswegen enthalten L297 und PBL3771 Strommmesshunts Rs und vergleichen 
deren Spannungsabfall mit einer Sollspannung. Irgendwie sehe ich 
überhaupt nichts davon in deinem Programm, aber vielleicht bin ich ja 
auch nur blind.

In C (sorry, ich krieg bei BASCOM Augenkrebs so wie du sicher bei C):

int 
sin[32]={0,20,38,56,71,83,92,98,100,98,92,83,71,56,56,38,20,0,-20,-38,-5 
6,-71,-83,-92,-98,-100,-98,-92,-83,-71,-56,-56,-38,-20};
int 
cos[32]={-100,-98,-92,-83,-71,-56,-56,-38,-20,0,20,38,56,71,83,92,98,100 
,98,92,83,71,56,56,38,20,0,-20,-38,-56,-71,-83,-92,-98};

for(i=0;;i=t%32)
{
    a=Analogmesswert shunt Wicklung X
    if(a>abs(sin[i])) if(sin[i]>0)) { portb.1=1; portb.2=0; } else { 
portb.1=1; portb.2=0; } else { portb.1=0; portb.2=0; }
    a=Analogmesswert shunt Wicklung X
    if(a>abs(cos[i])) if(cos[i]>0)) { portb.3=1; portb.4=0; } else { 
portb.3=1; portb.4=0; } else { portb.3=0; portb.4=0; }
    t=aktuelle Millisekundenzeit
    t*=Geschwindigkeitsfaktor; // also wie viele Steps pro Millisekunde
}

Nun wäre der Geschwindgkeitsfaktor interessant,
denn ein Schrittmotor läuft nicht nur mit vollem Tempo,
er will langsam beschleunigt werden und langsam bremsen,
man muß also den Geschwindigkeitsfaktor von aussen vorgeben,
eventuell durch ein Poti an einem Analogeingang des uC zu
Testzwecken.

Ebenso ist interessant, wie der uC seine aktuelle Millisekundenzeit 
bekommt. Man muß einen Timer programmieren und der kann überlaufen und 
die Überläufe wird man auch beachten müssen. Dieser Timer ist aber das 
einzige, was in einer Interrupt-Funktion gemacht werden sollte, die 
eigentliche Stromregelung muss so schnell wie möglich sein (gute 
Schrittmotortreiber machen das mit über 1MHz also unter 1us 
Reaktionszeit) also wird man die tunlichst als enge Assembleroptimierte 
Schleife bauen, wo A/D-Wandlung und Reaktion darauf zeitverschachtelt 
sind.

Ein TB6560 ist einfacher zu programmieren...

Autor: Christian Kl (dxrz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
erst mal vielen Dank für die Antworten!
Ich habe in den letzten Tagen das folgende Projekt nach gebaut:

http://www.hoelscher-hi.de/hendrik/light/dmxstep.htm

Es ist ein DMX-Interface, welches bis zu zwei Schrittmotoren antreibt.
Ergebnis: Bei der Resetfahrt wackelt der Motor ein bisschen, dreht sich 
aber nicht. Schubst man ihn aber an, dreht er sich. Also gibt der L293D 
wohl nicht genug Strom her. Bzw. Muss man den Strom wohl an gewissen 
Punkten absenken. Somit hat sich der L293 erst mal erledigt.


Bei der PBL 3771 / PBM 3960 Kombination, bin ich ein Stück weiter 
gekommen, aber nicht viel:

Es gibt zwei Kanäle mit je 7 bit. Also einen Kanal pro Spule. A0 
schaltet zwischen Kanal 1 und Kanal 2 um. Mit A1 kann man zwischen 
Drehrichtung oder Spannung umschalten.  Die Werte für Drehrichtung oder 
Spannung werden über die 7 bits eingestellt. Die Werte werden mit zwei 
write- Pulsen übernommen. Was ich jetzt noch wissen müsste: In welcher 
Folge müssen sich die Kanal-bits ändern? Fange ich mit Kanal 1 bei 128 
an und subtrahiere und bei Kanal 2 bei 1 und addiere? Das scheint nicht 
zu funktionieren. Allerdings habe ich die Spannung erst mal völlig außer 
Acht gelassen. Wie muss ich die bits für die Spannung ändern?

Bezüglich des TB6560:
Wie würde dieser denn funktionieren und wo kann man ihn bekommen?

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest es vielleicht mal mit systematischer Suche nach
deinen fehlenden Erkenntnissen probieren, und nicht drei
verschiedene Aufbauten machen und jedesmal wohl wieder in
dieselbe Falle stolpern.

Motor kaputt, Kabel ab, vielleicht ist es gar kein Schrittmotor,
es gibt viele Möglichkeiten warum etwas nicht funktioniert.

Wenn du ein Netzteil hast, kannst du doch erst mal mit Kabeln
versuchen, den Motor drehen zu lassen, immer abwechselnd die
Spulen bestromen in Handarbeit, das geht, muss man nur was tun.

Dann lässt man ihn per L293 langsam drehen (wobei er wohl nur
zappelt) und misst dabei die Ausgangsspannungen. Dann sieht
man ja wohl, ob was nicht stimmt.

u.s.w.

> und wo kann man ihn bekommen?

Beim Elektronikhändler wie Darisus.de

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.