Stappenmotor blokkeert en maakt raar geluid

Op 16 maart 2020 12:44:10 schreef buckfast_beekeeper:
Waar roep je de methode void slag1() en void slag3() aan? Ik vind die niet in je loop. In beide geef je ook geen snelheid aan.

In je loop staat een if die altijd false zal zijn joywaarde kan niet gelijk kleiner zijn dan 435 en groter dan 485. Bekijk eens de functie if - else if - else.

Bovenaan geef je aan dat 1 volle draai 200 stappen is. Is er geen functie waar je het aantal graden kan ingeven? Een goede librarie gaat dan zelf het aantal stappen voor je berekenen.

Begin eens met de code van stepper.h en stepper.c uit vlooien. Hoe gaat deze code om met de commando's. Mocht ik leerkracht zijn, kreeg je deze vraag sowieso op je boterham tijdens de verdediging van je project. Een aanwezige librarie gebruiken is 1, je moet het wiel inderdaad niet terug uitvinden, weten hoe deze zijn werk doet is toch een must.

ramp up ramp down. Ik zal het even in een andere context plaatsen. Vertrekt een auto op volle snelheid? Stopt deze plots? (een ongeval even niet meegerekend) Welke wet heeft hier invloed? Is deze ook gerelateerd aan je stappenmotor?

@rew: hij geeft zelf de constante stepsRevolution mee in de declaratie van zijn steppers als 1ste argument. Lijkt me dan logisch dat de software dit wel kent.

void slag1() en void slag3() worden aangeroepen zodra de interuptPin een signaal krijgt (zie attachtInterupt()).
Ja, ik wil dat die if functie false is. Op deze manier creëer ik op de joystick een "dode zone" waardoor er niks zal gebeuren. De motor zal niet draaien, wanneer ik de joystick niet aanraak.

Als ik je programma goed lees, dan verwacht ik dat je motor een enkele stap doet als je de ene of de andere kant op gaat met je joystick. Waar roep je slag1 en slag2 aan?

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

Op 16 maart 2020 13:06:07 schreef rew:
Als ik je programma goed lees, dan verwacht ik dat je motor een enkele stap doet als je de ene of de andere kant op gaat met je joystick. Waar roep je slag1 en slag2 aan?

Dat klopt helemaal. In mijn if functies roep ik mijn DC-motor aan om heen en weer te bewegen en mijn void slag1() en void slag(3) roep ik mijn stappenmotor aan om snel heen en weer te bewegen. Mijn void slag() wordt aangeroepen van zodra mijn interuptPin (zie attachInterrupt() vanboven) een signaal krijgt.

Sangre

Golden Member

Je kan in een interrupt geen stappenmotor bedienen.
Functies als millis() en delay() werken daar namelijk niet.

Je moet een interrupt functie extreem simpel houden, bijvoorbeeld

code:

volatile bolStep1 = false;

void setup {}

void loop {
  if (bolStep1) {
     do stuff
     bolStep1 = false;
  }
}

void step1 {
  bolStep1 = true;
}

Ik gebruik trouwens nooit libraries voor een stepper.
stel je wilt 1 rondje draaien:

code:


#define dirPin 6
#define stepPin 7
#define stepsPerRev 200
#define timePerRev 500

void setup {
  pinMode (dirPin, OUTPUT);
  pinMode (stepPin, OUTPUT);
  digitalWrite (dirPin, HIGH); \\ of low, CW of CCW
}

void loop {
  for (int x=0;x<stepsPerRev;x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroSeconds(timePerRev);
    digitalWrite(stepPin, LOW);
    delayMicroSeconds(timePerRev);
  }
  delay(5000);
}

[Bericht gewijzigd door Sangre op 16 maart 2020 13:41:17 (43%)]

@Sangre Ik stuur de stappenmotor aan met L298n. Kan ik deze ook programmeren met een for loop? Of is er een mogelijkheid om toch met delay te werken in een interrupt functie?

[Bericht gewijzigd door Pallieman op 16 maart 2020 14:18:11 (30%)]

Sangre

Golden Member

Ik zie daar geen dir en step pin op als ik zo snel kijk.

Ik gebruik zelf stepperdrivers zoals de DRV8825, die hebben een direction pin en een step pin, en elke keer als je de steppin hoog en laag maakt, zet de motor 1 stapje. Ook ondersteunen die microsteppen waarmee je een stepper 6400 stapjes geeft ipv 200, per omwenteling waardoor die veel mooier loopt

buckfast_beekeeper

Golden Member

Op 16 maart 2020 13:01:37 schreef Pallieman:
[...]
void slag1() en void slag3() worden aangeroepen zodra de interuptPin een signaal krijgt (zie attachtInterupt()).
Ja, ik wil dat die if functie false is. Op deze manier creëer ik op de joystick een "dode zone" waardoor er niks zal gebeuren. De motor zal niet draaien, wanneer ik de joystick niet aanraak.

Ok. Ik ben wel mee in C maar niet in het omgebouwde pseudo C van een Arduino.

Zelfs dan klopt je IF niet. waarde kan NOOIT gelijktijdig < 435 EN > 485 zijn. Maak er dan tenminste if <435 OR > 485 van. Onderstaande (pseudo) code doet net hetzelfde. Maar is een stuk duidelijker.

c code:


If(waarde > 535){
    doe iets
}
else if(waarde < 485){
    doe iets anders
}
else{
    doe weer wat anders
}

Bekijk ik de code van de librarie bij setspeed.

c code:

/*
 * Sets the speed in revs per minute
 */

Dan is starten met 300 omwentelingen/minuut=5 omwentelingen/seconde wel heel optimistisch. Een ramp up, ramp down zit er blijkbaar niet in. 5 omwentelingen/seconde * 200 puls/omwenteling = 1000 puls/seconde als STARTSNELHEID. Begin eens met setspeed op bijvoorbeeld 12 of 1 omwenteling per 5 seconden.

Persoonlijk zou ik de librarie al aanpassen. Startspeed, maxspeed en (de)acceleration toevoegen. Eigenlijk de complete librarie herschrijven en de steptiming interrupt based maken.

Van Lambiek wordt goede geuze gemaakt.
Lambiek

Special Member

Op 16 maart 2020 14:13:12 schreef Pallieman:
Ik stuur de stappenmotor aan met L298n.

Heb je de datasheet wel eens doorgenomen van de L298N?

https://www.sparkfun.com/datasheets/Robotics/L298_H_Bridge.pdf

Kan ik deze ook programmeren met een for loop?

Ja, als je daar de stapvolgorde in zet wel.

Of is er een mogelijkheid om toch met delay te werken in een interrupt functie?

Kan beide.

Maar ik vraag me een beetje af of je wel weet hoe een stappenmotor precies werkt. :) Want als je nu ook puls en richting doet met een L298N, dan gaat het nooit werken.

Dat is ook de reden dat ik om een schema vroeg.

En kijk hier eens naar.

code:


Hele stappen - CW
Stap	A.1	A.2	B.1	B.2
1	On	Off	On	Off
2	On	Off	Off	On
3	Off	On	Off	On
4	Off	On	On	Off
Hier zie je hoe de spoelen aangestuurd moeten worden om de motor te laten draaien. Je ziet dat er steeds vier stappen gemaakt worden, als hij bij stap vier is wordt er weer naar stap één gesprongen. Er staat ook CW bij, clockwise, dus met de klok mee.

Als je de stappenmotor nu de andere kant op wil laten draaien, moet het stappendiagram anders afgelopen worden.

Hele stappen - CCW
Stap	A.1	A.2	B.1	B.2
1	Off	On	On	Off
2	Off	On	Off	On
3	On	Off	Off	On
4	On	Off	On	Off
Hierboven zie je het stappendiagram voor CCW, counterclockwise, tegen de klok in dus. Je kan zien dat stap vier bij CW nu stap één bij CCW geworden is. Stap drie bij CW wordt stap twee bij CCW, stap twee bij CW wordt stap drie bij CCW, en stap één bij CW wordt stap vier bij CCW. Op deze manier kan je de stappenmotor de andere kant op laten draaien.

Dit zijn hele stappen, maar je kan zelf ook halve stappen maken. Dan komen er vier stappen bij.

Halve stappen - CW
Stap	A.1	A.2	B.1	B.2
1	On	Off	On	Off
2	On	Off	Off	Off
3	On	Off	Off	On
4	Off	Off	Off	On
5	Off	On	Off	On
6	On	Off	Off	Off
7	Off	On	On	Off
8	Off	Off	On	Off
Op het voorbeeld hierboven kan je zien hoe dat eruit ziet. Dit is weer clockwise, dus met de klok mee. De stappen lopen nu van stap één tot en met acht, als stap acht bereikt is dan wordt er weer naar stap één gesprongen. De stappen twee, vier, zes, en acht zijn erbij gekomen. Deze stappen zijn er tussen gevoegd, dus een stappenmotor met 200 stappen maakt nu ineens 400 stappen per omwenteling. Een 200 staps stappenmotor maakt nu geen 1,8 graden per stap, maar 0,9 graden per stap.

Hieronder het voorbeeld voor halve stappen CCW.

Halve stappen - CCW
Stap	A.1	A.2	B.1	B.2
1	Off	Off	On	Off
2	Off	On	On	Off
3	On	Off	Off	Off
4	Off	On	Off	On
5	Off	Off	Off	On
6	On	Off	Off	On
7	On	Off	Off	Off
8	On	Off	On	Off

[Bericht gewijzigd door Lambiek op 16 maart 2020 16:21:24 (59%)]

Als je haar maar goed zit, GROETEN LAMBIEK.

Ik heb een project waarbij als ik op een knop druk, de stappenmotor snel 90 graden heen en weer moet bewegen. Dit doe ik doodmiddel van een interrupt. Echter om de stappenmotor te laten bewegen heb ik een delay nodig (anders blokkeert de motor). Het probleem is dat je geen delay kan gebruiken in een interrupt functie. Wie weet hoe je dit, waarschijnlijk via een "omweg", welk kunt programmeren?

mod edit: deze post is uit dubbeltopic naar hier verplaatst.

[Bericht gewijzigd door GJ_ op 17 maart 2020 19:02:32 (7%)]

roep ik mijn stappenmotor aan om snel heen en weer te bewegen.

Het is niet altijd eenvoudig om een stappenmotor snel te laten bewegen. Dit komt door de opbouw ervan. Als je de motor te snel aanstuurt dan mist het stappen. Als de motor eenmaal een stap gemist heeft en staat bv in stap2 dan verwacht de motor daarna naar stap 3 te gaan. Maar je software wil hem dan al naar stap 4 sturen wat dan helemaal niet kan.
Een motor mist stappen door:
Je wilt te snel gaan met ramp-up of down
De belasting van de motor is te groot motor draait te zwaar
Spanning op de regelaar is te laag.
Je wilt sneller dan de motor aan kan.

De stroom moet je niet gaan aanpassen in een LM298 schakeling en zeker niet hoger gaan dan de max van de motor.

JE zegt dat je al delen werkend heb en andere delen niet. Ga nu eerst van het werkende deel uit en schrijf dat naar een apart programma en ga dan langzaam stukjes toevoegen dan zie je vanzelf wat wel en niet werkt. Doe ik ook ik kan ook niet een compleet programma in 1 keer werkend krijgen.

Op 16 maart 2020 19:15:47 schreef benleentje:
[...]Het is niet altijd eenvoudig om een stappenmotor snel te laten bewegen. Dit komt door de opbouw ervan. Als je de motor te snel aanstuurt dan mist het stappen. Als de motor eenmaal een stap gemist heeft en staat bv in stap2 dan verwacht de motor daarna naar stap 3 te gaan. Maar je software wil hem dan al naar stap 4 sturen wat dan helemaal niet kan.

JE zegt dat je al delen werkend heb en andere delen niet. Ga nu eerst van het werkende deel uit en schrijf dat naar een apart programma en ga dan langzaam stukjes toevoegen dan zie je vanzelf wat wel en niet werkt. Doe ik ook ik kan ook niet een compleet programma in 1 keer werkend krijgen.

Correct, het probleem is dat de stappenmotor snel en accuraat moet werken. Het probleem is waarschijnlijk dat ik in mijn interrupt functie delay gebruik. Dit kan niet en ik moet hier dus een alternatief voor vinden.

Op 16 maart 2020 19:20:50 schreef Pallieman:
Dit kan niet en ik moet hier dus een alternatief voor vinden.

Dat is dan weer te kort door de bocht. In de arduino code "marlin" voor 3D printers staat in de timer-interrupt routine gewoon iets van

digitalWrite (STEPX, 1); delay_us (1); digitalWrite (STEPX, 0);

Nu staat dat er niet letterlijk, zo weet ik zeker dat er geen digitalWrite gebruikt wordt om dat dat te langzaam is.

Die delay van 1 microseconde is goed te doen. Liever niet, maar het kan. Maar wil je delays in de orde van miliseconden dan kan het zijn dat de delay_ms functie de timer interrupts gebruikt om te zien of het juiste aantal ms al voorbij is. En die komen niet meer als je in een interrupt staat te wachten. (de AVR kan niet makkelijk meerdere interrupts tegelijk als ik het goed heb).

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

(de AVR kan niet makkelijk meerdere interrupts tegelijk als ik het goed heb).

De AVR kan het best wel, maar avr-gcc laat de interrupt standaard gedisabled tijdens een ISR. Als je dat niet wilt moet je de interrupt handler non-blocking declareren.

bprosman

Golden Member

Even in het algemeen , niet naar je code gekeken te hebben kun je natuurlijk best een “Delay” maken in een interrupt routine je moet alleen niet de interrupt routine ophouden met een Delay statement. Maar stel je hebt een interrupt die iedere 1ms loopt, met daarin een teller van 0..1000 dan heb je bij 1000 iets wat iedere seconde uitgevoerd word.

De jongere generatie loopt veel te vaak zijn PIC achterna.
Hensz

Golden Member

Op 16 maart 2020 19:20:50 schreef Pallieman:
[...]
Correct, het probleem is dat de stappenmotor snel en accuraat moet werken. Het probleem is waarschijnlijk dat ik in mijn interrupt functie delay gebruik. Dit kan niet en ik moet hier dus een alternatief voor vinden.

Interrupts gebruik je voor dingen die maar heel kort duren en het lopende programma niet serieus in de weg zitten.
Bijv. ff een input pin of een timer checken, byte in een seriele buffer stoppen, regel van je toetsenbordmatrix inlezen, etc.
Een routine die een stappenmotor heen-en-terug laat bewegen duurt veel te lang.

Don't Panic!

Iedereen blijft richtlijnen "het is in het algemeen beter als...." verkondigen als absolute waarheden "je kan nooit....".

Onder omstandigheden kan je best een interrupt lang laten duren. Stel je doet software ws2812's aansturen. Dan moet je iedere 1.25 µs de uitgang kunnen veranderen. Dat is enerzijds te snel om een 800kHz interrupt voor te regelen anderzijds zo tijdkritisch dat je toch geen andere interrupts kan toestaan. Dus al ZOU je het in de mainloop doen dan nog moet je interrupts blokkeren. Dan kan je het net zo goed in de interrupt routine zelf doen.

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

Golden Member

@TS: interessante lectuur.

@REW hier onder: als TS even op de link klikt en dan even wat moeite doet heeft hij een compleet werkend geheel van ATmel, inclusief ramp up, ramp down met RS232 aansturing (terminal software). Kan het nog beter geschreven worden voor een AVR? Ik betwijfel het. Leest hij de Application note dan heeft hij de totale achtergrond hoe het werkt. Het enige wat hij moet doen is de libraries correct implementeren.

[Bericht gewijzigd door buckfast_beekeeper op 17 maart 2020 18:54:51 (66%)]

Van Lambiek wordt goede geuze gemaakt.

Guys,

De TS is kennelijk een beginnende programmeur. Basis dingen als "kan je beter niet in een interrupt doen" zijn onbekend. Geeft niet, heb ik ook moeten leren. Dan is het: "Maak zelf effe een interrupt gebaseerde constant-accelleration stepper driver " misschien een stapje te ver.

TS heeft een library gevonden die in de eerste instantie claimed te doen wat hij wil. Een: "Deze kan dat ook, maar heeft een ramp-up, ramp-down." zou helpvol zijn. Een: "zo maak je je driver vanaf scratch" niet zo zeer.

Het enige is, en daarom vroeg ik daar een paar dagen geleden naar: Tegenwoordig zijn "12V steppers" erg zeldzaam. Normale moderne steppers zijn 2.5 of 3.1V. Dat betekent dat je ze veel beter met een A4988 of DRV8825 kan aansturen. Aangezien de TS z'n motoren nog niet opgeblazen heeft vraag ik me af waar ie die steppers vandaan heeft en of die inderdaad gewoon "12V" zijn.

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

Gebruik in je interrupt dan 1 of meerdere variabele bv delay_aan = 1. In je programma doe je dan met een if statement kijken of de variabele op 1 staat en voer dan de delay uit.

Iets zegt me dat je al te vroeg met Interrupts bent begonnen voordat je genoeg kennis hebt in programmeren. Interrupts zijn meestal niet eens nodig door gewoon slimmer te programmeren. En als je er zeker van bent dat via een interrupt de enige manier is om je programma goed te laten verlopen dan kan je dat gaan gebruiken. Als iets op 1 seconde moet gaan plaatsvinden kan dat in de Arduino omgeving prima zonder interrupts en gebruik je gewoon millis() Moet iets om de 10mS gaan plaats vinden dan zou dat ook nog wel kunnen met millis() maar is de 10mS zeer tijd kritisch dan zou een interrupt beter zijn.

Overigens is millis() zelf ook interrupt gestuurt dus voor de meeste toepassing nauwkeurig genoeg.

Als je veelvuldig millis() gebruikt zijn delays in je programma niet nodig en zijn interrupts meestal ook niet nodig. Dus lees jezelf in over het gebruik van millis()

[Bericht gewijzigd door benleentje op 17 maart 2020 18:38:04 (71%)]

Is schoolmateriaal ... moderne steppers bestaan daar niet. https://www.tinytronics.nl/shop/nl/motoren/motor/stappen-mot....5a-nema17

[Bericht gewijzigd door GJ_ op 17 maart 2020 18:57:05 (78%)]

GJ_

Moderator

ik heb wat posts uit een dubbeltopic naar hier verplaats. Helaas zitten die nu door dit topic heen gevlochten.

Ik heb ondertussen de interrupt eruit gehaald en een iets ander programma. Wanneer ik de joystick indruk, draait de stappenmotor. Echter als ik de joystick heen en weer beweeg, om de DC-motor te laten bewegen, dan "hapert" (schokt) de DC-motor even. Nadien draait draait de motor wel gewoon zoals het moet. Is dit een programmeerfout of een fout in mijn circuit?

Lambiek

Special Member

Als jij het schema níet plaatst, kunnen we er weinig over zeggen.

Als je haar maar goed zit, GROETEN LAMBIEK.

Op 17 maart 2020 18:32:32 schreef Pallieman:
Is schoolmateriaal ... moderne steppers bestaan daar niet. https://www.tinytronics.nl/shop/nl/motoren/motor/stappen-mot....5a-nema17

Dat is een prima moderne stepper. 2.4 volt. Redelijk dicht bij de 2.5 die ik eerder noemde, maar /nog/ iets moderner dan degenen die ik normaliter gebruik.

Deze kan je niet simpel aansturen met een LM298.

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

@TS Gebruik je een aparte voeding voor je arduino of een usb voeding, ik heb al meegemaakt dat de regelaar op het arduinobordje te weinig stroom levert, zeker als er nog een driver mee bestuurd wordt Ik kreeg toen allerlei abnormale stappen , behalve als mijn PC nog verbonden was met de usb van de arduino .