Hey Ihr Ich habe mir ein neues Projekt vorgenommen. In meiner Freizeit mache ich gerne Videos mit meiner Gopro Hero 4. Jetzt möchte ich mir ein Gerät bauen mit dem ich eine Pan Tilt Time-Lapse auf nehmen kann Wer nicht weis was das ist hier ist ein Link. https://www.youtube.com/watch?v=2U5tpWPP6F4 Ich möchte die mit dem Arduino Uno und 2 Schrittmotoren realisieren. Ich denke der Arduino ist einigen von euch bekannt ich selbst bin aber noch nicht sooo fit. Die Motoren haben folgende Bezeichnung - DC 5V 4 - Phase 5 Draht Micro Elektro Step Motor 28BYJ-48 mit Antrieb Modulplatine ULN2003 Soweit ich mich bis jetzt informiert habe sind diese sogar mit dem Arduino kompatibel. Meine Frage ist jetzt einmal Kann ich die Schrittmotoren überhaupt so steuern das sie z.B. pro sekunden oder 2 Sekunden nur einen Step machen oder geht das und reicht die Kraft dazu aus. Der untere Motor muss ja den Tilt Motor und die Gopro drehen. und desweiteren. kann ich auch irgendwie ein Limit setzten das er sich nicht mehr als einmal um die eigene Achse dreht (wegen den Kabel ist das sehr wichtig) Wer Lust hat bisschen mit zu planen einfach melden :)) VG Tim
Wie viele Steps du in der Stunde machst, legst du in deinem Programm fest. Wenn das ganze leichtgängig ist, reicht die Kraft sicher aus. Du rechnest dir aus wie viele Schritte eine ganze Umdrehung sind, zählst diese Schritte mit und wenn das Maximum erreicht ist, dann halt.
Timelapse schrieb: > Die Motoren haben folgende Bezeichnung - DC 5V 4 - Phase 5 Draht Micro > Elektro Step Motor 28BYJ-48 mit Antrieb Modulplatine ULN2003 > Soweit ich mich bis jetzt informiert habe sind diese sogar mit dem > Arduino kompatibel. > > Meine Frage ist jetzt einmal > Kann ich die Schrittmotoren überhaupt so steuern das sie z.B. pro > sekunden oder 2 Sekunden nur einen Step machen oder geht das und reicht > die Kraft dazu aus. Diese Motoren sind kleine Spielzeug-Steppermotoren, die sich mit einem Arduino prima ansteuern lassen. Die haben ein angeflanschtes Getriebe aus gestanzten Blech-Zahnrädern, das eine Untersetzung der Rotation von ca. 1:64 ins Langsame vornimmt. Und Langsamkeit ist eher nicht das Thema: Wenn Du willst, dann kannst Du die Steper so ansteuern, dass sie pro Woche oder pro Monat einen Schritt machen. Mit hoher Geschwindigkeit sieht es eher schlecht aus: Bereits eine Abtriebsdrehzahl von 1 U/s ist an der Getriebewelle nicht mehr zu schaffen. Aber langsamer geht immer. Begrenzung des Drehwinkels mußt Du Dir bei Bedarf selber bauen, entweder in Deiner Software, oder per Hardware, z.B. über Endschalter.
okay cool danke euch beiden für die zügige Antwort. Dann habe ich jetzt meine Beschäftigung für den anstehenden Urlaub :))
Hubert G. schrieb: > Wenn das ganze leichtgängig ist, reicht die Kraft sicher aus. Leichtgängigkeit hat was mit Reibung zu tun, Kraft des Motors wird üblicherweise als Drehmoment bezeichnet und je besser die Mimik austariert ist, um so weniger Drehmoment muss der Motor aufbringen. Oft kann man das Austarieren durch ein passendes Gegengewichten erreichen.
Hi also die erste achse funktioniert sie dreht sich so wie sie soll. jetzt hab ich allerdings ein problem ich hab das programm aus dem internet und ich schaffe es nicht sozusagen nochmal die gleiche funktion rein zu bekommen für den 2 motor ich mag ihn aber seperat steuern. hier das programm //declare variables for the motor pins int motorPin1 = 2; // Blue - 28BYJ48 pin 1 int motorPin2 = 3; // Pink - 28BYJ48 pin 2 int motorPin3 = 4; // Yellow - 28BYJ48 pin 3 int motorPin4 = 5; // Orange - 28BYJ48 pin 4 // Red - 28BYJ48 pin 5 (VCC) int motorSpeed = 9999; //variable to set stepper speed int count = 0; // count of steps made int countsperrev = 200; // number of steps per full revolution int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001}; //////////////////////////////////////////////////////////////////////// ////// void setup() { //declare the motor pins as outputs pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); pinMode(motorPin3, OUTPUT); pinMode(motorPin4, OUTPUT); Serial.begin(9600); } //////////////////////////////////////////////////////////////////////// ////// void loop(){ if(count < countsperrev ) clockwise(); else if (count == countsperrev * 2) count = 0; else anticlockwise(); count++; } //////////////////////////////////////////////////////////////////////// ////// //set pins to ULN2003 high in sequence from 1 to 4 //delay "motorSpeed" between each pin setting (to determine speed) void anticlockwise() { for(int i = 0; i < 8; i++) { setOutput(i); delay(200); } }
Timelapse schrieb: > jetzt hab ich allerdings ein problem ich hab das programm aus dem > internet und ich schaffe es nicht sozusagen nochmal die gleiche funktion > rein zu bekommen für den 2 motor ich mag ihn aber seperat steuern. Ich kann nicht nicht mal ansatzweise erkennen, dass Du es probiert hättest. Da sind ja nicht mal Pin-Nummern für den zweiten Stepper deklariert. > hier das programm > ... > delay(200); Jede Programmlgik mit "delay()" kannst Du komplett vergessen. Ein Arduino UNO wird mit 16 MHz getaktet, das sind 16 Millionen Instruktionen pro Sekunde. Aber mit "delay()" blockierst Du nur die Programmausführung. Und zwar delay(200) für 0,2s = 16 Mio. * 0,2 = 3,2 Millionen Instruktionen. Wenn Dein zweiter Motor mit exakt demselben delay() laufen soll wie der erste, dann wäre das kein Problem und Du kannst beide Motoren innerhalb Deiner delay-Schleife synchron ansteuern: Macht der eine eine Schritt, dann macht auch der andere einen Schritt. Und wenn delay-Pause ist, machen beide Motoren gleichlange Pause. Sobald beide Motoren mit unterschiedlichem Takt steppen sollen, kannst Du delay komplett in die Tonne schmeißen, das funktioniert nicht.
okay- also doch ich hab schon sehr viel herum probiert. habe aber immer wieder strg+Z... das ist ja genau das problem die motoren sollen nicht synchron laufen sonder der eine ca halb so langsam. hab es so probiert hat auch nicht geklappt //declare variables for the motor pins int motorPin1 = 2; // Blue - 28BYJ48 pin 1 int motorPin2 = 3; // Pink - 28BYJ48 pin 2 int motorPin3 = 4; // Yellow - 28BYJ48 pin 3 int motorPin4 = 5; // Orange - 28BYJ48 pin 4 int motorPin6 = 8; // Blue - 28BYJ48 pin 6 int motorPin7 = 9; // Pink - 28BYJ48 pin 7 int motorPin8 = 10; // Yellow - 28BYJ48 pin 8 int motorPin9 = 11; // Orange - 28BYJ48 pin 9 // Red - 28BYJ48 pin 5 (VCC) int motorSpeed = 9999; //variable to set stepper speed int count = 0; // count of steps made int countsperrev = 200; // number of steps per full revolution int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001}; //////////////////////////////////////////////////////////////////////// ////// void setup() { //declare the motor pins as outputs pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); pinMode(motorPin3, OUTPUT); pinMode(motorPin4, OUTPUT); pinMode(motorPin6, OUTPUT); pinMode(motorPin7, OUTPUT); pinMode(motorPin8, OUTPUT); pinMode(motorPin9, OUTPUT); Serial.begin(9600); } //////////////////////////////////////////////////////////////////////// ////// void loop(){ if(count < countsperrev ) clockwise(); else if (count == countsperrev * 2) count = 0; else anticlockwise(); count++; } //////////////////////////////////////////////////////////////////////// ////// //set pins to ULN2003 high in sequence from 1 to 4 //delay "motorSpeed" between each pin setting (to determine speed) void anticlockwise() { for(int i = 0; i < 8; i++) { setOutput(i); delay(5); } } void clockwise() { for(int i = 7; i >= 0; i--) { setOutput(i); delay(5); } } void setOutput(int out) { digitalWrite(motorPin1, bitRead(lookup[out], 0)); digitalWrite(motorPin2, bitRead(lookup[out], 1)); digitalWrite(motorPin3, bitRead(lookup[out], 2)); digitalWrite(motorPin4, bitRead(lookup[out], 3)); digitalWrite(motorPin6, bitRead(lookup[out], 0)); digitalWrite(motorPin7, bitRead(lookup[out], 1)); digitalWrite(motorPin8, bitRead(lookup[out], 2)); digitalWrite(motorPin9, bitRead(lookup[out], 3));
Vergiss die ULN2003 Treiber und kauf Dir A4988 Treiber, z.B.: http://www.ebay.de/itm/Geeetech-Stepper-driver-A4988-with-heatsink-for-RAMPS-GT2560-Prusa-3D-Printer-/281834393156?hash=item419ea38e44:g:ZE8AAOSwyQtVzq0f (Die bekommt Du auch hier, allerdings teurer) Versorge die mit 9V bis 12V und die kleinen Motörchen haben dann wenigstens etwas Drehmoment. Deine Arduino-Software vereinfacht sich damit auch wesentlich, weil die A4988 Boards nur jeweils Takt- und Richtungs-Signale brauchen.
Albert M. schrieb: > Deine Arduino-Software vereinfacht sich damit auch wesentlich, weil die > A4988 Boards nur jeweils Takt- und Richtungs-Signale brauchen. Das ist nicht das Problem. Die delay sind das Problem bzw. die ganze Art und Weise wie das Programm aufgezogen ist. So wird das nichts. Bei den Arduino Tutorials gibt es ein Beispiel einer blinkenden Led, bei der das Blinken nicht mittels delay sondern über Zeitvergleiche durch millis() gemacht wird. Das ist die grundsätzliche Basistechnik, wie man auf einem Arduino mehrer Dinge quasi gleichzeitig unabhängig voneinander ablaufen lassen kann. Und so
1 | void clockwise() |
2 | {
|
3 | for(int i = 7; i >= 0; i--) |
4 | {
|
5 | setOutput(i); |
6 | delay(5); |
7 | }
|
wird das auch nichts. Aus dem blinkenden LED Beispiel holst du dir die Basistechnik, wie man zeitgesteuert zu einem bestimmten Zeitpunkt eine Aktion machen kann. Und genau das benutzt du. Wenn für einen Motor die Zeit gekommen ist, einen Schritt zu machen, dann macht er genau diesen einen Schritt und nur diesen einen Schritt. Und es wird vermerkt wann der nächste Schritt zu machen ist. Aber
1 | void setOutput(int out) |
2 | {
|
3 | digitalWrite(motorPin1, bitRead(lookup[out], 0)); |
4 | digitalWrite(motorPin2, bitRead(lookup[out], 1)); |
5 | digitalWrite(motorPin3, bitRead(lookup[out], 2)); |
6 | digitalWrite(motorPin4, bitRead(lookup[out], 3)); |
7 | digitalWrite(motorPin6, bitRead(lookup[out], 0)); |
8 | digitalWrite(motorPin7, bitRead(lookup[out], 1)); |
9 | digitalWrite(motorPin8, bitRead(lookup[out], 2)); |
10 | digitalWrite(motorPin9, bitRead(lookup[out], 3)) |
nicht beide Motoren gleichzeitig, sondern jeder für sich.
:
Bearbeitet durch User
Karl H. schrieb: > Das ist nicht das Problem. > > Die delay sind das Problem bzw. die ganze Art und Weise wie das Programm > aufgezogen ist. So wird das nichts. Karl Heinz, ich wollte dem TO nur einen Hinweis geben wie er den Mini-Motoren ein wenig Kraft beibringt. Warum die Arduino Anfänger immer so verliebt in das Delay sind ist mir bis heute ein Rätsel.
Albert M. schrieb: > Warum die Arduino Anfänger immer > so verliebt in das Delay sind ist mir bis heute ein Rätsel. Na ja. Irgendwo muss man mal anfangen. Das versteh ich schon. Das Problem ist eher, dass sie dann auf dieser Stufe stehen bleiben und meinen das reicht schon, um das weltbeste Motorsteuerprogramm (in diesem Fall) zu schreiben. Ist wie in einem gewissen Sinne die Taferlklassler. Nachdem sie Addieren können, kann man sich auch mal fragen, warum man denn eigentlich noch Multiplizieren lernen muss. Anstatt 3 * 2 kann man ja schliesslich auch 2 + 2 + 2 rechnen und kriegt auch das richtige Ergebnis. Tut es. Und bei so einfachen Beispielen macht das auch keinen Unterschied. Aber bei 345*872 sieht die Sache dann eben schon anders aus.
Albert M. schrieb: > Vergiss die ULN2003 Treiber und kauf Dir A4988 Treiber, z.B.: > > Ebay-Artikel Nr. 281834393156 > > (Die bekommt Du auch hier, allerdings teurer) > > Versorge die mit 9V bis 12V und die kleinen Motörchen haben dann > wenigstens etwas Drehmoment. Drehmoment reicht vollkommen aus habe es schon aufgebaut läuft auch aber danke. Karl H. schrieb: > Aus dem blinkenden LED Beispiel holst du dir die Basistechnik, wie man > zeitgesteuert zu einem bestimmten Zeitpunkt eine Aktion machen kann. Und > genau das benutzt du. Wenn für einen Motor die Zeit gekommen ist, einen > Schritt zu machen, dann macht er genau diesen einen Schritt und nur > diesen einen Schritt. Und es wird vermerkt wann der nächste Schritt zu > machen ist. okay das sehe ich mir mal an mal sehen ob ich damit dann weiter komme. Danke! Albert M. schrieb: > Karl Heinz, ich wollte dem TO nur einen Hinweis geben wie er den > Mini-Motoren ein wenig Kraft beibringt. Warum die Arduino Anfänger immer > so verliebt in das Delay sind ist mir bis heute ein Rätsel. triff vollkommen zu ich bin ein blutiger anfänger und dachte das ganze ist relativ leich realisierbar
Tim schrieb: > triff vollkommen zu ich bin ein blutiger anfänger und dachte das ganze > ist relativ leich realisierbar Wenn man ein wenig Plan hat, ist es auch nicht besonders schwierig, jeweils 4 Ausgänge in einen von 8 möglichen Zuständen zu schalten. Ich habe zwar irgendwo in der Grabbelkiste so einen Spielzeugstepper liegen, aber nicht hier griffbereit. Ich habe mal was versucht, ohne die Hardware testen zu können:
1 | struct toyStepper_t{ byte bluePin; byte pinkPin; byte yellowPin; byte orangePin; unsigned int stepDelay; bool clockwise; byte curState; unsigned int steps2go; unsigned long lastStepMicros;}; |
2 | |
3 | toyStepper_t stepper[2]={ |
4 | {2,3,4,5, 2000L*100, true, 0, 0, 0 }, |
5 | {8,9,10,11, 4000L*100, true, 0, 0, 0 }, |
6 | };
|
7 | |
8 | const int NUMSTEPPERS= sizeof(stepper)/sizeof(toyStepper_t); |
9 | const byte lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001}; |
10 | |
11 | void updateStepper(byte index, long nowMicros) |
12 | {
|
13 | if (stepper[index].steps2go==0) return; |
14 | if (nowMicros-stepper[index].lastStepMicros >= stepper[index].stepDelay) |
15 | {
|
16 | stepper[index].lastStepMicros= nowMicros; |
17 | if (stepper[index].steps2go>0) |
18 | {
|
19 | stepper[index].steps2go--; |
20 | if (stepper[index].curState>0) stepper[index].curState--; else stepper[index].curState=7; |
21 | setOutput(index, stepper[index].curState); |
22 | }
|
23 | else if (stepper[index].steps2go<0) |
24 | {
|
25 | stepper[index].steps2go++; |
26 | if (stepper[index].curState<7) stepper[index].curState++; else stepper[index].curState=0; |
27 | setOutput(index, stepper[index].curState); |
28 | }
|
29 | }
|
30 | }
|
31 | |
32 | void setup() { |
33 | //declare the motor pins as outputs
|
34 | for (int i=0; i<NUMSTEPPERS; i++) |
35 | {
|
36 | pinMode(stepper[i].bluePin, OUTPUT); |
37 | pinMode(stepper[i].pinkPin, OUTPUT); |
38 | pinMode(stepper[i].yellowPin, OUTPUT); |
39 | pinMode(stepper[i].orangePin, OUTPUT); |
40 | setOutput(i, stepper[i].curState); |
41 | }
|
42 | Serial.begin(9600); |
43 | Serial.println("Stepper demo"); |
44 | }
|
45 | |
46 | const unsigned int stepsPerRevolution= 1600; |
47 | |
48 | void loop(){ |
49 | long now=micros(); |
50 | for (int i=0; i<NUMSTEPPERS; i++) |
51 | {
|
52 | updateStepper(i, now); |
53 | if (stepper[i].steps2go==0) |
54 | {
|
55 | stepper[i].clockwise= !stepper[i].clockwise; |
56 | stepper[i].steps2go= stepsPerRevolution; |
57 | }
|
58 | }
|
59 | }
|
60 | |
61 | void setOutput(byte index, byte state) |
62 | {
|
63 | digitalWrite(stepper[index].bluePin, bitRead(lookup[state], 0)); |
64 | digitalWrite(stepper[index].pinkPin, bitRead(lookup[state], 1)); |
65 | digitalWrite(stepper[index].yellowPin, bitRead(lookup[state], 2)); |
66 | digitalWrite(stepper[index].orangePin, bitRead(lookup[state], 3)); |
67 | }
|
Vielleicht magst Du mal probieren, od da etwas passiert. Die verschiedenen Stepper habe ich mit den zugehörenden Variablen in ein stuct-Array gepackt, und in dem Array werden immer alle Stepper (also alle beide) nacheinander abgearbeitet. "steps2go" sind allerdings jetzt direkt "Achtelschritte", also die Unterteilung aus Deinem oben geposteten Programm, dass ein Aufruf von "clockwise()" insgesamt acht Achtelschritte macht, damit die Variable "count" um 1 weitergezählt wird, gibt es so in meinem Beispielcode nicht mehr. Probiers's mal! Wenn Du es nicht zum Laufen bekommst, müßte ich mal die nächsten Tage in meiner Grabbelkiste wühlen und so ein Ding an einem Arduino-Board anschließen, um Sketch und Hardware im Zusammenspiel zu testen. Die Steppgeschwindigkeit habe ich mit 2000L*100 bzw. 4000L*100 relativ langsam eingestellt, also ggf. den Faktor 100 dort herauslöschen oder kleiner einstellen, damit schneller gesteppt wird. [Edit/Nachtrag] Ich sehe gerade, dass die Stepperlogik nochmal überarbeitet werden muss. Ursprünglich wollte ich wohl positive und negative Schritte zählen und damit die Drehrichtung festlegen, aber irgendwie ist steps2go jetzt unsigned und dafür gibt es eine boolsche "clockwise" Variable. Das Zählen der Schritte muss daher überarbeitet werden, bevor das Beispielprogramm funktionieren kann. Dazu habe ich heute aber keine Lust mehr.
:
Bearbeitet durch User
Jürgen S. schrieb: > Probiers's mal! werde ich machen vielen danke ich überarbeite aber gerade nochmal die Hardware habe mir extra stecker und so besorgt :) denke in einer stunde bin ich betriebsbereit. ich lade es dann mal hoch und berichte. Vielen Dank schon mal :) wenn es fertig ist kann ich bei interesse auch mal ein Video hochladen :) Tim
Tim schrieb: > werde ich machen vielen danke ich überarbeite aber gerade nochmal die > Hardware habe mir extra stecker und so besorgt :) denke in einer stunde > bin ich betriebsbereit. Ich habe heute nochmal kurz drübergeschaut, was ich gestern als Code gepostet hatte: Für extra langsame Schritte dürfte der Mikrosekundenzähler mit "unsigned int" zu klein definiert sein, nimm mal besser "unsigned long", also struct-Deklaration
1 | struct toyStepper_t{ |
2 | byte bluePin; byte pinkPin; byte yellowPin; byte orangePin; |
3 | unsigned long stepDelay; bool clockwise; byte curState; |
4 | unsigned int steps2go; unsigned long lastStepMicros; |
5 | };
|
Und die clockwise-Logik in der "updateStepper()" Funktion sollte eher so wie beabsichtigt funktionieren:
1 | void updateStepper(byte index, long nowMicros) |
2 | {
|
3 | if (stepper[index].steps2go==0) return; |
4 | if (nowMicros-stepper[index].lastStepMicros >= stepper[index].stepDelay) |
5 | {
|
6 | stepper[index].lastStepMicros= nowMicros; |
7 | stepper[index].steps2go--; |
8 | if (stepper[index].clockwise) |
9 | {
|
10 | if (stepper[index].curState>0) stepper[index].curState--; else stepper[index].curState=7; |
11 | }
|
12 | else
|
13 | {
|
14 | if (stepper[index].curState<7) stepper[index].curState++; else stepper[index].curState=0; |
15 | }
|
16 | setOutput(index, stepper[index].curState); |
17 | }
|
18 | }
|
Alles wie gesagt, ohne Hardwaretest. Uhrzeigersinn ist eventuell auch vertauscht. Viel Spass beim Experimentieren, bin dann mal weg bis morgen...
Jürgen S. schrieb: > Ich habe heute nochmal kurz drübergeschaut, was ich gestern als Code > gepostet hatte: Für extra langsame Schritte dürfte der > Mikrosekundenzähler mit "unsigned int" zu klein definiert sein, nimm mal > besser "unsigned long", also struct-Deklaration Hab die neuen Codes übernommen und vom Grundprinzip funktioniert es jetzt sehr gut. Ich habe aber allerdings ein wenig Probleme die geschwindigkeit und die Drehung einstellen es sollte folgender Maßen sein. Motor 1 dreht sich um ca 300° in ca 1Stunde Motor 2 dreht sich um 80° in """""""""""""" Ich habe das gefühl mit Jürgen S. schrieb: > toyStepper_t stepper[2]={ > {2,3,4,5, 2000L*100, true, 0, 0, 0 }, > {8,9,10,11, 4000L*100, true, 0, 0, 0 }, > }; mit dem bekomme ich das nicht hin
okay aber ich habe jetzt die richung geändert und jetzt funktioniert es so wie ich mich das vorgestellt habe. ich schaue das ich in den nächsten tagen mal ein video poste :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.