Brauche Hilfe Schrittmotor soll nur X Sekunden laufen

Hallo,

Ich bin neu hier und kenne mich mit der Programmierung leider noch nicht so gut aus. Ich benötige eine Schaltung (Wasser Pegelschalter) der einen Schrittmotor antreibt, sobald der Wasserstand erreicht wird.

Die Schaltung habe ich fertig (Arduino Nano und Pololu Treiber sowie einen Schwimmschalter). Alles funktioniert wie es soll, nur möchte ich eine Zeitsperre haben. Also wenn der Pegelschalter mal verklemmen sollte, darf der Motor nicht unendlich lange weiter laufen. Er soll nach z.B. einer Minute automatsich abschalten, egal was der Pegelschalter sagt.

Hier mein bisher zusammengepfuschter Code :slight_smile: nur noch ohne die Notabschaltung.

Kann mir da bitte jemand behilflich sein, gerne auch gegen Bezahlung.

// testing a stepper motor with a Pololu A4988 driver board or equivalent

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other and it turns CCW

byte directionPin = 9;
byte stepPin = 8;

byte buttonCWpin = 5;

boolean buttonCWpressed = false;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 3; // milliseconds

void setup() { 

     Serial.begin(9600);
     Serial.println("Starting Stepper Demo with millis()");

     pinMode(directionPin, OUTPUT);
     pinMode(stepPin, OUTPUT);
     pinMode(ledPin, OUTPUT);
     pinMode(7, OUTPUT); // Enable
     
     pinMode(buttonCWpin, INPUT_PULLUP);
     
     digitalWrite(7, HIGH);
     
}

void loop() { 
    
    curMillis = millis();
    readButtons();
    actOnButtons();
    
}

void readButtons() {
    
    
    buttonCWpressed = false;
    
    if (digitalRead(buttonCWpin) == LOW) {
        digitalWrite(7, LOW);
        buttonCWpressed = true;
    }
}

void actOnButtons() {
    if (buttonCWpressed == true) {
        digitalWrite(directionPin, LOW);
        singleStep();
    }

else if (buttonCWpressed == false) {
        digitalWrite(7, HIGH);
}

}

void singleStep() {
    if (curMillis - prevStepMillis >= millisBetweenSteps) {
            // next 2 lines changed 28 Nov 2018
        //prevStepMillis += millisBetweenSteps;
        prevStepMillis = curMillis;
        digitalWrite(stepPin, HIGH);
        digitalWrite(stepPin, LOW);
    }
}

Bau dir ein Timer :slightly_smiling_face:

Int Counter = 0;


In deinem loop machst du dann.. 

curMillis = millis(); 
readButtons(); 
actOnButtons();
 
If(Counter < 1000 and buttonCWpressed = true){
Counter +=1; 
Serial.print(Counter); 

}else if(buttonCWpressed = false){
Counter =0;

}else if(Counter >=1000){
buttonCWpressed = false;

}

P.s ich bin mir grad nicht sicher ob buttonCWpressed der richtige ist. Eventuell doch lieber digitalWrite(7, HIGH) abfragen. Einfach testen, 1000 ist nur ein beispiel konnten bei dir eventuell ms sein und nicht sec.. mit Serial.print(Counter); checken ob es paßt :wink:

Du hast außerdem ein Fehler drinen...

buttonCWpressed = false; // gibt beim durchlaufen IMMER False Auch dann wenn konditionen passen....
if(digitalRead(buttonCWpin) == LOW) { 
digitalWrite(7, LOW); 
buttonCWpressed = true; } //Ergibt: False,True,False,True.....

Richtig..


if(digitalRead(buttonCWpin) == LOW) { //Bei diese kondition
digitalWrite(7, LOW); 
buttonCWpressed = true;

 }else if(digitalRead(buttonCWpin) ==HIGH{//Oder diese Kondition 
buttonCWpressed = false;
}

Oder..


if(digitalRead(buttonCWpin) == LOW) { //Bei diese Kondition 
digitalWrite(7, LOW); 
buttonCWpressed = true;

 }else{ //Bei alle andre Konditionen wenn digitalRead(buttonCWpin) ist nicht = LOW
buttonCWpressed = false;
}

Vielen Dank für deine Hilfe. Ich werde das nachher mal direkt versuchen so umzusetzen. Ich melde mich dann wieder.

LG
Andreas

Funktioniert irgendwie noch nicht. Das wird wahrscheinlich daran liegen, weil ich überhaupt keine Ahnung habe die richtigen Stellen zu finden :slight_smile: Sorry, ich weiß kaum was ich da tu.

// testing a stepper motor with a Pololu A4988 driver board or equivalent

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other and it turns CCW

byte directionPin = 9;
byte stepPin = 8;

byte buttonCWpin = 5;

boolean buttonCWpressed = false;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 3; // milliseconds
int Counter = 0;

void setup() { 

     Serial.begin(9600);
     Serial.println("Starting Stepper Demo with millis()");

     pinMode(directionPin, OUTPUT);
     pinMode(stepPin, OUTPUT);
     pinMode(ledPin, OUTPUT);
     pinMode(7, OUTPUT); // Enable
     
     pinMode(buttonCWpin, INPUT_PULLUP);
     
     digitalWrite(7, HIGH);
     
}

void loop() { 
    
    curMillis = millis();
    readButtons();
    actOnButtons();

    if(Counter < 10 and buttonCWpressed == true){
    Counter +=1; 
    Serial.print(Counter); 

    }else if(buttonCWpressed = false){
    Counter =0;

    }else if(Counter >=10){
    buttonCWpressed = false;

}
    
}

void readButtons() {
    
    
if(digitalRead(buttonCWpin) == LOW) { //Bei diese kondition
digitalWrite(7, LOW); 
buttonCWpressed = true;

 }else if(digitalRead(buttonCWpin) ==HIGH){//Oder diese Kondition 
buttonCWpressed = false;
}
}

void actOnButtons() {
    if (buttonCWpressed == true) {
        digitalWrite(directionPin, LOW);
        singleStep();
    }

else if (buttonCWpressed == false) {
        digitalWrite(7, HIGH);
}

}

void singleStep() {
    if (curMillis - prevStepMillis >= millisBetweenSteps) {
            // next 2 lines changed 28 Nov 2018
        //prevStepMillis += millisBetweenSteps;
        prevStepMillis = curMillis;
        digitalWrite(stepPin, HIGH);
        digitalWrite(stepPin, LOW);
    }
}

Erklärung zu digitalWrite(7..... : Pin 7 Schaltet den Motor stromlos, um Energie im Ruhezustand zu sparen. Nur nebenbei erwähnt. Funktioniert auch.

Ich auch nicht

// testing a stepper motor with a Pololu A4988 driver board or equivalent

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other and it turns CCW

byte directionPin = 9;
byte stepPin = 8;

byte buttonCWpin = 5;

boolean buttonCWpressed = false;
bool lastButtonMerker = false;
uint32_t buttonStartTime = 0;
const uint32_t driverLockTime = 5000; // Zeit in ms

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 3; // milliseconds

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting Stepper Demo with millis()");
  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(7, OUTPUT); // Enable
  pinMode(buttonCWpin, INPUT_PULLUP);
  digitalWrite(7, HIGH);
}

void loop()
{
  curMillis = millis();
  readButtons();
  actOnButtons();
}

void readButtons()
{
  buttonCWpressed = false;
  if (digitalRead(buttonCWpin) == LOW)
  {
    digitalWrite(7, LOW);
    buttonCWpressed = true;
    if (!lastButtonMerker)
    {
      buttonStartTime = curMillis;
      lastButtonMerker = true;
    }
  }
  else
    lastButtonMerker = false;
}

void actOnButtons()
{
  if (buttonCWpressed == true)
  {
    digitalWrite(directionPin, LOW);
    singleStep();
  }
  else if (buttonCWpressed == false)
  {
    digitalWrite(7, HIGH);
  }
}

void singleStep()
{
  if (lastButtonMerker == true &&
      curMillis - buttonStartTime > driverLockTime)
  {
    return;
  }
  if (curMillis - prevStepMillis >= millisBetweenSteps)
  {
    // next 2 lines changed 28 Nov 2018
    //prevStepMillis += millisBetweenSteps;
    prevStepMillis = curMillis;
    digitalWrite(stepPin, HIGH);
    digitalWrite(stepPin, LOW);
  }
}
1 Like

Schon klar... aufgespielt und funktioniert sofort auf Anhieb. Du weißt genau was du tust :slight_smile: Ich danke dir vielmals. Muss jetzt nur noch hinbekommen, dass bei dem Notaus ein Alarmsignal oder eine LED an geht und der Motor dann ebenfalls stromlos geschaltet wird.

DU BIST GROßARTIG!

also der code von @seby1302 ist kein richtiger Timer sondern ein Zähler
Das hochzählen braucht natürlich auch eine gewisse Zeit.

So jetzt mal der Reihe nach:

1 Schritt eine Beschreibung der Funktionalität ohne Programm

Es gibt einen Wasserpegelschalter
Wenn der Pegelschalter schaltet dann
Schrittmotor laufen lassen

Normalablauf:
Pegelschalter schaltet ein
Schrittmotor läuft an.
Der laufende Schrittmotor senkt den Wasserpegel
Wenn Wasserpegel gesunken ist schaltet der Pegelschalter aus
dann soll der Schrittmotor abschalten

Störungsfall mit Zeitüberwachung:
Pegelschalter schaltet ein
Schrittmotor läuft an.
Der laufende Schrittmotor senkt den Wasserpegel
da aber sich der Pegelschalter verklemmt hat schaltet der Pegelschalter nicht um
==> Schrittmotor läuft (erst einmal weiter)

Damit der Schrittmotor nicht stundenlang weiterläuft soll nach einer programmierten Zeit
der Schritmotor abschalten obwohl der Pegelschalter immer noch eingeschaltet ist.

Ist das so richtig?
vgs

Ja, dass ist genau richtig so. Der Motor wickelt ein Vlies von der Rolle ab. Das neue Vlies lässt das Wasser wieder besser durchlaufen, deshalb sinkt der Wasserstand. Bei einem Pegelfehler würde die ganze 200 Meter lange Rolle abgewickelt werden, dass möchte ich vermeiden.

// testing a stepper motor with a Pololu A4988 driver board or equivalent

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other and it turns CCW

byte directionPin = 9;
byte stepPin = 8;

byte buttonCWpin = 5;

boolean buttonCWpressed = false;
bool lastButtonMerker = false;
uint32_t buttonStartTime = 0;
const uint32_t driverLockTime = 5000; // Zeit in ms
const byte alarmPin = 6;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 3; // milliseconds

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting Stepper Demo with millis()");
  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(7, OUTPUT); // Enable
  pinMode(buttonCWpin, INPUT_PULLUP);
  pinMode(alarmPin, OUTPUT);
  digitalWrite(7, HIGH);
}

void loop()
{
  curMillis = millis();
  readButtons();
  actOnButtons();
}

void readButtons()
{
  buttonCWpressed = false;
  if (digitalRead(buttonCWpin) == LOW)
  {
    digitalWrite(7, LOW);
    buttonCWpressed = true;
    if (!lastButtonMerker)
    {
      buttonStartTime = curMillis;
      lastButtonMerker = true;
    }
  }
  else
  {
    lastButtonMerker = false;
    digitalWrite(alarmPin, LOW);
  }
}

void actOnButtons()
{
  if (buttonCWpressed == true)
  {
    digitalWrite(directionPin, LOW);
    singleStep();
  }
  else if (buttonCWpressed == false)
  {
    digitalWrite(7, HIGH);
  }
}

void singleStep()
{
  if (lastButtonMerker == true &&
      curMillis - buttonStartTime > driverLockTime)
  {
    digitalWrite(directionPin, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(alarmPin, HIGH);
    return;
  }
  if (curMillis - prevStepMillis >= millisBetweenSteps)
  {
    // next 2 lines changed 28 Nov 2018
    //prevStepMillis += millisBetweenSteps;
    prevStepMillis = curMillis;
    digitalWrite(stepPin, HIGH);
    digitalWrite(stepPin, LOW);
  }
}
1 Like

Na bitte na also wer sagst denn
Sobald man eine Beschreibung des Gesamtprojektes bekommt tun sich neue Lösungsmöglichkeiten auf:

Da du ja schon einen Schrittmotor hast kannst du den Schrittmotor eine programmierte Anzahl Schritte fahren lassen und dann den Motor anhalten. Die Anzahl Schritte könnten 10 oder 10tausend oder auch 10 Milionen sein ganz das was man tatsächlich braucht.

Schrittmotoren werden so betrieben, dass im Betrieb keine so hohe mechanische Belastung auftritt, dass der Schrittmotor Schritte verliert. Schritte verlieren heißt Es wird zwar die passende Umschaltung der Bestromung (im Schrittmotortreiber) durchgeführt aber die Welle des Schrittmotors dreht sich nicht mit. Schritt "ausgegeben" Welle hat sich aber nicht gedreht = Schritt verloren.

Ich nehme jetzt an dass dein Schrittmotor das Weiterbewegen des Fließes gut hinbekommt
= keine Schritte verliert.

Passende Schrittzahl ausgeben und dann Motor wieder anhalten. Jedes mal.

Eventuell eine gewisse Zeit abwarten und dann checken hat sich der Wasserpegel auch wirklich gesenkt. Wenn nicht Störungslampe anschalten.

vgs

Das ist irrrelevant, da Du nicht weisst:
a: Wie gross der Wickel ist
b: wie Straff gewickelt wird.

DAS ist es! Ich spreche hier meine Hochachtung aus. Blitzschnell reagiert und selbstlos einer anderen Person geholfen. Dieses Forum ist der Hammer... ich freue mich riesig!

Noch ein wichtiger Hinweis:
als ganze neuer User hat man zunächst nur eine begrenzte Anzahl postings pro Tag
Das sind 10 Stück.
Wenn man den sogenannten Trust-Level 1 erreicht hat kann man mehr posten und auch Bilder posten
Um auf Trustlevel 1 zu kommen muss man
Get to trust level 1 by…

  • mindestens 5 verschiedene themen angeklickt haben
  • mindestens 30 postings gelesen haben (= müssen auf dem Bildschirm angezeigt wurden sein)
  • mindestens 10 minutes lang im Forum unterwegs gewesen sein

Wo ich mir noch nicht ganz sicher bin ob das mit zu den Bedingungen gehört ist
mindestens 24 Stunden lang registriert sein.
Also am Anfang sparsam posten. Nicht einfach so drauf los wie beim wamsen.
(Wat is wamsen??? WhatsAppen sagt sich nur schneller so wie "simsen")

Das dient als Sperre gegen SPAM-Bots. Also jetzt nicht einfach dauflosposten sondern

gut

überlegen was will ich als Info alles noch rüberbringen?

Wo wir schon bei gründlicher Analyse sind:
Wenn der Pegelschalter verklemmen kann wie sieht denn die gesamte Anlage aus?
Wäre es ein Problem wenn sich das Wasser immer höher staut?
Gibt es einen Überlauf?
Kann man an dem Überlauf einen Wassersensor anbringen?
Wenn Wassersensor am Überlauf "naß" meldet Störungssignal setzen.
vgs

1 Like

Ich danke dir. Das Wasser kann ruhig überlaufen, es ist ein Notüberlauf vorhanden. Lediglich die Vliesrolle darf sich nicht weiter abwickeln. Es wäre mühsam 200 Meter wieder zurück zu rollen :wink:

Wer einmal den Wickel aus dem Kühlmittelfilter eines CNC-Bearbeitungszentrum hat....

1 Like

Ja dann eben Zähler :grinning:

Mit richtigem Timer ist natürlich schneller.

Mit buttonCWpressed = false; Jap merke ich grade auch, sorry mein Fehler das ist wohl der Aktueller Botton zustand. :sweat_smile:
Dann passt es so auch einigermaßen, wobei ich das explizit auswerte.
Wobei Solange es Kein Haltemichlänger gedrückt taste sein soll passt das auch wie oben.
Ansonsten hätte ich beim durchlaufen der schleife, anfangs immer False zu erst..

 if (digitalRead(buttonCWpin) == LOW){
buttonCWpressed = false;
}else  if (digitalRead(buttonCWpin) == HIGH){
buttonCWpressed = true;
}

Was ich mich noch frage ist, digitalWrite(7, HIGH); Ist das nicht der ENABLE Pin Vom Stepper?
Demnach muss der Arduino über den Pin 7 Power Abgeben, damit der Stepper Innaktiv ist?
Würde Wiederum Heißen, sollte der arduino Hängen Oder aus gehen Also (Pin7 = LOW).
Dan Hast du ein Brumm Stepper der Nebenbei Schön Heiß Läuft?

void Setup(){
digitalWrite(7, HIGH);
}

Hallo.

Beim ersten Testlauf habe ich festgestellt, dass der Motor besser beim auslösen des Pegels eine bestimmte Zeit laufen sollte.

Also z.B. Pegel löst aus. Motor läuft ca. 40 Sekunden, obwohl der Pegelschalter schon wieder unten ist. Dann stoppt der Motor nach 40 Sekunden und wartet wieder auf den Pegelstand, bis er wieder auslöst. Läuft der Motor länger als 2 Minuten, greift der Notaus.

Bekommt man das auch hin?

LG und bleibt gesund.

Andreas

Ja sicher.
Da kann man dann gleich direkt programmieren den Schrittmotor 40 Sekunden lang laufen zu lassen. Und dann soll er auf jeden Fall anhalten. Wie viel Fließ damit weitergewickelt wurde hängt dann aber von der Schrittausgabe-Frequenz ab. Andere Frequenz andere Laufzeit.

Wenn man eine bestimme Anzahl Schritte ausgibt dann ist die Ausgabefrequenz völlig egal weil man ja eine bestimmte Anzahl Schritte ausgibt.
Schrittmotor heißt: ein Impuls = 1 Schritt (= 1,8° Drehung oder bei Halbschrittmodus 0,9° Drehung der Motorachse
das ist bei einem Schrittmotor immer so.

So ein Mikrocontroller kann auch vier Milliarden Schritte am Stück ausgeben wenn es sein muss Das ist jetzt keine Übertreibung
unsigned long = 32 bit
= 2 hoch 32 = 4.294.967.296

Kannst du bitte mal einen Link zu dem Motor und/oder das Datenblatt des Motors posten?
Ich möchte überprüfen ob das wirklich ein Schrittmotor ist.
Da du so sehr auf "Motor eine bestimmte Zeit laufen lassen" fixiert bist habe ich da inzwischen Zweifel.

vgs

Das ist mir alles bekannt, nur habe ich Probleme das im Script mit einzubinden. Was ein Schrittmotor ist, ist mir auch bekannt :slight_smile:

// testing a stepper motor with a Pololu A4988 driver board or equivalent

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other and it turns CCW

byte directionPin = 9;
byte stepPin = 8;

byte buttonCWpin = 5;

boolean buttonCWpressed = false;
bool lastButtonMerker = false;
uint32_t buttonStartTime = 0;
const uint32_t driverLockTime = 20000; // Zeit in ms
const uint32_t laufZeit = 5000;
const byte alarmPin = 6;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 3; // milliseconds

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting Stepper Demo with millis()");
  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(7, OUTPUT); // Enable
  pinMode(buttonCWpin, INPUT_PULLUP);
  pinMode(alarmPin, OUTPUT);
  digitalWrite(7, HIGH);
}

void loop()
{
  curMillis = millis();
  readButtons();
  actOnButtons();
}

void readButtons()
{
  buttonCWpressed = false;
  if (digitalRead(buttonCWpin) == LOW)
  {
    digitalWrite(7, LOW);
    buttonCWpressed = true;
    if (!lastButtonMerker)
    {
      buttonStartTime = curMillis;
      lastButtonMerker = true;
    }
  }
  else
  {
    digitalWrite(alarmPin, LOW);
  }
}

void actOnButtons()
{
  if (buttonCWpressed == true)
  {
    digitalWrite(directionPin, LOW);
    singleStep();
  }
  else if (buttonCWpressed == false)
  {
    digitalWrite(7, HIGH);
  }
}

void singleStep()
{
  if (lastButtonMerker == true && curMillis - buttonStartTime > driverLockTime) // Alarmzeit
  {
    digitalWrite(directionPin, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(alarmPin, HIGH);
    return;
  }
  if (curMillis - buttonStartTime < laufZeit)
  {
    if (curMillis - prevStepMillis >= millisBetweenSteps)
    {
      // next 2 lines changed 28 Nov 2018
      //prevStepMillis += millisBetweenSteps;
      prevStepMillis = curMillis;
      digitalWrite(stepPin, HIGH);
      digitalWrite(stepPin, LOW);
    }
  }
}