Stepperregelung

Grundsatzfragen. ..

Kann ich in einer If Anweisung eine for Schleife einbinden?

zb.

void loop() {
   if(Status=2) {
    Vorlauf=20;
    analogRead(PotiLänge);
    Wert2= map (PotiLänge,0,1023,275,Vorlauf) 
    analogRead(PotiGeschwindigkeit);
    Wert1= map (PotiGeschwindigkeit,0,1023,0,65000);     
    Wegfaktor=Länge-Vorlauf*Schritte/PotiGeschwindigkeit;           // Weglänge konstant.....Schritte pro cm
    
  for (int i = 0; i <= (Wegfaktor*275); i++) {          
    tone,3, (Wert1) ;  
    Status=1;        
    
    delay(10);
            }
        else{
            Status=2;
        }
  }

Waermerohr:
Kann ich in einer If Anweisung eine for Schleife einbinden?

Klar geht das. Du solltest Deinen Code lesbarer machen.

Gruß

Gregor

Da loop() schon eine Schleife ist, sollte man die auch für wiederholende Aktionen benutzen, und dabei blockierenden Code wie delay() rauswerfen. Spätestens dann, wenn das Projekt wegen unpassender Programmierung nicht mehr erweitert werden kann.

Danke Gregor,
dann werde ich mir mal selber erst ein Bild von den Variablen und Konstanten zeichnen und meine Einstellmöglichkeiten passend definieren.

Danke Dietrich,
das mit dem Delay ist mir schon klar, aber für manche Abläufe ist es einfacher mal kurz zu warten, weil sowieso da nix passiert.
Dann setze ich auch delay dafür ein. Natürlich war es hier in der Schleife unpassend.

Mir wäre es sowieso lieber, die Regler im setup () abzufragen als im loop () um den loop zu beschleunigen, aber dann lässt sich ja nix mehr auf aktuellen RegelWert im loop nutzen.

Das tut nicht, was Du möchtest:

    analogRead(PotiLänge);
    Wert2= map (PotiLänge,0,1023,275,Vorlauf)

vermutlich so:

    PotiLänge = analogRead(analogPin);
    Wert2= map (PotiLänge,0,1023,275,Vorlauf);

Bitte beachte das Semikolon!

Danke,agmue....
Hatte ich auf Tablet geschrieben und noch nicht getestet.....

Mir fehlen einfach noch paar Grundgedanken um das erforderliche Ziel zu erreichen.

Waermerohr:
... aber dann lässt sich ja nix mehr auf aktuellen RegelWert im loop nutzen.

Du kannst auch mehrere Dinge quasi gleichzeitig tun. Von der „Programmier-Strategie“ hängt vieles ab. Ein Strickmuster, das ich oft nutze, nennt sich „Endlicher Automat“. Lies mal das hier - vielleicht hilft's.

Gruß

Gregor

Waermerohr:

   if(Status=2) {

Auch das macht nicht das, was Du erwartest. das in der Klammer ist eine einfache Zuweisung, und als Ergebnis immer wahr.

Was Du möchtest ist:

  if(Status==2) {

Waermerohr:
Mir fehlen einfach noch paar Grundgedanken um das erforderliche Ziel zu erreichen.

Das scheint in der Tat so. Aber was nicht ist, kann ja noch werden :wink:

Du kannst eine IF Bedingung in einer FOR Schleife haben aber das Sketchbröckchen, das Du zeigst, tut das nicht.

for (int i = 0; i <= (Wegfaktor*275); i++) 
    {         
    tone,3, (Wert1) ; 
    Status=1;       
    delay(10);
    }
else
    {
    Status=2;
    }

Das ist ein FOR-ELSE und das ist nicht zulässig.

Grüße Uwe

Hi

Einfach Mal in der IDE STRG+T drücken und schauen, ob die Klammern wieder 'vorne anschlagen' oder ob mehrere Klammern ganz vorne anliegend gezeigt werden.
Wenn Du also
}
}
in Deinem SKetch siehst, hast Du eine Klammer-Zu zuviel (oder, wohl eher, es fehlt eine Klammer-Auf).
Das Gegenteil, wenn die Endklammer von loop() nicht mehr ganz vorne steht, also um ein paar Zeichen eingerückt steht - dann fehlt irgendwo eine Klammer-Zu.

MfG

Edit DU->Du
@#10 ArduinoDroid klingt irgendwie nach Handy ... nix für Papa's Sohn - Der braucht nen kompletten oldschool-Rechner für so Kram.

Strg+T wird mir von ArduinoDroid nicht angeboten.

Gibt es eine App, die mir meinen Sketch im HID darstellt?

postmaster-ino:
... nix für Papa's Sohn - Der braucht nen kompletten oldschool-Rechner für so Kram.

Das gilt auch für mich, auch wenn es schon ein Läppi ist :slight_smile:

Hab mich wieder an meinen Hauptrechner gesetzt, den kompletten Sketch neu gestaltet, Anforderungen geändert, gestestet, und nur noch einen Fehler drin.

mein Buzzertaster(SpeedPedalSchalter) schaltet den Motor an bis er seine Strecke abgelaufen hat.
er soll aber als Totmanntaster funktionieren, also nur den Motor laufen lassen wenn er gedrückt ist.

vielen Dank erstmal an alle die mich inspiriert haben, es waren soviele neue Möglichkeiten, die ich erstmal verarbeiten musste.

Hier der komplette Sketch

// 03.08.2019  auf  COM18
// Version 1.7            steps an DM542
// (800(5on,6off,7on,8on))   > aus
// (1600(5off,6off,7on,8on)) > aktiv
// (2000(5off,6on,7on,8off)) > aus
// Einschalten Stillstand ok;         > Status0
// Voreinstellung der Länge ok;       > kalibriert
// Cutter ok Länge ok Lauf ok;        > Status1
// Geschwindigkeit-Voreinstellung ok; > kalibriert
// Buzzer ok Länge ok; Lauf ok;       > Status2
//
// Version 1.7
// Gerät einschalten
// Befehl SET >> Button RUN drücken und POTI Gesamtlänge einstellen
// Befehl CUT >> Cutterhebel betätigen für Vorablänge und
// Befehl CUT >> Taster +/- für Einstellung Vorablänge
// Befehl Go  >> Buzzertaster für Restlänge (Gesamtlänge - Vorlauflänge)
// Befehl Go  >> Taster +/- für Einstellung Geschwindigkeit Restlänge

// TODO:  Befehl Go von schalten auf Totmanntaster umstellen
//        Regelpedal für Dauerlauf einbauen  >dann Geschwindigkeit neu kalibrieren

#include <LiquidCrystal.h>
#include <AccelStepper.h>
LiquidCrystal mylcd(8, 9, 4, 5, 6, 7);

#define LCDdimmer 10
#define Brightness 200
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5
#define DIR     2               // Endstufe: DIR grün
#define STEP  3                 // Endstufe: Puls rot
#define ENABLE 12
//#define frei 11

AccelStepper stepper (1, 3, 2);    // Driver 1, Step 3, Dir2)
int sens1;
int fake1;
int sens2;
int fake2;
int cms;
int Vorlauf;                      // LCD-switch case für Vorlauflänge
int SpeedPedalSensor = A1;        // Sensor Eingang A1 für Speed-Pedal-Regler
int Cutter = 18;                  // Sensor Eingang A4 /D18 für Schalter
int SpeedPedalSchalter = 17;      // Sensor Eingang A3 /D17 für Speed-Pedal-Schalter
int LaengenRegler = A2;           // Sensor Eingang A2 für Längen-Regler
char Status;
char ascii[10];                   //--------LCD-Anzeigeformat
int lcd_key     = 0;              //--------LCD-Buttons
int adc_key_in  = 0;
//-------------------------------switch--case--LCD------------
int read_LCD_buttons() {
  adc_key_in = analogRead(0);
  if (adc_key_in > 1000) return btnNONE;
  if (adc_key_in < 50)   return btnRIGHT;
  if (adc_key_in < 250)  return btnUP;
  if (adc_key_in < 450)  return btnDOWN;
  if (adc_key_in < 650)  return btnLEFT;
  if (adc_key_in < 850)  return btnSELECT;
  return btnNONE;
}

void setup() {
  pinMode(DIR, OUTPUT);
  digitalWrite(DIR, HIGH);
  pinMode(ENABLE, OUTPUT);
  digitalWrite(ENABLE, LOW);
  pinMode(STEP, OUTPUT);
  digitalWrite(STEP, HIGH);
  pinMode(LCDdimmer, INPUT);
  pinMode(Cutter, INPUT);
  pinMode(SpeedPedalSchalter, INPUT);
  digitalWrite(LCDdimmer, LOW);
  mylcd.begin(16, 2);
  mylcd.setCursor(0, 0);
  mylcd.print(" CUTTER-2NM ");
  mylcd.setCursor(0, 1);
  mylcd.print("V1.7  03.08.2019");
  delay(3000);
  mylcd.clear();
  mylcd.setCursor(4, 0);
  mylcd.print("Soll ");
  mylcd.setCursor(13, 0);
  mylcd.print(" mm");
  mylcd.setCursor(4, 1);
  mylcd.print("Vorab");
  mylcd.setCursor(13, 1);
  mylcd.print(" mm");
  Vorlauf = 20;
  mylcd.setCursor(10, 1);
  mylcd.print (dtostrf(Vorlauf * 10, 3, 0, ascii));
  Status = 0;
  mylcd.setCursor(0, 0);
  mylcd.print ("SET");
  cms = 20;
  mylcd.setCursor(0, 1);
  mylcd.print (dtostrf(cms, 3, 0, ascii));

  stepper.setMaxSpeed(4000);
  stepper.setAcceleration(4000.0);
}


//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

void loop() {
  lcd_key = read_LCD_buttons();
  switch (lcd_key) {
    case btnUP: {
        if (Status == 1) {                        //Vorlaufeinstellung
          Vorlauf++;
          Vorlauf = constrain(Vorlauf, 1, 100);
          mylcd.setCursor(10, 1);
          mylcd.print (dtostrf(Vorlauf * 10, 3, 0, ascii));
          delay(500);
        }
        if (Status == 2) {                        //Geschwindigkeitseinstellung
          cms++;
          cms = constrain(cms, 1, 25);
          mylcd.setCursor(0, 1);
          mylcd.print (dtostrf(cms, 3, 0, ascii));
          delay(500);
        }
        break;                                    //Vorlaufeinstellung
      }
    case btnDOWN: {
        if (Status == 1) {
          Vorlauf--;
          Vorlauf = constrain(Vorlauf, 1, 100);
          mylcd.setCursor(10, 1);
          mylcd.print (dtostrf(Vorlauf * 10, 3, 0, ascii));
          delay(500);
        }
        if (Status == 2) {                       //Geschwindigkeitseinstellung
          cms--;
          cms = constrain(cms, 1, 25);
          mylcd.setCursor(0, 1);
          mylcd.print (dtostrf(cms, 3, 0, ascii));
          delay(500);
        }
        break;
      }
    case btnRIGHT: {
        //-------------------analogRead(A2)------LängeneinstellPoti------
        sens2 = analogRead(LaengenRegler);             // 0-1023 -> 0-265
        fake2 = map(sens2, 0, 1023, 275, Vorlauf);
        mylcd.setCursor(9, 0);
        mylcd.print (dtostrf(fake2 * 10, 4, 0, ascii));
        mylcd.setCursor(0, 0);
        mylcd.print ("CUT");
        Status = 1;
        break;
      }
  }
  //---------------------Status 0---RegelPedal auslesen----------------------
  //-------------------analogRead(A1)------SpeedPedalSensor------------------
      // sens1 = analogRead(SpeedPedalSensor);         // 0-1023 -> 0-25 cms
      // fake1 = map(sens2, 0, 1023, 0, 25);
  //---------------------Status 1---Cutter auslesen--------------------------
  if (Status == 1) {
    if (digitalRead(18) == HIGH) {                 //Cutter betätigt
      stepper.setMaxSpeed(2200);
      stepper.setAcceleration(2200.0);
      stepper.move(88.25 * Vorlauf);               //Vorlauf setzen
      delay(1500);                           //Wartezeit Cutter Rücksprung
      mylcd.setCursor(0, 0);
      mylcd.print ("GO ");
      Status = 2;
    }
    else {
      Status = 1;
    }
  }
  //---------------------Status 2---Regellänge und Buzzer auslesen---------
  if (Status == 2) {
    if (digitalRead(17) == HIGH) {                  // Buzzer betätigt
      stepper.setMaxSpeed(105 * cms);
      stepper.setAcceleration(2500.0);
      stepper.move(88.25 * (fake2 - Vorlauf));
      mylcd.setCursor(0, 0);
      mylcd.print ("CUT");
      Status = 1;
    }
    else {
      Status = 2;
    }
  }
  stepper.run();
}

Versuche mal dies:

  if (Status == 2) {
    if (digitalRead(17) == HIGH) {                  // Buzzer betätigt
      stepper.setMaxSpeed(105 * cms);
      stepper.setAcceleration(2500.0);
      stepper.move(88.25 * (fake2 - Vorlauf));
      mylcd.setCursor(0, 0);
      mylcd.print ("CUT");
      Status = 1;
    }
    else {
      stepper.stop();
      Status = 2;
    }
  }

Das digitalRead(17) ist blöd, weil ich nach "SpeedPedalSchalter" in Deinem Sketch gesucht habe, aber nicht fündig wurde. Eine unnötige Fehlerquelle.

Danke für den Versuch, agmue
aber dann läuft Status 1 nicht mehr.

mfg

Ich muss doch nochmal um Hilfe fragen, nachdem ich tagelang Accelstepper Befehle ausprobiert habe und mit stop () und run () experimentiert habe und keinen Lösungsansatz entdeckt habe.

Es geht mir darum dieses Problem zu lösen:

mein Buzzertaster(SpeedPedalSchalter) (17)(Buzzer)schaltet den Motor an bis er seine Strecke abgelaufen hat.
er soll aber als Totmanntaster funktionieren, also nur den Motor laufen lassen wenn er gedrückt ist.

Vielen Dank für Hilfestellungen

Hi

Und die Frage?
Klar kann ich mir denken, wie Diese wohl lautet - aber

  • Du darfst durchaus mitarbeiten
  • wir wollen nicht nur irgend was dahingeschmissen bekommen
  • Deinen aktuellen Sketch, WIE ER JETZT IST, wäre bestimmt nicht ganz verkehrt

Was hindert Dich daran, den Taster als Bedingung für den Motor einzubinden?

MfG

Was hindert Dich daran, den Taster als Bedingung für den Motor einzubinden?

Das ist eine gute Idee, aber eine zusätzliche if Anweisung verlangsamt die Steprate wieder.
Werde das mal ausprobieren obs damit passend zu machen ist.

stop ()
void AccelStepper :: stop ( )
Legt eine neue Zielposition fest, bei der der Stepper unter Verwendung der aktuellen Geschwindigkeits- und Beschleunigungsparameter so schnell wie möglich anhält.

"neue Zielposition"

Damit hat sich Accelstepper wohl als Lösung für meinen Totmanntaster selbst ausgeschlossen.

es gibt da keine Pausenmöglichkeit während der gesetzten Zielparameter, selbst wenn der loop läuft.

Vielen Dank für euer Engagement.

Hi

Wenn's um eine 'gleichmäßige Ansteuerung' geht könnten die MpBaTools einen Blick wert sein.
Die lösen die Stepper/Servo/LED-Schaltereien per Timer-Interrupt - also komplett abgekapselt vom Deiner loop();
Rampen sind ebenfalls mittlerweile integriert, in beiden Richtungen 'die Gleiche' - da Das aber auf den gleichen Motor wirkt, sehe ich Nichts, was dagegen spricht.

Allerdings haben auch die MoBaTools das Problem, daß, wenn Du aus voller Fahrt sagtst 'HIER IST STOP', daß der Motor erst abgebremst, auf Stop gebracht und dann in anderer Richtung beschleunigt, abgebremst wird um auf dem Punkt, wo der Befehl kam, anzuhalten.

Man könnte theoretisch vor dem Stop die Beschleunigung auf utopische Werte anheben, damit STOP binnen einem Step bewirkt wird - nur, ob sich der Motor daran hält ???

MfG