Kinderelektroauto Bremsassistent - Ardunio Nano Code

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!)
      }                                                            
 

Das bitte noch etwas genauer erklären.
Wieso Funk ? Und was mit Relais ?

1 Like

Kleiner Tip: Statt Pin Nummern benannte Konstanten benutzen. Das verbessert die Lesbarkeit, schützt vor Schreibfehlern und hilft, falls Pins mal getauscht werden müssen.

IMO sollte der Merker erst zurückgesetzt werden, wenn der Abstand wieder ausreicht.

Die 3 Sekunden erscheinen mir etwas hoch gegriffen.

1 Like

Hallo,
wow Danke für die flotten Antworten.
Wollte oben nicht noch mehr schreiben.
Es handelt sich um ein 12V Kinderfahrzeug das komplett umgebaut wurde. Nun können die Motoren 24V statt 12V und ich kann die beiden Batterien in Reihe schalten oder nur eine nutzen.
Bei dem Fahrzeug war eine Fernbedienung dabei (Lenken, Bremsen und Gasgeben) die auch weiterhin funktioniert.
Bisher wird alles (24V<>12V; low oder high speed) von Hand am Fahrzeug umgeschaltet. Ich habe mir aber eine zweite Funkfernbedienung gekauft (433Mhz) die 4 Relais steuer kann. Über diese Fernsteuerung würde ich gerne von 24V auf 12V manuell umschalten, von high auf low speed manuell umschalten oder wenn "24V+high speed aktiv" würde ich gerne als dritte Option den Arduino zuschalten können. Ist ein Gimmick und sollt quasi ein "Bremsassistent" sein der mehrstuftig eingreift um Kollisionen zu vermeiden (ich schreibe extra vermeiden, da mir klar ist, dass es kein verbindern sein wird).

Ich denke der Code ist so ok und ja auch recht komptakt und mehrfach copy&paste - sicherlich noch Optimierungsbedarf.

@DrDiettrich Danke für den Hinweis. Werde ich so versuchen zu verbessern und prüfe dann nochmal, dass ich keinen Syntax-Fehler einbaue.

@HotSystems
Lieben Dank.
Die 3 Sekunden waren zum Testen, damit ich "etwas" in der Konsole sehe ich nicht alles zu flott läuft.
Ich denke das eine ist die Hindernisserkennung der/des Ultraschallsensor(s) möglichst zuverlässig zu machen. Wie ? (1) entweder beide Sensoren als Bedingung aufführen, da sie ja hintereinander abgefragt werden und sich so nicht stören dürften. Bedeutet aber ich kann am Auto vorne die Sensoren nicht leicht nach rechts und links schauen lassen, da bei "&" ja dann nur der überlappende Bereich erkannt wird. Muss ich mal testen ob das unbedingt nötig ist. Daher (2) war meine Idee eher zu sagen, wenn er mal was erkennt "ist das wirklich da ?" sprich die Abstandsunterschreitung muss für einige ms oder z.B. 1 Sekunde vorhanden sein, dann wird ein Relais geschaltet (z.B. von high speed modus auf low speed modus als erste Stufe) und dieses Relais soll dann aber auch etwas gehalten werden, damit ein wildes Regeln nicht zu wilder Motorreglung am Fahrzeug führt. Lieber ein "Fehlalarm" sofern der noch durch kommt wie wildes bremsen und wieder freischalten (Gas geben).

Ist die Umsetzung wie oben so sinnvoll und gut oder gibt es bessere Wege ??
Ich bin mir auch nicht sicher, ob das mit dem Merker so sinnvoll ist oder eleganter geht. Von Prinzip aber müsste der Arduino ja flott genug sein und 1-2 Zeilen mehr Code macht ihm ja nichts aus oder ? Nur "Delay" wäre blöd als Befehl, da dann die Erfassung in der Zeit ruht. Korrekt ?

Somit könnte ich meine Idee oben mit "millis" quasi auf die Erfassung wie auch Relaisschaltung anwenden und so alles etwas ruhiger/störunanfälliger machen oder was meint ihr ?

Ganz lieben Dank für die nette und liebe Hilfe !

Gehören Endliche Automaten (state machine) zu Deiner Ausbildung? Das wäre ein Projekt für den Einstieg in diese Technik.

1 Like

Anbei mal mein geupdateter Code (Relais mit Name) und Merker bei "else" (somit wenn der Abstand nicht mehr unterschritten ist).

/* BREMSASSISTENT FÜR KINDERELEKTROAUTO v6
 *  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 relais1=2;                            // Relais 1**
**int relais2=3;                            // Relais 2**
**int relais3=4;                            // Relais 3**
**int relais4=5;                            // Relais 4**
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 >= 800 )     // Wenn z.B. 3 Sekunden vergangen (Vergleich Zeitstempel zur aktueller Zeit) dann führe nachfolgende Befehle aus
          {digitalWrite(relais1, LOW);    // Schalte Relais 1 über PIN 2
        Serial.print("|<!>| Maßnahme umsetzen -> Relais1 an |<!>|\n");}
      }
     else
      {digitalWrite(relais1, 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!)
      merker1=false;                      // Setzte Merker zurück, damit time1 bei erneutem Eintreten <150cm gesetzt werden kann.
      }                                                            
  
                                          //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 >= 800 )
        {digitalWrite(relais2, LOW);
        Serial.print("|<!>| Maßnahme umsetzen -> Relais2 an |<!>|\n");}   
      }
     else
      {digitalWrite(relais2, HIGH);
      time2 = zeit;
      merker2=false;
      }                   
      
                                          //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 >= 800 )
          {digitalWrite(relais3, LOW);
          Serial.print("|<!>| Maßnahme umsetzen -> Relais3 an |<!>|\n");}
      }
     else
      {digitalWrite(relais3, HIGH);
      time3 = zeit;
      merker3=false;
      }                   

}

Werde den Code aber nochmal optimieren und schauen, dass die prellen von Relais verhinder und dort auch "millis" einbaue.

@DrDiettrich
Bin mit den Begrifflichkeiten nicht so up-to-date. Vermute aber du meinst eine Art Ablaufdigramm oder ? Bin gelernter Mechatroniker und habe Mechatronik studiert.
Der Elekronikumbau ist komplett mit einem "ePlan" Programm gemacht wenn auch nicht normgerecht und recht simpel. Dort sind ja auch die Schalter eingezeichnet, die ich manuell betätigen kann. Der Arduino hat quasi zusätzliche Kontakte in diesen Kreisläufen und kann somit auch eingreifen (24V KFZ Relais abfallen lassen oder einen Stromkreis zum Aktivieren von "low speed" schließen). Daher weiß ich ziemlich genau was ich vor habe. Nur der Code soll flott und sauber laufen und eben nicht jeden "Mini-Impuls" der Ultraschallsensoren durchgeben und prellen von Relais möchte ich auch nicht, da muss bißchen Ruhe reinkommen :slight_smile:

Dankeschön !! Ihr seid spitze.

Das wäre mir für diese Anwendung zu unsicher. 433MHz ist eine "Allerwelts"-Frequenz, die ich dafür nicht einsetzen würde. Da ist zu viel drauf am werkeln.
Außer du bist nicht gerade in einer Großstadt damit am Fahren.

Mal was gebasteltes.

// Forensketch - Bremsassi - 22.09.20
// basiert auf https://forum.arduino.cc/t/kinderelektroauto-bremsassistent-ardunio-nano-code/1033615
// ungetestet - kompiliert Fehler- und Warnungsfrei

/* 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".
*/

const byte speedRelais = 2;
const byte voltageRelais = 3;
const byte brakeRelais = 4;
const byte anzahlSensors = 2;
const byte trigPin[anzahlSensors] = {7, 9};                         // Trigger-Signal PIN 7 HC-SR04_1
const byte echoPin[anzahlSensors] = {8, 10};                         // Echo-Signal PIN 8 HC-SR04_1
uint32_t duration[anzahlSensors] = {10000, 10000};
uint32_t distance[anzahlSensors] = {10000, 10000};

enum {normal, lowSpeed, lowVoltage, brake};
byte status = normal;

bool an = HIGH;
bool aus = LOW;

/*
  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);
  for (byte b = 0; b < anzahlSensors; b++)
  {
    pinMode(trigPin[b], OUTPUT);
    pinMode(echoPin[b], INPUT);
  }
  pinMode(speedRelais, 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(voltageRelais, 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(brakeRelais, OUTPUT);              // Relais 3 "Stufe 3" z.B. Öffnen den Stromkreis "Gasgeben" und leitet somit eine Bremsung ein
  //pinMode(5, OUTPUT);                      // Relais 4
}

void loop()
{
  readSensors(); // Abfrage HC-SR04_1 und HCSR04_2 mittels Code von Github: https://github.com/PranaliDesai/Multiple-Ultrasonic-Sensor-
  action();
}


void readSensors()
{
  const uint32_t intervall = 50;
  static uint32_t lastRead = 0;
  static byte sensors = 0;
  if (millis() - lastRead > intervall)
  {
    digitalWrite(trigPin[sensors], LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin[sensors], HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin[sensors], LOW);
    duration[sensors] = pulseIn(echoPin[sensors], HIGH);
    distance[sensors] = (duration[sensors] / 2) / 29.1;
    Serial.print(F("Sensor "));
    Serial.print(sensors);
    Serial.print(": ");
    if (distance[sensors] >= 500 || distance[sensors] <= 0)
    {
      Serial.println(F("Out of range"));
    }
    else
    {
      Serial.print (distance[sensors]);
      Serial.println(" cm");
    }
    lastRead = millis();
    sensors++; if (sensors >= anzahlSensors) sensors = 0;
  }
}

bool isInDistance(const uint32_t dist)
{
  bool inDistance = true;     // es wird davon ausgegangen, das immer in der Distanz
  for (byte b = 0; b < anzahlSensors; b++)
  {
    if (distance[b] > dist)   // wenn ein Sensor nicht im Bereich ist
    { inDistance = false; }   // wird hier false gesetzt
  }
  return inDistance;
}

void action()
{
  static uint32_t lastMillis = 0;
  const uint32_t hysterese = 2000;
  switch (status)
  {
    case normal:
      digitalWrite(speedRelais, aus);
      digitalWrite(voltageRelais, aus);
      digitalWrite(brakeRelais, aus);
      if (isInDistance(150) == true)      // Wenn im angegebenen Bereich
      {
        Serial.print(F("|<!>| Achtung Abstand < 150cm erkannt |<!>|\n"));
        digitalWrite(speedRelais, an);    // löse aus
        lastMillis = millis();            // merke wann
        status = lowSpeed;                // nächster Status
      }
      break;
    case lowSpeed:
      if (millis() - lastMillis > hysterese)     //
      {
        if (isInDistance(80) == true)            // Wenn im angegebenen Bereich
        {
          Serial.println(F("|<!>| Achtung Abstand < 80cm erkannt |<!>|\n"));
          digitalWrite(voltageRelais, an);
          lastMillis = millis();
          status = lowVoltage;
        }
        else if (isInDistance(150) == false)     // Wenn nicht im angegebenen Bereich
        {
          status = normal;
        }
      }
      break;
    case lowVoltage:
      if (millis() - lastMillis > hysterese)     //
      {
        if (isInDistance(30) == true)            // Wenn im angegebenen Bereich
        {
          Serial.println(F("|<!>| Achtung Abstand < 30cm erkannt |<!>|\n"));
          digitalWrite(brakeRelais, an);
          lastMillis = millis();
          status = brake;
        }
        else if (isInDistance(150) == false)     // Wenn nicht im angegebenen Bereich
        {
          status = normal;
        }
      }
      break;
    case brake:
      if (millis() - lastMillis > hysterese)     //
      {
        if (isInDistance(150) == false)          // Wenn nicht im angegebenen Bereich
        {
          Serial.println(F("|<!>| Abstand > 150cm erkannt |<!>|\n"));
          status = normal;
        }
      }
      break;
  }
}
1 Like

Wohne auf dem Land und fahre mit dem Teil echt nirgends wo viele Menschen sind.
433MHz von Aliexpress da günstig und ich alles möglichst preiswert halten möchte.
Habe die Fernsteuerung noch nicht probiert, hoffe aber das die irgendwie codiert ist und nicht zufällig schaltet. Ich werde es mal probieren. Umgebung hier aber "sehr ruhig". Danke

Poste doch mal einen Link der FB.

1 Like

Boooor....
Krass. Hatte mit hier Tipps erhofft und das mein Code etwas auf Kurs kommt.
Aber das von dir ist ja nochmal ne ganz andere Nummer und zeigt echt den eleganten Weg, wenn man Ahnung hat.
Kenne einige Sachen von Informatik-Vorlesungen (C/C++) wie for-Schleife oder cases... ist aber schon ne ganze Weile her. Ganz lieben Dank !!!
Werde das heute Abend mal in Ruhe testen und auch mal durchgehen damit ich das (hoffentlich) alles verstehe. Dankeschön :slight_smile:

Vielleicht blickst du da ja eher durch. Danke

Steht etwas von:
Support encoding
1527 Leaning code /2262 fixed code

Weiß aber nicht ob das eine Art Codierung/Verschlüsslung ist...

Ich hatte noch die Durchzählung der Sensoren vergessen..
Es muss nicht funktionieren, ist aber eine Idee, wie es gehen kann. Ich hab das hoffentlich ausreichend kommentiert.
Wenn Fragen sind frag.

1 Like

Du müsstest es mit einem Arduino und einem 433MHz Empfänger ausprobieren.
Wenn du den Code empfängst und dekodieren kannst, ist alles gut.

1 Like

Ich mache das echt richtig old school und mittelalterlich :wink:
Ich habe den Arduino mit einer Relais Karte (4 Relais) verbunden und die Fernbedinung läuft komplett seprart. Die Fernbedienung hat auch 4 Relais auf der Platine und diese Relais und die des Arduino sind jeweils in Reihe geschaltet. Sprich wenn einer von beiden sagt "Stromkreis auf", passt das und wird auch über LEDs angezeigt (grün zu rot).
Ich muss somit nicht die Fernbedienung irgendwie in den Arduino einbinden. Ist mir dann eine Spur zu brutal als ziemlicher Laie. Die aktuellen Anforderungen an den Arduino und den Code reichen mir schon :smile:

Ich schaue mir das alles heute Abend oder morgen an.
Melde mich dann sehr gerne nochmal hier. Ganz lieben Dank, tolles Forum :star_struck:

Ahh....ok. Dann sollte das funktionieren.
Die Code-Angabe der FB sagt nur, dass du verschiedenen Code am Relais-Empfänger anlernen kannst. Somit solltest du die Tasten einzeln an die Relais anlernen.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.