Sida 3 av 3

Postat: 28 juli 2006, 03:07:30
av strombom
Egentligen vill man inte starta pulsen till alla servon samtidigt eftersom de då drar ström samtidigt, om man har pulserna efter varandra får man lite jämnare strömförbrukning.

Har jag fått för mig i varje fall...

/Johan

Postat: 28 juli 2006, 08:15:07
av oJsan
Bra tanke strombom, det ska jag komma ihåg nästa gång jag pysslar med servon!

Detraw: Precis när jag postat kom jag på "få se nu, Detaw kanske skrev i asm?" =) Aja, du fattade "tänket" i allafall... Försök koda in stromboms förslag också, att lägga pulserna lite ur fas. (Bäst vore ju att även lägga en fast fasförskjutning för varje enskild modul också.)

Postat: 28 juli 2006, 17:44:33
av Chribbe76
Om man ändå ska ha servo-signalerna efter varandra är det lite onödigt med 256000 interrupt/sekund.
Jag skulle ha gjort det med interrupt bara när en servo-signal ska ändras.

Postat: 28 juli 2006, 22:18:17
av Andax
Precis Chribbe76,
smartaste vore ju att ha en interrupt som första gången sätter första servos utgång hög, programmerar tiden till nästa interrupt till önskade bredden.
Vid nästa interrupt clearar du första servosignalen och sätter nästa servo. Programmera tiden till nästa till önskade bredden för servo 2. ock så vidare.
Sista tiden man sätter är endöd tid som motsvarar 20 ms - summan av pulsbredderna för alla servona i interruptkedjan.
På så vis får man automatiskt effekten som strombom påpekade...
Metoden ger teoretisk möjlighet till att styra 10 servon (10x2ms = 20 ms total uppdateringstid)
Man får ju också väldigt låg processorbelastning.

Postat: 28 juli 2006, 22:50:35
av oJsan
Smart!

Postat: 29 juli 2006, 17:29:16
av $tiff
>> Andax

Det är en bra lösning, precis så kör jag också i mina lib. Dock räcker inte 2.0 ms i ändläge för de servo jag testat, det behövs faktist närmare 2,5 ms. Detta medför att man inte hinner med riktigt 10 st servo med en uppdateringsperiod om 20 ms.


Edit: No code

Postat: 29 juli 2006, 23:50:48
av Andax
Vet inte så mycket om hur pulsbredden avkodas inne i servot, men är det möjligt att "tune"-a det lite genom att ändra något motstånd inne i servot.
Gissar att det är en opamp eller nått som integrerar pulsbredden för att få en referenssignal.
Någon som vet?

Postat: 31 juli 2006, 22:16:06
av $tiff
Säkerligen, men jag tror hellre man kodar mjukvaran lite annorlunda än att börja modifiera alla sina servon. Inte minst om man ska producera mer än ett exemplar.

Postat: 6 augusti 2006, 15:21:01
av Detraw
Så där ja nu är man tillbaka efter lite resandes....

Hmmm mycket smarta lösningar ni har kommit fram till medan jag varit borta.... Det där med att man programmerar om interupt tiden efter varje interupt har jag varit inne och nosat på tidigare, och det verkar som en riktigt smidig metod, och eftersom varje drivare ska driva 4 servo, så är det inget problem med att ha en vänt delay på 20ms

Jag ska flytta nu denna vecka, men jag ska försöka bli klar med mjukvaran så snabbt som möjligt...

/Daniel

Postat: 19 augusti 2006, 20:25:26
av Detraw
Projektet har fått ligga lite på is nu ett tag medan jag flyttar, men jag har i alla fall skirivit klart mjukvaran för att röra alla servon, nu ska bara kommunikationen mellan drivarna och huvud processorn skrivas, jag vet inte riktigt vilket protokoll jag ska använda än, men det återstår att se.....

Mina små ATTiny kom nu också, så när jag har packat upp löd- och etsutrustningen så jag bygga drivarna....

Förhoppningsvis är det upppackat om två veckor, ska upp till fjällen nämligen nästa vecka, och kan då inte packa upp nått då....

/Daniel

Postat: 19 augusti 2006, 20:28:40
av Korken
Har du testat det med sevona på benet?
Isf FILM!!! :D

//Emil

Postat: 15 januari 2007, 14:40:42
av Detraw
Hej igen!

Tyckte att det var dags att uppdatera tråden lite nu när det har hänt en del grejjer.... Jag är fortfarande på första benparet, men nu rör sig alla servon som de ska, nästan :) Och man ändrar läget på servorna genom drivarens UART....

Men om man kopplar på mer än ett servo rör de sig skumt, eller ibland bara rycker de fram och tillbaka (med bara en inkopplad funkar allt som det ska)... Jag gissar på att de inte för tillräckligt med ström, men det borde inte va det som är fel eftersom jag pulsar ett servo i taget...

Här nedan är min interrupt kod för att pulsa servot:

Kod: Markera allt

update_servo:
	push r16

	cpi currentServo, 0									; Timer is in pause state
	breq updateServoA									; put it in servoA state
	cpi currentServo, 1									; Timer is in servoA state
	breq updateServoB									; put it in servoB state
	cpi currentServo, 2									; Timer is in servoB state
	breq updateServoC									; put it in servoC state
	cpi currentServo, 3									; Timer is in servoC state
	breq updateServoD									; put it in servoD state
	cpi currentServo, 4									; Timer is in servoD state
	breq updateServoPause								; put it in pause state	

return_update_servo:
	pop r16

	reti

updateServoA:
	sbi servoPORT, servoA								; Start the servo A pulse

	cli													; Disable global interrupt
	ldi r16, 0xFF										; Load the timer with the delay time for servo A
	out TCNT1H, r16
	out TCNT1L, servoAtime
	sei													; Enable global interrupt

	ldi currentServo, 0x01								; Set the current servo to servo A
	
	rjmp return_update_servo							; Return

updateServoB:
	cbi servoPORT, servoA								; Stop the servo A pulse
	nop
	sbi servoPORT, servoB								; Start the servo B pulse

	cli													; Disable global interrupt
	ldi r16, 0xFF										; Load the timer with the delay time for servo B
	out TCNT1H, r16
	out TCNT1L, servoBtime
	sei													; Enable global interrupt

	ldi currentServo, 0x02								; Set the current servo to servo B
	
	rjmp return_update_servo							; Return

updateServoC:
	cbi servoPORT, servoB								; Stop the servo B pulse
	nop
	sbi servoPORT, servoC								; Start the servo C pulse

	cli													; Disable global interrupt
	ldi r16, 0xFF										; Load the timer with the delay time for servo C
	out TCNT1H, r16
	out TCNT1L, servoCtime
	sei													; Enable global interrupt

	ldi currentServo, 0x03								; Set the current servo to servo C
	
	rjmp return_update_servo							; Return

updateServoD:
	cbi servoPORT, servoC								; Stop the servo C pulse
	nop
	sbi servoPORT, servoD								; Start the servo D pulse

	cli													; Disable global interrupt
	ldi r16, 0xFF										; Load the timer with the delay time for servo D
	out TCNT1H, r16
	out TCNT1L, servoDtime
	sei													; Enable global interrupt

	ldi currentServo, 0x04								; Set the current servo to servo D
	
	rjmp return_update_servo							; Return

updateServoPause:
	cbi servoPORT, servoD								; Stop the servo D pulse

	cli
	ldi r16, high(servoPauseTime)						; Load the timer to interrupt after 20ms
	out	TCNT1H, r16
	ldi r16, low(servoPauseTime)
	out TCNT1L, r16
	sei

	ldi currentServo, 0x00								; Set the current servo to none (timer pause state)

	rjmp return_update_servo
Är det nån som kan se nått fel ikoden, eller har nån annan idé om varför det inte funkar med två servon?

Tack på förhand
/Daniel

Postat: 15 januari 2007, 20:45:17
av Korken
Jag kan inte assembler eller så men jag måste säga att din kod gjorde så till och med jag förtog vad den skulle göra.
Vilket borde betyda något bra. :)

Lycka till med projektet!

//Emil