Hexapod
Nej jag har inte tänkt att ha sensorer som känner av om benet är på marken eller inte, men det är mycket möjligt att jag lägger till den sen...
Mitt problem nu är att om jag försöker få servot att röra sig långsammare genom att flytta den småsteg i taget, men då skakar den fram.... Finns det nån annan lösninga på detta, eller är enda lösningen att flytta den ännu mindre steg åt gången??
/Daniel
Mitt problem nu är att om jag försöker få servot att röra sig långsammare genom att flytta den småsteg i taget, men då skakar den fram.... Finns det nån annan lösninga på detta, eller är enda lösningen att flytta den ännu mindre steg åt gången??
/Daniel
Lämplig upplösning för vanliga servon är typ 256 lägen på hela rörelsen.
Bättre upplösning än så ger så lite att det i normala fall är onödigt.
Du ska ge servot en ny position varje puls (50 gånger / sekund) annars kommer servot att gå ojämnt.
Det finns risk att servot kommer gå lite ojämnt ändå pga dålig reglering(inget du kan påverka) när det ska flytta mycket massa men jag tycker inte det borde vara störande.
Hur kör du servot nu?
Bättre upplösning än så ger så lite att det i normala fall är onödigt.
Du ska ge servot en ny position varje puls (50 gånger / sekund) annars kommer servot att gå ojämnt.
Det finns risk att servot kommer gå lite ojämnt ändå pga dålig reglering(inget du kan påverka) när det ska flytta mycket massa men jag tycker inte det borde vara störande.
Hur kör du servot nu?
- JimmyAndersson
- Inlägg: 26547
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
- JimmyAndersson
- Inlägg: 26547
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
- JimmyAndersson
- Inlägg: 26547
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Jag kortade ner pausetiden lite och servot går nu ganska smidigt....
Just nu håller jag på med programvaran för AVR:en som ska sitta på servo drivarna.... Men hur ska man göra för att översätta att visst gradantal till motsvarande pulslängd? Med nått slags lookup table?? Nån borde ju haft samma problem tidigare?
/Daniel
Just nu håller jag på med programvaran för AVR:en som ska sitta på servo drivarna.... Men hur ska man göra för att översätta att visst gradantal till motsvarande pulslängd? Med nått slags lookup table?? Nån borde ju haft samma problem tidigare?
/Daniel
MÅSTE du använda just _grader_?! Använder du grader så innebär det att du överskrider det magiska talet 255. Jag skulle ha skapat ett eget system där servots ena ändläge är 0 "grader" och det andra är 255 "grader".
Sen beror de ju lite på hur du använder AVR:ens timer för att generera tiderna, men uppslagstabell behövs inte, använd istället någon faktor X som länkar ihop "gradtalet" med det register som du ställer in din PWM med.
Sen beror de ju lite på hur du använder AVR:ens timer för att generera tiderna, men uppslagstabell behövs inte, använd istället någon faktor X som länkar ihop "gradtalet" med det register som du ställer in din PWM med.
Varför skulle man överskrida 255 om man kör med grader, servot kan ju bara vrida sig max 180 grader, så i sådana fall skulle det bli 0 - 180
Sen kanske man kan diskutera om jag genererar pulserna på ett dumt sätt.... Nu gör jag det utan att använda några timers eller pwm kanaler, man kanske ska lösa det med de 4 pwm kanalerna som den avr jag ska använda har, eller vad tycker ni som gjort detta förut?
Sen har jag funderat på om man ska ha 5 stycken fasta lägen att välja på, istället ställa servot på en viss grad....
EDIT: Nu har jag suttit och läst databladet för AVR:en fram och tillbaka, men lyckas inte lista ut vad som menas med 4 PWM kanaler, det verkar ju inte som om det finns fyra utpinnar för PWM:en, bara två, och det räcker ju inte när jag ska driva fyra servon med en AVR.... Eller ska man istället med en timer tända de olika ut pinnarna för servona??
/Daniel
Sen kanske man kan diskutera om jag genererar pulserna på ett dumt sätt.... Nu gör jag det utan att använda några timers eller pwm kanaler, man kanske ska lösa det med de 4 pwm kanalerna som den avr jag ska använda har, eller vad tycker ni som gjort detta förut?
Sen har jag funderat på om man ska ha 5 stycken fasta lägen att välja på, istället ställa servot på en viss grad....
EDIT: Nu har jag suttit och läst databladet för AVR:en fram och tillbaka, men lyckas inte lista ut vad som menas med 4 PWM kanaler, det verkar ju inte som om det finns fyra utpinnar för PWM:en, bara två, och det räcker ju inte när jag ska driva fyra servon med en AVR.... Eller ska man istället med en timer tända de olika ut pinnarna för servona??
/Daniel
Jag hade servon som hade en vridningsvinkel som låg runt 270 har jag för mig... med de var lite knäppa också.. =)
När jag skrev PWM i förra inlägget så menade jag inte den inbygga, utan en mjukvaru-PWM av något slag...
Såhär skulle jag lösa problemet (icke-verifierad kod, direkt från huvud till forum... så jag varnar för buggar
):
-Sätt upp en timer som genererar avbrott med 256KHz
)Det är möjligt att du måste göra nån typecast i de fyra if-satserna för att kompilatorn ska vara nöjd.)
Låt timeravbrottet köra som en bakgrundsprocess, det enda du behöver ändra från det övriga programmet är de fyra globala variablerna... Tyvärr finns det (minst) en bugg, nämligen att du kan råka sätta ett nytt (lägre) värde för ett servo precis innan det skulle ha satts låg.. men det borrde inte märkas på servot tycker jag...
När jag skrev PWM i förra inlägget så menade jag inte den inbygga, utan en mjukvaru-PWM av något slag...
Såhär skulle jag lösa problemet (icke-verifierad kod, direkt från huvud till forum... så jag varnar för buggar

-Sätt upp en timer som genererar avbrott med 256KHz
Kod: Markera allt
volatile unsigned char Servo0_setting = 0;
volatile unsigned char Servo1_setting = 128;
volatile unsigned char Servo2_setting = 156;
volatile unsigned char Servo3_setting = 255;
Avbrottsrutin(Timer) //Denna körs med 256000Hz
{
static unsigned int ticks = 0;
//1 tick motsvarar ca 3,9us
//256 tick blir då 1ms
if(ticks++ == (256*15) //Låt räknaren slå runt var 15:e ms
{
ticks=0;
PORTA |= (UT0 | UT1 | UT2 | UT3); //Påbörja HÖG puls på alla servon
}
//Sätt LÅG individuellt för varje servo, men minst efter 1ms (256 ticks)
if(Servo0_setting+256 == ticks)
PORTA &= ~UT0;
if(Servo1_setting+256 == ticks)
PORTA &= ~UT1;
if(Servo2_setting+256 == ticks)
PORTA &= ~UT2;
if(Servo3_setting+256 == ticks)
PORTA &= ~UT3;
}
Låt timeravbrottet köra som en bakgrundsprocess, det enda du behöver ändra från det övriga programmet är de fyra globala variablerna... Tyvärr finns det (minst) en bugg, nämligen att du kan råka sätta ett nytt (lägre) värde för ett servo precis innan det skulle ha satts låg.. men det borrde inte märkas på servot tycker jag...
strombom>> Just nu sitter jag och testar med en ATMega16, men jag har beställt tre stycken ATTiny3213 som ska användas sen....
oJsan>> Hmm smidig ide, jag har kastat min kod och börjat med något liknande som du skrev, fast jag sänker pulsen från servot innan jag höjer nästa puls, så att det första servot för med andra ord en liten längre pulslängd.... Men jag ska helt klart testa din metod också... Ska bara se till att översätta det till ASM först eftersom jag hade tänkt att skriva drivarna i det....
/Daniel
oJsan>> Hmm smidig ide, jag har kastat min kod och börjat med något liknande som du skrev, fast jag sänker pulsen från servot innan jag höjer nästa puls, så att det första servot för med andra ord en liten längre pulslängd.... Men jag ska helt klart testa din metod också... Ska bara se till att översätta det till ASM först eftersom jag hade tänkt att skriva drivarna i det....
/Daniel