habe ein Projekt bei dem ich die Distanz messe. Die Entfernung soll so oft gemessen werden, bis sie kleiner als 25cm ist. Danach sollen die Motoren darunter angesteuert werden. Habe den Code schon so weit fertig, jedoch wird die Distanz nur einmal abgefragt. (Die Distanzmessung und das Programm funktionieren)
Hier der Codeausschnitt:
// z-Achse faehrt aus
digitalWrite(dirPinz,HIGH);
for(int x = 0; x < 14750; x++) {
digitalWrite(6, LOW);
digitalWrite(stepPinz,HIGH);
delayMicroseconds(speedz);
digitalWrite(stepPinz,LOW);
delayMicroseconds(speedz);
}
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;
Serial.print("Distance: ");
Serial.println(distance);
if (distance < 25){
digitalWrite(dirPinz,LOW);
while(digitalRead(zachsevorne) == LOW) {
digitalWrite(stepPinz,HIGH);
delayMicroseconds(speedz);
digitalWrite(stepPinz,LOW);
delayMicroseconds(speedz);
}
digitalWrite(dirPinx,HIGH);
while(digitalRead(referenzx) == LOW) {
digitalWrite(6, HIGH);
digitalWrite(stepPinx,HIGH);
delayMicroseconds(speedx);
digitalWrite(stepPinx,LOW);
delayMicroseconds(speedx);
}
digitalWrite(dirPinx,HIGH);
for(int x = 0; x < 320; x++) {
digitalWrite(stepPinx,HIGH);
delayMicroseconds(speedx);
digitalWrite(stepPinx,LOW);
delayMicroseconds(speedx);
}
digitalWrite(dirPiny,HIGH);
for(int x = 0; x < 1000; x++) {
digitalWrite(stepPiny,HIGH);
delayMicroseconds(speedy);
digitalWrite(stepPiny,LOW);
delayMicroseconds(speedy);
}
delay(500);
digitalWrite(dirPiny,LOW);
while(digitalRead(referenzy) == LOW) {
digitalWrite(stepPiny,HIGH);
delayMicroseconds(speedy);
digitalWrite(stepPiny,LOW);
delayMicroseconds(speedy);
}
digitalWrite(dirPiny,HIGH); // Enables the motor to move in a particular direction
// Makes 200 pulses for making one full cycle rotation
for(int x = 0; x < 500; x++) {
digitalWrite(stepPiny,HIGH);
delayMicroseconds(speedy);
digitalWrite(stepPiny,LOW);
delayMicroseconds(speedy);
}
islevelchecked = false;
isboxselected = false;
lcd.clear();
etage = 0;
spalte = 0;
counter + 1;
}
else{
lcd.print("Bitte zuerst");
lcd.setCursor(0, 1);
lcd.print("Box auswaehlen");
delay(3000);
lcd.clear();
}
break;
default:
Serial.println(key);
}
}
Wir mögen keine Ausschnitte. Das ist nämlich so wie wenn Du die Autoschlüssel suchst aber nur im Bad suchen mußt, in dem Du aber seit Du gekommen bist nicht drin warst.
Gib und bitte den gesamten Sketch.
Grüße Uwe
Dein Sketch ist IMO irre schlecht zu lesen. Die Einrückungen folgen irgendeinem undurchschaubaren (esoterischen?) Muster und viele Zeilen sind länger als 80 Zeichen.
Solchen Code lese ich äußerst ungern und lasse es daher bleiben.
Die Einrückungen folgen irgendeinem undurchschaubaren (esoterischen?) Muster
Na ja. Da hab ich schon Schlimmeres gesehen.
habe ein Projekt bei dem ich die Distanz messe. Die Entfernung soll so oft gemessen werden, bis sie kleiner als 25cm ist. Danach sollen die Motoren darunter angesteuert werden. Habe den Code schon so weit fertig, jedoch wird die Distanz nur einmal abgefragt
Wenn du das keypad und evtl. auch die lcd-Anzeigge rausschmeisst und die Motor-Ansteuerung durch eine Demo simulierst, hast du einen Sketch der zu der Problembeschreibung passt, und anhand dessen wir leicht über dein Problem reden können.
Dein Problem zu verstehen wäre mir übrigens auch recht:
So wie du es beschreibst, wäre dein ganzer Sketch nichts als:
void loop() {
int distance = getDistance(trigPin, echoPin);
if ( distance > 0 // kein Fehler bei Messung ?
&& distance < 25 ) moveMotors();
}
5 Zeilen ist erstens nicht sehr groß, und macht zweitens das was du willst (lt. deiner Beschreibung)
Beeinflussen die Motoren irgendwie die Entfernung die gemessen wird?
Man könntevoid moveMotors()auch so schreiben, dass es nicht blockiert und währenddessen die Entfernungsmessung weiter läuft. Dann könnte man das Ganze auch um ein keypad erweitern ...
michael_x:
Na ja. Da hab ich schon Schlimmeres gesehen.
Wenn du das keypad und evtl. auch die lcd-Anzeigge rausschmeisst und die Motor-Ansteuerung durch eine Demo simulierst, hast du einen Sketch der zu der Problembeschreibung passt, und anhand dessen wir leicht über dein Problem reden können.
Dein Problem zu verstehen wäre mir übrigens auch recht:
So wie du es beschreibst, wäre dein ganzer Sketch nichts als:
void loop() {
int distance = getDistance(trigPin, echoPin);
if ( distance > 0 // kein Fehler bei Messung ?
&& distance < 25 ) moveMotors();
}
5 Zeilen ist erstens nicht sehr groß, und macht zweitens das was du willst (lt. deiner Beschreibung)
Beeinflussen die Motoren irgendwie die Entfernung die gemessen wird?
Man könnte` void moveMotors() `auch so schreiben, dass es nicht blockiert und währenddessen die Entfernungsmessung weiter läuft. Dann könnte man das Ganze auch um ein keypad erweitern ...
---
` Zeile 579 : counter + 1;` bewirkt übrigens nichts
Danke schon mal für deine Antwort.
Der Sketch ist für einen Getränkeautomaten, der 3 Motoren ansteuert(X,Y,Z). Die Motoren sind dazu da einen Schieber zu positionieren, der dann einen Bolzen an das jeweilige Fach schiebt und das Getränk somit in die Ablage fällt. (Bolzen wird mit einem Relais vorgefahren, der automatisch zurück fährt wenn keine Spannung mehr anliegt) Dies mache ich mit
digitalWrite(6, LOW);
Das Fach in dem das Getränk liegt wird durch das Keypad angesteuert und die LCD-Anzeige gibt Anweisungen. So weit funktioniert auch alles. Ich kann das jeweils gewünschte Fach anfahren.
Jetzt wird der Ultraschallsensor gebraucht um zu überprüfen ob das Getränk auch durch eine Rutsche durchgefallen ist. Die Idee hierbei: Ich messe die Distanz zur Wand (sind etwa 35 cm) und sehe dann wenn das Getränk die Rutsche pasiert hat (<25cm). Schlägt also der Ultraschallsensor an soll der Schieber aufhören vorzufahren. Relais wird wieder abgeschaltet:
digitalWrite(6, HIGH);
Das Problem an meinem Code ist eben, dass durch meinen if Befehl die Distanz nur einmal abgefragt wird. Somit wird die Distanz abgefragt bevor das Getränk überhaupt hätte herausfallen können. Ich bräuchte eine Möglichkeit die Entfernung etwa alle 20ms abzufragen und dann, wenn die Distanz <25cm ist, das Programm erst weiterläuft.
Hast du die Ultraschallmessung als einzelnen Sketch in dem Automaten getestet? Weil Ultraschall hat eine keulenförmige Charakteristik beim messen. U.U. Brauchst du besondere Sensoren mit engem Öffnungswinkel.
Wenn du es kompliziert halten willst, wird die ganze Getränkeausgabe innerhalb eines einzigen loop-Durchlaufs abgehandelt. Auch da hilft dir eine Gliederung in mehrere Funktionen.
while(getDistance() > 25 ) {} // nichts tun
... wäre prinzipiell deine Lösung. Das Haupt-Problem an einer eigenen Schleife ist, dass du da nur über einen Reset wieder rauskommst, wenn mal was schief läuft.
Fehlerbehandlung (was du bisher weggelassen hast) nachträglich bei einem solchen Konzept hinzufügen, ist problematisch, weil du dann das Ganze an vielen Stellen verworren machen musst.
Wenn du es einfacher haben willst, nutzt du die Tatsache, dass loop() beliebig oft und schnell drankommen kann und du dir nur den aktuellen Zustand ( Taster-Wahl / Ansteuerung des Fachs / zurück / ... ) ausserhalb von loop() als globale Variable merken musst.
Im optimalen Fall langweilt sich der Arduino permanent, weil die 20 ms des Ultaschall-Mess-Intervalls noch nicht um sind und ein Stepper-Motor bei normaler Geschwindigkeit viele µs für jeden Schritt braucht.
Da Du nicht dauernd Tasten drückst und die Taste nicht dauernd ">" ist wird das nur einmal ausgeführt.
Außerdem ist die Distanzmessung nicht im der Schleife für die Z Achse
Gewöhne Dir mal an richtig einzurücken; so behälst Du den Überblick wo was in welcher Bedingung bzw Schleife ist.
Speichere die Eingabe ab und starte die Bewegung erst wenn die Eingabe bestätigt wird.
Tastendruck -> Eingaben Speichern -> Start -> Motore ansteuern.
Außerdem funktioniert eine Ultraschallmessung in einem ganz oder Teilweise geschlossenen Box sehr schlecht. Nimm Infrarotdistanzmesser.
Die Referenzfahrt solltest Du im setup() machen. Das wird automatisch einmal ausgeführt.
michael_x:
Wenn du es kompliziert halten willst, wird die ganze Getränkeausgabe innerhalb eines einzigen loop-Durchlaufs abgehandelt. Auch da hilft dir eine Gliederung in mehrere Funktionen.
while(getDistance() > 25 ) {} // nichts tun
... wäre prinzipiell deine Lösung. Das Haupt-Problem an einer eigenen Schleife ist, dass du da nur über einen Reset wieder rauskommst, wenn mal was schief läuft.
Fehlerbehandlung (was du bisher weggelassen hast) nachträglich bei einem solchen Konzept hinzufügen, ist problematisch, weil du dann das Ganze an vielen Stellen verworren machen musst.
Wenn du es einfacher haben willst, nutzt du die Tatsache, dass loop() beliebig oft und schnell drankommen kann und du dir nur den aktuellen Zustand ( Taster-Wahl / Ansteuerung des Fachs / zurück / ... ) ausserhalb von loop() als globale Variable merken musst.
Im optimalen Fall langweilt sich der Arduino permanent, weil die 20 ms des Ultaschall-Mess-Intervalls noch nicht um sind und ein Stepper-Motor bei normaler Geschwindigkeit viele µs für jeden Schritt braucht.
Das Problem ist, dass der Arduino einen Wert misst (z.B 39) und dieser Wert dann immer der gleiche ist. Es wird also auch nur einmal gemessen und immer der gleiche Wert mit <25 verglichen. Hat jemand eine Idee wie ich das Problem sonst noch lösen könnte?
richtig:
while(distance > 25 ) {
distance = readsensor(); //also irgendeine Abfrage des Sensors und die Variable distance neu befüllen.
Serial.println(distance);
} // nichts tun
richtig:
while(distance > 25 ) {
distance = readsensor(); //also irgendeine Abfrage des Sensors und die Variable distance neu befüllen.
Serial.println(distance);
} // nichts tun
Danke dir. Habe es jetzt mit folgendem Code hinbekommen:
Daß es jetzt funktioniert ist nur ein Zufall.
Lerne Programmieren und lerne den Sketch besser zu strukturieren und nimm einen Infrarotentfernungsmesser statt Ultraschall.
Grüße Uwe