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.

Vertel eens wat meer over je code... Hoe lang zit er pauze tussen de pauze?

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)

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 :D

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??