snelheid servo regelen

Pagina: 1
Acties:
  • 1.054 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

Anoniem: 157866

Topicstarter
Ik ben bezig met het aansturen van een servo met een micro-controller (PIC16F877). Als programmeertaal gebruik ik JAL. Ik wil mijn servo laten vertragen, versnellen en op verschillende constante snelheden laten draaien.
Ik heb hier al veel naar gezocht op internet, maar ik heb nog niks kunnen vinden. Wel over JAL en ook over servo's, maar niet hoe je met JAL een micro-controller programmeerd om een servo te besturen.

Acties:
  • 0 Henk 'm!

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 25-04 20:17
Je bedoelt met Servo denk ik een stuurmotortje van een bestuurbare auto.

Je moet gaan zoeken naar PWM met timers. Door zelf de PWM puls te besturen kun je de snelheid prima aanpassen.

ik heb dit zelf met een atmel toegepast. Heb echter zelf een routine geschreven voor de Servo omdat deze maar 1 keer per 20mS ge-update hoeft te worden. Dus een timer interrupt die eens per 20mS getriggerd word en dan een pin hoog voor bepaalde tijd en weer laag tot de volgende interrupt

[ Voor 47% gewijzigd door Steefph op 19-10-2005 19:14 ]

Alles is terug te redeneren naar 4


Acties:
  • 0 Henk 'm!

  • j-a-s-p-e-r
  • Registratie: December 2004
  • Laatst online: 14-04 00:11
En evt gecombineerd met een h-brug voor twee richtingen. Of is dat niet nodig?

Acties:
  • 0 Henk 'm!

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 07:20

Super_ik

haklust!

een h brug is niet nodig, een servo bepaald zn positie aan de hand van de lengte van het pulse

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


Acties:
  • 0 Henk 'm!

Anoniem: 157866

Topicstarter
Hieronder staat een standaard stukje programma om de servo naar een bepaald punt te laten gaan, in dit geval het beginpunt. Maar hoe laat ik hem dan sneller naar dat punt gaan, want op dit moment snap ik alleen de basis in combinatie met gewone java logica, zoals variablen etc.

for 100 loop -- aantal keer dat de loop doorlopen word om de servo in de goed stand te krijgen
pin_a0 = high
delay_10us ( 32 ) -- bepaald naar welke stand de servo gaat
pin_a0 = low
delay_1ms ( 20 ) -- zorgt dat t signaal iedere 20ms herhaald word, omdat de servo t anders vergeet
end loop

Acties:
  • 0 Henk 'm!

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 25-04 20:17
Als je hem gewoon van hoek x naar hoek y wil verplaatsen zo snel mogelijk dan moet je alleen de waarde 32 aanpassen. Bijvoorbeeld 32 eerst en dan direkt 60. De mechanische snelheid is nu de limit.

misschien wel handig om te lezen

Die for loop die eromheen staat is puur om de servo zijn refresh puls te gevn. Na die 100 keer zal de servo in een soort van stanby gaan en is hij dus ook zijn kracht kwijt. Wil je dat hij continu bekrachtigd is zul je in je code moeten verwerken dat hij elke 20mS een update krijgt.

[ Voor 57% gewijzigd door Steefph op 19-10-2005 22:19 ]

Alles is terug te redeneren naar 4


Acties:
  • 0 Henk 'm!

Anoniem: 157866

Topicstarter
Oké dit snap ik nu allemaal. En ik snap dat de snelste tijd niet sneller kan dan dat de servo mechanisch aan kan. Maar nu wil ik hem langzamer laten draaien, hoe doe ik dat dan?

Acties:
  • 0 Henk 'm!

Anoniem: 37450

door niet meteen die waarde te kiezen maar langzaam eerst de tussenliggende waardes af te gaan ?

Acties:
  • 0 Henk 'm!

Anoniem: 157866

Topicstarter
dan gaat hij zeg maar tikken, omdat hij toch zijn eigen snelheid behoud, want die heb je niet aangepast.

Acties:
  • 0 Henk 'm!

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 25-04 20:17
Anoniem: 157866 schreef op donderdag 20 oktober 2005 @ 10:46:
dan gaat hij zeg maar tikken, omdat hij toch zijn eigen snelheid behoud, want die heb je niet aangepast.
Je kan de stapjes ook zo klein maken dat het voor jou een vloeiende beweging lijkt ;).

Want je zit nu met stapjes van 10uS te werken. Maak daar eens 1uS van en laat de waarde per mS 1 verhogen dan gaat hij behoorlijk langzaam en klikt maar dat zie en hoor je niet ;)

Oh ja als laatste natuurlijk hoe maak je een delay van ongeveer 1uS met een klok van 1Mhz?

for(i = 0 ; i<ServoWaarde ; i++); <- in C dan weet niet precies welke taal jij gebruikt

Waarbij je de waarde ServoWaarde na elke loop met 1 laat verhogen.

Dus na delay_ms(20); ServoWaarde++;

Als je nu weet dat de servo tussen de waarde 300 en 1500 kan staan duurt deze rit dus (1500-300)*20mS =24 Seconden (dat is best lang ;) )

Als laatste nog een tip:
Initialiseer de waarde ServoWaarde met een waarde van meer dan 0 ;) Zo rond de 300 proberen.

Als je lager zit vind je servo dat niet helemaal het toppunt van gelukkig in een hoekstaan

Als aller aller laatste (van deze post dan)
code:
1
2
3
PORTB.3 = 1;
for(i=0; i < ServoPWM ; i++);
PORTB.3 = 0;


mijn stukje code dat in een timer overflow interrupt is geplaatst die eens per 20mS overflowd

[ Voor 79% gewijzigd door Steefph op 20-10-2005 17:08 ]

Alles is terug te redeneren naar 4


Acties:
  • 0 Henk 'm!

Anoniem: 157866

Topicstarter
Ik programmeer in JAL, maar zal eens kijken of ik ook zoiets in kan bouwen. Ga het morgen meteen maar eens proberen.

Acties:
  • 0 Henk 'm!

Anoniem: 157866

Topicstarter
Ohja nog een vraagje, omdat ik niet zou weten hoe ik het anders moet doen als met deze loops. Heeft iemand dan een idee hoe ik het anders zou moeten doen, of (lijkt me makkelijker) hoe ik kan uitlezen op welke stand de servo staat na 1 loop, zodat ik weet hoeveel hij er nog moet om op het eindpunt te komen?

Acties:
  • 0 Henk 'm!

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 07:20

Super_ik

haklust!

met variabelen en while loops?

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


Acties:
  • 0 Henk 'm!

Anoniem: 157866

Topicstarter
Ja het is gelukt om hem langzamer te laten draaien. Nu kan ik hem gewoon langzaam en snel laten draaien, maar om hem te versnellen of vertragen is nog niet gelukt. Heeft iemand daar nog tips voor?

Acties:
  • 0 Henk 'm!

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 25-04 20:17
Om mijn voorbeeld weer te nemen.

Als je de waarde ServoPWM neemt en deze na elke loop steeds harder laat oplopen (dus +1 +10 +100).
Dan zal hij versnellen en andersom vertragen.

of iets in de trant van

code:
1
2
3
4
5
6
7
8
9
10
i=0;
while(ServoPWM<1500){
i++;
PIN hoog
for(i2=0 ; i2<ServoPWM ; i2++);
PIN laag
delay 20mS
ServoPWM = (i*i)+300;   <- zal resulteren in 301 304 309 316 en zo voorts

}

offtopic:
Ben slecht met tips geef liever direkt oplossingen ;)

[ Voor 62% gewijzigd door Steefph op 21-10-2005 15:28 ]

Alles is terug te redeneren naar 4


Acties:
  • 0 Henk 'm!

Anoniem: 118825

Kleine tip..als je niet met interrupts werkt en je wilt nog iets anders doen met je 877 dan gewoon een servotje sturen, maak dan gebruik van de CCP module.Zal trouwens je programmeerwerk bij versnellen / vertragen enz serieus wat inkorten.

Acties:
  • 0 Henk 'm!

  • RetepV
  • Registratie: Juli 2001
  • Laatst online: 04-11-2024

RetepV

ALLES valt te repareren

Nog een tip: omdat zo'n microcontroller nogal langzaam rekent, kun je misschien beter van een tabelletje gebruik maken in plaats van te vermenigvuldigingen. Gewoon een tabelletje voor alle waarden van i in dat voorbeeldprogrammatje van steef1983.

Dat zou dan zoiets worden:

code:
1
2
3
4
5
6
7
8
9
10
i=0;
while(ServoPWM<1500){
    i++;
    PIN hoog
    for(i2=0 ; i2<ServoPWM ; i2++);
    PIN laag
    delay 20mS
    // ServoPWM = (i*i)+300;   <- zal resulteren in 301 304 309 316 en zo voorts
    ServoPWM = tabel[i];   <- zal resulteren in 301 304 309 316 en zo voorts
}


De tabel moet in dit geval dan alle voorberekende waardes voor (i*i)+300 bevatten, dus 301, 304, 309, 316 en zo voorts.

Wat je niet moet vergeten is dat meer instructies in de loop de CPU langzamer maken. Het duurt dan langer om de loop te doorlopen. Dat ga je volgens mij merken als een soort storing in de gang van het motortje. De delay van de loop is hier tenslotte 20mS plus de tijd die de instructies nodig hebben om hun werk te doen.

Macbook Pro


Acties:
  • 0 Henk 'm!

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 25-04 20:17
RetepV schreef op zaterdag 22 oktober 2005 @ 20:57:
Nog een tip: omdat zo'n microcontroller nogal langzaam rekent, kun je misschien beter van een tabelletje gebruik maken in plaats van te vermenigvuldigingen. Gewoon een tabelletje voor alle waarden van i in dat voorbeeldprogrammatje van steef1983.

Dat zou dan zoiets worden:

code:
1
2
3
4
5
6
7
8
9
10
i=0;
while(ServoPWM<1500){
    i++;
    PIN hoog
    for(i2=0 ; i2<ServoPWM ; i2++);
    PIN laag
    delay 20mS
    // ServoPWM = (i*i)+300;   <- zal resulteren in 301 304 309 316 en zo voorts
    ServoPWM = tabel[i];   <- zal resulteren in 301 304 309 316 en zo voorts
}


De tabel moet in dit geval dan alle voorberekende waardes voor (i*i)+300 bevatten, dus 301, 304, 309, 316 en zo voorts.

Wat je niet moet vergeten is dat meer instructies in de loop de CPU langzamer maken. Het duurt dan langer om de loop te doorlopen. Dat ga je volgens mij merken als een soort storing in de gang van het motortje. De delay van de loop is hier tenslotte 20mS plus de tijd die de instructies nodig hebben om hun werk te doen.
Is ook een mogelijkeid ;) Maar dan zou ik de waardes 1 4 9 16 enz opslaan dan kun je met de formule ServoPWM= tabel[i]+ waarde zelf bepalen waar hij begint ;)

Alles is terug te redeneren naar 4


Acties:
  • 0 Henk 'm!

Anoniem: 118825

Ik blijf het vreemd vinden hoe je een 8-bits microcontroller in C wil programmeren ;)
Sinds ik met assembler ben begonnen ga ik zelfs niet terug naar Jal...
Maarja, kwestie van persoonlijke smaak natuurlijk :)

Iemand trouwens een mooie tutorial voor visual c++ seriele poort sturing? vind alleen van die korte "dit moet je installeren, dit zijn de commando's" uitlegjes.. (en idd, C is niet mijn favo taal :+ )
Pagina: 1