Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : 3 Ultraschallsensoren HC-SR04 einbinden-> finde den Fehler nicht



danilo01
03.08.2019, 21:12
Hallo zusammen,

nach langer Zeit habe ich mal wieder ein Projekt geplant.
Es soll ein Auto Mower werden, vorerst aber erst über Ultras steuerbar.

Jetzt komme ich zu meinem Prob.
Ich kann jeden Ultra für sich alleine ansteuern, aber wenn ich versuche den zweiten einzubinden, passiert nichts mehr oder er fährt nur rückwärts.

ich stehe echt auf dem Schlauch.



#include <NewPing.h>

int trigPinF = 11;
int echoPinF = 12;
int trigPinR = 32;
int echoPinR = 33;
int enA = 2;
int revright = 3;
int fwdright= 4;
int revleft= 5;
int fwdleft = 6;
int enB = 7;

int c = 0;

void setup() {
//Serial.begin(9600);
pinMode(enA, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(enB, OUTPUT);

pinMode(trigPinF, OUTPUT);
pinMode(echoPinF, INPUT);
pinMode(trigPinR, OUTPUT);
pinMode(echoPinR, INPUT);

}

void loop() {

long duration,distanceF,distanceR;
digitalWrite(trigPinF,HIGH);
digitalWrite(trigPinR,HIGH);

delayMicroseconds(1000);

digitalWrite(trigPinF,LOW);
digitalWrite(trigPinR,LOW);

duration=pulseIn(echoPinF,HIGH);
duration=pulseIn(echoPinR,HIGH);
distanceF,distanceR=(duration/2)/29.1;
//Serial.print(distance);
//Serial.println("CM");
delay(10);



if((distanceF>=20&distanceR>=20))
{
moveforward();
}
if(distanceF<20&distanceR>=20)
{
movestop();
delay(400);
movereverse();
delay(3000);
movestop();
}
else if(distanceF>=20&distanceR<20)
{
movestop();
delay(400);
movereverse();
delay(3000);
movestop();
delay(400);
moveleft();
}
}
void moveforward()
{
digitalWrite(4,LOW);
digitalWrite(3,HIGH);
digitalWrite(6,LOW);
digitalWrite(5,HIGH);
analogWrite(enA, 160);
analogWrite(enB, 160);//
}
void moveleft()
{
digitalWrite(4,HIGH);
digitalWrite(3,LOW);
digitalWrite(6,LOW);
digitalWrite(5,HIGH);
analogWrite(enA, 140);
analogWrite(enB, 180);
}
void moveright()
{
digitalWrite(4,LOW);
digitalWrite(3,HIGH);
digitalWrite(6,HIGH);
digitalWrite(5,LOW);
analogWrite(enA, 180);
analogWrite(enB, 140);
}
void movereverse()
{
digitalWrite(4,HIGH);
digitalWrite(3,LOW);
digitalWrite(6,HIGH);
digitalWrite(5,LOW);
analogWrite(enA, 120);
analogWrite(enB, 120);
}
void movestop()
{
digitalWrite(4,LOW);
digitalWrite(3,LOW);
digitalWrite(6,LOW);
digitalWrite(5,LOW);
analogWrite(enA, 0);
analogWrite(enB, 0);
}

Vielleicht kann jemand mal drüber schauen und mir sagen wo der Fehler liegt.
Das wäre mir eine große Hilfe.

Danke schön im voraus.

Gruß Danilo

Moppi
04.08.2019, 05:41
Das wird wohl nicht richtig sein.
Behandle beide Ultraschallsensoren getrennt!
Beispiel:

duration=pulseIn(echoPinF,HIGH); duration=pulseIn(echoPinR,HIGH);



durationF=pulseIn(echoPinF,HIGH); durationR=pulseIn(echoPinR,HIGH);

Rabenauge
04.08.2019, 20:49
Beide gleichzeitig klappt wirklich nicht.
Die _müssen_ einzeln abgefragt werden.
Und: pulseIn() ist blockierend!
Das Standard-Timeout beträgt eine volle Sekunde, in der Zeit kannst du _gar nix_ anderes machen.
Abhilfe: ein kürzeres Timeout bei pulseIn() definieren.

Sisor
04.08.2019, 22:35
Die _müssen_ einzeln abgefragt werden.

Naja, wenn man NUR den nähesten Gegenstand sucht, kann man auch auf allen Sensoren gleichzeitig pingen. Dieser wäre dann in Richtung des Sensors mit der ersten Antwort zu finden.
Dann allerdings nicht mit pulseIn(), da auf mehreren Echopins gleichzeitig abgehört werden müsste.

danilo01
05.08.2019, 21:50
Danke für die Antworten.
Ich habe den Sketch noch komplett überarbeitet.

Der Ablauf stimmt auch fast, leider nur fast.

Als erstes mal der grobe Aufbau. Ist erst mal nur für das programmieren.
Die Kabel bleiben natürlich nicht so;)

34332

Und hier der Sketch:



int frontEchoPin = 12;
int frontTriggerPin = 11;
int leftEchoPin = 30;
int leftTriggerPin = 31;
int rightEchoPin = 33;
int rightTriggerPin = 32;
int enA = 2;
int motorL1 = 5;
int motorL2 = 6;
int motorR1 = 3;
int motorR2 = 4;
int enB = 7;
volatile float maxFrontDistance = 30.00;
volatile float frontDuration, frontDistanceCm, leftDuration, leftDistanceCm, rightDuration, rightDistanceCm;
volatile float maxLeftDistance, maxRightDistance = 30.00;
void setup() {
// serial
Serial.begin(9600);
// ultrasonic
pinMode(frontTriggerPin, OUTPUT);
pinMode(frontEchoPin, INPUT);
pinMode(leftTriggerPin, OUTPUT);
pinMode(leftEchoPin, INPUT);
pinMode(rightTriggerPin, OUTPUT);
pinMode(rightEchoPin, INPUT);
// motors
pinMode(motorL1, OUTPUT);
pinMode(motorL2, OUTPUT);
pinMode(motorR1, OUTPUT);
pinMode(motorR2, OUTPUT);
}
void loop() {
// front distance check
checkFrontDistance();
if (frontDistanceCm < maxFrontDistance) {
Serial.println("Too close");
checkLeftDistance();
delay(100);
checkRightDistance();
delay(100);
if (leftDistanceCm < rightDistanceCm)
{
moveBackward;
delay(100);
moveRight();
}
else if (leftDistanceCm > rightDistanceCm)
{
moveBackward;
delay(100);
moveLeft();
}
}
else {
Serial.println("OK");
moveForward();
}
// left distance check
checkLeftDistance();
if (leftDistanceCm < maxLeftDistance) {
Serial.println("Left too close");
delay(100);
checkFrontDistance();
delay(100);
checkRightDistance();
delay(100);
if (frontDistanceCm > rightDistanceCm)
{
moveForward();

}
else if (frontDistanceCm < rightDistanceCm)
{
moveBackward;
delay(100);
moveRight();

}
}
// right distance check
checkRightDistance();
if (rightDistanceCm < maxRightDistance) {
Serial.println("Right too close");
delay(100);
checkFrontDistance();
delay(100);
checkLeftDistance();
delay(100);
if (frontDistanceCm > leftDistanceCm)
moveForward();
else if (frontDistanceCm < leftDistanceCm)
{
moveBackward;
delay(100);
moveLeft();

}
}
}
void checkFrontDistance() {
digitalWrite(frontTriggerPin, LOW); //para generar un pulso limpio ponemos a LOW 4us
delayMicroseconds(4);
digitalWrite(frontTriggerPin, HIGH); //generamos Trigger (disparo) de 10us
delayMicroseconds(10);
digitalWrite(frontTriggerPin, LOW);
frontDuration = pulseIn(frontEchoPin, HIGH); //medimos el tiempo entre pulsos, en microsegundos
frontDistanceCm = frontDuration * 10 / 292 / 2; //convertimos a distancia, en cm
Serial.print("Distance: ");
Serial.print(frontDistanceCm);
Serial.println(" cm");
}
void checkLeftDistance() {
digitalWrite(leftTriggerPin, LOW); //para generar un pulso limpio ponemos a LOW 4us
delayMicroseconds(4);
digitalWrite(leftTriggerPin, HIGH); //generamos Trigger (disparo) de 10us
delayMicroseconds(10);
digitalWrite(leftTriggerPin, LOW);
leftDuration = pulseIn(leftEchoPin, HIGH); //medimos el tiempo entre pulsos, en microsegundos
leftDistanceCm = leftDuration * 10 / 292 / 2; //convertimos a distancia, en cm
Serial.print("Left distance: ");
Serial.print(leftDistanceCm);
Serial.println(" cm");
}
void checkRightDistance() {
digitalWrite(rightTriggerPin, LOW); //para generar un pulso limpio ponemos a LOW 4us
delayMicroseconds(4);
digitalWrite(rightTriggerPin, HIGH); //generamos Trigger (disparo) de 10us
delayMicroseconds(10);
digitalWrite(rightTriggerPin, LOW);
rightDuration = pulseIn(rightEchoPin, HIGH); //medimos el tiempo entre pulsos, en microsegundos
rightDistanceCm = rightDuration * 10 / 292 / 2; //convertimos a distancia, en cm
Serial.print("Right distance: ");
Serial.print(rightDistanceCm);
Serial.println(" cm");
}
void moveBackward() {
Serial.println("Backward.");
digitalWrite(motorL1, LOW);
digitalWrite(motorL2, HIGH);
digitalWrite(motorR1, LOW);
digitalWrite(motorR2, HIGH);
analogWrite(enA, 100);
analogWrite(enB, 100);
}
void moveForward() {
Serial.println("Forward.");
digitalWrite(motorL1, HIGH);
digitalWrite(motorL2, LOW);
digitalWrite(motorR1, HIGH);
digitalWrite(motorR2, LOW);
analogWrite(enA, 130);
analogWrite(enB, 130);
}
void moveLeft() {
Serial.println("Left.");
digitalWrite(motorL1, HIGH);
digitalWrite(motorL2, LOW);
digitalWrite(motorR1, LOW);
digitalWrite(motorR2, HIGH);
analogWrite(enA, 90);
analogWrite(enB, 100);
}
void moveRight() {
Serial.println("Right.");
digitalWrite(motorL1, LOW);
digitalWrite(motorL2, HIGH);
digitalWrite(motorR1, HIGH);
digitalWrite(motorR2, LOW);
analogWrite(enA, 90);
analogWrite(enB, 100);
}
void moveStop()
{
digitalWrite(4,LOW);
digitalWrite(3,LOW);
digitalWrite(6,LOW);
digitalWrite(5,LOW);
analogWrite(enA, 0);
analogWrite(enB, 0);
}


Mein Problem ist jetzt das der "leftDistance" rum Zickt.
Ich finde der Fehler leider nicht, den Ultra habe ich schon getauscht.
Aber es ist keine Veränderung zu sehen.

34333

Woran könnte es liegen?
An der Verkabelung?
Könnten die Ultras durch die Motoren gestört werden?

Vielleicht kann mir jemand auf die Sprünge helfen.


Gruß

Danilo

RoboHolIC
05.08.2019, 23:05
Nur mal so als Randnotiz:
Ich besitze einige HC-SR04 aus zwei verschiedenen Quellen. Sie unterscheiden sich bei ausbleibendem Echo in ihrer Funktion.
>> Die eine Sorte liefert den *) spezifizierten maximal langen Empfangspuls, der nur knapp länger als derjenige bei maximaler Reichweite ist.
>> Die anderen 'hängen' scheinbar in der Messung fest und der verfälschte Empfangspuls endet erst mit dem nachfolgenden Triggerimpuls (also eine Art Abbruch oder Reset der Messung)

*) 'spezifiziert' meint hier: irgendwo in den Weiten des WWW unter dem Namen 'SR-HC04' gefundene Anleitung; bei Dumpingpreisen darf man realistischerweise nicht allzu viel erwarten.

danilo01
05.08.2019, 23:17
Danke für die Info.
Ich habe zum Glück noch einige von unterschiedlichen Anbietern liegen.
Ich werde sie heute Abend mal einbauen und testen.

Ne ordentliche Verkabelung soll heute auch noch folgen.
Mich nervt das Kauderwelsch.

Sisor
06.08.2019, 18:45
Warum nutzt du nicht NewPing? Im OP hast du's im Code inkludiert. Das würde den Code wartbarer machen und das Timeout-Problem mittels MAX_DISTANCE_CM lösen:


#include <NewPing.h>

//...

#define MAX_DISTANCE_CM 200
NewPing sonarFront = NewPing(frontTriggerPin, frontEchoPin, MAX_DISTANCE_CM);

//...

loop() {

//..

auto front_cm = sonarFront.ping_cm();
Serial.println(front_cm);

//..

}

Rabenauge
07.08.2019, 12:00
Bei mir hatte die NewPing mehr Ärger gemacht, als sie Vorteile haben sollte.
Daher würde _ich_ von abraten. Ist allerdings ne Weile her, möglicherweise wurde da auch einiges gefixt inzwischen.
Man kann auch bei PulseIn ein Timeout angeben: pulseIn(pin, value, timeout)
Siehe: https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/

Sisor
07.08.2019, 14:19
Bei mir hatte die NewPing mehr Ärger gemacht, als sie Vorteile haben sollte.
Daher würde _ich_ von abraten. Ist allerdings ne Weile her, möglicherweise wurde da auch einiges gefixt inzwischen.
Man kann auch bei PulseIn ein Timeout angeben: pulseIn(pin, value, timeout)
Siehe: https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/

Welche Art Ärger gab's denn?

Rabenauge
09.08.2019, 13:34
Das weiss ich nicht mehr- ist ne ganze Weile her (darum sagte ich auch, gut möglich, dass da einiges inzwischen verbessert ist).
Dunkel glaube ich, mich daran zu erinnern, dass es dauernd Hakeleien gab, wenn man wirklich mehrere Sensoren betreiben wollte, bin da aber nicht sicher....

HaWe
09.08.2019, 16:17
Bei mir hatte die NewPing mehr Ärger gemacht, als sie Vorteile haben sollte.
Daher würde _ich_ von abraten.
ich halte solche diffuse Aussagen für absolut nicht hilfreich, v.a. wenn man noch nicht einmal sagen kann welche Version welchen "Ärger" genau gemacht haben soll.
Die Lib gibt es inzwischen in der Version 1.9.x

https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home
https://bitbucket.org/teckel12/arduino-new-ping/downloads/NewPing_v1.9.1.zip

Ich würde sie mal testen, und wenn sie wirklich "Ärger" macht, mal genau beschreiben, welchen, mit Beispiel.
Anfangen würde ich mit 1 USS, und wenn der funktioniert, dann den 2. und dann den 3. mit dazu nehmen.
Was grundsätzlich immer "Ärger" machen kann bei verschiedenen USS nebeneinander sind Zweit- und Dritt-Reflex-Echos, die von den jeweils anderen Sensoren stammen - aber das muss man testen, ggf. neu justieren, Ping-Abstände verlängern, ggf. auch wieder auf 2 USS zurückgehen.

Sisor
09.08.2019, 17:15
ich halte solche diffuse Aussagen für absolut nicht hilfreich, v.a. wenn man noch nicht einmal sagen kann welche Version welchen "Ärger" genau gemacht haben soll.

Sehe ich auch so, darum hatte ich nochmal nachgehakt.
Ich hab den Lib-Code mal überflogen: Wenn man NewPing so benutzt, wie oben von mir beschrieben, kann da nicht viel schief gehen.

Moppi
11.08.2019, 11:35
Mit den Ultraschallsensoren sollte gar nichts schief gehen. Klar muss nur sein:

1. Jeden Sensor einzeln zu verwenden, niemals mehrere parallel (hatte HaWe schon gesagt), ist eigentlich auch klar, wenn man die Funktionsweise betrachtet.
2. Die Sensoren nach Möglichkeit an unterschiedliche Ports hängen, so dass sie auch physisch dort getrennt sind und für die Programmierung.

Ich habe nur mit einem SRF-05 rumprobiert. Die Beispielcodes sind irre einfach und funktionieren einwandfrei.


void loop() { digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);



const unsigned long duration= pulseIn(ECHO_PIN, HIGH);
int distance= duration/29/2;
if(duration==0){
Serial.println("Warning: no pulse from sensor");
}
else{
Serial.print("distance to nearest object: ");
Serial.print(distance);
Serial.println(" cm");
}




Ähnlich sollte es mit den anderen Sensoren auch funktionieren.

MfG