steppers meerdere assen tegelijk.

trix

Golden Member

zoals bij sommige bekend ben ik bezig met een wat groter project, waarin meerdere steppers zitten met ieder een eigen stepper driver.
de assen werken al wel, maar zijn zodanig geprogrameerd dat er maar 1 as tegelijk kan draaien. het is voor nu nog geen echte noodzaak, maar ik denk wel dat ik later meerdere assen tegelijk moet kunnen laten draaien.
dus ik ben aan het nadenken hoe dit te doen.
nou heeft daar in een ander topic, stijnos al eens ooit hier iets over gezegd, wat ik hier onder dus quote.
vraag is eigenlijk hoe gaat het dan met de acc en deceleratie.
of hoe worden normaal gesproken meerdere assen aan gestuurd inclusief acc en deceleratie ?

Je hebt een homing sensor dus bij de init loop je terug naar de aanslag en dan ben je op positie 0. Vanaf daar hou je het aantal stappen bij en weet je altijd waar je zou moeten zitten (er vanuit gaan de dat je geen slip hebt)

Een 2e tip is als je hiervoor openstaat het zo te maken dat de functie MoveNumberOfSteps enkel een variabele richting en aantal stappen zet, maar niet zelf de pulsen voor de stepper gaat maken.

Ik heb je stepper driver bekeken en ik snap eigenlijk niet waarom jouw 1 Mhz uberhaubt van belang is. Jouw stepper driver bepaald het aantal stappen en 1 stap is gewoon een vaste verplaatsing van afstand.
Dus als je hem 1000 pulsen geeft ongeacht op welke snelheid dan verplaatst de motor zich even ver.

Ik zou een interrupt maken met je timer 1 op bijvoorbeeld 500uS of misschien wat sneller als dat toelaat.

En die interrupt controlleert of het aantal stappen is gemaakt en zo niet dan doet hij de een keer de pulse pin hoog maken en de andere keer de pulse pin laag.
Meer niet.
Als je dit aan het doen bent zet je een vlaggetje (beter een enum met status) STEPPER_IS_MOVING en heb je het aantal stappen bereikt in je interrupt dan zet je deze status op STEPPER_IN_POSITION

In je main loop hoef je dan enkel een gewenste positie te schrijven en parallel op de achtergrond gaat die stepper wel naar de positie die jij wilt. Ondertussen doe je van alles tot de status meld STEPPER_IN_POSITION.

Op deze manier kun je in de main 10 of 100 verschillende taken doen en doet die stepper etc zijn ding wel, waar jij niet op hoeft te wachten.

Goed genoeg tips :)
Doe ermee wat je wilt, maar neem van mij aan, als je straks tegen issues aanloopt dat het niet werkt of niet meer wilt werken dan zat hier je fout. Het design, de schaalbaarheid en het overzicht. Dat zijn dingen die je later niet nog even doet of aanpast.

eigenwijs = ook wijs

Ik heb voor iedere motor een positie, een snelheid en een accelleratie. Iedere interrupt doe ik snelheid += accelleratie; positie += snelheid.

De positie en snelheid moet je zien als "fixed point" getallen, maar dus wel met een zwik bits achter de comma. pas als de positie voorbij bijvoorbeeld 2^24 komt dan geef je een stap-commando naar de stepper driver. Als je "snelheid" dan 2^23 is dan geef je dus iedere 2 interrupts een stap-commando aan de stepper driver.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Lambiek

Special Member

Lees dit eens door, ik laat ook meerdere motoren te gelijk draaien. Maar ik gebruik hier geen rampup en rampdown.

https://www.circuitsonline.net/artikelen/view/58

Als je haar maar goed zit, GROETEN LAMBIEK.
trix

Golden Member

ga ik bekijken, en dat van rew, moet ik nog eens over nadenken.

eigenwijs = ook wijs

Dan moet je dus de drie motoren tegelijk processen.
En in een soort state machine bijhouden waar je bent.

Bijvoorbeeld zo:
-- Wel in C++, dus je sourcefile moet de extensie .cpp hebben.

code:



class Stepper
{
public:
   Stepper(uint8_t Id)
   {  m_Id        = Id;
      m_Timer     = millis();
      m_StepDelay = 0;
   }

   void SetSpeed(uint16_t StepsPerSecond)
   {  m_StepDelay = 1000 / StepsPerSecond;
   }

   void Run()
   {  if(m_StepDelay)
      {
         if( (millis() - m_Timer) >= m_StepDelay)
         {  m_Timer += m_StepDelay;
            Step();
         }
      }
      else
      {  m_Timer = millis();
      }
   }

   void Step()
   {  // Hier de code voor een step...
      switch(m_Id)
      {  case 1:   // Code may be different per motor
         {  // ..
            break;
         }
         case 2:
         {  // ..
            break;
         }
         case 3:
         {  // ..
            break;
         }
      }
   }

   uint8_t  m_Id;
   uint32_t m_Timer;
   uint32_t m_StepDelay;
};


Stepper Motor1(1);
Stepper Motor2(2);
Stepper Motor3(3);

void setup()
{  Motor1.SetSpeed(200);
   Motor2.SetSpeed(175);
   Motor3.SetSpeed( 25);
}

void loop()
{
   for( ;; )
   {  Motor1.Run();
      Motor2.Run();
      Motor3.Run();
   }
}

trix

Golden Member

probeer het tot me te laten doordringen,....duurt dus nog even :)

eigenwijs = ook wijs

Bij "marlin" de 3D-printer-firmware loopt de stepper-loop op 10kHz. Op hoge loop-snelheden geven ze dan ongeveer 3 pulsjes aan 1 stepper in 1 interrupt. 30 stapjes per ms.

Dat kan je dus niet halen als je idee van tijd gebaseerd is op "millis ()".

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Tuurlijk, er zijn grenzen aan de toepasbaarheid.

Het is maar een simpel voorbeeldje hoe je drie dingen tegelijk kunt laten lopen.

trix

Golden Member

zit in dat voorbeeld ook acc en decc verwerkt ?

eigenwijs = ook wijs

Nee, dat zit er niet in. Ik weet ook niet wat de bedoeling is.
Wil je een bepaald aantal stappen zetten? Of wil je een bepaalde snelheid halen?

Ook de aansturing van de motoren moet je nog toevoegen binnen de Step() funktie. Dat hangt af van de stepper library die je gebruikt..

Het is alleen een voorbeeldje om te laten zien hoe je 3 dingen tegelijk kunt besturen. De verdere details zul je nog moeten toevoegen.

trix

Golden Member

oke,....snelheid is constant, belangrijkste is de afgelegde afstand, of het positioneren van de as.
ik gebruik nu geen libary, mischien moet ik daar eens naar kijken ?

[Bericht gewijzigd door trix op vrijdag 8 mei 2020 21:19:28 (26%)

eigenwijs = ook wijs
trix

Golden Member

weet iemand waar ik zo'n libary kan vinden ?

eigenwijs = ook wijs

Je zou een S-curve moeten implementeren om de snelheid/acceleratie te optimalizeren en het minste trillingen te krijgen.
Dat is nog niet zo heel erg simpel om dat goed te doen. Je zou met een sinus vormig profiel je acceleratie op moeten voeren.

Zie ook het discussie topic van 'rew' hierover (alhoewel daar volgens mij alleen een trapezium curve gebruikt wordt die nog steeds niet optimaal is).

-edit-
Dit verhaal vond ik over een S-curve implementatie:
http://fightpc.blogspot.com/2018/04/how-to-get-sinusoidal-s-curve-for.…

[Bericht gewijzigd door henri62 op zondag 10 mei 2020 16:31:34 (16%)

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
trix

Golden Member

zoals ik het nu doe, ga ik met een constante versnelling naar de gewenste eindsnelheid, (trapezium dus) en dat werk perfect. nergens last van vibiraties of dergelijke.
die gewenste eindsnelheid wijzigt tijdens het bewegen nooit. dat is een van te voren door de gebruiker gekozen snelheid. waarmee dan de volledige ciclus word uit gevoerd.

eigenwijs = ook wijs

Je zult toch een keer moeten stoppen? Om je positie niet kwijt te raken moet je ook netjes afremmen.

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.

Hij zegt trapezium dus ik denk dat ie dat wel degelijk heeft...

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
trix

Golden Member

inderdaad ook deceleratie.

eigenwijs = ook wijs