Hi all,
Ik ben weer volop aan het programmeren voor m'n eindwerk en zit met een irritant probleem.
Bij het aansturen van RC servo's zou ik graag een soepele snelheidsregeling inbouwen, dus bv van positie A naar positie B bewegen binnen X aantal tijd.
Nu heb ik dit verwezenlijkt door de pulsen steeds te increasen (elke keer komt er ongeveer 1µs bij, dus bv van 1,5ms naar 2ms met stappen van 1µs).
Op de scoop zie je de puls mooi breder worden, echter als ik de servo erop aansluit schokt deze altijd met stapjes.
Komt dit door de servo zelf, omdat de potmeter maar een beperkte nauwkeurigheid heeft?
Of bestaat er een andere manier om een soepele beweging uit zo'n ding te krijgen?
Groeten,
Sven.
elmowww
PA0EJE - www.eje-electronics.nl - e.jongerius[aapje]eje-electronics.nl - EJE Electronics - Elektronica/firmware ontwikkeling
De code gaat simpel gezegd als volgt:
Eerst wordt de eerste servopuls opgewekt dmv timer0.
Als deze puls afgewerkt is wordt de volgende servopuls opgewekt, daarna de derde.
Na deze 3 pulsen komt er een vaste lage periode van 10ms, waarna de lus opnieuw begint.
Het ziet er dus ongeveer zo uit:
|-|____________
__|-|__________
_____|-|________
|<-10ms->|
Ik heb al geprobeerd van de 10ms laag te veranderen in 20ms en 5ms, maar dit geeft weinig tot geen verschil (buiten dan dat de snelheid van de verandering uiteraard wat verschil)
Pertinax
Mijn thuis is waar mijn Weller staat
Ik dacht dat een servo om de 20mS een puls krijgt, maar dat heeft niet zoveel belang. (Heeft bij modelbouw meer te maken dat er andere servo's moeten aangestuurd worden).
In principe is het idee goed. Ik vermoed echter dat de servo moeilijk doet doordat je met enorme kleine stapjes gaat werken. Nu heb je er 500 (van 1 us). Een gewone servo kan dit waarschijnlijk niet aan. Op een bepaald moment wordt de fout (wrijving) te groot, en corrigeert hij, met schokjes tot gevolg. Je moet ook rekening houden met de reactietijd van de servo...
Wat je zou kunnen doen is de stap vergroten, bvb 10uS. Om dan in de periode dat de servo zijn beweging maakt voldoende pulsen te geven, geef je dezelfde puls een aantal keren na elkaar.
Bvb. je wil in 5s een beweging van 90° maken. Repetitie = 10ms
5s = 5000ms
De servo ontvangt in die tijd dus 500 pulsen, oplopend van 1.5 naar 2 ms (of naar 1 ms.
Ofwel geef je 500 pulsen oplopend met een stap van 1 us
Ofwel geef je eerst 10 pulsen van 1.5ms, daarna 10 van 1.51ms enz.
ofwel 20 van 1.5ms, daarna 20 van 1.52, enz
Met een beetje geëxperimenteer vind je wel iets dat vloeiender gaat.
Misschien kun je eens een nieuwe servo proberen. Of een digitale.
Op dit moment werk ik als volgt:
Het register met de snelheid (8 bits) wordt bij elke interrupt die voor hem geld (dus bv servo1, snelheid1)gedecrementeerd, zolang deze geen nul is wordt dezelfde pulsbreedte aangehouden.Is deze wel nul word de pulsbreedte aangepast, en het snelheidsregister terug gereset.
Maar ik denk idd dat je gelijk hebt wat betreft de stappen, ik ga het eens proberen met wat grotere stappen.
Assembler is tof tot een bepaald aantal regels code :d
Bedankt voor de reply's alvast!
Edit: je kan dus stellen dat de snelheid bepaald hoeveel keer een bepaalde puls gestuurd word.
Snelheid = 8 -> elke puls word 8 keer herhaald
[Bericht gewijzigd door ScuD op ]
Duuh...
Aangezien ik zowel met m'n eindwerk als project bezig ben zat ik nog volledig met de PIC in m'n hoofd terwijl ik nu op een ADuC aan het werken ben 
Het zijn dus geen stapjes van 1µs (4Mhz /4 bij de pic) maar van 5,7µs (2.097Mhz / 12)
Nonetheless, heb wat met de waardes zitten spelen, nog steeds hetzelfde probleem.
Ik heb echter wel gemerkt dat wanneer de puls zijn definitiefe punt bereikt heeft er wat jitter op de neergaande flank zit, alsof ie bv zit te switchen tss een puls van 1,01ms en 1,02ms.
Nu vraag ik me alleen nog af hoe dit mogelijk is aangezien ik met een timer-interrupt werk, waarbij de timer bij het begin van de ISR wordt gestopt en op het einde pas geset, dus zou een vaste timing moeten zijn, toch?
Ok, I give up, ik ben nu al dagen aan het zoeken en ik vind het probleem maar niet.
Hierbij dus de code, niet letten op eventuele rommel, ik ben constant aan het zoeken waar fouten zitten, vandaar:
T0INT:
push acc
push psw
clr TR0
ANL P3,#11100011b ;clear servo pins
mov a,@R0 ;indirect addressing
mov POSX,a ;Get current position
mov a,R0
add a,#003h
mov R0,a
mov a,@R0
mov POSY,a ;Get desired position
mov a,R0
add a,#006h
mov R0,a
mov a,@R0
mov SPEEDX,a
clr c
mov A,R0
subb A,#008h ;reset R0 to correct vector
cjne A,#036h,ok1
jmp Laag
ok1: jnc Laag
mov R0,a
;_________________________________________________________________
; Check speed
;
DJNZ SPEEDX,yup ;10 times, calculate next servo position
mov a,R0
add a,#005h
mov R0,a ;set R0 to speed
mov a,@R0 ;reload Speedx with speed
mov SPEEDX,a
mov a,R0
subb a,#005h ;reset R0
mov R0,a
;_________________________________________________________________
; This part calculates the increase or decrease
; of the current value according to desired value.
mov A,POSX ;move current position into accu
cjne A,POSY,DET ;compare to desired position
jmp yup ;values are equal, so exit
DET:
jc Increase ;Current position is lower then desired
Decrease: dec POSX ;Decrease current position
jmp yup
Increase: inc POSX ;Increase current position
jmp yup
yup: clr c ;clear carry
mov A,#073h ;zet topwaarde LSB in accu
subb A,POSX ;trek waarde positie af
mov TL0,A ;zet in timer
mov A,#0ffH ;zet topwaarde MSB in accu
subb A,#000h ;aftrekken eventuele carry
mov TH0,A ;zet in timer
dec R0
mov @R0,POSX ;save position in current position
mov a,R0
add a,#009h ;set R0 to speed banks
mov R0,a
mov @R0,SPEEDX ;save speed
subb a,#009h ;reset R0
mov R0,a
inc R0
ljmp IntEx
Laag:
mov R0,#032h ;reset indirect address
mov TH0,#0F9h ;10 ms delay
mov TL0,#02Bh
mov SHIFT,#004h ;reset shift register
ljmp IntEnd ;exit isr
IntEx:
mov a,SHIFT ;rotate shift to select
orl P3,a ;Set correct pins, making sure
;other pins on port are unaffected
RL a ;correct servo pin
mov SHIFT,a
IntEnd:
setb TR0
pop psw
pop acc
RETI ;return
Dit is dus enkel de timer0 interrupt functie, even tussen haakjes.
Als iemand me kan vertellen waarom de tijd dat een pin hoog is de ene keer langer duurt dan de andere (wanneer posX = posY) zou ik heel dankbaar zijn...
Het meest bizarre deel is dit: in mijn main staat gewoon een lus die constant een led aan en uit doet flikkeren dmv softwarematige delay, die gebruik maakt van R7-R6-R5.
Wanneer ik de delay niet aanroep heb ik beduidend minder jitter, hoe kan dat ding in godsnaam invloed hebben op een interrupt??