Hallo Zusammen,
ich bin grade dabei einen CAm Slider zu bauen - soweit ist alles gut.
Links / rechts (also der Schlitten) wird er mit einem Schrittmotor bewegt.
Die Cam wird auf einem Drehteller befestigt - dieser wir mit mit einem Servo angesteuert.
Jetzt mein Problem:
Sobald die "val" Daten vom Poti an den Servo übertragen werden läuft mein Schrittmotor
um die hälfte langsamer
Hat mir evtl. jemand einen Tipp was ich falsch mache?
Grüße
#include <Potentiometer.h>
#include <Servo.h>
Servo turnTable; // create servo object to control a servo
Potentiometer potentiometer = Potentiometer(0); //a Potentiometer at analog in 0
Potentiometer potiturnTable = Potentiometer(1); //a Potentiometer at analog in 1
#define stepPin 3
#define dirPin 2
const int buttonPin_RL = 7;
int lastbuttonState_RL;
int buttonState_RL;
int dirPinState;
int val;
void setup()
{
// Serial.begin(9600); // open the serial connection at 9600bps
turnTable.attach(8); // attaches the servo on pin 8 to the servo object
pinMode(buttonPin_RL, INPUT); // Switch
pinMode(stepPin, OUTPUT); //stepper pin
pinMode(dirPin, OUTPUT); //direction pin
digitalWrite(dirPin, HIGH); //sets the direction one way
digitalWrite(stepPin, LOW); //starts the steppin'
}
void loop() {
turntable();
stepper();
}
void stepper(){
digitalWrite(stepPin, HIGH);
delayMicroseconds(1 + potentiometer.getValue());
digitalWrite(stepPin, LOW);
delayMicroseconds(1 + potentiometer.getValue());
lastbuttonState_RL = buttonState_RL ;
buttonState_RL = digitalRead(buttonPin_RL);
if (buttonState_RL != lastbuttonState_RL)
if (buttonState_RL == HIGH)
{ if (dirPinState == LOW)
{ dirPinState = HIGH;
} else {
dirPinState = LOW;
}
}
digitalWrite(dirPin, dirPinState);
}
void turntable() {
val = potiturnTable.getValue(); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
turnTable.write(val); // sets the servo position according to the scaled value
}
Hallo Uwe,
kann ich so nicht sagen - der Servo hat eine normale Geschwindigkeit.
Der Schrittmotor ist, sobald eben der Servo eingebunden ist, um die Hälfte langsamer.
Ich werde heute Abend mal einen Zähler vor den Servo hängen, da mit der Poti des Servo nicht immer ausgelesen wird.
Sondern nur jedes 10. oder 20. mal...
Aber vll. gibt es noch ander Ideen und Ansätze.
Hab auch schon das NT gegen ein 12V PC NT getauscht - brachte auch nichts.
Schrittmotortreiber ist der EasyDriver 4.4 von Sparkfun.
und meinem alten Hameg 203-4 Oszilloskop gemessen, wie lange der Arduino für das Servo.write() braucht. Das ist zwar nicht so genau, wie mit einem von diesen neuen Digital-Oszilloskopen, aber die Größenordnung dürfte hinkommen.
Ich kam da auf 68 µS für das Servo.write(); Das entspricht also einem delayMicroseconds(68);
Wenn Du Dir vorstellst, dass Du im loop()
void loop() {
delayMicroseconds(68);
stepper();
}
stehen hast, kann der Schrittmotor schon gebremst werden.
Eine Lösung wäre vielleicht, den Servo nur alle 100 ms oder so anzusteuern. Das sollte für eine Einstellung über ein Poti immer noch ausreichend schnell sein, handelt Dir aber nur 10 mal pro Sekunde die Verzögerung von 68 ms ein.
Gruß,
Ralf
[Edit:] Habe mich verrechnet, es sind nicht 68 µs sondern 680 µs. Ich will das oben nicht ändern, aber bitte beachten.
Es ist sogar mehr als das. Laut Referenz dauert ein analogRead(), und vermutlich macht die Potentiometer-Klasse genau das, auch schon 100µs. Damit verdreifacht sich die Wartezeit sogar noch.
Ich würde mal sowas wie
void loop() {
if (!(millis() % 100)) turntable();
stepper();
}
probieren. Dann wird turntable() nur alle 100ms aufgerufen. 10x pro sekunde sollte eigentlich reichen, wenn nicht, einfach den Wert anpassen.
Dann wird turntable() nur alle 100ms aufgerufen. 10x pro sekunde sollte eigentlich reichen, wenn nicht, einfach den Wert anpassen.
Das hat aber einen entscheidenden Nachteil. Der Schrittmotor wird nicht mehr gleichmäßig angesteuert.
Wenn nicht bei jedem Schritt auch die Servofunktion turntable() aufgerufen wird gibt es dann schnelle Schritte und langsamere Schritte. Die einzige Lösung die ich sehe ist den Schrittmotor über einen Timer der den Schrittimpuls in einer Interruptroutine abgibt. Der Schrittimpuls muß nicht 50% duty cycle haben, sondern braucht nur 1µS HIGH sein (sie he Datenblatt A3967)
Der EasyDriver 4.4 ist nicht von Sparkfun sondern von Schmalzhaus. Easy Driver stepper motor driver
Wie Steuerst Du den Schrittmotor an? Volschritte oder Microsteps? Welchen Motor verwendest Du?
Hallo Uwe,
klar ist es Schmalzhaus - hab da wohl was verwechselt - angeschlossen ist der Motor wie bei Schmalzhaus beschrieben Easy Driver Examples
Angesteuert über Microstep - also Default wie von Schmalzhaus gezeigt.
mkl0815:
Es ist sogar mehr als das. Laut Referenz dauert ein analogRead(), und vermutlich macht die Potentiometer-Klasse genau das, auch schon 100µs. Damit verdreifacht sich die Wartezeit sogar noch.
Ich würde mal sowas wie
void loop() {
if (!(millis() % 100)) turntable();
stepper();
}
probieren. Dann wird turntable() nur alle 100ms aufgerufen. 10x pro sekunde sollte eigentlich reichen, wenn nicht, einfach den Wert anpassen.
Hallo, hab das jetzt mal probiert und funktioniert wunderbar.
Ist zwar nicht die volle Geschwindigkeit wie ohne Servo aber für mein Vorhaben ausreichend.
(Soll ja kein High-Speed-Slider geben )
@Uwe: Das mit den Interrupts hab ich noch nicht soo wirklich geschnallt - wird aber sicher auch
noch kommen (hoff ich)
Vielen Dank an mkl0815 und an Alle die hier mit gepostet haben.