Absturz bei sehr vielen Schrittmotorsteps

Hallo zusammen!

ich bin gerade dabei ein Smartrollo zu bauen.
Momentan versuche ich das Hoch- und Runterfahren zu programmieren. Ich benutze als Antrieb einen Schrittmotor mit einem Schneckengetriebe, einen A4988 Motortreiber und ein Esp8266 NodeMCU Board.
Da das Schneckengetriebe eine ziemlich große Untersetzung hat und das Rollo sehr groß ist, muss ich sehr viele Motor-steps machen. Zu dem steuere ich den Motor mit 1/16 Step an.Irgendwann stützt mein Controller dann einfach ab.
Hier mal mein Code:

#include <Arduino.h>

const uint8_t PinEnable = D0;
const uint8_t PinStep = D4;
const uint8_t PinRichtung = D5;
const uint8_t PinSchrittgroesse1 = D1;
const uint8_t PinSchrittgroesse2 = D2;
const uint8_t PinSchrittgroesse3 = D3;

void setup() 
{
  pinMode(PinStep, OUTPUT); 
  pinMode(PinRichtung, OUTPUT); 
  pinMode(PinEnable, OUTPUT);
 
  // Pins zum Schrittgröße einstellen
  pinMode(PinSchrittgroesse1, OUTPUT);
  pinMode(PinSchrittgroesse2, OUTPUT);
  pinMode(PinSchrittgroesse3, OUTPUT);


  // Kleinste Schrittgröße einstellen
  digitalWrite(PinSchrittgroesse1, HIGH);
  digitalWrite(PinSchrittgroesse2, HIGH);
  digitalWrite(PinSchrittgroesse3, HIGH);

  // Motor anschalten
  digitalWrite(PinEnable, LOW);

  // Richtung einstellen
  digitalWrite(PinRichtung, HIGH);
}

void loop() 
{    
    for (int i=0; i < 20000; i++)
    {
      digitalWrite(PinStep, HIGH);
      delayMicroseconds(200);
      digitalWrite(PinStep, LOW);
      delayMicroseconds(200);
    }
    delay(2000);  
}

Mit 2000 Schritten funktioniert es noch.

Vielleicht habt ihr da eine Idee wie man das Problem umgehen kann.

Viele Grüße

fps_boost

statt einer Variable vom typ int eine Variable vom typ unsigned long verwenden.
Int speichert Zahlen +-32768, unsigned long 0 bis 4 Milliarden.

oder eine Schrittmotor-library accelstepper oder moba-tools da gibt es Befehle lass Schrittmotor laufen
bis stop-Befehl gegeben wird.

FPS_Boost:
Da das Schneckengetriebe eine ziemlich große Untersetzung hat und das Rollo sehr groß ist, muss ich sehr viele Motor-steps machen. Zu dem steuere ich den Motor mit 1/16 Step an.

Welchen Sinn sollen bei dieser starken Untersetzung des Getriebes Microsteps haben?

Gruß Tommy

Der Motor läuft dann deutlich leiser und ruhiger.

StefanL38:
statt einer Variable vom typ int eine Variable vom typ unsigned long verwenden.
Int speichert Zahlen +-32768, unsigned long 0 bis 4 Milliarden.

oder eine Schrittmotor-library accelstepper oder moba-tools da gibt es Befehle lass Schrittmotor laufen
bis stop-Befehl gegeben wird.

Habe es gerade mit einem ulong probiert hat nicht funktioniert. Beim Esp 8266 ist long auch nur 8 Byte
groß. Länge der Datentypen beim ESP8266

Mein Tipp wären auch die MobaTools, die Du mit der IDE installieren kannst. Wenn der Lauf dann ruhiger sein sollte, könntest Du noch mal mit den Microsteps probieren.

Versuche mal uint32_t als Typ.

StefanL38:
statt einer Variable vom typ int eine Variable vom typ unsigned long verwenden.
Int speichert Zahlen +-32768, unsigned long 0 bis 4 Milliarden.

Auf einem ESP8266 hat int einen Wertebereich von +/- 2Mrd, das sollte reichen.

Der ESP stürzt ab, wenn der loop zu lange aufgehalten wird. Verwendet man delay() passiert das nicht, da dort intern yield aufgerufen wird. Ob das bei delayMicroseconds auch so ist weis ich allerdings nicht. Wenn nicht, dürfte das der Grund sein.

Ich habe gerade delay(1) getestet und siehe da es funktioniert! Leider ist der Motor dann viel zu langsam für meine Anwendung. Ich werde mir deshalb mal die Libraries anschauen.

MicroBahner:
Der ESP stürzt ab, wenn der loop zu lange aufgehalten wird.

Gut zu wissen, man lernt halt nie aus :slight_smile:

FPS_Boost:
Leider ist der Motor dann viel zu langsam für meine Anwendung.

Zum Testen würde es ja auch reichen, erstmal nur eines der delayMicroseconds auf delay81) umzustellen, und die Impulsdauer ( das erste delay ) auf 10µs zu stellen ( das reicht ); Du könntest auch versuchen, in deiner for-Schleife selbst yield(); aufzurufen ( bin mir nicht ganz sicher, aber das müsste reichen ).
Die Option mit den Libs hast Du dann immer noch :wink: .

Vielen Dank für Eure Antworten! Ist ein super Forum!

Ich konnte das Problem lösen, indem ich yield() zwischendurch aufrufe.
Jetzt funktioniert alles wunderbar. :grinning:

Hier mein funktionierender Code:

#include <Arduino.h>

const uint8_t PinEnable = D0;
const uint8_t PinStep = D4;
const uint8_t PinRichtung = D5;
const uint8_t PinSchrittgroesse1 = D1;
const uint8_t PinSchrittgroesse2 = D2;
const uint8_t PinSchrittgroesse3 = D3;

void setup()
{
  pinMode(PinStep, OUTPUT);
  pinMode(PinRichtung, OUTPUT);
  pinMode(PinEnable, OUTPUT);
 
  // Pins zum Schrittgröße einstellen
  pinMode(PinSchrittgroesse1, OUTPUT);
  pinMode(PinSchrittgroesse2, OUTPUT);
  pinMode(PinSchrittgroesse3, OUTPUT);


  // Kleinste Schrittgröße einstellen
  digitalWrite(PinSchrittgroesse1, HIGH);
  digitalWrite(PinSchrittgroesse2, HIGH);
  digitalWrite(PinSchrittgroesse3, HIGH);

  // Motor anschalten
  digitalWrite(PinEnable, LOW);

  // Richtung einstellen
  digitalWrite(PinRichtung, HIGH);
}

void loop() 
{    
    for (uint32_t  i=0; i < 1400000; i++)
    {
      digitalWrite(PinStep, HIGH);
      delayMicroseconds(20);
      digitalWrite(PinStep, LOW);
      delayMicroseconds(20);
      yield();
    }
    delay(5000);  
}
}

Hier ist ein Artikel aus der Arduinodokumentation dazu:
https://www.arduino.cc/en/Reference/SchedulerYield