Wie kann ich meine Variable langsam reduzieren auf null?

Hey Leute, da ich noch ein ziemlicher Anfänger bin wollte ich euch mal nach Rat fragen. Mein Problem ist, dass ich meine Variable "drehZahl" von null auf 255 langsam erhöhen kann, jedoch nicht von 255 langsam auf 0 wieder runter, deshalb wollte ich euch mal fragen was an meinem Programm falsch sein könnte.

int Motor3 = 10;
int Motor4 = 11;
int MotorEnable = 9;
int drehZahl = 0;

void setup() { 
  pinMode(Motor3,OUTPUT);
  pinMode(Motor4,OUTPUT);
  pinMode(MotorEnable,OUTPUT);
  Serial.begin(9600);
}

void loop() {  // Aendere das Programm so ab, dass die 
  // Drehzahl nur langsam erhoeht und dann wieder langsam
  // reduziert wird.
  
  if(drehZahl<255){
  digitalWrite(Motor3,HIGH);
  digitalWrite(Motor4,LOW);
  drehZahl=drehZahl+5;
  Serial.println(drehZahl);
  analogWrite(MotorEnable,drehZahl);

  
  }
  if (drehZahl>250){
  digitalWrite(Motor3,LOW);
  digitalWrite(Motor4,HIGH);
  drehZahl=drehZahl-5;
  analogWrite(MotorEnable,drehZahl);
  Serial.println(drehZahl);
    
  }
  
 
}

Wie kommt's , dass da überhaupt was langsam läuft?
Serial ist die einzige Bremse, die ich sehe. Nach 64 Zeichen Ausgabe brauchst du 1 ms je Zeichen (Wegen 9600)
Außerdem geht drehZahl nicht wieder unter 250...

Das mit der drehZahl will ich ja ändern weil ich das gerade nicht anders kann, aber danke das du dir die Zeit genommen hast mir zu antworten.

Und noch vergessen zu sagen, danke für deinen Hinweis.

Und was für einen Motor hast du wie angeschlossen an den drei Pins?
Was hat "Eine Variable langsam reduzieren auf Null" mit der Drehzahl des Motors zu tun ?

Du willst einen Zustandsautomaten bauen!

Hat der Lehrer euch noch ein paar Tipps, für die Umsetzung dieser Aufgabenstellung, gegeben?

Keine Ahnung, was die Frage mit einem Motor zu tun hat:

byte drehZahl = 0; // ändert sich langsam zwischen 0 und 255
bool auf = true;  // bei false langsam abwärts

void setup() { 
  Serial.begin(9600);
}

void loop() {  
  if (auf) drehZahl++ ; else drehZahl--;
  if (drehZahl == 255) auf = false;
  if (drehZahl == 0) auf = true;

  analogWrite(9, drehZahl);
  
  delay(10) ; // 2,5 sec je Richtung

  if (drehZahl % 10 == 0) {
      // nur jeden zehnten Wert protokollieren
     Serial.print( auf?"^ ":"v "); Serial.println(drehZahl);
  }
}
1 Like
constexpr byte Motor3 {10};
constexpr byte Motor4 {11};
constexpr byte MotorEnable {9};
int drehzahl;

enum class STATUS {auf, ab, halt};
STATUS state = STATUS::halt;

constexpr uint32_t intervall {70};
uint32_t lastmillis;
void setup()
{
  Serial.begin(9600);
  Serial.println(F("Start..."));
  pinMode(Motor3, OUTPUT);
  pinMode(Motor4, OUTPUT);
  pinMode(MotorEnable, OUTPUT);
}

void loop()    // Aendere das Programm so ab, dass die
{
  statemachine();
  motor();
}
//
void statemachine()
{
  if (millis() - lastmillis > intervall)
  {
    lastmillis += intervall;
    switch (state)
    {
      case STATUS::halt:
        drehzahl = 0;
        state = STATUS::auf;
        break;
      case STATUS::auf:
        ++drehzahl;
        if (drehzahl >= 255)
        {
          drehzahl = 255;
          state = STATUS::ab;
        }
        break;
      case STATUS::ab:
        --drehzahl;
        if (drehzahl <= 0)
        {
          drehzahl = 0;
          state = STATUS::halt;
        }
        break;
    }
  }
}
//
void motor()
{
  if (drehzahl != 0)
  {
    analogWrite(Motor3, drehzahl);
    analogWrite(Motor4, drehzahl);
    digitalWrite(MotorEnable, HIGH);
  }
  else
  {
    digitalWrite(Motor3, LOW);
    digitalWrite(Motor4, LOW);
    digitalWrite(MotorEnable, LOW);
  }
}

Mit besten Grüßen an den Kursleiter.

1 Like

Es geht weder langsam noch schnell wieder runter - es geht gar nicht runter.
Du solltest die Bedingungen kritisch überprüfen.
(Edit: Das Ihr bezog sich auf die Komilitonen aus einer anderen Frage)

Modifizierter Code
int Motor3 = 10;
int Motor4 = 11;
int MotorEnable = 9;
int drehZahl = 0;

void setup()
{
    pinMode(Motor3, OUTPUT);
    pinMode(Motor4, OUTPUT);
    pinMode(MotorEnable, OUTPUT);
    Serial.begin(9600);
}

void loop()
{    // Aendere das Programm so ab, dass die
    // Drehzahl nur langsam erhoeht und dann wieder langsam
    // reduziert wird.

    Serial.print("drehZahl vor den ifs: ");
    Serial.println(drehZahl);

    if (drehZahl < 255)
    {
        // digitalWrite(Motor3, HIGH);
        // digitalWrite(Motor4, LOW);
        drehZahl = drehZahl + 5;
        Serial.print("in (drehZahl < 255) : ");
        Serial.println(drehZahl);
        // analogWrite(MotorEnable, drehZahl);
    }
    if (drehZahl > 250)
    {
        // digitalWrite(Motor3, LOW);
        // digitalWrite(Motor4, HIGH);
        drehZahl = drehZahl - 5;
        // analogWrite(MotorEnable, drehZahl);
        Serial.print("in (drehZahl > 250) : ");
        Serial.println(drehZahl);
    }

    delay(500);
}

liefert

...
20:45:29.646 -> drehZahl vor den ifs: 235
20:45:29.646 -> in (drehZahl < 255) : 240
20:45:30.143 -> drehZahl vor den ifs: 240
20:45:30.143 -> in (drehZahl < 255) : 245
20:45:30.639 -> drehZahl vor den ifs: 245
20:45:30.639 -> in (drehZahl < 255) : 250
20:45:31.138 -> drehZahl vor den ifs: 250
20:45:31.138 -> in (drehZahl < 255) : 255
20:45:31.138 -> in (drehZahl > 250) : 250
20:45:31.648 -> drehZahl vor den ifs: 250
20:45:31.648 -> in (drehZahl < 255) : 255
20:45:31.648 -> in (drehZahl > 250) : 250
20:45:32.141 -> drehZahl vor den ifs: 250
20:45:32.141 -> in (drehZahl < 255) : 255
20:45:32.141 -> in (drehZahl > 250) : 250
1 Like

Ist vollkommen egal, was da errechnet wird.
Hast Du mal nachgeschaut, was mit der Variablen drehzahl passiert?
:rofl:

Eben. Das Ergebnis davon habe ich ja mitgeteilt; da winkt schon der ganze Zaun.

Fehlersuch-Tipp für @lamito:
Wenn was nicht geht, lass Dir mit den Ausgaben nicht nur anzeigen, wie bestimmte Werte stehen, sondern auch wo das Programm langläuft. Das führt gelegentlich (auch bei mir) zu einiger Verwunderung, weil das Ergebnis manchmal so ganz anders ist als gedacht.

1 Like

Kurz gesagt: Wenn drehzahl >250 werden 5 abgezogen, somit ist die Bedingung drehzahl < 255 wieder wahr...eine zusätzliche Bedingung könnte da Abhilfe schaffen.

wurde zwar gerade genannt aber schau dir noch mal diesen if an:
das ist nur einmal wahr und daher wird nicht weiter runtergezählt.

Dem Wert von drehZahl kann man nicht ansehen, ob aktuell wachsen oder reduzieren angesagt ist. Dazu braucht es einen zusätzlichen Merker, der an den Endpunkten wechselt.
( Beispiel gabs schon in #8 )

ach das kann man schon auch bauen:
in Zweierschritten arbeiten
gerade Zahlen --> raufzählen lassen,
ungerade Zahlen --> runterzählen

dann spart man sich eine Richtungsvariable. Irgendwo hab ich so einen Code.

Aber eigentlich ging es mir in #15 darum dem TO zu erklären, warum sein Code nicht das macht was er erwartet.

Wenn man es gut doku-kommentiert, ein netter Trick wie man eine bool-Variable tatsächlich in einem Bit statt einem Byte speichern kann. Ob's den Aufwand wert ist?

Ach, es würde wohl schon reichen, eine der Bedingungen mit einem zusätzlichen = zu verzieren oder die zweite wegzulassen und stattdessen ein else zu benutzen.

Der TO scheint aber eine für sich befriedigende Lösung gefunden zu haben, denn seit über einer Woche haben wir hier nichts mehr dazu gehört.

So könnte man es auch lösen:

uint8_t drehzahl {0};
int8_t crement {5};
uint8_t highValueToChangeDirektion {255-crement};
uint8_t lowValueToChangeDirektion {0+crement};

void setup(){}

void loop(){
  drehzahl += crement;
  if(drehzahl > highValueToChangeDirektion || drehzahl < lowValueToChangeDirektion) crement *=-1;
}

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