ich möchte mir einen motorbetriebenen Kameraslider bauen (mit Schrittmotor und Arduino UNO). Der Schrittmotor soll den Schlitten ein stück fortbewegen, dann anhalten und dann soll die Kamera vom Arduino ausgelöst werden.
Das Auslösen der Kamera wird hier durch eine LED dargestellt, da ich hier leichter sehe, ob der Code funktioniert.
Ich bin ein Anfänger im Programmieren, bin aber bisher soweit gekommen, dass der Schrittmotor ein Stück läuft, anhält, läuft usw.
In den Pausen soll die LED immer eine Sekunde aufleuchten (Kamera wird ausgelöst). In meinen Augen funktioniert der Code, aber die LED leuchtet genau umgekehrt; d.h. sie leuchtet die ganze Zeit und geht dann für eine Sekunde aus. Was mache ich falsch?
Hier gibt's noch ein Video meines Aufbaus: - YouTube
Hallo!
Wenn ich das in deinem Video richtig sehe, hängt deine LED + Vorwiderstand zwischen +5V und D12 und D12 ist LOW während dein Stepper dreht - klar, dass sie dann leuchtet.
Es gibt 2 Möglichkeiten das zu ändern:
entweder Code:
Fototobi94:
ich möchte mir einen motorbetriebenen Kameraslider bauen (mit Schrittmotor und Arduino UNO). Der Schrittmotor soll den Schlitten ein stück fortbewegen, dann anhalten und dann soll die Kamera vom Arduino ausgelöst werden.
Und das immer wieder und wieder?
In dem Fall mußt Du Deine Variable "var" entweder als static deklarieren oder die Deklaration außerhalb der loop-Funktion als globale Variable machen.
static int var = 0;
Und wenn der Vorgang mehrmals in Wiederholung laufen soll, muß "var" beim Ansteuern der led auch wieder von 1000 auf 0 zurückgesetzt werden.
Ja. Die Sliderschiene ist 1m lang. Am ende werden sich später zwei Reed-Kontakte befinden (d.h. wenn HIGH, dann STOP)
jurs:
In dem Fall mußt Du Deine Variable "var" entweder als static deklarieren oder die Deklaration außerhalb der loop-Funktion als globale Variable machen.
static int var = 0;
Und wenn der Vorgang mehrmals in Wiederholung laufen soll, muß "var" beim Ansteuern der led auch wieder von 1000 auf 0 zurückgesetzt werden.
if(var == 1000)
{
var=0;
...
Erstmal DANKE, dass es hier so schnell so viele Antworten gibt.
Das mit den +5V und P12 habe ich nicht beachtet. Jetzt hängt die LED an GND und P12 und blinkt wirklich nur eine Sekunde auf.
Bisher funktioniert der Code also. Würde er mit deinem Vorschlag ('Var') besser funktionieren? Denn momentan wiederholt sich der schritt ja auch immer wieder.
Die LED soll nun durch ein Reed-Relais ersetzt werden, damit der Stromkreis des Arduinos von dem der Kamera getrennt wird.
Dann werde ich wie eben beschrieben, die 2 Reed-Kontakte anschließen und einprogrammieren.
Ich denke, das schaffe ich alleine, falls nicht, werde ich mich wieder melden
Fototobi94:
Bisher funktioniert der Code also. Würde er mit deinem Vorschlag ('Var') besser funktionieren?
Nochmal drübergeschaut: Nein, die Funktion würde gleich sein.
Da Du Code schreibst, der den Ablauf jedesmal blockiert während der Schrittmotor läuft oder die LED blinkt und Du jeden Durchlauf Deines Codes mit Nullsetzen von "var" beginnst
int var = 0;
hat die Variable var dann auch stets einen definierten Wert, ohne dass "var" als global oder static definiert sein braucht.
Mein Hinweis wäre für nicht-blockierenden Code in einem Programm ohne "Busy Waiting" im Ablauf nützlicher gewesen, bei einem Programm, das mehrere Dinge "gleichzeitig" steuern kann.
Ich hab den Code trotzdem geändert. Sieht besser aus
Wie kann ich denn den loop stoppen? Wenn einer der beiden Reed-Kontakte am Ende betätigt wird, ist ein Pin am Arduino HIGH.
Ich wollte mit einer if-Abfrage diesen Pin abfragen. Wenn HIGH, dann soll alles anhalten. Könnte man das lösen, indem man die Variable auf einen größeren Wert als 2000 stellt?
jurs:
Du könntest den Pin abfragen, und falls er HIGH ist einfach eine Endlosschleife starten.
Dann hängt der Controller in der Endlosschleife bis zum nächsten Reset.
Macht aber einen ziemlich kaputten Eindruck, wenn nichts mehr geht ausser dem Reset -Taster.
Langfristig wirst du dich schämen, sowas gebaut zu haben.
Wenn du Endschalter hast, dreh doch die Richtung um.
Auch blinken per delay ist unschön, wenn man was interaktives bauen will.
In der Regel soll was blinken während ein Motor was bewegt, und nicht umgekehrt.
Ich hab's jetzt folgendermaßen gelöst. Im Loop wird 2x abgefragt, ob der "endschalter'' (pin 4) HIGH ist. Jeweils nach dem bewegen des Schrittmotors und nach dem Blinken der LED. Wenn ich den Schalter betätige, stoppt das auch. Allerdings erst nachdem der Motor alle Schritte gefahren ist. Er hört sich nicht einfach auf zu drehen, sondern die While Schleife läuft erst durch, bis var=2000 ist.
int stepper = 3; //Steps
int DIR = 2; //Richtung
int led = 12; //LED
int endschalter = 4; //REED-Kontakte am Ende des Sliders (2x)
static int var = 0;
void setup() {
pinMode(4,INPUT);
pinMode(stepper, OUTPUT);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
digitalWrite(
}
void loop() {
digitalWrite(led, LOW);
while(var < 2000){
var++;
digitalWrite(led, LOW);
digitalWrite(stepper, HIGH);
delay(1);
digitalWrite(stepper, LOW);
delay(1);
}
while(digitalRead(endschalter) == HIGH){
digitalWrite(led, LOW);
digitalWrite(stepper, LOW);
}
if(var == 2000)
{
var=0;
delay(700);
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(300);
}
while(digitalRead(endschalter) == HIGH){
digitalWrite(led, LOW);
digitalWrite(stepper, LOW);
}
}
Die Richtungsänderung wollte ich übrigens nicht automatisch machen, sondern immer von Hand umschalten (mit einem einfachen Umschalter)
die While Schleife läuft erst durch, bis var=2000 ist.
ja, das hast du so programmiert.
delay und while ist beides Mist.
loop würde gern immer wieder durchlaufen werden, wenn du es lässt.
Ein loop -Durchlauf braucht nur einen Schritt deines Steppers lang zu sein. var machst du entweder global ( ausserhalb von loop definieren oder als static Variable.
Und eine Abfrage, ob die LED lang genug an war. ( s. BlinkWithoutDelay Tutorial )
Und die Abfrage auf den Endschalter und den Richtungs-Umschalter ...
Ich habe den Code jetzt soweit umgeschrieben, dass ein Loop-Durchlauf auch nur ein Schritt lang ist. Der Motor läuft wie vorher auch schön im Intervall Und sobald ich den Reedschalter betätige, stoppt der Motor.
Danke michael_x !! ;D
Ich habe mir erlaubt, noch einen Alarm einzubauen, damit ich auch merke, dass der Motor aus ist:
Als nächstes werde ich den Taster durch die Reedschalter und die LED durch ein Reed-Relais ersetzen. Später brauche ich noch 2 Potentiometer, mit denen ich die anzahl der Steps und die Wartezeit nach dem Auslösen der Kamera einstellen kann.
Welche nimmt man da so?
int DIR = 2; // Richtung
int stepper = 3; // Schritte
int endschalter = 4; // Reedkontakte (2x)
int summer = 5; // akustisches Signal bei STOP
int kamera = 12; // Auslösesignal der Kamera
int var = 0; // deklariert Variable var mit Wert 0
int x = 0; // deklariert Variable x mit Wert 0
void setup(){
pinMode(DIR,OUTPUT);
pinMode(stepper,OUTPUT);
pinMode(kamera,OUTPUT);
pinMode(summer,OUTPUT);
pinMode(endschalter,INPUT);
digitalWrite(kamera,LOW);
}
void loop(){
digitalWrite(stepper,HIGH);
delay(2);
digitalWrite(stepper,LOW);
delay(2);
var++;
if(var == 400){
delay(500);
digitalWrite(kamera,HIGH);
delay(500);
digitalWrite(kamera,LOW);
var = 0;
}
while(digitalRead(endschalter) == HIGH){
digitalWrite(stepper,LOW);
digitalWrite(kamera,LOW);
while(x < 100){
x++;
digitalWrite(5,HIGH);
delay(2);
digitalWrite(5,LOW);
delay(2);
}
while(x < 300){
x++;
digitalWrite(5,HIGH);
delay(1);
digitalWrite(5,LOW);
delay(1);
}
if(x < 500){
x = 0;
}
}
}
Später brauche ich noch 2 Potentiometer, mit denen ich die anzahl der Steps und die Wartezeit nach dem Auslösen der Kamera einstellen kann.
Welche nimmt man da so?
Hängt nur davon ab, was für einen Drehknopf du dir leisten willst. Der bestimmt den Preis. Sonst passt jedes Poti (nimm was zwischen 1k und 20k)
Linear oder logarithmisch wäre eine interessante Frage:
Wenn du zwischen 1 und 10000 Schritten wählen willst, was soll in Mittelstellung sein: 100 oder 5000 ?
Kannst du natürlich auch per Software machen, aber wenn du das Poti extra aussuchst...
Äh, schicker ist natürlich heutzutage ein Endlos-Drehencoder und eine numerische Anzeige, aber deutlich komplizierter, auch wenn man dafür natürlich Code findet.
Ich habe die Auslöseverzögerung nun mit einem Druckknopf gelöst. Pro 1x Drücken steigt die zeit um 500ms.
Beim Motor brauche ich allerdings das Poti. Ich habe habe das Poti aus meinem Starterset (glaube 10k Ohm) angeschlossen und den Wert als Schrittanzahl definiert. Normalerweise sollte der Motor von 0-1023 Schritten Alles ermöglichen. In der Mitte bewegt sich der Motor noch im Intervall; aber am Anfang und am Ende nicht. Dort hört der Motor nicht auf sich zu drehen.
Liegt das an einem 'billigen' Potentiometer?