Einparkhilfe Arduino

Hallo,
da ich noch ein Anfänger bin und bei meinem Schulprojekt noch kleinere Schwierigkeiten habe, wollte ich hier mal nach Hilfe fragen.

Und zwar programmiere und baue ich zurzeit eine Einparkhilfe mit dem Arduino. Sie funktioniert bis jetzt auch einwandfrei, jedoch wollte ich sie ein wenig verbessern. Ich habe in meinem Code bestimmte Werte festgelegt, die je nach Entfernung einen von vier bestimmten Tönen ausgeben. Jedoch meinte mein Lehrer es wäre besser, wenn diese Übergänge "flüssig" wären. Leider ist mir auch nach einer Überlegungszeit nicht klar geworden, wie ich hier eine Variable einbaue und diese so verwenden kann, dass sie meinen Zweck erfüllt.

Ich würde mich sehr über eure Hilfe freuen :slight_smile:

int trigger=7; 
int echo=6; 
long dauer=0; 
long entfernung=0; 

const int kurzerTON = 50;
const int leiserTON = 25;
const int mittlererTON = 12;
const int lauterTON = 3;

void setup()
{
Serial.begin (9600); 
pinMode(trigger, OUTPUT); 
pinMode(echo, INPUT); 
}


void loop()
{
digitalWrite(trigger, LOW); 
delay(5); 
digitalWrite(trigger, HIGH); 
delay(10);
digitalWrite(trigger, LOW);
dauer = pulseIn(echo, HIGH); 
entfernung = (dauer/2) * 0.03432; 
if (entfernung >= 500 || entfernung <= 0) 
{
Serial.println("Kein Messwert"); 
}
else 
{
Serial.print(entfernung); 
Serial.println(" cm"); 
}
delay(1000); 

if(entfernung >= kurzerTON)
{
 tone(8, 200);
 delay(500);
 noTone(8);
 delay(400);
} 
else if(entfernung >= leiserTON)
{
  tone(8, 500);
  delay(1000);
  noTone(8);
  delay(300);
}
else if(entfernung >= mittlererTON)
{
  tone(8, 1500);
  delay(1500);
  noTone(8);
  delay(200);
}
else if(entfernung >= lauterTON)
{
  tone(8, 1000);
  delay(2500);
  noTone(8);
  delay(50);
}
}

Schau Dir mal map an.

so in der Art:

if (entfernung <= 50) { // über 50 ist Stille
  unsigned int tonhoehe = map(entfernung,50,1, niedrigerTon, hoherTon);
  tone(8,tonhoehe);
  ...
}

Mit niedrigerTon (200) und hoherTon (2000) musst Du etwas experimentieren, wie es klingt.

Gruß Tommy

Soll die Einparkhilfe für eine Garage sein?

Bedenke, die Verwendung von delay stoppt das Programm eben solange. In der Zwischenzeit kannst du schon an die Wand gefahren sein.
Bau das ganze auf millies um.

Finnlay:
Soll die Einparkhilfe für eine Garage sein?

Bitte den ganzen Beitrag lesen. Im Eröffnungsposting stand:

Adrian11223:
da ich noch ein Anfänger bin und bei meinem Schulprojekt noch kleinere Schwierigkeiten habe, wollte ich hier mal nach Hilfe fragen.

Prinzipiell hast Du mit dem Delay recht, das scheint aber nicht die aktuelle Aufgabenstellung des Lehrers zu sein.

Gruß Tommy

Adrian11223:
Jedoch meinte mein Lehrer es wäre besser, wenn diese Übergänge "flüssig" wären. Leider ist mir auch nach einer Überlegungszeit nicht klar geworden, wie ich hier eine Variable einbaue und diese so verwenden kann, dass sie meinen Zweck erfüllt.

Eine Möglichkeit wäre, die if-Abfragen zu vermehren, um eine feinere "Treppe" zu erhalten.

Kontinuierlicher wird es mit einer mathematischen Funktion der Art y=ax+b

Aus den verwendeten Daten könnte man folgende Kurve gestalten:

Die Steigung ist 500/10, der x-Offset 2 und der y-Offset 1000:

tonhoehe = 50 * (entfernung - 2) + 1000

Zusammen mit der (von mir nicht überprüften) entfernung = (pulsdauer / 2.0) * 0.03432
ergibt sich:

tonhoehe = 50 * ((dauer * 0.01716) - 2) + 1000

In der Entfernung 2 bis 12 cm hört man mit diesem Testprogramm eine kontinuierlich abfallende Tonhöhe:

const int tonPin = 8;
const int triggerPin = 7;
const int echoPin = 6;
const unsigned long tondauer = 500;
unsigned long pulsdauer = 0;
unsigned long entfernung = 0;
unsigned int tonhoehe = 0;

const int kurzerTON = 50;
const int leiserTON = 25;
const int mittlererTON = 12;
const int lauterTON = 3;

void setup()
{
  Serial.begin (9600);
  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

unsigned int berechneTon(unsigned long d, unsigned long e) {
  unsigned int t = 0;
  if (e >= kurzerTON)
  {
    t = 200;
  }
  else if (e >= leiserTON)
  {
    t = 500;
  }
  else if (e >= mittlererTON)
  {
    t = 1500;
  }
  else if (e >= lauterTON)
  {
    t = 50 * ((d * 0.01716) - 2) + 1000;
  }
  return t;
}

void loop()
{
  digitalWrite(triggerPin, LOW);
  delay(5);
  digitalWrite(triggerPin, HIGH);
  delay(10);
  digitalWrite(triggerPin, LOW);
  pulsdauer = pulseIn(echoPin, HIGH, 30000);
  entfernung = (pulsdauer / 2.0) * 0.03432;
  if (entfernung >= 500 || entfernung < 3)
  {
    Serial.println("Kein Messwert");
  }
  else
  {
    tonhoehe = berechneTon(pulsdauer, entfernung);
    tone(tonPin, tonhoehe, tondauer);
    Serial.print(pulsdauer);
    Serial.print('\t');
    Serial.print(entfernung);
    Serial.print(" cm\t");
    Serial.print(tonhoehe);
    Serial.println(" Hz");
  }
}

Wenn Du es schaffst, die restlichen Funktionsabschnitte zu erstellen, kannst Du Deinem Lehrer beweisen, daß Du das Prinzip verstanden hast.

PS: Beim Schreiben habe ich gerade ein Fehlerchen entdeckt. Mal sehen, ob Du es findest.

agmue:
Eine Möglichkeit wäre, die if-Abfragen zu vermehren, um eine feinere "Treppe" zu erhalten.

Kontinuierlicher wird es mit einer mathematischen Funktion der Art y=ax+b

Aus den verwendeten Daten könnte man folgende Kurve gestalten:

Die Steigung ist 500/10, der x-Offset 2 und der y-Offset 1000:

tonhoehe = 50 * (entfernung - 2) + 1000

Zusammen mit der (von mir nicht überprüften) entfernung = (pulsdauer / 2.0) * 0.03432
ergibt sich:

tonhoehe = 50 * ((dauer * 0.01716) - 2) + 1000

In der Entfernung 2 bis 12 cm hört man mit diesem Testprogramm eine kontinuierlich abfallende Tonhöhe:

const int tonPin = 8;

const int triggerPin = 7;
const int echoPin = 6;
const unsigned long tondauer = 500;
unsigned long pulsdauer = 0;
unsigned long entfernung = 0;
unsigned int tonhoehe = 0;

const int kurzerTON = 50;
const int leiserTON = 25;
const int mittlererTON = 12;
const int lauterTON = 3;

void setup()
{
  Serial.begin (9600);
  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

unsigned int berechneTon(unsigned long d, unsigned long e) {
  unsigned int t = 0;
  if (e >= kurzerTON)
  {
    t = 200;
  }
  else if (e >= leiserTON)
  {
    t = 500;
  }
  else if (e >= mittlererTON)
  {
    t = 1500;
  }
  else if (e >= lauterTON)
  {
    t = 50 * ((d * 0.01716) - 2) + 1000;
  }
  return t;
}

void loop()
{
  digitalWrite(triggerPin, LOW);
  delay(5);
  digitalWrite(triggerPin, HIGH);
  delay(10);
  digitalWrite(triggerPin, LOW);
  pulsdauer = pulseIn(echoPin, HIGH, 30000);
  entfernung = (pulsdauer / 2.0) * 0.03432;
  if (entfernung >= 500 || entfernung < 3)
  {
    Serial.println("Kein Messwert");
  }
  else
  {
    tonhoehe = berechneTon(pulsdauer, entfernung);
    tone(tonPin, tonhoehe, tondauer);
    Serial.print(pulsdauer);
    Serial.print('\t');
    Serial.print(entfernung);
    Serial.print(" cm\t");
    Serial.print(tonhoehe);
    Serial.println(" Hz");
  }
}



Wenn Du es schaffst, die restlichen Funktionsabschnitte zu erstellen, kannst Du Deinem Lehrer beweisen, daß Du das Prinzip verstanden hast.

PS: Beim Schreiben habe ich gerade ein Fehlerchen entdeckt. Mal sehen, ob Du es findest.

Danke für deine Bemühungen.
Hab deine Option am Freitag ausprobiert und mir ist kein Fehler aufgefallen, jedoch hätte ich paar Fragen.
Muss ich den x- & y-Offset ändern, wenn ich eine größere Spanne als die 2cm - 12cm haben will?
Und habe ich laut deiner Kurve nicht den selben Ton bei einer Entfernung von 2cm wie bei ca. 20cm?
Wäre es dann nicht schlauer eine Exponentialfunktion zu nehmen?

Und habe ich laut deiner Kurve nicht den selben Ton bei einer Entfernung von 2cm wie bei ca. 20cm?

Ja, nur ist das Kurvenbild was anderes als der Sketch.

Und falls du dich wunderst, dass agmues Funktion berechneTon 2 Aufruf-Parameter hat, hast du das gut beobachtet.

Adrian11223:
Danke für deine Bemühungen.

Bitte gerne!

Adrian11223:
Und habe ich laut deiner Kurve nicht den selben Ton bei einer Entfernung von 2cm wie bei ca. 20cm?

Ja, als Grundlage habe ich die Werte aus Deinem Programm genommen und mit Linien verbunden. Die Kurve stellt die mögliche Wunschfunktion dar, die nur im linken Teil von meinem Programm realisiert wird. Den Rest wollte ich Dir überlassen.

Adrian11223:
Wäre es dann nicht schlauer eine Exponentialfunktion zu nehmen?

Ein Arduino ist kein Mathegenie, da sind Geraden schon ganz gut. Kommt halt darauf an, was man machen will. Es ist auch ein bischen Probieren gefragt, was am besten gefällt.

Mein Programm soll eine Anregung sein, nicht die Lösung :slight_smile:

Wäre es dann nicht schlauer eine Exponentialfunktion zu nehmen

Ja, Tonhöhe geht exponentiell ( Ein Halbtonschritt ist eine Multiplikation mit ca. 1,06 )
Die meisten Menschen haben aber kein absolutes Gehör und die sinnvolle Tonhöhe für Alarmtöne ist begrenzt. Daher hat sich bei Einparkhilfen das intuitive (mehr oder weniger schnelle) Piepsen durchgesetzt.