Kinder Kart Softstart die 2.te

Moin,
ich habe vor einiger Zeit hier mal eine Anfrage gestellt, für mein Kinder Kart.
Dort wurde mir von @agmue super weitergeholfen, bzw er hat fast alles umgesetzt.
Nun möchte ich gern noch was ändern, stehe aber leider etwas aufm Schlauch.
Ich habe dort noch Änderungen vorgenommen. ( Blinker, Licht, jetzt auch ne Bremse.)

Hier ist der geschlossene Ursprungsport Kinder Kart Motor Softstart - #49 by agmue
Hier der Aktuelle Code.

#define DEBUGGING                     // Einkommentieren für die Serielle Ausgabe

#ifdef DEBUGGING
#define DEBUG_B(...) Serial.begin(__VA_ARGS__)
#define DEBUG_P(...) Serial.print(__VA_ARGS__)
#define DEBUG_L(...) Serial.println(__VA_ARGS__)
#else
#define DEBUG_B(...)
#define DEBUG_P(...)
#define DEBUG_L(...)
#endif

#include <Noiasca_led.h>   // ab Version 0.0.6 von https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm
#include <Servo.h>

const byte LICHT  = 2;     // Licht einschalten
const byte DIR  = 4;       // VOR / ZURÜCK
const byte EIN  = 5;       // Einschalten
const byte MOTOR_PWM = 6;  // an PWM
const byte V_EN = 7;       // vorwärts Freigabe; an RPWM oder LPWM
const byte R_EN = 0;       // rückwärts Freigabe; an LPWM oder RPWM
const byte BEEP = 8;       // Rückwärtsfahrsignal
const byte SPEED_PWM = 9;   // Blinker takt
const byte LICHT_EIN = 10; // Licht ausgang
const byte BLINKER = 11;   // Blinker takt
const byte SLOW  = 12;     // Langsamfahrt
const byte POTI = A0;      // Gaspedal
const byte POTI_S = A1;    // Begrenzer 
int bremse = A2; // Analog Pin, an dem das Potentiometer angeschlossen ist 
int val; // Variable um den Wert des Analogen Pin zwischenzuspeichern
BlinkPin beep {BEEP};
BlinkPin blinker {BLINKER};
BlinkPin speed_pwm {SPEED_PWM};
SmoothPin motor {MOTOR_PWM};   // UNO PWM pins 3, 5, 6, 9, 10, 11
Servo myservo; // erstellt ein Servo-Objekt, um einen Servomotor zu steuern


void setup() {
  DEBUG_B(115200);
  DEBUG_L("\nStart");
  pinMode(DIR, INPUT_PULLUP);
  pinMode(SLOW, INPUT_PULLUP);
  pinMode(LICHT, INPUT_PULLUP);
  pinMode(V_EN, OUTPUT);
  pinMode(R_EN, OUTPUT);
  pinMode(EIN, OUTPUT);
  pinMode(LICHT_EIN, OUTPUT);
  myservo.attach(3); // verknüpft den Servomotor an Pin 3 mit dem Servo-Objekt

  
  motor.begin();               // you have to call the .begin() method for the LED pair
  motor.setMaxBrightness(0);   // you can limit the maximum brightness. Highest value on Arduino is 255. Default 255.
  motor.off();                 // you can switch the LED off
  motor.setOnInterval(80);      // you can modify the delay time for the smothing
  motor.setOffInterval(70);     // you can modify the delay time for the smothing
  beep.begin();                // you have to call the .begin() method for this LED
  beep.setOnInterval(200);     // 200ms on
  beep.setOffInterval(600);    // 600ms off
  beep.off();                  // you can switch the LED off
  blinker.begin();                // you have to call the .begin() method for this LED
  blinker.setOnInterval(1000);     // 200ms on
  blinker.setOffInterval(1000);    // 600ms off
  blinker.on();                   // you can switch the LED off
  speed_pwm.begin();                // you have to call the .begin() method for this LED
  speed_pwm.setOnInterval(0);     // 200ms on
  speed_pwm.setOffInterval(0);    // 600ms off
  speed_pwm.on();                   // you can switch the LED off
}

void fahren(const uint8_t EN_L, const uint8_t EN_H, const uint8_t MAX)
{
  const int32_t POTI_MIN = 200;     // Analogwert bei Pedal losgelassen
  const int32_t POTI_MAX = 840;
  const int32_t POTI_SLOW = 19;     // Analogwert bei Pedal durchgetreten
  int32_t poti = analogRead(POTI);
  int32_t poti_s = analogRead(POTI_S);   // Typ ist für nachfolgende Rechnung wichtig
  uint8_t geschw = constrain(((poti - POTI_MIN) * MAX / (POTI_MAX - POTI_MIN)) - (poti_s / POTI_SLOW) , 0, MAX);
  
 

  DEBUG_P(poti_s);
  DEBUG_P('\t');
 

  digitalWrite(EN_L, LOW);
  speed_pwm.setOnInterval(poti_s + 30);
  speed_pwm.setOffInterval(poti_s + 30);
  motor.setMaxBrightness(geschw);
  if ((MAX > 0) && (analogRead(bremse)< 250)) {
    digitalWrite(EN_H, HIGH);
    motor.on();
  } else {
    digitalWrite(EN_H, LOW);
    motor.off();
  }
}

void loop()

 {
  val = analogRead(bremse); // liest das Potentiometer aus (Wert zwischen 0 und 1023)
  val = map(val, 210, 850, 20, 110); // rechnet den Wert in den Wertebereich des Servomotors (zwischen 0 und180)
  myservo.write(val); // überträgt die Zielposition an den Servomotors
  delay(5); // lässt dem Servomotor Zeit, die Zielposition zu erreichen

 blinker.update();
 speed_pwm.update();
  enum {VORWAERTS, RUECKWAERTS, LICHT};
  const uint8_t MAX_VORWAERTS = 88; //128
  const uint8_t MAX_RUECKWAERTS = 55;
  const uint8_t MAX_VORWAERTS_SLOW = 50;
  const uint8_t MAX_RUECKWAERTS_SLOW = 35;
  static uint8_t schritt = 0;
{
  if (!digitalRead (LICHT) ==HIGH) {
    digitalWrite(LICHT_EIN, HIGH);
  } else {
    digitalWrite(LICHT_EIN, LOW);
  }
  }

  switch (schritt)
  {
    
    case VORWAERTS:
      if (digitalRead(DIR))
      {
        if (digitalRead(SLOW)) fahren(V_EN, R_EN, MAX_VORWAERTS_SLOW); else fahren(V_EN, R_EN, MAX_VORWAERTS);
        if ( motor.getCurrentBrightness() > 0 ) digitalWrite(EIN, HIGH); else digitalWrite(EIN, LOW) ;
      } else {
        fahren(R_EN, V_EN, 0);
        if ( motor.getCurrentBrightness() <= 1 ) schritt = 1;
      }
      break;

    case RUECKWAERTS:
      if (!digitalRead(DIR)) {
        if (digitalRead(SLOW)) fahren(R_EN, V_EN, MAX_RUECKWAERTS_SLOW); else fahren(R_EN, V_EN, MAX_RUECKWAERTS);
        if ( motor.getCurrentBrightness() > 0 ) beep.on(); else beep.off();
        if ( motor.getCurrentBrightness() > 0 ) digitalWrite(EIN, HIGH); else digitalWrite(EIN, LOW);
      } else {
        fahren(R_EN, V_EN, 0);
        beep.off();
        if ( motor.getCurrentBrightness() <= 1 ) schritt = 0;
      }
      break;
  }
  DEBUG_L(motor.getCurrentBrightness());
  motor.update();   // you have to call update() for the LED
  beep.update();
}

Nun möchte ich gern, das wenn die Bremse betätigt wird, der Motor sofort eine Drehzahl von "0" hat. Jetzt läuft der Motor ja noch nach, das soll bei Betätigung der Bremse verhindert werden.

Ich hoffe mein Wusch/frage ist soweit verständlich.

Und ja, der Code ist sicherlich nicht sauber geschrieben, bzw verändert, aber funktioniert soweit.

Gruß Christian

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Die Frage ist verständlich, der Code wegen Bibliotheksbenutzung nicht.

Dein Motorcontroller-Board sollte einen Bremszustand (brake) haben. Eine gute Bibliothek sollte eine entsprechende Methode publizieren.

Mein Motorcontroller ist ein Akkuschrauber, der nur über PWM angesteuert wird.
Daher sollte die Drehzahl/PWM nur soft angehalten werden, sondern beim Bremsen direkt auf NULL gehen.

Dann bleibt nichts anderes übrig als den Duty Cycle zum Anhalten auf 0 zu setzen, oder?

Hm, verstehe ich nicht. Ich bein kein Experte. verstehe nur sehr wenig. Das meiste, also quasi fast alles was im Code, sauber geschrieben wurde, wurde von @agmue geschrieben, das es sauber und kompakt ist.

Da bietet die Bibliothek die Methode offForced() an, bei Dir also motor.offForced();. Die Methodennamen passen nicht optimal für Motoren, da sie für LEDs gedacht sind :slightly_smiling_face:

hast du Paar Bilder von deinem(bzw.deines Sohnes) Flitzer?

Habe das so umgesetzt, geht aber nicht. Meine Bremse fängt beim Analog pin bei 210 an.



  DEBUG_P(poti_s);
  DEBUG_P('\t');
 

  digitalWrite(EN_L, LOW);
  speed_pwm.setOnInterval(poti_s + 30);
  speed_pwm.setOffInterval(poti_s + 30);
  motor.setMaxBrightness(geschw);

    if  (analogRead(bremse)< 250){
   motor.offForced();}
  
  if ((MAX > 0)) {
    digitalWrite(EN_H, HIGH);
    motor.on();
  } else {
    digitalWrite(EN_H, LOW);
    motor.off();
  }

 
}

void loop()

@kolaha kommen noch. :wink:

Willst Du das wirklich ?
Wenn der Motor eine Drehzahl von 0 hat, dann blockieren sofort die Antriebsräder (außer das Teil hat eine Kupplung, was aber bei E (Kinder) Autos nicht üblich ist)... :wink:

Wie bremst das Auto überhaupt? Mechanisch (Bremsbeläge in irgend einer Form) oder elektrisch (über den Motor) ?

Mal eine schnelle Frage:

Kann man durch das Bremsen eine Rekuperation realiseren ?

GRÜBEL

herbk war schneller :+1:

Wie soll der Motor auf Drehzahl 0 kommen? Dazu muß man den Akkuschrauber untersuchen, der ja im konkreten Fall die Steuerung übernimmt, und der kann die Drehzahl anscheinend nicht abrupt auf 0 regeln.

Liegt das nun an der Bibliothek, die ja eine eigene offForced() Funktion zum Bremsen hat, oder (auch?) an der Trägheit des ganzen Gefährts? Schließlich hat ein Motor auch nur eine begrenzte Bremskraft, selbst wenn die Regelung entsprechend ausgelegt wäre. Erfahrungsgemäß gibt es außer Antrieb=0 und Motor (Generator) kurzgeschlossen keine Bremsmöglichkeit. Ein gesteuertes Blockieren der Räder halte ich daher für ziemlich ausgeschlossen.

ja kann man, dass sich der Aufwand lohnt bezweifle ich allerdings... :wink: :slight_smile:

@DrDiettrich : die Frage war absichtlich etwas provozierend an den TO gestellt, und alles was Du da aufzählst sehe ich auch so... :slight_smile:
Wie Du oben schon geschrieben hast: Man kann bestenfalls den Motor sofort auf 0 Leistung schließen (dann dreht er sich leicht), oder kurz schließen ( dann dreht er sich schwerer).

Ich denke aber dass der TO auf 0 Leistung schalten meint und deshalb die "" bei "0" Drehzahl verwendet hat.

Der Akkuschrauber (Brushless) hat ja eigentlich eine Bremse, für das Einhandbohrfutter. Die mechanische Bremse habe ich ausgebaut.
Das hat den Vorteil, die Räder blockieren nicht und man kann den Wagen schieben.
Die Steuerung aus dem Akkuschrauber hat keinen nachlauf. Ich habe zusätzlich eine mechanisch/hydraulische Bremse verbaut.
Wenn man vom Gas runter geht, Brems die Motorbremse ( Trägheit durch die Magneten und Anker) und zusätzlich kann dann auch gebremst werden.
Ich könnte natürlich den nachlauf verkürzen, aber es würde ja Sinn machen, wenn die Bremse betätigt wird, der Motor halt gar nicht mehr läuft ( also drehen tut er ja, aber nicht mehr mit Energie versorgt wird)


Noch ist nicht alles schick, aber das kommt ganz am Ende.

OK, - was Du hier beschreibst ist "wie erwartet"... Ich verstehe aber nicht was Du mit "Nun möchte ich gern, das wenn die Bremse betätigt wird, der Motor sofort eine Drehzahl von "0" hat." meinst.

Es ist ja jetzt so, daß beim betätigtigen des Gaspedal, die Geschwindigkeit/Drehzahl langsam auf den gewünschten Wert angehoben wird. Das selbe passiert auch beim loslassen des Gaspedal. Der Motor dreht langsam runter, um keinen großen ruck zu bekommen. Das ist ja noch dem alten Akkuschrauber geschuldet, der noch die Bremse im getriebe hatte, und sofort blockiert hat. Jetzt habe ich die Bremse ausgebaut, jetzt ist nur noch der Drehwiderstand vom Akkuschrauber da (getriebe + Magnete und Anker). Das ist eigentlich ganz ok. Aber um schneller abbremsen zu können, oder bei Fahrten mit Anhänger, gibt es ein 2te Pedal. Die Bremse. Diese wirkt auf die Bremsscheibe. Wenn jetzt von Vollgas, direkt die Bremse betätigt wird ( oder sogar gleichzeitig) wirkt die Bremse, gegen den laufenden Motor, bis die Verzögerung / Smooth anhalten abgelaufen ist.
Ich würde gern, wenn die Bremse betätigt wird, die Drehzahl/ PWM Signal direkt auf 0 springt, und nicht erts Smooth runter läuft, bzw wenn beide Pedale Zeitgleich betätigt werden, die Bremse höhere Priorität hat, und kein Gas angenommen wird.

Ich könnte ja auch sagen, wenn A2 > 0 dann einen Ausgang setzten, der ein Relais trennt, um dem Akkuschrauber die Spannung zu trennen.. Aber die Variante finde ich nicht so schön.

Ich hatte gehofft, das geht anders, aber das kann ich nicht umsetzten und habe daher hier gefragt.

ich schaus mir am Abend an.
Bitte lade dir auf alle Fälle die letzte Version der Library runter

2023-02-18 Version 0.3.0

Ich verstehe das so, dass du nicht den Motor durch Kurzschluß blockieren willst, aber eine Sanft-Anfahr- und Sanft-Abbrems- Funktion hast, die du manchmal beim Abbremsen außer kraft setzen willst.

ist wohl der Kandidat, den du dir anschauen musst.
Statt motor.setOffInterval(70); muss vermutlich unter manchen Bedingungen was anderes rein, wenn es schneller auf 0 runter soll.

Aber du bist es, der die library verwendet und vor uns versteckst.

Ich verstehe sie? Wie kann ich sie anzeigen lassen? @agmue hatte sie verwendet, weil sie gut passt, was ich brauche. Ich habe keine Ahnung, wie ich sie mit anzeigen lassen könnte. Für mich ist das ein Stück Code, der irgendwie im Hintergrund ist, und man dinge daraus verwenen kann.

Aber ja, sonnst soweit richtig.

#define DEBUGGING                     // Einkommentieren für die Serielle Ausgabe

#ifdef DEBUGGING
#define DEBUG_B(...) Serial.begin(__VA_ARGS__)
#define DEBUG_P(...) Serial.print(__VA_ARGS__)
#define DEBUG_L(...) Serial.println(__VA_ARGS__)
#else
#define DEBUG_B(...)
#define DEBUG_P(...)
#define DEBUG_L(...)
#endif

#include <Noiasca_led.h>   // ab Version 0.0.6 von https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm
#include <Servo.h>

const byte LICHT  = 2;     // Licht einschalten
const byte DIR  = 4;       // VOR / ZURÜCK
const byte EIN  = 5;       // Einschalten
const byte MOTOR_PWM = 6;  // an PWM
const byte V_EN = 7;       // vorwärts Freigabe; an RPWM oder LPWM
const byte R_EN = 0;       // rückwärts Freigabe; an LPWM oder RPWM
const byte BEEP = 8;       // Rückwärtsfahrsignal
const byte SPEED_PWM = 9;  // Blinker takt
const byte LICHT_EIN = 10; // Licht ausgang
const byte BLINKER = 11;   // Blinker takt
const byte SLOW  = 12;     // Langsamfahrt
const byte POTI = A0;      // Gaspedal
const byte POTI_S = A1;    // Begrenzer
int bremse = A2; // Analog Pin, an dem das Potentiometer angeschlossen ist
int val; // Variable um den Wert des Analogen Pin zwischenzuspeichern
BlinkPin beep {BEEP};
BlinkPin blinker {BLINKER};
BlinkPin speed_pwm {SPEED_PWM};
SmoothPin motor {MOTOR_PWM};   // UNO PWM pins 3, 5, 6, 9, 10, 11
Servo myservo; // erstellt ein Servo-Objekt, um einen Servomotor zu steuern


void setup() {
  DEBUG_B(115200);
  DEBUG_L("\nStart");
  pinMode(DIR, INPUT_PULLUP);
  pinMode(SLOW, INPUT_PULLUP);
  pinMode(LICHT, INPUT_PULLUP);
  pinMode(V_EN, OUTPUT);
  pinMode(R_EN, OUTPUT);
  pinMode(EIN, OUTPUT);
  pinMode(LICHT_EIN, OUTPUT);
  myservo.attach(3); // verknüpft den Servomotor an Pin 3 mit dem Servo-Objekt


  motor.begin();               // you have to call the .begin() method for the LED pair
  motor.setMaxBrightness(0);   // you can limit the maximum brightness. Highest value on Arduino is 255. Default 255.
  motor.off();                 // you can switch the LED off
  motor.setOnInterval(80);      // you can modify the delay time for the smothing
  motor.setOffInterval(70);     // you can modify the delay time for the smothing
  beep.begin();                // you have to call the .begin() method for this LED
  beep.setOnInterval(200);     // 200ms on
  beep.setOffInterval(600);    // 600ms off
  beep.off();                  // you can switch the LED off
  blinker.begin();                // you have to call the .begin() method for this LED
  blinker.setOnInterval(1000);     // 200ms on
  blinker.setOffInterval(1000);    // 600ms off
  blinker.on();                   // you can switch the LED off
  speed_pwm.begin();                // you have to call the .begin() method for this LED
  speed_pwm.setOnInterval(0);     // 200ms on
  speed_pwm.setOffInterval(0);    // 600ms off
  speed_pwm.on();                   // you can switch the LED off
}

void fahren(const uint8_t EN_L, const uint8_t EN_H, const uint8_t MAX) {
  const int32_t POTI_MIN = 200;     // Analogwert bei Pedal losgelassen
  const int32_t POTI_MAX = 840;
  const int32_t POTI_SLOW = 19;     // Analogwert bei Pedal durchgetreten
  int32_t poti = analogRead(POTI);
  int32_t poti_s = analogRead(POTI_S);   // Typ ist für nachfolgende Rechnung wichtig
  uint8_t geschw = constrain(((poti - POTI_MIN) * MAX / (POTI_MAX - POTI_MIN)) - (poti_s / POTI_SLOW) , 0, MAX);
  static int BremsWert = 0;

  DEBUG_P(poti_s);
  DEBUG_P('\t');

  digitalWrite(EN_L, LOW);
  speed_pwm.setOnInterval(poti_s + 30);
  speed_pwm.setOffInterval(poti_s + 30);
  motor.setMaxBrightness(geschw);

  BremsWert = analogRead(bremse);
  if (BremsWert < 250) {
    if ((MAX > 0) ) {
      digitalWrite(EN_H, HIGH);
      motor.on();
    } else {
      digitalWrite(EN_H, LOW);
      motor.off();
    }

  } else if (BremsWert > 750) {
    analogWrite(MOTOR_PWM, 0) ;
    digitalWrite(EN_H, HIGH);
    motor.on();
  }
}


void loop() {
  val = analogRead(bremse); // liest das Potentiometer aus (Wert zwischen 0 und 1023)
  val = map(val, 210, 850, 20, 110); // rechnet den Wert in den Wertebereich des Servomotors (zwischen 0 und180)
  myservo.write(val); // überträgt die Zielposition an den Servomotors
  delay(5); // lässt dem Servomotor Zeit, die Zielposition zu erreichen

  blinker.update();
  speed_pwm.update();
  enum {VORWAERTS, RUECKWAERTS, LICHT};
  const uint8_t MAX_VORWAERTS = 88; //128
  const uint8_t MAX_RUECKWAERTS = 55;
  const uint8_t MAX_VORWAERTS_SLOW = 50;
  const uint8_t MAX_RUECKWAERTS_SLOW = 35;
  static uint8_t schritt = 0;

  digitalWrite(LICHT_EIN, !digitalRead (LICHT));

  switch (schritt)  {
    case VORWAERTS:
      if (digitalRead(DIR)) {
        if (digitalRead(SLOW)) fahren(V_EN, R_EN, MAX_VORWAERTS_SLOW);
        else fahren(V_EN, R_EN, MAX_VORWAERTS);
        if ( motor.getCurrentBrightness() > 0 ) digitalWrite(EIN, HIGH);
        else digitalWrite(EIN, LOW) ;
      }
      else {
        fahren(R_EN, V_EN, 0);
        if ( motor.getCurrentBrightness() <= 1 ) schritt = 1;
      }
      break;
    case RUECKWAERTS:
      if (!digitalRead(DIR)) {
        if (digitalRead(SLOW))
          fahren(R_EN, V_EN, MAX_RUECKWAERTS_SLOW);
        else
          fahren(R_EN, V_EN, MAX_RUECKWAERTS);

        if ( motor.getCurrentBrightness() > 0 )
          beep.on();
        else
          beep.off();

        if ( motor.getCurrentBrightness() > 0 )
          digitalWrite(EIN, HIGH);
        else
          digitalWrite(EIN, LOW);
      }
      else {
        fahren(R_EN, V_EN, 0);
        beep.off();
        if ( motor.getCurrentBrightness() <= 1 ) schritt = 0;
      }
      break;
  }
  DEBUG_L(motor.getCurrentBrightness());
  motor.update();   // you have to call update() for the LED
  beep.update();
}