Hallo zusammen,
ich habe soeben ein Programm zur Ansteuerung von dem oben genannten
Schrittmotor geschrieben und möcht es mit euch teilen. Ev. werde ich es
später noch ausbauen und z.B. Startrampen einbauen usw...
Für Tips und konstruktive Kritik bin ich sehr dankbar.....
1
//Schrittmotorsteuerung für 28BYJ-48 5VDC mit ULN2003A
2
3
4
//Befehle für Drehrichtung definieren
5
byteMotorStop=0;//wird automatisch am Ende nach Ausführung der Schritte aufgerufen
6
byteMotorRechts=1;//Definition von Rechts und Linksdrehung, bei Bedarf vertauschen
7
byteMotorLinks=2;
8
9
//Schrittabfolge definieren 1 Muster ergibt einen Schritt Vorwärts
10
byteStepValues[][4]={
11
{0,0,0,1},
12
{0,0,1,1},
13
{0,0,1,0},
14
{0,1,1,0},
15
{0,1,0,0},
16
{1,1,0,0},
17
{1,0,0,0},
18
{1,0,0,1},
19
};
20
21
//Motor Pins für Ausgänge 1-4 definieren (auf ->> Eingänge ULN2003A)
22
byteMotor_Ausgaenge[]={10,11,12,13};
23
24
25
// the setup routine runs once when you press reset:
26
27
voidsetup(){
28
29
//Alle Pins als Ausgänge setzen und auf LOW schalten
30
for(bytei=0;i<=3;i++){
31
pinMode((Motor_Ausgaenge[i]),OUTPUT);
32
digitalWrite(Motor_Ausgaenge[i],LOW);
33
}
34
35
}
36
37
// the loop routine runs over and over again forever:
Die erreichbare Auflösung ist nicht so besonders, wenn man den Motor
immer nur um ein Vielfaches dieser 8 Sub-Schritte ansteuern kann.
Was willst du denn selber mit diesem Motor noch so anstellen? Einfach
nur so mal drehen lassen ist doch etwas langweilig.
(Mein eigenes Projekt mit 2 dieser Motoren:
Beitrag "Plotter aus Billig-Steppern ( 28BYJ-48)")
Stefan Geheim schrieb:> Stepper.jpg> 2 MB, 18 Downloads
Auf den ersten Blick würde ich sagen: "Arduino mit simplem Treiber,
einem Stepper und ein paar Kabeln".
Was sollen mir diese 2MB sonst noch sagen?
wieder ab.
Wenn du hier ein <= siehst, musst du hellhörig werden. In mehr als 80%
aller Fälle ist das ein Fehler.
Ein Array mit 8 Elementen
1
inta[8];
bearbeitet man so in einer for-Schleife
1
for(i=0;i<8;i++)
2
machwasmita[i]
das hat nämlich den Vorteil, dass an beiden Stellen im Code dieselbe 8
vorkommt. Wodurch man die beiden Teile im Code per #define auch
zusammenfassen und damit vereinheitlichen kann
1
#define NR_WERTE 8
2
3
inta[NR_WERTE];
4
5
..
6
7
for(i=0;i<NR_WERTE;i++)
8
machwasmita[i]
Nachdem der Präprozessor dann die Textersetzung von 'NR_WERTE' mit dem
Text '8' gemacht hat, steht damit automatisch an beiden Stellen immer
der gleiche Wert. Selbst dann wenn sich dieser Wert mal ändert
1
#define NR_WERTE 15
sorgt dann der Präprozessor dafür, dass die beiden Werte wieder
zusammenstimmen. Er ersetzt ja beide Vorkommen von NR_WERTE durch 15. So
etwas reduziert Fehler und erleichter Anpassungen.
Oder man kann auch so arbeiten
1
inta[]={0,1,2,3}
2
3
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])
4
5
...
6
7
for(i=0;i<ARRAY_SIZE(a);i++)
8
machwasmita[i]
dann rechnet der Compiler selber aus, wie groß er das Arrya aufgrund der
Initialisierung dimensioniert hat. Voraussetzung ist allerdings, das er
das Array auch als Array zu Gesicht bekommt.
Du hast zwar an fast allen Stellen in deinem Programm dieses
berücksicht, wenn du an die Arrays gegangen bist, aber nicht hier
1
...
2
for(inti=0;i<=Steps;i++){//Schleife für Anzahl Schritte
3
...
deine Funktion macht einen 'Schritt' zu viel. Wenn du die Funktion
aufrufst mit
1
MotorMove(MotorLinks,1000,256);
macht sie keine 256 Schritte, sondern 257.
Mal ganz davon abgesehen, dass deine 'Schritte' nicht das sind, was man
gemeinhin unter 'Schritte' eines Schrittmotors versteht.
Sabine schrieb:> Die erreichbare Auflösung ist nicht so besonders,
Nunja bei 512 Schritten/Umdrehung ergibt sich ja ein Schrittwinkel von
c.a. 0.7 Grad. Mit einer Spindel von z.B. 2mm Steigung eine Auflösung
von knapp 0,004 mm. Meiner ansicht nach für die allermeisten Projekte im
Hobbybereich absolut brauchbar.
Mir geht es hier darum die Grundlagen der Mikrokontrollerprogrammierung
ein bisschen zu erforschen und kennenzulernen. Ich möchte dann erstmal
ein kleines Solarpanel damit automatisch ausrichten...
Vielen Dank für den Link, werde mir das mal anschauen, sieht interessant
aus. Ich habe vor Jahren eine komplette 4 Achsen CNC gebaut, gesteuert
durch Mach 3...
Karl Heinz:
vielen herzlichen Dank für deine sehr konstruktive und hilfreiche
Kritik! Solche Kommentare wünscht man sich :-D
1
for(i=0;i<8;i++)
2
machwasmita[i]
Klar da hast du recht, macht für mich auch mehr Sinn...
1
#define NR_WERTE 8
2
3
inta[NR_WERTE];
auch dies ein sehr nützlicher Hinweis. Ich habe jetzt die Anzahl der
Ausgänge und die Anzahl der Muster so definiert. Das macht den Code
flexibler und besser anpassbar... zudem noch übersichtlicher.. :-)
1
for(inti=0;i<=Steps;i++)
uups... das war ein Flüchtigkeitsfehler. Nach 2 Stunden Programmieren
und lernen.. wohl schon etwas müde ;-)
1
Mal ganz davon abgesehen, dass deine 'Schritte' nicht das sind, was man gemeinhin unter 'Schritte' eines Schrittmotors versteht.
Wäre schön wenn du mir das noch genauer erläutern könntest?
Vielen Dank erstmal!!!
Und hier erstmal den korrigierten Code:
1
//Schrittmotorsteuerung für 28BYJ-48 5VDC mit ULN2003A
2
3
#define AnzAusgange 4 //Anzahl der Ausgänge zur Ansteuerung des Motors
4
#define AnzMuster 8 //Anzahl der Muster zur Ansteuerung eines Schritts
5
6
7
//Befehle für Drehrichtung definieren
8
byteMotorStop=0;//wird automatisch am Ende nach Ausführung der Schritte aufgerufen
9
byteMotorRechts=1;//Definition von Rechts und Linksdrehung, bei Bedarf vertauschen
10
byteMotorLinks=2;
11
12
//Schrittabfolge definieren 1 Muster ergibt einen Schritt Vorwärts
13
byteStepValues[AnzMuster][AnzAusgange]={
14
{0,0,0,1},
15
{0,0,1,1},
16
{0,0,1,0},
17
{0,1,1,0},
18
{0,1,0,0},
19
{1,1,0,0},
20
{1,0,0,0},
21
{1,0,0,1},
22
};
23
24
//Motor Pins für Ausgänge 1-4 definieren (auf ->> Eingänge ULN2003A)
25
byteMotor_Ausgaenge[AnzAusgange]={10,11,12,13};
26
27
28
// the setup routine runs once when you press reset:
29
30
voidsetup(){
31
32
//Serial.begin(9600); //zu Testzwecken Debuggen
33
34
//Alle Pins als Ausgänge setzen und auf LOW schalten
35
for(bytei=0;i<AnzAusgange;i++){
36
pinMode((Motor_Ausgaenge[i]),OUTPUT);
37
digitalWrite(Motor_Ausgaenge[i],LOW);
38
}
39
40
}
41
42
// the loop routine runs over and over again forever:
> Auf den ersten Blick würde ich sagen: "Arduino mit simplem Treiber,> einem Stepper und ein paar Kabeln".>
Genau! Das hast du richtig erkannt :-)
> Was sollen mir diese 2MB sonst noch sagen?
Ich denke das reicht doch oder? Ist ja schon eine ganze Menge....
Stefan Geheim schrieb:> Ich denke das reicht doch oder? Ist ja schon eine ganze Menge....
Dafür, dass die Datenmenge 20000 mal so groß ist, wie der
zusammenfassende Satz, würde ich doch noch etwas mehr Information
erwarten.
Mal ganz davon abgesehen, dass deine 'Schritte' nicht das sind,
2
> was man gemeinhin unter 'Schritte' eines Schrittmotors versteht.
3
>
>> Wäre schön wenn du mir das noch genauer erläutern könntest?
Dein Schrittmotor macht ja immer 8 Schritte auf einmal, wenn ich ihn
anweise 1 Schritt zu machen. Muss ja nicht sein. Du verschenkst dadurch
ja Auflösung des Motors für nichts.
und achte ein wenig mehr auf deine Codekommentare. Die Hälfte deiner
Kommentare im Code sind sinnlose Kommentare
1
for(inti=0;i<Steps;i++){//Schleife für Anzahl Schritte
das das eine Schleife ist, sehe ich im Code auch so. Und wenn die
Schelifenvariable Step heisst, dann brauchst du mir im Kommentar auch
nicht dazu schreiben, dass es sich um die Schleife für die Anzahl der
Schritte handelt. Das kann ich "zur Not" auch so noch in 2 Sekunden
erraten.
Als Ausgleich sollst du aber anstatt
1
//Motor Rechtsdrehung
2
if(Direction==1){
was besseres schreiben. Du hast dir sooooo schöne Wertedefinitionen
dafür gemacht (ein const davor würde noch guttun)
1
constbyteMotorStop=0;
2
constbyteMotorRechts=1;
3
constbyteMotorLinks=2;
warum benutzt du sie denn nicht?
1
if(Direction==MotorRechts){
dann brauchst du auch den Kommentar nicht. Denn das was mir der
Kommentar erzählt, steht sowieso schon im Code mehr oder weniger im
Klartext. Da steht "Wenn Richtung gleich Rechts". Noch ein paar
Füllwörter dazu gedacht und fertig ist der komplette Satz. Ganz ohne
Kommentar und nur durch Code ausgedrückt.
PS: Einen Schrittmotor brauchst du nicht im eigentlichen Sinne
'Stoppen'. Wenn du keine Schritte machst, dann bewegt sich der auch
nicht. Was du maximal tun kannst, ist alle Spulen stromlos schalten. Das
will man aber meistens nicht wirklich. Denn dann hält der Motor nichts
mehr - er lässt sich dann ganz leicht drehen. Und das will man dann ja
meistens nicht, dass die vom Motor angetriebene Last den Motor
verstellt, weil der keine Kraft hat, die Last an Ort und Stelle zu
halten. Wenn schon, dann willst du das aber ganz sicher dem
Anwendungscode überlassen, ob er das tun möchte oder nicht.
Basisroutinen sollten eine derartig schwerwiegende Entscheidung nicht
für sich selber treffen. Vor allen Dingen dann nicht, wenn es für den
Anwendungscode keine Möglichkeit gibt, das zu umgehen. Ein
1
...
2
MotorMove(MotorMove,0,0);
3
...
kann der Anwendungscode immer aufrufen, wenn er die Spulen stromlos
schalten will. Aber die Umkehrung kann er nicht erreichen. Er kann
keinen
1
MotorMove(MotorRechts,1,1000);
aufrufen und nach vollzogener Bewegung den Motor unter Strom halten,
damit der die Liftkabine, die er gerade hochgezogen hat, auch in der
Station halten kann ohne dass die Kabine mit ihrem Eigengewicht den
Motor in die andere Richtung zurückdreht.
Karl Heinz schrieb:> Dein Schrittmotor macht ja immer 8 Schritte auf einmal, wenn ich ihn> anweise 1 Schritt zu machen. Muss ja nicht sein. Du verschenkst dadurch> ja Auflösung des Motors für nichts.
Genau da hast du natürlich Recht. Da dieser Motor aber stark untersetzt
ist, würde dies immer noch lange reichen für mein gedachtes Projekt. Da
ich aber jetzt ein Programm erstellen möchte welches universell ist,
werde ich das entsprechend abändern.
Vielen Dank für deine Lösung für dieses "Problem". Ich habe mir den Code
durchgeschaut und soweit verstanden.
Elegante Lösung um einen Minuswert zu verhindern... da brauchte ich eine
Weile :)
> if( stepNr == 0 )> stepnr = 7;> else> stepNr--;
Kann es sein dass hier das "byte_t" ein Fehler ist?
> for (byte_t k=0; k < 4; k++)
Würde etwas dagegen sprechen die "oneStepRechts" und "oneStepLinks"
Funktion direkt in die "MotorMove" Funktion einzubauen? Oder hat dies
Nachteile?
Auch was die Kommentare angeht, bin ich mit dir einverstanden. Ich habe
das so aufgebaut, weil ich mit den Kommentaren zuerst ein Gerüst
erstellt habe und dann den Code eingefügt habe... Anfängermethode halt
:-) Ist sicher mit kommender Routine und gut gewählten Namen völlig
überflüssig..
> Als Ausgleich sollst du aber anstatt //Motor Rechtsdrehung> if (Direction == 1){> was besseres schreiben.
Klar ein weiterer Flüchtigkeitsfehler... Ich werde den Code nochmals
überarbeiten und die Namen noch klarer und besser definieren.
> Einen Schrittmotor brauchst du nicht im eigentlichen Sinne> 'Stoppen'. Wenn du keine Schritte machst, dann bewegt sich der auch> nicht.
Das ist mir schon klar, ich habe auch schon eine 4 achsen NC mit
Schrittmotoren gebaut und arbeite seit 20 Jahren als Feinmechaniker. Das
Wort Stop ist hier natürlich ein bisschen unglücklich gewählt.
Eigentlich dient es nur dazu die Motoren Stromlos zu schalten
(Überhitzung/Stromverbruach). Das war auch der Hintergedanke für mein
Projekt "Solarpanel ausrichten". Da macht es natürlich Sinn den Strom
noch für das halten eines Motores zu verpuffen. Da es ein "stark"
übersetzter Getriebemotor ist, reicht das Haltemoment allemal aus... Ev.
könnte man das auch noch über ein Schneckengetriebe verbessern. Aber
eben, der Code soll ja universeller werden. Deshalb stimme ich dir auch
hier wieder zu...
Wahrscheinlich werde ich dies über einen Parameter lösen, wo man diese
Funktion ein und auschalten kann.
Bei der Schrittmotorsteuerung die ich für die NC Fräse verwendet habe,
gab es eine "Stromabsenkungsfunktion" damit die Motoren "halten" und
doch nicht zu heiss werden. Wie wäre dies realisierbar?
Dann bedanke ich mich erneut bei dir für dein Mühe, ich weiss das sehr
zu schätzen... ich habe viel dazu gelernt :-)
Stefan Geheim schrieb:> Bei der Schrittmotorsteuerung die ich für die NC Fräse verwendet habe,> gab es eine "Stromabsenkungsfunktion" damit die Motoren "halten" und> doch nicht zu heiss werden. Wie wäre dies realisierbar?
Mit einem Schrittmotortreiber, bei dem es die Möglichkeit gibt, den
Sollwert für den Strom durch ein Steuersignal zu ändern, z.B. indem man
die Referenzspannung für den Stromsollwert per PWM (mit TP-Filter)
vorgibt.
/////////////// Funktion für Motoransteuerung Ende //////////////////
Jetzt habe ich noch einen Bipolar Stepper vom Betrieb bekommen und werde
diesen mit einem L293D ansteuern und ein paar neue Funktionen einbauen
wie: Stromabsenkungsfunktion, mehrere Motoren, Anfahr/Stop Rampe.
mike schrieb:> Mit einem Schrittmotortreiber, bei dem es die Möglichkeit gibt, den> Sollwert für den Strom durch ein Steuersignal zu ändern, z.B. indem man> die Referenzspannung für den Stromsollwert per PWM (mit TP-Filter)> vorgibt.
Dies wäre also mit dem L293D möglich und dem Bipolarstepper. Ich nehme
an der TP Filter ist da um die Spannung zu glätten? Wie müsste ich
diesen berechnen? Würde sich ohne TP-Filter ev. die Position des Motors
ändern oder würde es auch ohne gehen?
Ohne wirst du ein starkes Rauschen hören, weil sich der Strom in den
Motorwicklungen ständig leicht ändert. Es geht aber auch ohne PWM, in
dem man einen Spannungsteiler aufbaut, den man über einen Transistor
umschalten kann. So z.B.:
http://www.mechapro.de/pdf/3D-Step_Doku_20120915.pdf (Schaltplan S. 7)
Oder einfacher:
http://www.mechapro.de/pdf/tinystep_doku.pdf (Schaltplan auf S. 4)
Mit freundlichen Grüßen
Thorsten Ostermann
Thorsten Ostermann schrieb:> Ohne wirst du ein starkes Rauschen hören, weil sich der Strom in> den> Motorwicklungen ständig leicht ändert.
Hallo Thorsten,
vielen Dank für deinen Hinweis. Ich habe vor Jahren bei dir Bausätze für
die 3d Step, HP Step und Tiny Step gekauft als ich meine NC Maschinen
gebaut habe, welche ich inzwischen leider wieder verkauft habe. Damals
hiess es glaube ich noch NC-Step... Von daher kenne ich auch diese
Stromabsenkungsfunktion. Schön dass es deinen Shop immer noch gibt. Ich
war sehr zufrieden mit den Produkten und dem super Support.
Ich werde mir die Schaltpläne mal anschauen... auf die Idee bin ich gar
nicht gekommen. Ich habe den Motor mit dem L293D mittlerweilen mal
angeschlossen und das Rauschen ist deutlich zu hören... :-)
Ich könnte mir natürlich einfach eine professionelle Karte von dir
kaufen, aber ich möchte ja etwas mehr über Elektronik lernen... (arbeite
als Mechaniker auf NC-Maschinen)
Lässt sich eigentlich mit entsprechend angepassten Strömen auch jeder
beliebige Zwischenwinkel erzeugen, um z.B. einen weicheren Lauf oder
eine höhere Auflösung zu bekommen?
Sabine W. schrieb:> Lässt sich eigentlich mit entsprechend angepassten Strömen auch jeder> beliebige Zwischenwinkel erzeugen,
das nennt sich dann 'Microstepping'
Sabine W. schrieb:> Lässt sich eigentlich mit entsprechend angepassten Strömen auch jeder> beliebige Zwischenwinkel erzeugen, um z.B. einen weicheren Lauf oder> eine höhere Auflösung zu bekommen?
Ja, das nennt sich dann Mikroschrittbetrieb. Die Genauigkeit mit der die
Winkelunterteilung stattfindet, hängt sehr vom Aufbau des Motor ab. Der
Lauf wird auf jeden Fall ruhiger.
Hallo,
bin neu hier und absoluter Noob was Programmieren angeht .
Demzufolge fand ich die anfänglichen Codekommentare einfach klasse auch
wenn für viele überflüssig.
mit dem Code Läuft mein Stepper jetzt , anstatt dieses " delay(1000);"
möchte ich den Befehl mit Tastern ausführen.
Taster an Pin 2,3,4
Pin 2 Start Motor rechts
Pin 3 Stop
Pin 4 Start Motor links.
Die anzahl der Steps kann ich im Sketch ändern und diese soll er per
Tastendruck ablaufen lassem.
Gruß Marcel.