Hallo Zusammen,
bin absolut neu hier und auch mit Arduino recht "neu" unterwegs.
Habe Grundkenntnisse im Programmieren, arbeite jedoch nicht im IT Bereich und bin somit kein Profi, eher Laie. Allerdings bin ich handwerklich recht fit und würde sagen, dass die "Mechatronik" meine Heimat ist.
Daher habe ich das Kinderfahrzeug meiner Jungs etwas optimiert. Über die Sinnhaftigkeit und Gefahren möchte ich bitte nicht diskutieren, da das Fahrzeug auch mechanisch optimiert wurde und ausschließlich auf privaten Grund bewegt wird. Ich würde gernen einen Parkour aufbauen und hierfür das Auto gerne noch etwas optimieren. Dieser Assistent ist eher als Spielerei gedacht, da ich sowieso immer dabei bin und über eine Fernsteuerung in das Fahrgeschehen eingreifen kann. Daher bitte nichts falsches rein interpretieren und denken wie gefährlich so etwas sein kann. Danke.
Das Fahrzeug hat verschiedene Möglichkeiten die Geschwinidigkeit einzustellen, kurz:
24V flott / 12V lahm
high speed flott / low speed langsamer
Gasgeben flott / kein Gasgeben stehen bleiben
Diese 3 bzw. 6 Parameter möchte ich gerne nutzen und über Funk (Relais) einen Arduino Nano zuschaltbar machen. Sinn hierbei ein Brems-/Sicherheitsassistent.
Sobald das Kinderelektroauto auf ein Hinternis zufährt, soll es erst einmal
"high speed" zu "low speed" ändern
wenn man dann noch näher kommt soll es
"24V" auf "12V" umschalten und so die Geschwindigkeit deutlich reduzieren
reicht das noch nicht aus, kann man notfalls kurz vor Kontakt den Gaskontakt öffnen
"Gas auf" und somit bremsen.
Ich habe mal einen Code geschrieben (bzw. mir Teile aus dem Internet gesucht und solange optimiert bis es halbwegs klappt).
Was ist nun das Problem ?
Die beiden Ultraschallsensoren sollten nicht parallel sondern nacheinander laufen (sprich Delay wohl sinnvoll). Allerdings hätte ich gerne 2 Sicherheiten die ich noch nicht gut einbauen konnte:
(1) Ich möchte das Relais nicht schalten, wenn mal ein Blatt ö.ä. vorbei fliegt. Somit wäre es gut, wenn man sagen könnte, dass < xx cm für yy Sekunden vorhanden sein muss, dass der Arduino ein Relais schaltet. Hatte ich über merker/time/zeit bereits eingebaut aber hatte das Gefühl, dass dadurch alles etwas verzögert wird und nicht mehr so flott reagiert. Sollte bei millis ja eigentlich nicht der Fall sein, da ich kein "Delay" erzeuge.
(2) Wenn ein Relais schaltet, würde ich gerne prellen etwas verhindern und auch, dass der Arduino das Auto dadurch unruhig macht. Wenn er meint er muss eingreifen, sollte eine
Relaisschaltung z.B. 5 Sekunden betragen und erst danach wieder flott geöffnet werden.
Ich weiß nicht ob das zu viel verlangt ist, aber vielleicht kann sich Jemand mal meinen Code anschauen und mir sagen wie ich (1) und (2) am saubersten und einfachsten einbaue und damit (mit Zeiten) etwas spielen kann? Gerne auch Anmerkungen wie man den Code besser gestalten kann.
Ganz lieben Dank vorab !
/* BREMSASSISTENT FÜR KINDERELEKTROAUTO
* Arduino Nano v3 mit HW-315 4 Relay Board (schaltet bei "low")
* Relais über 12V JD-VCC angeschlossen und Ardunio über 12V VIN
* 2x HC-SR04 Sensoren die vorne an einem Kinderelektroauto installiert werden sollen
* ggf. gleicher Bereich oder unterschiedlicher Bereich (mit leichter Überschneidung).
* 3 Stufiger Bremsassisten geplant:
* Stufe 1: Schaltet von high speed modus auf low speed modus. Leichte Geschwinidigkeits abnahme
* Relais 1 schließt hierbei einen Kontakt (NO) und aktiviert auf dem Kontroller somit "low speed"
* Stufe 2: Schaltet Elektroautomotor über KFZ Relais Versorgung von 24V auf 12V um. Starke Geschwindigkeitsabnahme.
* Relais 2 öffnet hierbei einen Kontakt (NC) und lässt die Spannung vom KFZ Relais abfallen. KFZ Relais schaltet von 24V auf 12V um.
* Stufe 3: Öffnet den Stromkreislauf vom Gaspedal im Auto und leitet somit eine Bremsung ein. Fahrzeug wird gestoppt!
* Relais 3 öffnet Stromkreislauf und Auto Controller schließt somit die Antriebsmotoren kurz und bremst "massiv".
*/
int trigPin1=7; // Trigger-Signal PIN 7 HC-SR04_1
int echoPin1=8; // Echo-Signal PIN 8 HC-SR04_1
int trigPin2=9; // Trigger-Signal PIN 9 HC-SR04_2
int echoPin2=10; // Echo-Signal PIN 10 HC-SR04_2
unsigned long zeit = 0; // Variable zum Schreiben von "millis" (aktuelle Zeit)
unsigned long time1 = 0; // Zeitstempel 1 für Tests z.B. das HC-SR04 nicht sofort schaltet, sondern nur wenn Hindernus 200ms vorhanden ist oder wenn Relais angezogen für 200ms halten.
unsigned long time2 = 0; // Zeitstempel 2
unsigned long time3 = 0; // Zeitstempel 3
bool merker1 = false; // Merker 1 wenn aktuelle Zeit in Zeitstempel 1 geschrieben wurde (einmalige Aktion bis Zeit abgelaufen ist)
bool merker2 = false; // Merker 2
bool merker3 = false; // Merker 3
void setup() {
Serial.begin (9600);
pinMode(trigPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(2, OUTPUT); // Relais 1 "Stufe 1" z.B. umschalten von high speed mode zu low speed mode (NO schließt low speed Stromkreis des Controller)
pinMode(3, OUTPUT); // Relais 2 "Stufe 2" z.B. Elektroauto von 24V auf 12V umschalten (NC öffnet Stromversorgung Steuerrelais - Relais fällt dann ab und schaltet auf 12V)
pinMode(4, OUTPUT); // Relais 3 "Stufe 3" z.B. Öffnen den Stromkreis "Gasgeben" und leitet somit eine Bremsung ein
pinMode(5, OUTPUT); // Relais 4
}
void loop() {
// Abfrage HC-SR04_1 und HCSR04_2 mittels Code von Github: https://github.com/PranaliDesai/Multiple-Ultrasonic-Sensor-
long duration1, distance1;
digitalWrite(trigPin1, LOW);
delayMicroseconds(2);
digitalWrite(trigPin1, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin1, LOW);
duration1 = pulseIn(echoPin1, HIGH);
distance1 = (duration1/2) / 29.1;
if (distance1 >= 500 || distance1 <= 0){
Serial.println("Sensor 1: Out of range");
}
else {
Serial.print ( "Sensor1 ");
Serial.print ( distance1);
Serial.println("cm");
}
delay(50);
long duration2, distance2;
digitalWrite(trigPin2, LOW);
delayMicroseconds(2);
digitalWrite(trigPin2, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin2, LOW);
duration2 = pulseIn(echoPin2, HIGH);
distance2= (duration2/2) / 29.1;
if (distance2 >= 500 || distance2 <= 0){
Serial.println("Sensor 2: Out of range");
}
else {
Serial.print("Sensor2 ");
Serial.print(distance2);
Serial.println("cm");
}
delay(50);
// Ausgänge schalten
// Relais 1 wenn Distanz <150cm (aktuell &-Bedingung um Erkennungsfehler etwas vorzubeugen - nicht ideal)
if (distance1 <= 150 && distance2 <= 150)
{
Serial.print("|<!>| Achtung Abstand < 150cm erkannt |<!>|\n");
/* if(merker1=false) // 'merker1' default "false" wenn Bedigung <150cm erfüllt ist, wird zeit (millis) in Zeitstempel1 (time1) geschrieben.
{time1 = zeit; merker1=true;}
zeit = millis(); // aktuelle Zeit (millis) in Variable 'zeit' schreiben.
if ( zeit - time1 >= 3000 ) // Wenn z.B. 3 Sekunden vergangen (Vergleich Zeitstempel zur aktueller Zeit) dann führe nachfolgende Befehle aus
*/ {digitalWrite(2, LOW); // Schalte Relais 1 über PIN 2
Serial.print("|<!>| Maßnahme umsetzen -> Relais1 an |<!>|\n");}
// merker1=false; // Setzte Merker zurück, damit time1 bei erneutem Eintreten <150cm gesetzt werden kann.
}
else
{digitalWrite(2, HIGH); // Schalte Relais wieder aus
// time1 = zeit; //Wenn Wert unter <150cm nicht gehalten wird, hüpft man durch "Else" hier rein und time1 bekommt immer aktuelle Zeit (quasi Reset!)
}
//Relais 2 mit Distanz <80cm
if (distance1 <= 80 && distance2 <= 80)
{
Serial.print("|<!>| Achtung Abstand < 80cm erkannt |<!>|\n");
/* if(merker2=false)
{time2 = zeit; merker2=true;}
zeit = millis();
if ( zeit - time2 >= 3000 )
*/ {digitalWrite(3, LOW);
Serial.print("|<!>| Maßnahme umsetzen -> Relais2 an |<!>|\n");}
// merker2=false;
}
else
{digitalWrite(3, HIGH);
// time2 = zeit;
}
//Relais 3 mit Distanz <30cm
if (distance1 <= 30 && distance2 <= 30)
{
Serial.print("|<!>| Achtung Abstand < 30cm erkannt |<!>|\n");
/* if(merker3=false)
{time3 = zeit; merker3=true;}
zeit = millis();
if ( zeit - time3 >= 3000 )
*/ {digitalWrite(4, LOW);
Serial.print("|<!>| Maßnahme umsetzen -> Relais3 an |<!>|\n");}
// merker3=false;
}
else
{digitalWrite(4, HIGH);
// time3 = zeit;
}
}
Im wesentlichen dreht es sich ja "nur" um diesen Bereich - oben der komplette Code:
// Ausgänge schalten
// Relais 1 wenn Distanz <150cm (aktuell &-Bedingung um Erkennungsfehler etwas vorzubeugen - nicht ideal)
if (distance1 <= 150 && distance2 <= 150)
{
Serial.print("|<!>| Achtung Abstand < 150cm erkannt |<!>|\n");
/* if(merker1=false) // 'merker1' default "false" wenn Bedigung <150cm erfüllt ist, wird zeit (millis) in Zeitstempel1 (time1) geschrieben.
{time1 = zeit; merker1=true;}
zeit = millis(); // aktuelle Zeit (millis) in Variable 'zeit' schreiben.
if ( zeit - time1 >= 3000 ) // Wenn z.B. 3 Sekunden vergangen (Vergleich Zeitstempel zur aktueller Zeit) dann führe nachfolgende Befehle aus
*/ {digitalWrite(2, LOW); // Schalte Relais 1 über PIN 2
Serial.print("|<!>| Maßnahme umsetzen -> Relais1 an |<!>|\n");}
// merker1=false; // Setzte Merker zurück, damit time1 bei erneutem Eintreten <150cm gesetzt werden kann.
}
else
{digitalWrite(2, HIGH); // Schalte Relais wieder aus
// time1 = zeit; //Wenn Wert unter <150cm nicht gehalten wird, hüpft man durch "Else" hier rein und time1 bekommt immer aktuelle Zeit (quasi Reset!)
}