Soft Start Kinder Traktor

Hallo zusammen,

ich bin neu hier und wollte eigentlich erst eine PN senden, das hat aber nicht geklappt :frowning:
Ich bin Anfänger bei Arduino, würde aber trotzdem gerne etwas umsetzen und dabei lernen:
Ich suche für einen 12V Kinder Traktor einen Softstart Code. Ich habe hier einen Arduino Nano und zwei BTS7960B Motor Treiber, die Motoren haben jeweils 165W (2 Stück).

Ich habe bereits diesen hier gefunden:

#include <Noiasca_led.h>   // download library from https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm ab Version 0.0.5

const byte DIR  = 4;
const byte MOTOR_PWM = 6;  // an PWM
const byte V_EN = 7;       // vorwärts Freigabe; an RPWM oder LPWM
const byte R_EN = 8;       // rückwärts Freigabe; an LPWM oder RPWM
const byte POTI = A0;

SmoothPin motor {MOTOR_PWM};   // UNO PWM pins 3, 5, 6, 9, 10, 11

void setup() {
  pinMode(DIR, INPUT_PULLUP);
  pinMode(V_EN, OUTPUT);
  pinMode(R_EN, OUTPUT);

  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(5);      // you can modify the delay time for the smothing
  motor.setOffInterval(1);     // you can modify the delay time for the smothing
}

void loop() {
  const uint8_t MAX_VORWAERTS = 250;
  const uint8_t MAX_RUECKWAERTS = 85;
  static uint8_t schritt = 0;
  uint8_t geschw = analogRead(POTI) / 4;

  switch (schritt)
  {
    case 0:
      if (digitalRead(DIR))
      {
        digitalWrite(R_EN, LOW);
        digitalWrite(V_EN, HIGH);
        if (geschw > MAX_VORWAERTS) geschw = MAX_VORWAERTS;
        motor.setMaxBrightness(geschw);
        motor.on();
      } else {
        digitalWrite(R_EN, LOW);
        digitalWrite(V_EN, LOW);
        motor.off();
        if ( motor.getCurrentBrightness() <= 2 ) schritt = 1;
      }
      break;
    case 1:
      if (!digitalRead(DIR))
      {
        digitalWrite(V_EN, LOW);
        digitalWrite(R_EN, HIGH);
        if (geschw > MAX_RUECKWAERTS) geschw = MAX_RUECKWAERTS;
        motor.setMaxBrightness(geschw);
        motor.on();
      } else {
        digitalWrite(R_EN, LOW);
        digitalWrite(V_EN, LOW);
        motor.off();
        if ( motor.getCurrentBrightness() <= 2 ) schritt = 0;
      }
      break;
  }
  motor.update();   // you have to call update() for the LED
}

Er stammt von @agmue aus dem Kinder Kart Motor Thema.

Problem ist, ich habe keine Poti sondern nur einen einfachen EIN/AUS Schalter und einen Schalter welche Geschwindigkeit 1/2 und Rückwärts steuert.
Sobald Schalter auf 1 steht, soll 50% Geschwindigkeit ausgegeben werden, Schalter 2 soll 100% erzeugen. Rückwärts soll 35% Rückwärts erzeugen. Das ganze halt mir dem Soft Start.

Kann mir jemand behilflich sein das umzuschrieben?

Ich hoffe ich habe alle Regeln hier befolgt.

Nur wenn du einen Schaltplan zeichnest wie der EIN/AUS Schalter verkabelt ist - und zu welchem Pin.
Und wie der Schalter 1/2 und Rückwärts angeschlossen ist - und zu welchem Pin (oder welche Pins).

2 robuste Potis besorgen sollte jetzt aber nicht wirklich ein Problem sein, oder?

Also 200W Potis?

Hallo nochmal,

ich habe mir mittlerweile einiges angesehen und geändert und auch schon gebaut.

Der gewünschte Schaltplan vom Traktor wie er original war:

Die Idee mit dem Poti als Gaspedal habe ich übernommen und schon verbaut, funktioniert auch soweit.

Was aktuell nicht funktioniert ist das Bremsen.
Vorher haben die Räder sofort nach loslassen des Fußpedals blockiert.
Das ist jetzt garnicht mehr. Er rollt quasi den Abhang runter.

Ich habe das Gefühl, dass das Element welches im Schaltplan "Thermo Protector" genannt wird noch etwas anderes macht, sonst wäre es nicht am Fußpedal angeschlossen. Werden die Räder durch Kurzschluss blockiert?

Das ist das ThermoElement:

Ich habe dazu im Code beide PWM Ausgänge bzw. alle 3 Ausgänge auf HIGH gesetzt, dadurch soll ja der Treiber ja eigentlich kurzschließen. Funktioniert aber nicht. Hat da jemand eine Idee?

Hier der aktuelle Code:

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

const byte RWD  = 5;       // Schaltung Rückwärts ; an D5 (Schließer)
const byte MOTOR_PWM = 6;  // 2x R_EN und L_EN ; an D6
const byte V_EN = 7;       // vorwärts Freigabe; an RPWM
const byte R_EN = 8;       // rückwärts Freigabe; an LPWM
BlinkPin beep {9};
const byte FAST  = 2;      // zweite Gang; an D2 (Schließer)
const byte POTI = A0;      // Gaspedal
SmoothPin motor {MOTOR_PWM};   // UNO PWM pins 3, 5, 6, 9, 10, 11

void setup() {
  Serial.begin(115200);
  Serial.println("\nStart");
  pinMode(RWD, INPUT_PULLUP);
  pinMode(FAST, INPUT_PULLUP);
  pinMode(V_EN, OUTPUT);
  pinMode(R_EN, OUTPUT);

  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(5);      // you can modify the delay time for the smothing
  motor.setOffInterval(1);     // 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
}

void loop()
{
  enum {VORWAERTS, RUECKWAERTS};
  const uint8_t MAX_VORWAERTS = 255;
  const uint8_t MAX_RUECKWAERTS = 150;
  const uint8_t MAX_VORWAERTS_SLOW = 150;
  static uint8_t schritt = 0;
  
  const int32_t POTI_MIN = 203;     // Analogwert bei Pedal losgelassen
  const int32_t POTI_MAX = 878;     // Analogwert bei Pedal durchgetreten
  int32_t poti = analogRead(POTI);  // Typ ist für nachfolgende Rechnung wichtig
  uint8_t geschw = constrain((poti - POTI_MIN) * 256 / (POTI_MAX - POTI_MIN), 0, 255);

  Serial.print(poti);
  Serial.print('\t');
  Serial.print(geschw);
  Serial.print('\t');

  switch (schritt)
  {
    case VORWAERTS:
      if (digitalRead(RWD))
      {
        digitalWrite(R_EN, LOW);
        digitalWrite(V_EN, HIGH);
        if ( (geschw > MAX_VORWAERTS) && (digitalRead(FAST) == 1) ) geschw = MAX_VORWAERTS;
        else if ( (geschw > MAX_VORWAERTS_SLOW) && (digitalRead(FAST) == 0) ) geschw = MAX_VORWAERTS_SLOW;
        motor.setMaxBrightness(geschw);
        motor.on();
      } else {
        digitalWrite(R_EN, HIGH);
        digitalWrite(V_EN, HIGH);
        motor.on();
        if ( motor.getCurrentBrightness() <= 2 ) schritt = 1;
      }
      break;

    case RUECKWAERTS:
      if (!digitalRead(RWD)) 
      {
        digitalWrite(V_EN, LOW);
        digitalWrite(R_EN, HIGH);
        if ( geschw > MAX_RUECKWAERTS) geschw = MAX_RUECKWAERTS;        
        motor.setMaxBrightness(geschw);
        motor.on();
        if (geschw > 0) beep.on(); else beep.off();
      } else {
        digitalWrite(R_EN, HIGH);
        digitalWrite(V_EN, HIGH);
        motor.on();
        beep.off();
        if ( motor.getCurrentBrightness() <= 2 ) schritt = 0;
      }
      break;
  }
  Serial.println(geschw);
  motor.update();   // you have to call update() for the LED
  beep.update();    // call the update function in loop() to refresh the LED
}

Für die Motorbremse musst du halt einen Grenzwert bei Poti nehmen, irgend was <10% macht Motorbremse.

An welcher Stelle würdest du es einsetzen?

Ich dachte vorher dass diese Stelle das schon umsetzt:

else {
        digitalWrite(R_EN, HIGH);
        digitalWrite(V_EN, HIGH);
        motor.on();
        beep.off();
        if ( motor.getCurrentBrightness() <= 2 ) schritt = 0;

Sorry bin noch nicht so fit in der Programmierung, bzw. ziemlicher Anfänge :slight_smile:

Ich kenn' deine Verkabelung nicht --> keine Ahnung was motor.on() macht und warum du motor.getCurrentBrightness() hier drinnen stehen hast. irgendwo sollte etwas in der Form da stehen:

int poti=analogRead(POTI);
if (poti<100) { 
  MOTOR_AUS();
  MOTOR_BREMSE_EIN();
  MOTOR_RICHTUNG(digitalRead(RÜCKWÄRTSGANG)); 
}
else { 
  MOTOR_SPEED(map(poti,...); 
}

... also Richtung nur umschalten wenn kein Gas, und wenn kein Gas kein PWM nur Kurzschlussbremse, sonst nur PWM ändern

motor.on() schaltet den motor "sanft" an

motor.getCurrentBrightness() liefert die aktuelle PWM zurück (im weitesten Sinne)

@prydox

das schaut "unschön" aus

if ( motor.getCurrentBrightness() <= 2 ) schritt = 1;

Annahme, du hast die Schritte in der enumeration VORWAERTS und RUECKWAERTS. Dann solltest du auch diese nehmen

if ( motor.getCurrentBrightness() <= 2 ) schritt = RUECKWAERTS;

@zwieblum
ich werde mal versuchen einen Schaltplan vom aktuellen Anschluss inkl. Arduino zu erstellen.

@noiasca Danke das werde ich mal ändern mit den Schritten. Hat das denn aktuell Auswirkungen auf etwas?

Ich selber kenne den Code ja eigentlich auch nicht. Ursprünglich ist das von @agmue und @bastel-box . Ich glaube agmue kennt ihn am besten.

Ich glaube das Problem ist MOTOR_PWM auf HIGH setzen zu können? das übernimmt ja "SmoothPin motor" bzw. motor.on() und motor.off()

Oder wüsstest du was @noiasca ? motor.offForced(); gibt es noch, das wäre aber genau das Gegenteil :slight_smile:

1 Like

Huhu,

bin mittlerweile weiter und konnte das mit <Poti-Wert für Bremsen umsetzen.

Zwei Probleme bleiben immernoch:

  • Wenn man einen Berg hochfährt und anhalten will, d.h. vom Gaspedal geht, rollt er manchmal rückwärts, aber eben nur manchmal. Läuft irgendwo noch eine Zeit ab oder übersehe ich etwas? Bergab bremst er immer sofort ab und rollt nicht nach.
  • Ich habe Probleme mit der 1. Geschwindigkeit. Diese wird nicht aktiviert.
    Ich habe anders als bei Bastel-Box einen Schalter für den 2. (schnellen) Gang. Dies ist ein Schließer. Der erste muss aktiv sein wenn 2. Gang und Rückwärtsgang nicht aktiv sind.
#include <Noiasca_led.h>   // download library from https://werner.rothschopf.net/microcontroller/202202_tools_led_en.htm
                           // ab Version 0.0.6

const byte RWD  = 5;       // Schaltung Rückwärts ; an D5 (Schließer)
const byte MOTOR_PWM = 6;  // 2x R_EN und L_EN ; an D6
const byte V_EN = 7;       // vorwärts Freigabe; an RPWM
const byte R_EN = 8;       // rückwärts Freigabe; an LPWM
BlinkPin beep {9};         // Rückwärts Pieper an D9
const byte FAST  = 2;      // zweite Gang; an D2 (Schließer)
const byte POTI = A0;      // Gaspedal Hallsensor
SmoothPin motor {MOTOR_PWM};   // UNO PWM pins 3, 5, 6, 9, 10, 11

void setup() 
{
  Serial.begin(115200);
  Serial.println("\nStart");
  pinMode(RWD, INPUT_PULLUP);
  pinMode(FAST, INPUT_PULLUP);
  pinMode(V_EN, OUTPUT);
  pinMode(R_EN, OUTPUT);

  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(5);      // you can modify the delay time for the smothing
  motor.setOffInterval(1);     // you can modify the delay time for the smothing
  beep.begin();                // you have to call the .begin() method for this LED
  beep.setOnInterval(300);     // 200ms on
  beep.setOffInterval(800);    // 600ms off
  beep.off();                  // you can switch the LED off
}

void loop()
{
  enum {VORWAERTS, RUECKWAERTS};
  const uint8_t MAX_VORWAERTS = 255;
  const uint8_t MAX_RUECKWAERTS = 200;
  const uint8_t MAX_VORWAERTS_SLOW = 200;
  static uint8_t schritt = 0;
  
  const int32_t POTI_MIN = 218;     // Analogwert bei Pedal losgelassen , ohne Änderung =203
  const int32_t POTI_MAX = 878;     // Analogwert bei Pedal durchgetreten, ohne Änderung =878
  // const uint8_t MAX = 0;
  int32_t poti = analogRead(POTI);  // Typ ist für nachfolgende Rechnung wichtig
  uint8_t geschw = constrain((poti - POTI_MIN) * 256 / (POTI_MAX - POTI_MIN), 0, 255);

  Serial.print(poti);
  Serial.print('\t');
  Serial.print(geschw);
  Serial.print('\t');

if (poti <= 217)                     //Potiwert wenn Pedal nicht getreten
{
motor.off();
beep.off();
motor.setMaxBrightness(geschw);
digitalWrite(MOTOR_PWM, HIGH);
digitalWrite(R_EN, HIGH);
digitalWrite(V_EN, HIGH);
}
else
{
  switch (schritt)
  {
    case VORWAERTS:
      if (digitalRead(RWD))                                                                                   // High = Schalter nicht betätigt, LOW = Schalter betätigt/Rückwärtsgang eingelegt
      {
        digitalWrite(R_EN, LOW);
        digitalWrite(V_EN, HIGH);
        if ( (geschw >= MAX_VORWAERTS) && (digitalRead(FAST) == LOW) ) geschw = MAX_VORWAERTS;                 // High = Schalter nicht betätigt, LOW = Schalter betätigt/2. Gang eingelegt
        else if ( (geschw > MAX_VORWAERTS_SLOW) && (digitalRead(FAST) == HIGH) ) geschw = MAX_VORWAERTS_SLOW;
        motor.setMaxBrightness(geschw);
        motor.on();
      } 
      else 
      {
        digitalWrite(R_EN, LOW);
        digitalWrite(V_EN, LOW);
        motor.off();
        if ( motor.getCurrentBrightness() <= 1 ) schritt = 1;
      }
      break;

    case RUECKWAERTS:
      if (!digitalRead(RWD))                                                                                   // High = Schalter nicht betätigt, LOW = Schalter betätigt/Rückwärtsgang eingelegt
      {
        digitalWrite(V_EN, LOW);
        digitalWrite(R_EN, HIGH);
        if ( geschw > MAX_RUECKWAERTS) geschw = MAX_RUECKWAERTS;        
        motor.setMaxBrightness(geschw);
        motor.on();
        if (geschw > 0) beep.on(); else beep.off();
      } 
      else 
      {
        digitalWrite(R_EN, LOW);
        digitalWrite(V_EN, LOW);
        motor.off(); 
        beep.off();
        if ( motor.getCurrentBrightness() <= 1 ) schritt = 0;
      }
      break;
  }
  }
  Serial.println(geschw);
  motor.update();   // you have to call update() for the LED
  beep.update();    // call the update function in loop() to refresh the LED
}

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