2 Stepper Gleichzeitig und Andere Aktionen Paralell

Hallo,
Zur zeit baue ich einen Bewegten Bühnenscheinwerfer, der über DMX angesteuert werden soll.
2 Motoren paralell laufen zu lassen ist mir mit Accelstepper.h und run() schon gelungen. Auch eine ansterung der Motoren über DMX ist kein Probelm. Was mir jedoch Probleme bereitet ist, wenn ich Paralell zur Motor bewegung DMX Werte einlese und diese auf LED's ausgebe. Gleichzeitig soll auch ein 7 Segment Display angesteuert werden. Wenn ich alle diese Funktionen verknüpfe funktioniert jedoch keine Motor bewegung mehr. Die motoren bekommen nur alle Sekungen einen schritt und drehen sich desshalb nur mehr sehr sehl langsam. Die unterschiedlichen Funktionen blokieren sich irgendwie gegenseitig

Hat jemand eine Lösung. Ich suche schon sehr lange, aber finde einfach nichts das Funktioniert.
Danke im Vorraus.

#include <DMXSerial.h>
#include <HCMAX7219.h>
#include <EEPROM.h>
#include "SPI.h"
#define LOAD 53
#include <AccelStepper.h> 

HCMAX7219 HCMAX7219(LOAD);

int Adr=1;    //DMX Adresse
int mult = 0; //Multiplikator fuer Helligkeit
int i=1;      //I Fuer Booten von System
int a=1;      //Zaehlvariable zum Booten
int b=0;      //Zaehlvariable zum Booten
int c=0;      //Zaehlvariable zum Booten
int pos1;     //Motorvariable fuer Automatikprogramm
int pos2;     //Motorvariable fuer Automatikprogramm
int AUTO=1;   //Variable fuer den Automatikkanal ueber DMX
int x=0;      //Zaehlvariable fuer Automatik Display

AccelStepper stepper1(1, 29, 3);
AccelStepper stepper2(1, 37, 2);

void setup() 
{
  DMXSerial.init(DMXReceiver); //DMX Empfaenger, nicht Sender
  
  pinMode(49, INPUT);//Eingnag Taster Hoch
  pinMode(47, INPUT);//Eingang Taster runter

  stepper1.setMaxSpeed(1200);
  stepper1.setAcceleration(10000);
  stepper2.setMaxSpeed(1200);
  stepper2.setAcceleration(5000);
}
void loop()
{
  unsigned long lastPacket = DMXSerial.noDataSince();
  if (lastPacket < 3000 && i==2) 
  {
if((digitalRead(49)==HIGH) || (digitalRead(47)==HIGH))
    {
      if ((Adr >0)&&(Adr <506))
      {
        if (digitalRead(49)==HIGH) //Hoch zaehlen
        {
          Adr=Adr+1;
        }
        if(digitalRead(47)==HIGH) //Runter zaehlen
        {
          Adr=Adr-1;
        }
      }
      if((Adr==0)&&(digitalRead(47)==HIGH))//fall, Adr ist genau 1 (hoch)
      {
        Adr=Adr+1;
      }  
      if((Adr==506)&&(digitalRead(49)==HIGH))//fall, Adr ist genau 505(runter)
      {
        Adr=Adr-1;
      }
   
      delay(120); //entprellen
      EEPROM.write(0, Adr); //neue Adresse in das EEPROM abspeichern
  
      HCMAX7219.Clear();
      HCMAX7219.print7Seg(Adr,4);   //Text "Adr" auf das Display ausgeben
      HCMAX7219.print7Seg("Adr",8); //Wert der Adresse auf das Display ausgeben
      HCMAX7219.Refresh(); 
    }
 
    mult = DMXSerial.read(Adr) *AUTO;                         
    analogWrite(8,  (DMXSerial.read(Adr + 1)*mult / 255)); // Rot Pin 8
    analogWrite(9,  (DMXSerial.read(Adr + 2)*mult / 255)); // Gruen Pin 9
    analogWrite(10, (DMXSerial.read(Adr + 3)*mult / 255)); // Blau Pin 10
    Motor();

  
  if(DMXSerial.read(Adr+6)==255)
  {
    AUTO=0;
  }
  else
  {
    AUTO=1;
  }
  }

void Motor()
{
    digitalWrite(23, LOW);
    digitalWrite(25, LOW);
    digitalWrite(27, LOW);
    if (stepper1.distanceToGo() == 0)
    {
      pos1=map(DMXSerial.read(Adr + 4), 0, 255, 0, -50);
      stepper1.moveTo(pos1);
    }   
    
    if (stepper2.distanceToGo() == 0)
   {
      pos2=map(DMXSerial.read(Adr + 5), 0, 255, 0, -2700);
      stepper2.moveTo(pos2);
   }
    stepper1.run();
    stepper2.run();
}
    stepper1.run();
    stepper2.run();

Das sollte so oft wie möglich aufgerufen werden. Wird es besser, wenn Du diese Zeilen an das Ende von loop() bewegst?

Dein Sketch ist schwierig zu lesen, da Du den Pins keine sprechenden Namen gibst bzw. eine Konkordanz Pinnummer zu Bedeutung fehlt. Du hast das im Kopf, aber ich nicht :frowning:

Ich habe es versucht, die beiden run() ans ende vom loop zu geben, leider ändert sich jedoch garnichts, was die geschwindigeit der Motoren betrifft, beide drehen sich trotzdem noch sehr sehr langsam. So, dass man kaum merkt, das sie sich bewegen.

Hier noch das Pinning:

//Kanal 1..........Dimmer fuer Farben
//Kanal 2..........Rot
//Kanal 3 .........Gruen
//Kanal 4 .........Blau
//Kanal 5 .........Motor 1
//Kanal 6 .........Motor 2
//Kanal 7 .........Automatikprogramm

//LED Platine:
//LED ROT       8  //
//LED GRUEN     9  //
//LED BLAU      10 //

//Display:
//DIN           51 //
//CLK           52 //
//CS            53 //

//Anschlaege:
//Taster 1      43 //
//Taster 2      45 //

//Adresstaster:
//TASTER RUNTER 47 //
//TASTER HOCH   49 //

//Motor 1:            Motor 2:
//DIR           3  // DIR           2  //
//STEP          29 // STEP          37 //  
//M2            27 // M2            35 //
//M1            25 // M1            33 //
//M0            23 // M0            31 //
int i=1;      //I Fuer Booten von System
...
	if (lastPacket < 3000 && i==2)
	{
...
		Motor();
...
	}
}

Da i nie verändert wird, wird i==2 nie wahr, weshalb Motor() nie aufgerufen werden dürfte, sagt der Prozessor zwischen meinen Ohren. Oder?

Es ist so das am anfang noch ein kleines unterprogramm ausgeführt wird, bei dem beide Motoren auf eine 0 position fahren, bis sie einen Taster berührern, danach wird i auf 2 gesetzt.
Das gleiche gilt für AUTO am ende des Programmes. Wenn AUTOP auf 0 gesetzt wird, wird eine Weiteres unterprogramm aufgerufen. Diese beiden Programmteile hab ich hier nur weg gelassen, da sie nichts mit den Problemen der Motoren zu tun haben.

Wenn ich in meinem Programm das Abfragen der Adresstaster und das Abfragen des Wertes für AUTO auskommentiere funktioniert das Programm so wie es ist, mit Motor ansterung.

Peeceet:
Diese beiden Programmteile hab ich hier nur weg gelassen, ...

Erwischt :slight_smile:

Schmeiß mal diese Zeilen raus, delay wegen der Verzögerung, EEPROM um es zu schützen, Clear weil es Zeit benötigt:

			delay(120); //entprellen
			EEPROM.write(0, Adr); //neue Adresse in das EEPROM abspeichern
			HCMAX7219.Clear();

Taste Dich langsam an die störende(n) Zeile(n) ran.

Ich hab das Problem gelöst!
Zum einen habe ich herrausgefunden das ich meine Taster auf LOW abfragen muss und nicht auf HIGH, das war mal der eine Fehler und zum Anderen habe ich die das delay, EEPROM und Display in eine if geschrieben, dass es nur ausgeführt wird, wenn eine Taste gedrückt wird.
Und jetzt funktionierts perfekt!
Danke!! :wink: