Ultraschallsensor Signalauswertung

Hallo

ich habe einen Arduino Mega2560 und einen HC-SR04 Ultraschallsensor. Wenn sich ein Objekt ca 10 cm vor dem US befindet soll eine LED angesteuert werden.

Das Grundprogramm habe ich nach folgendem Sketch übernommen:
http://www.robodino.de/2011/12/ultraschall-distanz-sensor-hc-sr04.html

In diesem Fall wird die Enfernung am Serial Monitor angezeigt.
Ich habe schon versucht mit vergleichern zu arbeitern, dass bei 10cm die LED leuchtet.
So habe ich den Sketch erweitert:

pinMode(led, OUTPUT);
val = digitalRead(inPin);

if(val == 15);
{
digitalWrite(led,HIGH);
}

Ich würde mich freuen wenn jemand eine Antwort weiß. Bin noch ein ziemlicher Anfänger :wink:

Vergleich doch einfach die umgerechneten Zentimeter in einer if-Abfrage und setze dann einen Pin auf HIGH, wenn die Bedingung erfüllt ist.

danke für die Antwort. Wo kann ich die umgerechneten Zentimeter abfragen? Ich habe gedacht das ich den inPin auslese...

Steht doch im Code drin. Such mal nach "cm".

ich glaub du verwechselst da was, wenn die variable "val" aus digitalRead() kommt kann sie ja nur einen boolschen wert haben, 15 ist nicht so ganz boolsch :wink: bei dem HC-SR04 misst du die zeit vom senden des signals über den OUTPin und dem level-wechsel des INpins, diese zeit, geteilt durch die doppelte schallgeschwindigkeit (doppelt wegen hin- und rückweg, unbedingt die einheiten beachten) ist dann die gemessene distanz

die variable val habe ich vor void setup mit Integer deklariert. Wenn ich das jetzt richtig verstanden habe muss mein Code so aussehen:

pinmode(led,OUTPUT);
int val = 0;

val = cm;

if(val == 15cm);
{
digitalWrite(led,HIGH);
}

poste doch am besten mal deinen kompletten code, ich glaube du hast ein generelles verständnisproblem und noch nicht so viel erfahrung mit programmierung?

Ich muss mir das morgen nochmal in Ruhe anschauen. Ja das trifft beides zu. Ich habe bisher nur mit FUP wirklich gearbeitet. Bisher kann ich nur die Grundlegenden Dinge :frowning:

Ich benutze diesen Sketch für den HC-SR04:

int TriggerPin = 12; // Digital 12 -> HC-SR04 Trigger
int EchoPin = 13;    // Digital 13 -> HC-SR04 Echo
// HC-SR04 Vcc -> 5V, GNG -> GND

void setup() 
{
  Serial.begin(9600);
}

void loop()
{
  // establish variables for duration of the ping, 
  // and the distance result in inches and centimeters:
  long duration, cm;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(TriggerPin, OUTPUT);
  digitalWrite(TriggerPin, LOW);
  delayMicroseconds(2);
  digitalWrite(TriggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(TriggerPin, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(EchoPin, INPUT);
  duration = pulseIn(EchoPin, HIGH);

  // convert the time into a distance
  cm = microsecondsToCentimeters(duration);
  if (cm <= 500)
  {
    Serial.print(cm);
    Serial.println("cm");
  }
  else Serial.println("Ungueltige Messung ! Entfernung groesser als 5 Meter !!!");
  delay(100);
}

long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}
[quote author=Megaionstorm link=topic=122817.msg924213#msg924213 date=1347689991]

  duration = pulseIn(EchoPin, HIGH);

}

[/quote]

wie wäre es mit duration = pulseIn(EchoPin, HIGH, 13051);
dann würde pulsein nach 13051 mikrosekunden abbrechen und 0 zurückgeben, ansonsten läuft es doch glaube ich unendlich lange durch und behindert das programm am weiteren ablauf?

sorry, ich hab grad mit meinem US ding rumgefriemelt und muss mich korrigieren, hab die rücklaufzeit nicht beachtet, man sollte den doppelten timeout nehmen, also etwa 26100, je nach dem wie man runden will

edit: hab das ganze mal schön in eine funktion ausgelagert... distance(trigger, echo); gibt jetzt die entfernung in cm zurück, wobei trigger und echo die beiden pins des US definieren, das delayMicroseconds könnte vielleicht kürzer oder länger gehalten werden, muss man mal mit rumspielen, ich hab das gefühl das es mehr fehlmessungen (out of range, rückgabewert 0) gibt, wenn es zu kurz eingestellt wird, auf kurze distanzen hab ich allerdings auch mit 50us keine probleme gehabt, die messzeit verkürzt sich hierdurch verständlicher weise, auch der messfehler dürfte geringer werden, wobei ich hier druck- und feuchtigkeitsschwankungen auf kurzen distanzen schon für schlimmer halte...

void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
}

void loop() {
  // put your main code here, to run repeatedly: 
  Serial.println(distance(13,12));
  delay(200);
}

long distance(int trigger,int echo) {
  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);
  long duration, distance;   //distance könnte, wie auch die funktion evtl. als float definiert werden, weiß nur nicht ob die genauigkeit technisch sinnvoll ist
  digitalWrite(trigger, HIGH);
  delayMicroseconds(500);  //hier ein wenig rumprobieren, auf jeden fall aber >10
  digitalWrite(trigger, LOW);
  duration = pulseIn(echo  , HIGH, 26240); //hiermit könnte auch die maximale messreichweite begrenzt werden, ab 300cm muckt meiner ziemlich rum und brauch kleine messwinkel
  distance = (duration/2) / 29.1545;  //hier kann man noch beliebig runden, halte 4 nachkommastellen aber für hinreichend genau, eine dürfte es auch tun (beachte: 29.2 ist korrekte rundung)
  return distance;
  
}

Kopf hoch, ich fand das alles auch sehr schwierig. Ich besorge mir immer den Code und lerne ihn durch rumprobieren zu verstehen.
Besorge dir die Bibliothek Ultrasonic.h, die berechnet alles für dich, dann brauchst du dich am Anfang nicht damit rumschlagen.
Lade diesen Sketch. Schliesse 2 LED an PIN 9 und 8, TriggerPin an 12, EchoPin an 13, öffne den Serial Monitor und schau was passiert. Es ist selbsterklärend.

Viel Spass

#include <Ultrasonic.h>

#define TRIGGER_PIN  12
#define ECHO_PIN     13

Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
int led1 = 9;
int led2 = 8;
void setup()
  {
  Serial.begin(9600);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  }

void loop()
  {
  float cmMsec, inMsec;
  long microsec = ultrasonic.timing();   //funktion, welche die zeit berechnet

  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM); //rechnet die gemessene Zeit in cm um
  inMsec = ultrasonic.convert(microsec, Ultrasonic::IN);   // Inch
  Serial.print("MS: ");
  Serial.print(microsec);
  Serial.print(", CM: ");
  Serial.print(cmMsec);
  Serial.print(", IN: ");
  Serial.println(inMsec);
  delay(100);
  if (cmMsec > 10){                         //hier ist klar was passiert
    digitalWrite(led1,HIGH);
    digitalWrite(led2,LOW);
  }
  else {
    digitalWrite(led1,LOW);
    digitalWrite(led2,HIGH);
  }
  }

so sehr ich fertige libraries mag, aber in diesem fall halte ich die prozeduren zum messen für so einfach, das eine library nur verwirrend ist, weil in dem code, der diese nutzt eben nicht erklärt wird, wie die einzelnen funktionen arbeiten... ich meine der code den ich geschrieben hab ist ein 10-zeiler, dafür muss man sich nicht eine kryptische lib nehmen...

da gebe ich dir vollkommen recht. deinen code werde ich mir auch demnaechst zu gemuete ziehen. lieber etwas eigenes und dafuer verstehen.
ich weiß aber noch, wie schwer es fuer mich war, das ding ueberhaupt zum laufen zu bekommen. ich habe gekotzt :wink:

von daher bleibe ich bei der empfehlung die ich zuvor gab, erstmal ausprobieren und freuen, dann verstehen.
danach schaust du in die bibo, siehst das du vieles nicht brauchst und das die bibo die gleiche formel zum berechnen nimmt und dann ist die zeit gekommen den code von DERDER zu verstehen :wink:

gruß vansen

Vielen Dank für die Hilfe.
So langsam komme ich dahinter^^.
Ich wollte zuerst den Sketch von Vansen ausprobieren. Wenn ich den Sketch laden will kommt eine Fehlermeldung das
bei Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN); kein Datentyp angegeben ist.
Muss ich hierfür die Bibliothek Ultrasonic.h downloaden?

gruß

ja, genau das musst du, und sie in den code einbinden, das ist der sinn einer bibliothek, sie definiert den befehel ultrasonic(), das meinte ich auch damit, das ich bibliotheken eher für verwirrend halte, mein code funktioniert ohne das du eine einbinden musst

So ich habe es hinbekommen. :wink:
Ich habe mir noch 5 weitere Ultraschallsensoren dazubestellt um einen größeren Bereich abzudecken. Ist es möglich eine Art Bibliotheksfähiges Programm zu entwerfen? Oder gibt es hierfür eine andere Vorgehensweise?

bibliotheksfähiges programm? jedes programm sollte fähig sein bibliotheken einzubinden, ich verstehe nicht was du sagen willst... mehrere sensoren gleichzeitig (oder eher sehr schnell hintereinander) zu nutzen ist möglich, zmindest mit dem von mir geposteten code, mit der bibliothek sicherlich auch

naja das "bibliotheksfähig" war in anlehnung an FUP in S7. Ich habe gedacht das vielleicht eine ähnliche Struktur möglich ist. Bei S7 kenne ich es so: man hat einen Funktionsbausein und die jeweiligen Datenbausteine für Anlagen. Das wird sicher nicht so auf die Arduino Umgebung übertragbar sein. Ich habe da in erster Linie an eine Vereinfachung des Programmes gedacht.

Ich möchte 5 Ultraschallsensoren anschließen um eine größere Fläche abzudecken. Wenn einer der Sensoren ein Objekt auf 10cm erkennt soll ein Aktor angesteuert werden (led,Motor...). Die Sensoren sollten wenn möglich gleichzeitig Signale weitergeben.
Genügend DI/DO habe ich mit meinem Mega2560.
Die Frage ist ob so etwas überhaupt mit einem Arduino möglich ist...

gruß

brim arduino kommst du mit imperativer programmierung sicher schneller weiter, falls FUP überhaupt möglich ist. "Gleichzeitig" geht ohnehin nicht, da der arduino alles seriell abarbeitet, aber an sich denke ich, das eine ultraschallmessung in unter einer millisekunde abgeschlossen ist, somit hast du es "gleichzeitig" wenn die anwendung ne auflösung von 5ms verkraftet, was für sehr viele fälle ausreichen sollte