Leider noch nicht ganz... ich probiere weiter
Dann habe ich wohl etwas beim "finalen Ergebnis" falsch verstanden.
Ich habe jetzt heute nochmal meine beiden Ultraschallsensoren angeschlossen und eine Schaltlogik gebastelt.
/*
Verkabelung von zwei HC-SR04 Ultraschall-Entfernungssensoren
VCC vom Sensor jeweils an Arduino 5v
GND vom Sensor an Arduino GND
beide Trigger Pins vom Sensor an Arduino Pin 7
Echo1 Pin vom Sensor an Arduino Pin 6
Echo2 Pin vom Sensor an Arduino Pin 8
*/
#define TRIGGERPIN 7 // beide Trigger-Pins verbunden
#define ECHOPIN1 6 // Echo Pin Sensor 1
#define ECHOPIN2 8 // Echo Pin Sensor 2
#define LEDPIN 13 // Onboard LED
#define V_SCHALL 34300L // Schallgeschwindigkeit in cm/s
#define MAXRANGE 200 // Maximale Entfernung in cm, über die nicht gemessen werden braucht
enum states {sDEFAULT,sLEFT, sRIGHT, sWIPELEFT, sWIPERIGHT, sLOUD};
int state=sDEFAULT; // state enthält den aktuell ausgewerteten Status
int distance1, distance2; // Berechneter Abstand
int loudValueRaw, loudValue; // berechnete Lautstärke
void setup() {
Serial.begin (57600); // Baudrate des Seriellen Monitors
pinMode(TRIGGERPIN, OUTPUT);
pinMode(ECHOPIN1, INPUT);
pinMode(ECHOPIN2, INPUT);
pinMode(LEDPIN, OUTPUT); // LED, falls verwendet
Serial.println("Programm gestartet...");
}
void Eingabe()
{
unsigned long duration1=0; // Dauer bis zum Eintreffen des Echos auf Null setzen
unsigned long duration2=0; // Dauer bis zum Eintreffen des Echos auf Null setzen
distance1=MAXRANGE; // Annahme, dass wir ausser Reichweite sind
distance2=MAXRANGE; // Annahme, dass wir ausser Reichweite sind
digitalWrite(TRIGGERPIN, LOW); // Beide Sensoren mit demselben Pin triggern
delayMicroseconds(2);
digitalWrite(TRIGGERPIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGERPIN, LOW);
unsigned long start=micros();
while ((digitalRead(ECHOPIN1)==LOW || digitalRead(ECHOPIN2)==LOW)&& micros()-start<1000);
if (micros()-start>=1000) // Falls ein Fehler beim Triggern vorkommen kann???
{
distance1=-1;
distance2=-1;
return;
}
do // Messschleife starten
{
if (duration1==0 && digitalRead(ECHOPIN1)==LOW) // Stop Messung Sensor1
{
duration1=micros()-start;
}
else if (duration2==0 && digitalRead(ECHOPIN2)==LOW) // Stop Messung Sensor 2
{
duration2=micros()-start;
}
else if (duration1!=0 && duration2!=0) break; // Beide Messungen beendet
if (micros()-start> 2*MAXRANGE*1000000L/V_SCHALL) break; // Timeout beim Messen
}
while (1);
// Abstand der Sensoren auf Basis der Schallgeschwindigkeit berechnen
if (duration1>0) distance1 = duration1*V_SCHALL/2000000L;
if (duration2>0) distance2 = duration2*V_SCHALL/2000000L;
}
void Verarbeitung()
{
static unsigned long timer;
if (distance1>100 && distance2<=100) // Sensor-2 misst zuerst kleinere Werte
{
if (state==sDEFAULT)
{
state=sLEFT;
timer=millis();
}
}
else if (distance2>100 && distance1<=100) // Sensor-1 misst zuerst kleinere Werte
{
if (state==sDEFAULT)
{
state=sRIGHT;
timer=millis();
}
}
else if (distance1>100 && distance2>100)
{
if (state==sRIGHT) state=sWIPERIGHT;
else if (state==sLEFT) state=sWIPELEFT;
else if (millis()-timer>333) state=sDEFAULT;
}
else if (distance1<=100 && distance2<=100 && millis()-timer>1000)
{
state=sLOUD;
// Der kleinere gemessene Abstand bestimmt die Lautstärke
if (distance1<distance2) loudValueRaw=distance1;
else loudValueRaw=distance2;
// den Wert aktualisieren mit exponentieller Glättung
loudValue=(loudValue*7+map(loudValueRaw,10,74,0,32))/8; // Wert von 10...74cm mappen auf 0..32 Lautstärkewert
}
}
void Ausgabe()
{
Serial.print(distance1);
Serial.print('\t');
Serial.print(distance2);
Serial.print('\t');
switch (state)
{
case sLEFT : Serial.print("Left");break;
case sWIPELEFT : Serial.print("Wipe LEFT");break;
case sRIGHT : Serial.print("Right");break;
case sWIPERIGHT: Serial.print("Wipe RIGHT");break;
case sLOUD : Serial.print("Loud ");Serial.print(loudValue);break;
}
Serial.println();
}
void Schalten()
{
static unsigned int lastState;
static unsigned int lastLoud;
if (state==sWIPELEFT && lastState!=sWIPELEFT)
{
Serial.println("Wischen LINKS");
}
else if (state==sWIPERIGHT && lastState!=sWIPERIGHT)
{
Serial.println("Wischen RECHTS");
}
else if (state==sLOUD && loudValue!=lastLoud)
{
lastLoud=loudValue;
Serial.print("Einstellung aendern auf Lautstaerke ");
Serial.println(loudValue);
}
lastState=state;
}
void loop() {
unsigned long loopstart=micros(); // Zeit beim Start der loop merken
Eingabe();
Verarbeitung();
// Ausgabe();
Schalten();
while(micros()-loopstart<20000); // mindestens 20 ms bis zur nächsten Messung warten
}
Bedienung:
Bei einer schnellen Bewegung über den Sensoren entscheidet der zuerst einen Wert unter 100 messende Sensor darüber, ob "Wischen links" oder "Wischen rechts" erkannt wird. Die Wischbewegung kann im Prinzip in einer beliebigen Höhe bis maximal 100cm über den Sensoren erfolgen, sie muß jedoch so schnell ausgeführt werden, dass die Wischbewegung spätestens 1 Sekunde danach beendet ist und beide Sensoren wieder einen Abstand von >100cm messen. Um eine Wischbewegung zu erkennen, müssen nicht einmal beide Sensoren die Hand erkennen, es reicht aus, wenn eine Hand im Erfassungsbereich von einem Sensor erkannt und wieder zurückgezogen wird. Natürlich kann man die Hand aber auch komplett über beide Sensoren hinweg führen.
Wenn auf beiden Sensoren mindestens 1 Sekunde lang ein Abstand unter 100cm gemessen wird, springt die Lautstärkeregelung an. Die Lautstärke wird von einem Abstand von 10cm bis 74cm auf eine Lautstärkenskala von 0 bis 32 gemappt, mittels des Codes
map(loudValueRaw,10,74,0,32)
Falls sich die Regelung in einem anderen Abstandsbereich abspielen sollen, die 10 und 74 entsprechend anpassen.
Falls die Lautstärkeskala anders als von 0 bis 32 laufen soll, die 0 und die 32 entsprechend anpassen.
Damit sich bei bei der hohen Messrate die Lautstärke nicht schnell und sprunghaft ändert, sondern eher langsam und gleitend, wird der Wert noch einer exponentiellen Glättung unterworfen.
Bitte nicht wundern, wenn Du die Hand zum Lautstärkeregeln über den Sensor hältst und scheinbar kein Lautstärkewert gesetzt wird: Überfüssige Einstellvorgänge sind wegoptimiert, d.h. nur wenn die Lautstärke sich tatsächlich ändert, wird auch eine Lautstärkeänderung geschaltet.
Die ursprüngliche Funktion mit den vielen Debug-Daten habe ich auskommentiert, wenn Du diese Daten wieder sehen möchtest, dann die Kommentarstriche vor der Zeile "// Ausgabe();" entfernen
Die eigentlichen Steuer- und Schaltvorgänge müßtest Du in die Funktion "Schalten()" einbauen, dort wo jetzt die Texte ausgegeben werden.
Um die Messrate konstant hoch zu halten, wäre es natürlich sinnvoll, auch beim Steuern und Schalten auf Blockierungen des Programms mit "delay" möglichst zu verzichten.