Pulstrein voor stappenmotor genereren

Dag allemaal,

Eerst een introductie van wat ik precies wil bouwen;
Een 4de as voor mijn manuele freesmachine.
Dit is een klauwplaat die ik onder een bepaalde hoek kan laten roteren met een stappenmotor.
Dit wil ik aansturen met een microcontroller.
De microcontroller is een dsPIC30F4011 dat op 80Mhz loopt.

Nu wil ik graag volgende zaken kunnen doen:
-Snelheid traploos kunnen instellen (dmv potmeter die analoog een signaal van 0-1000 stappen weergeeft), wat betekend dat ik de frequentie moet kunnen sturen.
-Een "ramp up" acceleratie en "ramp down" de-acceleratie inbouwen.

Om dit stap-voor-stap op te bouwen ben ik nu bezig(probeer) om een variabel pulserend signaal te creëren.
Het inlezen van de potmeter, werkt alsook het weergeven van de analoge waarden.
De limieten van de pulsen die ik nodig heb, ligt op 10kHz, dat is de max frequentie waarmee ik de stappenmotor kan aansturen, waarbij het koppel nog goed blijft.
Ik zou dus graag van ongeveer een 500Hz naar 10000Hz (vrijwel) traploos willen regelen.

Mijn eerste poging was met een vaste interrupt, maar dat lukt niet.
Je moet al een véél snellere interrupt dan je basisfrequentie hebben om traploos de frequentie te kunnen sturen.
(de periode van bvb 10kHz is, 100µs, van 9800Hz is 102µs, je moet dus bijna per 1µs een interrupt hebben om die nauwkeurigheid te halen)

Voor elke puls een "preset" waarde voor een timer berekenen en die timer laten aflopen, waarbij een interrupt gegenereerd wordt is mijn 2de plan.
Dit heb ik nog niet getest.

Hoe zouden jullie dit programmeren? Is een pre-set naar een timer sturen de beste oplossing?

Alvast bedankt,
Coldrestart.

Lambiek

Special Member

Als je haar maar goed zit, GROETEN LAMBIEK.

Ik begrijp wel dat je een constante snelheid wilt, maar moet de motor ook niet exact synchroon lopen met de rest van de machine?

dat is de max frequentie waarmee ik de stappenmotor kan aansturen, waarbij het koppel nog goed blijft.

Is ook wel sterk driver afhankelijk en van de spanning op je driver.

Kijk eens naar GRBL, een open source motion controller.
Niet precies wat jij wilt maar het motion gedeelte geeft je mischien wat ideeen.
https://github.com/gnea/grbl/wiki

Lambiek

Special Member

Dit heb ik een keer voor iemand gemaakt, kijk op blz. 132. Een vijfde as voor een CNC freesbank. Hier maken ze nozzles op voor lijmspuit installaties "hot glue". De as bevat vijf klauwkoppen en een hydraulische rem.

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

Op 22 oktober 2020 19:42:49 schreef coldrestart:
Eerst een introductie van wat ik precies wil bouwen;
Een 4de as voor mijn manuele freesmachine.
Dit is een klauwplaat die ik onder een bepaalde hoek kan laten roteren met een stappenmotor.

Heb je info over de gebruikte stappenmotor en stappenmotordriver.

De limieten van de pulsen die ik nodig heb, ligt op 10kHz, dat is de max frequentie waarmee ik de stappenmotor kan aansturen, waarbij het koppel nog goed blijft.

Dat ligt eraan of je microstepping gaat gebruiken.

En ik vraag me af of je geen rem functie nodig hebt. Als je aan het frezen bent komen er grote krachten op. Of heb je een motor met een vertraging?

Dus iets meer info graag. :)

EDIT:

De bediening van mijn robotarm heb ik ook met Profilab gemaakt in combinatie met een pic controller.

Hier het bedienpaneel.

Hiermee kan ik de vier stappenmotoren bedienen en de DC motor van de grijparm. Met de PC geef ik de commando's aan de controller en die stuurt de stappenmotordrivers aan.

Dit is maar een voorbeeld van hoe het allemaal eventueel kan.

Hier nog een simpel voorbeeld van een stappenmotor besturing met Profilab.

https://www.youtube.com/watch?v=lpvKcu01y28

Als je haar maar goed zit, GROETEN LAMBIEK.

Dag allen,

Alvast bedankt voor de ideeën.

Ik zal nog wat verder uitleggen wat de stappenmotor nu juist doet.
Ik heb een conventionele freesmachine, dus géén cnc machine.
Er bestaan verdeelkoppen (manueel mechanisch bediend), die een as onder een bepaalde hoek kunnen plaatsen.
Op die manier kan je bvb tandwielen frezen, of gaten boren in een as onder een bepaalde hoek.

https://www.wabeco-remscheid.de/pub/media/catalog/product/cache/64c4e0b6a2e5dd9818e4dd94bc78c8fb/1/1/11557-Teilapparat-mit-3-Backen-Drehbankfutter-einzeln-1506_1.jpg

Die manuele koppen hebben een schaalaanduiding, je moet dus manueel je verdraaiing gaan tellen. Nu bestaan er ook zo'n koppen voor cnc machines. Echter kan je die ook gewoon met een microcontroller aansturen, en dat is nu net mijn bedoeling.
Ik geef in de controller in, verdeel 360° in 30 gelijke delen, en ik hoef enkel maar een commando te geven, ga naar het volgende punt. De rest van de berekeningen doet de controller.
De kop die ik heb is de volgende:
https://www.proxxon.com/en/images/produkte/24364_24423.png

De verhouding van de aandrijving is 80:1 met een wormwiel, dus een rem of dergelijke is niet nodig.
Ivm microstepping, ik gebruik een driver dat reeds 16 microsteps doet. Om de stappenmotor één omwenteling te laten doen, moet ik 3200 pulsen geven.
De stappenmotordriver is een tb6600 (gekende chinees).

Er is een gelijkaarding project, waarvan de software erg goed in elkaar steekt/compleet is, echter is de software niet open source.
(Enkel een hex file ter beschikking)
Daarnaast leer ik niks bij door een project na te bouwen, ik wil dit graag zelf doen.

Gelijkaardig project:
https://www.worldofward.com/rotarycontroller/overview/

De software wil ik in een microcontroller houden, om het compact te houden. Een extra pc bijplaatsen is wat omslachtig.

Ik heb test "2" gedaan, dus spelen met de pre-set tijd van een timer, en die continue een interrupt laten triggeren.
Dit werkt geweldig goed, echter is de tijdsvertraging, als ik de timer verhoog, niet lineair is met de frequentie..
Ik heb een vermoeden dat dit komt, omdat ik met een basistijd start, en deze verleng.
*EDIT: ok domme opmerking, ik verleng de tijd op een lineaire manier, echter, hoe langer de totale puls, hoe minder procentuele invloed die verlenging heeft.
Ik moet de totale tijd in rekening brengen om de verlenging lineair te krijgen.

Aangezien mijn uitleg hierboven niet echt duidelijk is, hier het code voorbeeld.

De eerste routine is de interrupt routine.
Die gaat niets anders doen dan mijn uitgang laten toggelen.

pic basic code:


sub procedure Timer1Interrupt() iv IVT_ADDR_T1INTERRUPT
     PulseBool = not PulseBool
     DOUT_PIN_PULSE_CMD =  PulseBool

end sub

In de "main" loop ga ik de analoge ingang uitlezen.
Daar komt een waarde van 0-1000 uit.
Die waarde vermendigvuldig ik met 19 en voeg een offset toe van 1000.

De PR1, of preset register van timer 1, zal per bit, 0,05µs of 50ns vertraging geven.

pic basic code:


 while TRUE
      adc_rd     = ADC1_read(8)  
      Speed  = adc_rd   'analoge waarde 0-1000 zit in "Speed" variabele

      LoopCounterSPInt  =     (Speed*19)+1000 'bereken de pre-set tijd
      PR1 = LoopCounterSPInt 'zet de pre-set tijd in de PR1
                
      'Zet de berekende waarde op het lcd ter controle
      WordToStr(LoopCounterSPInt  ,size)
      LCD_Out(3,1,  "   Size:")
      LCD_Out_Cp(  size )
wend

Ik ga in ieder geval de voorbeelden eens bekijken hoe jullie die zaken regelen.
Groeten,
Coldrestart.

Lambiek

Special Member

Op 24 oktober 2020 15:41:53 schreef coldrestart:
Ik heb een conventionele freesmachine, dus géén cnc machine.

Dat had ik al begrepen. :)

Er bestaan verdeelkoppen (manueel mechanisch bediend), die een as onder een bepaalde hoek kunnen plaatsen.
Op die manier kan je bvb tandwielen frezen, of gaten boren in een as onder een bepaalde hoek.

Ook bekent, gebruik ik zelf ook. Je gaat dus een verdeel apparaat gebruiken.

De verhouding van de aandrijving is 80:1 met een wormwiel, dus een rem of dergelijke is niet nodig.

Er zit altijd iets speling op en tijdens het frezen kan het dan gaan trillen.

Ivm microstepping, ik gebruik een driver dat reeds 16 microsteps doet. Om de stappenmotor één omwenteling te laten doen, moet ik 3200 pulsen geven.

Je moet dus 3200 X 80 = 256000 stappen maken voor 360 graden van je klauwkop, dat is 0.00140625 graden per stap.

Ik geef in de controller in, verdeel 360° in 30 gelijke delen,...

Dat zijn dus 30 X 12 graden verdraaiing. Dan moet je dus 30 X 8533,333333333333 stappen maken voor een 360 graden verdraaiing. 12 graden verdraaiing zijn dus 8533,333333333333 stappen, dan zal je dus met een float moeten werken. Een float kost veel instructie tijd vergeet dat niet.

De software wil ik in een microcontroller houden, om het compact te houden. Een extra pc bijplaatsen is wat omslachtig.

Dat moet ook gaan, die PC was maar een voorbeeld. :)

Als je haar maar goed zit, GROETEN LAMBIEK.

Een float is ook maar een benadering en dus geen 8 cijfers achter de komma dacht ik maar dat zou je dus uit moeten zoeken met je gebruikte CPU en de gebruikte compiler hoe die een float definieert.
Als je bv 6 cijfers achter de komma wilt kan je ook een integer nemen en die met 1.000.000 vermenigvuldigen. Want of je nu bv 8,333333 stappen maakt in een 1µS is hetzelfde als 8333333 stappen per seconden

Maar ik begrijp nog niet waarom die constante snelheid zo belangrijk is als je enkel maar naar een positie hoeft

Lambiek

Special Member

Op 24 oktober 2020 20:52:39 schreef benleentje:
Maar ik begrijp nog niet waarom die constante snelheid zo belangrijk is als je enkel maar naar een positie hoeft

Dat begrijp ik ook niet helemaal. Gewoon niet al te snel laten draaien om geen stappen te missen.

Die ramp-up en ramp-down is wel oké.

Op 24 oktober 2020 15:41:53 schreef coldrestart:
Gelijkaardig project:

code:


Configurable for most worm sizes. (Specify number of steps per 360 degrees. 200 step motor in half step mode and 90:1 worm equals 36,000 steps per revolution with 0.01 degree resolution).

Als je van die float af wil moet je dit doen. Je moet op die 3600 stappen uit komen.

Dus als jij 200 X 16 = 3200 stappen doet kom je eigenlijk 400 stappen te kort. Als je nu een extra tandriem overbrenging van bijv. 1.125 zou maken1. 1.125 X 3200 = 3600 X 80 = 288000 : 360 = 800 stappen per graad. Dus 1 stap is dan 0.00125 graden.

Dan kom je dus op hele getallen uit en heb je niets meer met een float te maken. En het wordt veel preciseer en makkelijker met hele getallen.

Dus met een tandriemwiel van 40 en 45 tanden wordt dat 45 : 40 = 1.125.

Als je haar maar goed zit, GROETEN LAMBIEK.

Maar ik begrijp nog niet waarom die constante snelheid zo belangrijk is als je enkel maar naar een positie hoeft

De snelheid hoeft ook niet exact constant te zijn.
Het is het tellen van het aantal pulsen dat cruciaal is, dat is de hoek die ik wil behalen.
Ik wil wél de snelheid lineair kunnen regelen.

Het berekenen van float waarden zijn geen probleem, de mcu die ik gebruik heeft meer dan rekenkracht genoeg.

Er zit altijd iets speling op en tijdens het frezen kan het dan gaan trillen.

Mijn machientje is erg compact en ik bewerk enkel non-ferro metalen en POM-C, een rem is wat overkill. De fabrikant heeft dit niet voorzien, ook een bout om de kop te klemmen staat er niet op, dus ik veronderstel dat de overbrengingsverhouding, samen met het koppel van de stappenmotor wel voldoende zal (moeten) zijn.

Als je van die float af wil moet je dit doen. Je moet op die 3600 stappen uit komen.

Inderdaad, het is een goede opmerking om te proberen het aantal pulsen af te stemmen op die 360°, echter is dat afhankelijk van de mechanische opbouw, en daar kan ik helaas niets aan veranderen.
Laat het me zo stellen, ik wil geen mechanische aanpassingen gaan doen.
Maar zeker een terechte opmerking, en eigenlijk heeft de fabrikant daar niet zo goed over nagedacht.

Mijn laatste test is succesvol.
Ik zat fout, te denken dat een periode in tijd, lineair is met de frequentie.
1/f =T of 1/T=f
Ik moet dus de ingang met de potentiometer niet direct de periode laten bepalen, maar de frequentie. Die frequentie moet ik dan omzetten naar een bepaalde periode.
Pas dan is mijn potmeter 0-100% 1000Hz - 10000Hz lineair.

[Bericht gewijzigd door coldrestart op 25 oktober 2020 14:51:06 (14%)]

Hoewel het mij heel leerzaam lijkt om het helemaal zelf te bouwen greep ik een tijdje terug naar een library voor dit soort dingen: https://www.airspayce.com/mikem/arduino/AccelStepper/
Let verder niet op mij, maar dan is de optie een keer genoemd.

Lambiek

Special Member

Op 25 oktober 2020 14:43:58 schreef coldrestart:
Mijn machientje is erg compact en ik bewerk enkel non-ferro metalen en POM-C, een rem is wat overkill.

Als er totaal geen speling op zit is het niet nodig en de praktijk zal het leren. :)

De fabrikant heeft dit niet voorzien, ook een bout om de kop te klemmen staat er niet op, dus ik veronderstel dat de overbrengingsverhouding, samen met het koppel van de stappenmotor wel voldoende zal (moeten) zijn.

Het zal echt niet gaan verdraaien met die wormwiel vertraging, maar daar gaat het ook niet om. Het is de eventuele speling op de worm en wormwiel.

...., en eigenlijk heeft de fabrikant daar niet zo goed over nagedacht.

Er zit notabene een tandriem overbrenging op "of is het met tandwielen?" dus waarom dan niet gelijk goed gemaakt door de fabrikant.

Of komt het uit China?

Mijn laatste test is succesvol.
Ik zat fout, te denken dat een periode in tijd, lineair is met de frequentie.

Grafiek ziet er goed uit zo.

Verwacht wel een filmpje als het klaar is. :)

Als je haar maar goed zit, GROETEN LAMBIEK.

Er zit notabene een tandriem overbrenging op "of is het met tandwielen?" dus waarom dan niet gelijk goed gemaakt door de fabrikant.
Of komt het uit China?

Er zit een tandriem tussen de stappenmotor en de worm.
Was het maar waar dat het uit china kwam...
Het is een standaard Proxxon verdeelapparaat. Duits dus.
Misschien had ik beter een manueel verdeelapparaat van wabeco zelf omgebouwd.

Lambiek

Special Member

Op 25 oktober 2020 15:57:13 schreef coldrestart:
Er zit een tandriem tussen de stappenmotor en de worm.

Die bedoel ik ook, die kun je toch aanpassen, Dat spul kost echt niets meer tegenwoordig.

Was het maar waar dat het uit china kwam...

Hoezo?, qua prijs dan zeker. Niet voor de kwaliteit zeker. :)

Het is een standaard Proxxon verdeelapparaat. Duits dus.

Dan zou je verwachten dat daar beter over nagedacht zou worden ja.

Dat ding is nog niet echt goedkoop ook. :(

Misschien had ik beter een manueel verdeelapparaat van wabeco zelf omgebouwd.

Dat is achteraf hé. :)

Als je haar maar goed zit, GROETEN LAMBIEK.

Op 22 oktober 2020 19:42:49 schreef coldrestart:
(de periode van bvb 10kHz is, 100µs, van 9800Hz is 102µs, je moet dus bijna per 1µs een interrupt hebben om die nauwkeurigheid te halen)

De truuk is om iedere 100us te doen:

code:


  ppos += freq;
  if (ppos > 10000) {
     ppos -= 10000; 
     send_pulse ();
  }

Nu kan je de freq instellen op 9999 of 9998, geen probleem. Omdat je schijnbaar 10000 stap-pulsjes per seconde kan, vermoed ik dat je microstepping gebruikt. Als er dan 1 op de zoveel stapjes ontbreekt is dat niet zo erg. Als je de "if" vervangt door een "while" kan je ook nog iets boven de 10000 Hz gaan.

In de praktijk zou ik op jou CPU waarschijnlijk voor een interrupt frequentie van 30kHz gaan. De 9999 Hz is dan niet meer dat er een hele puls ontbreekt iedere hele seconde, maar dat het volgende pulseje 33us later komt drie keer per seconde....

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

Het berekenen van float waarden zijn geen probleem, de mcu die ik gebruik heeft meer dan rekenkracht genoeg.

Dat is het probleem ook niet met float lees mijn post anders even opnieuw. Probleem is dat het een benadering is van een komma getal en er dus een kleine fout in zit. stel dat elke fout 0,0001 is dan is na een miljoen keer de fout een aantal stappen ernaast.
Misschien is dat bij jouw toepassing nu geen probleem maar als je voor je bewerking 100x rond moet word dat wel vervelend. Of je moet dat oplossen door bij elke rondgang weer op nul te initialiseren.

De truuk is om iedere 100us te doen:

Ik snap waar je naartoe wil, een aantal pulsen uit de interrupt knijpen, en zo de freq verlagen.
Echter wordt dat een probleem als ik 5000Hz wil ipv 10000Hz.
Op dat moment zal de stappenmotor 500ms draaien, 500ms wachten en terug 500ms draaien.

Ik ben hier verkeerd -> zie volgende post.

Mijn eerste idee was ook met een vaste interrupt, waarbij ik de modulus nam om die pulsen gelijkmatig eruit te halen.
Met die oplossing verdeel je het aantal momenten waarbij je "niets" doet, maar die oplossing is te "grof".Bij stap 1 deel je de frequentie direct door 2.

De manier hoe ik het nu doe is de pre-set tijd van de interrupt timer zo instellen dat ik de gewenste frequentie krijg.

Dat is het probleem ook niet met float lees mijn post anders even opnieuw. Probleem is dat het een benadering is van een komma getal en er dus een kleine fout in zit. stel dat elke fout 0,0001 is dan is na een miljoen keer de fout een aantal stappen ernaast.
Misschien is dat bij jouw toepassing nu geen probleem maar als je voor je bewerking 100x rond moet word dat wel vervelend. Of je moet dat oplossen door bij elke rondgang weer op nul te initialiseren.

Ik begrijp dat, als je met een float werkt,er steeds een fout in gaat zitten die je elke berekening "meeneemt".
Echter moeten we 2 zaken onderscheiden:
-De snelheidsberekening
-De positieberekening

Voor de snelheidsberekening maakt dit niks uit.
Voor de positieberekening zal de gebruiker steeds met "graden" of aantal "verdelingen" werken.
Dus de gebruiker "ziet" 360° op het scherm, maar mijn programma gaat steeds rekenen met (80*3200=256000) 256000 punten voor 1 toer.
Daarmee zal ik de nauwkeurigheid zo hoog mogelijk proberen te houden. Maar inderdaad, aangezien de mechanische kant maakt dat ik een kommagetal per graad heb, blijf ik met een rekenfout zitten.
Praktisch gezien zal ik op een as geen 1000 bewerkingen hebben, waarbij er via graden de positie wordt ingegeven.
Als ik bvb een tandwiel wil frezen met 250 tanden, zal de gebruiken in de "verdeelmodus / menu" gaan en 250 verdelingen vragen.
Dan zal het programma 256000/250=1024 pulsen per verdeling geven, zonder met enig kommagetal te gaan rekenen.

Lambiek

Special Member

Bij 250 tanden komt dat mooi uit ja, maar bij 249 tanden weer niet.

Het blijft in mijn ogen een beetje tobben zo.

Ik heb ooit zelf een CNC freesmachine gemaakt, maar ik heb er wel voor gezorgd dat 1 omwenteling van de stappenmotor 1mm verplaatsing is. En daar heb lk geen spijt van. Je zit anders altijd met een fout die steeds groter wordt.

Als je haar maar goed zit, GROETEN LAMBIEK.

Op 25 oktober 2020 17:24:04 schreef coldrestart:

Echter wordt dat een probleem als ik 5000Hz wil ipv 10000Hz.
Op dat moment zal de stappenmotor 500ms draaien, 500ms wachten en terug 500ms draaien.

Nee met mijn code wordt het wel/niet een pulsje geven zo egaal mogelijk verdeeld over de hele seconde.

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

Bij 250 tanden komt dat mooi uit ja, maar bij 249 tanden weer niet.

Het blijft in mijn ogen een beetje tobben zo.

Je blijft altijd een mogelijkheid vinden waarbij dit optreed. Zelfs met de door Lambiek voorgesteld correctie van 256000 naar 288000 stappen per omwenteling blijft delen door 249 tanden een komma getal geven
288000 / 249 = 1156,625

Ik begrijp dat, als je met een float werkt,er steeds een fout in gaat zitten die je elke berekening "meeneemt".

Dat hoeft niet perse misschien valt het bij jouw toepassing wel, en er zijn workarounds Als je niet elke berekeing laar afhangen van de vorige berekening maar van het totaal uitgaat dan valt het wel mee.

In een winkel moesten we tl-bakken ophangen steeds op 2 meter van elkaar, dat hebben we keurig gedaan elke keer 2 meter ertussen. Toe werden de stellingen geplaatsen en hingen de eerste 2 rijen precies in het midden echter gingen ze daarna steeds verder afwijken. We hadden vanaf de eerste niet steeds 2 meter moeten pakken maar vanaf de eerste 2, 4, 6, 8 enz meters moeten nemen dus altijd rij 1 als referentie moeten gebruiken i.p.v. de laats gemonteerde als nieuwe referentie gebruiken.

[Bericht gewijzigd door benleentje op 25 oktober 2020 21:50:25 (53%)]

Er van uit gaande dat je stap klein genoeg is qua nauwkeurigheid is er toch geen probleem. Je rondt gewoon het eventuele kommagetal netjes af. Voor elke nieuwe positie maak je je sommetje weer. Pas als je incrementeel gaat werken stapel je de fouten op. Pas wel op met microstepping. Als je de driver uitschakelt springt de motor terug (of vooruit) naar een hele stap.

Niet alles wat op internet staat is waar... Dat geldt ook voor CO.

Nee met mijn code wordt het wel/niet een pulsje geven zo egaal mogelijk verdeeld over de hele seconde.

Inderdaad, ik was verkeerd.
Slimme oplossing, daar was ik zelf niet opgekomen.

(offtopic vraag, maar zou er ergens een overzicht bestaan met verschillende handige "mini" routines /technieken?)

Je blijft altijd een mogelijkheid vinden waarbij dit optreed. Zelfs met de door Lambiek voorgesteld correctie van 256000 naar 288000 stappen per omwenteling blijft delen door 249 tanden een komma getal geven
288000 / 249 = 1156,625

Inderdaad, het zal nooit steeds perfect uitkomen.

Er van uit gaande dat je stap klein genoeg is qua nauwkeurigheid is er toch geen probleem. Je rondt gewoon het eventuele kommagetal netjes af. Voor elke nieuwe positie maak je je sommetje weer. Pas als je incrementeel gaat werken stapel je de fouten op. Pas wel op met microstepping. Als je de driver uitschakelt springt de motor terug (of vooruit) naar een hele stap.

Dat klopt, dus zoveel mogelijk "absoluut" van de nulpunt werken.
De driver zal steeds onder spanning blijven staan, dus dat is geen probleem.