Nabend in die Runde, ich dachte eigentlich das es recht einfach ist, wurde aber eines besseren belehrt. Ich möchte das ein Schrittmotor möglichst genau einem Drehencoder Signal, der an einem anderen Motor hängt, Synchron folgt mit einstellbarem Multiplikator. Die start Position und Endposition soll er sich merken um später im selben Winkel wieder an zu fangen... Soweit so gut, Arduino bietet ja Bibliotheken die aber durch die Interrupts des Encoders nicht sonderlich sauber Laufen. Was ich suche wäre eine Bibliothek ähnlich wie die aus der AppNote von Atmel 466. Also über den Timer gesteuerte Takte samt linearer Rampenfunktion. Eigentlich dachte ich das es ein Tägliches Problem währe und ich die Qual der Wahl habe... Der Stepper wird über Step/Dir angesprochen. 1. Gibt es eine Bibliothek die mit dem Timer arbeitet? 2. Kann man den Quellcode aus der AppNote 466 auf den Mega2560 Anpassen? 3. Wie könnte die Positions Regelung aussehen? Grüße und Danke T
http://interface.khm.de/index.php/lab-log/arduino-stepperlab3-motor-library/ Die habe ich noch gefunden...
mr.T schrieb: > Die start Position und Endposition soll er > sich merken um später im selben Winkel wieder an zu fangen... Das ist das erste Problem, um das du dich kümmern musst - weder der Encoder noch der Schrittmotor haben ohne weiteres eine definierte Nullpunktstellung. Ein Encoder kann eine dritte Spur mit Nullsignal haben, aber die ist erst verwertbar, wenn nach dem Einschalten diese Position überfahren wird. Ein Schrittmotor hat überhaupt keine definierte Nullstellung, die kann man nur extern erzeugen, etwa mit einem Schalter oder einer Lichtschranke, und auch die müssen erst mal angefahren werden. Was auch so funktioniert: beide stehen wie sie eben stehen, nach dem Einschalten bewegt sich der Motor nach links wenn du nach links drehst usw. Du darfst nur nicht im ausgeschalteten Zustand was bewegen. Die Sache ist auch nicht ganz so einfach: wenn der Motor von selbst in Nullstellung fährt, sollte ja auch der Drehgeber auf Null stehen, das tut er aber nicht, es sei denn man baut einen Motor dran... Gruss Reinhard
Hallo, ich verwende zur zeit
1 | #define encoder0PinA 2
|
2 | #define encoder0PinB 3
|
3 | #define resolution 800
|
4 | #define CCW 0
|
5 | #define CW 1
|
6 | |
7 | |
8 | boolean _direction; |
9 | volatile long encoder0Pos = 0; //absolut |
10 | volatile int encoderWPos = 0; //Winkel |
11 | unsigned int tmp = 0; |
12 | unsigned int Aold = 0; |
13 | unsigned int Bnew = 0; |
14 | void setup() { |
15 | pinMode(encoder0PinA, INPUT); |
16 | pinMode(encoder0PinB, INPUT); |
17 | // encoder pin on interrupt 0 (pin 2)
|
18 | attachInterrupt(0, doEncoderA, CHANGE); |
19 | // encoder pin on interrupt 1 (pin 3)
|
20 | attachInterrupt(1, doEncoderB, CHANGE); |
21 | // set up the Serial Connection
|
22 | Serial.begin (115200); |
23 | }
|
24 | void loop(){ |
25 | //Check each changes in position
|
26 | if (tmp != encoder0Pos) { |
27 | Serial.println(encoder0Pos, DEC); |
28 | Serial.println(encoderWPos, DEC); |
29 | Serial.println(_direction, DEC); |
30 | tmp = encoder0Pos; |
31 | }
|
32 | delay(500); |
33 | }
|
34 | // Interrupt on A changing state
|
35 | void doEncoderA(){ |
36 | Bnew^Aold ? encoder0Pos++:encoder0Pos--; |
37 | Bnew^Aold ? encoderWPos++:encoderWPos--; |
38 | Bnew^Aold ? _direction = CW :_direction = CCW ; |
39 | |
40 | // winkelpositionen !! 0 und resolution liegen auf einem punkt, 0 = resolution!!
|
41 | if (encoderWPos >= resolution ){encoderWPos = 0; } |
42 | if (encoderWPos < 0){encoderWPos = resolution-1 ;} |
43 | Aold=digitalRead(encoder0PinA); |
44 | }
|
45 | // Interrupt on B changing state
|
46 | void doEncoderB(){ |
47 | Bnew=digitalRead(encoder0PinB); |
48 | Bnew^Aold ? encoder0Pos++:encoder0Pos--; |
49 | Bnew^Aold ? encoderWPos++:encoderWPos--; |
50 | Bnew^Aold ? _direction = CW :_direction = CCW ; |
51 | |
52 | // winkelpositionen !! 0 und resolution liegen auf einem punkt, 0 = resolution!!
|
53 | if (encoderWPos >= resolution ){encoderWPos = 0; } |
54 | if (encoderWPos < 0){encoderWPos = resolution-1 ;} |
55 | }
|
das klappt eigentlich ganz gut... jetzt geht es an die Stepper Funktion die eigentlich der encoder0Pos erstmal folgen sollte...
Jetzt wollte ich da noch eine Drehzahl und eventuell Beschleunigungs Erfassung einbauen... grüße und danke Malte
Ich hab das jetzt mit dem Bresenham Algorithmus gut hinbekommen... Nun geht es darum den Schrittmotor noch ein zu koppeln...
http://www.youtube.com/watch?v=E1eEvpV33OQ&feature=youtu.be Läuft nun erstmal... im Anhang die Graphen für Weg und Geschwindigkeit, hab da die jeweiligen Impulse addieren lassen, Rot ist die Geschwindigkeit, Blau der Weg des Schrittmotors... bin erstmal zufrieden. A Sind meine Führungsimpulse, B mein Weg, C die Geschwindigkeit.
ich sitze aktuell an dem selben problem, könntest du mir vielleicht deinen fertigen Code zur Verfügung stellen... stell mich gerade etwas glatt an hab vielen lieben dank für deine Bemühungen Stefan
Hallo zusammen, ich muss zugeben, dass ich in Sachen Arduino noch neu unterwegs bin, jedoch mit Variablen usw. vertraut bin. zum aktuellen Thread hier hätte ich auch eine Frage und zwar habe ich einen Sketch geschrieben in dem der Schrittmotor sich erst mal komplett nach links dreht und im anschluss wieder nach rechts. Nun möchte ich noch eine Wegverfolgung implementieren und habe an der Welle des Steppers einen kleinen [[Drehgeber]https://www.conrad.de/de/iduino-drehgeber-1-st-se055-1485328.html?WT.mc_id=google_pla&WT.srch=1&hk=SEM&insert_kz=VQ&s_kwcid=AL!222!3!98230272297!!!g!!]] angeschlossen. nun dreht sich zwar der Stepper, aber im seriellen Monitor sehe ich nur mit extremer Verzögerung das sich die Position ändert.
1 | #include <Stepper.h> |
2 | |
3 | #define TaktA 8 |
4 | #define TaktB 9 |
5 | |
6 | int SPU = 2048; |
7 | int counter = 0; |
8 | int apos; |
9 | int apos_alt; |
10 | |
11 | Stepper Motor(SPU, 3,5,4,6); |
12 | |
13 | void setup() { |
14 | Motor.setSpeed(15); |
15 | pinMode (TaktA, INPUT); |
16 | pinMode (TaktB, INPUT); |
17 | |
18 | Serial.begin (9600); |
19 | } |
20 | |
21 | void loop() { |
22 | apos = digitalRead(TaktA); |
23 | if (apos!=apos_alt){ |
24 | if (digitalRead(TaktB) !=apos_alt){ |
25 | counter ++; |
26 | } |
27 | else { |
28 | counter --; |
29 | } |
30 | Serial.print("Position: "); |
31 | Serial.println(counter); |
32 | } |
33 | |
34 | Motor.step(2048); |
35 | delay(1000); |
36 | Motor.step(-2048); |
37 | delay(1000); |
38 | |
39 | } |
was mache ich falsch? ich wollte schon das der Zähler synchron hochzählt. Bitte entschuldigt die evlt. dumme Frage, aber wie gesagt in Sachen Arduino bin ich noch neu :-(
Florian B. schrieb: > nun dreht sich zwar der Stepper, aber im seriellen Monitor sehe ich nur > mit extremer Verzögerung das sich die Position ändert. > ... > was mache ich falsch? 1. delay(1000); 2. Formatiere mal deinen Code vernünftig, damit du deine Blöcke siehst Du legst dein Programm 2x für jeweils eine Sekunde lahm. Was erwartest du?
Das mit der 1 Sekunde pause ist so gewollt, aber der Drehgeber zählt während der Drehung des Steppers nicht hoch :-( Soweit ich weiß sind doch µC echtzeitfähig oder?
Florian B. schrieb: > Soweit ich weiß sind doch µC echtzeitfähig oder? Nur, wenn man sie nicht mit delay() blockiert und das Programm entsprechend geschrieben ist. Du aber fragst deinen Encoder in der zeitweise blockierten Schleife ab, so dass der µC jeweils über 1s nicht mitbekommt, was an den Encodereingängen passiert.
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.