Řízení RC serva PICem - servo se cuká. Proč?
Moderátor: Moderátoři
- VirtualMan
- Příspěvky: 63
- Registrován: 18 bře 2005, 01:00
- Bydliště: Brno
Řízení RC serva PICem - servo se cuká. Proč?
Ahoj!
Třeba má někdo zkušenost a poradí, možná na to jdu blbě. Nevím.
PIC 16F1825, servo připojeno na výstup RA4
TMR0 mám nastavený na 100 Hz. (vím že RC serva běžně běhají na 50 Hz, ale při 50 Hz se mi cukání projevovalo víc, asi proto že servo stihlo zajet dál, než přišla další "oprava" polohy)
V obsluze přerušení od TMR0 si nastavím do TMR1 počet cyklů, odpovídající požadované poloze serva, RA4 nahodím do jedničky a spustím odpočet TMR1
V obsluze přerušení od TMR1 zase odpočet zastavím a shodím RA4 do nuly.
Servo jaksi udržuje tuto polohu, ale sem-tam někdy i víckrát za sekundu poskočí, jako by ho někdo nakopnul. Jakoby ta jednička na pinu RA4 nespadla do nuly nebo co. (nevyvolá se včas přerušení od TMR1, nebo se nevyvolá vůbec?)
Nenapadá mě, co by se kde dalo vymyslet líp, ale třeba má na to někdo lepší mast a já to řeším nějak blbě...
Díky za každé nakopnutí správným směrem.
Třeba má někdo zkušenost a poradí, možná na to jdu blbě. Nevím.
PIC 16F1825, servo připojeno na výstup RA4
TMR0 mám nastavený na 100 Hz. (vím že RC serva běžně běhají na 50 Hz, ale při 50 Hz se mi cukání projevovalo víc, asi proto že servo stihlo zajet dál, než přišla další "oprava" polohy)
V obsluze přerušení od TMR0 si nastavím do TMR1 počet cyklů, odpovídající požadované poloze serva, RA4 nahodím do jedničky a spustím odpočet TMR1
V obsluze přerušení od TMR1 zase odpočet zastavím a shodím RA4 do nuly.
Servo jaksi udržuje tuto polohu, ale sem-tam někdy i víckrát za sekundu poskočí, jako by ho někdo nakopnul. Jakoby ta jednička na pinu RA4 nespadla do nuly nebo co. (nevyvolá se včas přerušení od TMR1, nebo se nevyvolá vůbec?)
Nenapadá mě, co by se kde dalo vymyslet líp, ale třeba má na to někdo lepší mast a já to řeším nějak blbě...
Díky za každé nakopnutí správným směrem.
- VirtualMan
- Příspěvky: 63
- Registrován: 18 bře 2005, 01:00
- Bydliště: Brno
- VirtualMan
- Příspěvky: 63
- Registrován: 18 bře 2005, 01:00
- Bydliště: Brno
Oscilo mám jen takový malý žebrák - QUAD Na rozdíl od skleněné klasiky kde stopa po parsku přece jen chvilku vyhasína na tom člověk tak krátkou špičku nepostřehne.
Ale s těma přerušeníma to může být ono. Mám tam ještě přerušení od sériové linky, protože to pracuje jako I2C slave.
Takže bych měl do obsluhy toho přerušení od TMR1 přidat na začátek zákaz všech přerušení nebo jak o udělat? Neumím nastavit prioritu přerušení (pokud to vůbec u PIC jde...)
Ale s těma přerušeníma to může být ono. Mám tam ještě přerušení od sériové linky, protože to pracuje jako I2C slave.
Takže bych měl do obsluhy toho přerušení od TMR1 přidat na začátek zákaz všech přerušení nebo jak o udělat? Neumím nastavit prioritu přerušení (pokud to vůbec u PIC jde...)
Kód: Vybrat vše
void interrupt() {
if (SSP1IF_bit){ // Od I2C mastera prisla nova data
SSP1IF_bit = 0;
++rear %= maxque; // Inkrementace kruhového bufferu
if (front == rear) return; // pokud je buffer plný, nedelej nic
else {
Buff[rear].Status = SSPSTAT;
Buff[rear].Value = SSPBUF;
}
CKP_bit = 1;
}
if (TMR0IF_bit) { // preruseni od TMR0
TMR0IF_bit = 0;
TMR0 = 100; // Nastavit novy odpocet
ServoHandler(); // Nastaveni polohy serva, port A4=1
}
if (TMR1IF_bit) { // Odpocet pulsu pro servo dobehnul
TMR1ON_bit = 0; // Zastav citac TMR1
LATA4_bit = 0; // Ukonci puls pro servo - port A4 = 0
TMR1IF_bit = 0; // Clear interrupt flag bit
}
}
Kód: Vybrat vše
void ServoHandler(void){
int PosDiff;
PosDiff = NewServoPos-CurrentPos; // Velikost zmeny polohy serva
if (PosDiff >5) { // Odchylku mensi nez 5 ignoruj
CurrentPos += sqrt(PosDiff); // polohu upravujeme v jednom kroku jen
} else if (PosDiff <5) { // o druhou odmocninu celkové odchylky
CurrentPos -= sqrt(PosDiff*-1);
}
TMR1H = ((CurrentPos & 0xff00) >> 8) ^ 0xFF; // Nastav nové hodnoty
TMR1L = (CurrentPos & 0x00ff) ^ 0xFF; // pro odpocet
LATA4_bit = 1;
TMR1ON_bit = 1; // Spustit odpocitavani
}
- forbidden
- Příspěvky: 8808
- Registrován: 14 úno 2005, 01:00
- Bydliště: Brno (JN89GF)
- Kontaktovat uživatele:
Quad neznám, ale zaráží mě, že v dnešní době neumí digitál, i jen tak jednoduchej, záznam, alespoň kousek.
V Cčku to nezkontroluju, ale základ v obsluze je ihned po skoku na vektor přerušení veškerý přerušení globálně zakázat. PIC žádný priority nemá, ale tento konkrétní z hlavy neznám. Nevylučuju, že některý typy to můžou mít.
V Cčku to nezkontroluju, ale základ v obsluze je ihned po skoku na vektor přerušení veškerý přerušení globálně zakázat. PIC žádný priority nemá, ale tento konkrétní z hlavy neznám. Nevylučuju, že některý typy to můžou mít.
- VirtualMan
- Příspěvky: 63
- Registrován: 18 bře 2005, 01:00
- Bydliště: Brno
No, to on samozřejmě umí zaznam, i přehrávání, ale už asi dva roky mi při pokusu o záznam píše Write error a já nevím proč. Přehrání na nový firmware nepomohlo. Asi má nějak nadrbnutý filesytem, a funkci na formátování nemá.forbidden píše:Quad neznám, ale zaráží mě, že v dnešní době neumí digitál, i jen tak jednoduchej, záznam, alespoň kousek..
Jo, to zkusím. Já se s PICkem moc nekamarádím, toto je moje třetí aplikace, tak se v tom tady tak nějak plácám a většinu času se hrabu v datasheetu a googlu.forbidden píše:V Cčku to nezkontroluju, ale základ v obsluze je ihned po skoku na vektor přerušení veškerý přerušení globálně zakázat. PIC žádný priority nemá, ale tento konkrétní z hlavy neznám. Nevylučuju, že některý typy to můžou mít.
- VirtualMan
- Příspěvky: 63
- Registrován: 18 bře 2005, 01:00
- Bydliště: Brno
Tak se přáteé musím přiznat, že poté co jsem nad tím strávil den a noc jsem nakonec hodil ručník do ringu.
Vyzkoušel jsem mnoho způsobů, různě navzájem blokoval přerušení a dělal různé kličky jak přerušení obsluhovat v požadovaném pořadí, ale nic nezabralo, a poloha serva při žádné z variant nebyla stabilní.
Když jsem v obsluze přerušení od TMR1 blokoval přerušení od I2C, tak měl zase problémy I2C master, prostě nebylo to ono. Master má zase jiné úkoly, které musí stíhat v reálném čase, proto jsem chtěl obsluhu serva přesunout na tento druhý procesor, kterému bych jen přes I2C diktoval polohu serva.
Udělat obsluhu serva přes dva časovače a přerušení není problém, chodí to krásně a servo drží polohu jako přibité.
Udělat funkční I2C komunikaci master-slave s kruhovým bufferem a následným zpracováním přijatých dat někde v main proceduře také lze, a chodí to pěkně, možná by ani nebylo nutné dělat CRC kontrolu.
Skloubit tyhle dvě věci dohromady je ale možná nad síly toho procesoru. I2C slave obsluha je natolik časově náročná, že udržet šířku pulsu pro servo s tolerancí pár mikrosekund se asi nedá. Nad moje síly je to určitě.
Na netu jsem našel spoustu odkazů na nějaké řízení serv, dokonce i šestnáct najednou, několik jsem jich vyzkoušel, ale bez úspěchu.
Taky jsem tam ale našel dost rozsáhlý popis od člověka, který asi před dvěma lety poměrně dlouho řešil přesně stejný problém jako já, prakticky totožné zadání. Věnoval tomu mnohem více času, a bohužel taky dospěl ke stejnému výsledku.
Takže ještě zkusím pro přenos požadované polohy použít místo I2C mormální PWM signál a měřit/počítat si šířku pulsu (ale tady taky moc nevěřím že by to bylo stabilní) a nebo zkusím, jestli by si s tím neporadil jiný procesor. Zajímavým kandidátem se zdá být PICAXE-08M2.
Vyzkoušel jsem mnoho způsobů, různě navzájem blokoval přerušení a dělal různé kličky jak přerušení obsluhovat v požadovaném pořadí, ale nic nezabralo, a poloha serva při žádné z variant nebyla stabilní.
Když jsem v obsluze přerušení od TMR1 blokoval přerušení od I2C, tak měl zase problémy I2C master, prostě nebylo to ono. Master má zase jiné úkoly, které musí stíhat v reálném čase, proto jsem chtěl obsluhu serva přesunout na tento druhý procesor, kterému bych jen přes I2C diktoval polohu serva.
Udělat obsluhu serva přes dva časovače a přerušení není problém, chodí to krásně a servo drží polohu jako přibité.
Udělat funkční I2C komunikaci master-slave s kruhovým bufferem a následným zpracováním přijatých dat někde v main proceduře také lze, a chodí to pěkně, možná by ani nebylo nutné dělat CRC kontrolu.
Skloubit tyhle dvě věci dohromady je ale možná nad síly toho procesoru. I2C slave obsluha je natolik časově náročná, že udržet šířku pulsu pro servo s tolerancí pár mikrosekund se asi nedá. Nad moje síly je to určitě.
Na netu jsem našel spoustu odkazů na nějaké řízení serv, dokonce i šestnáct najednou, několik jsem jich vyzkoušel, ale bez úspěchu.
Taky jsem tam ale našel dost rozsáhlý popis od člověka, který asi před dvěma lety poměrně dlouho řešil přesně stejný problém jako já, prakticky totožné zadání. Věnoval tomu mnohem více času, a bohužel taky dospěl ke stejnému výsledku.
Takže ještě zkusím pro přenos požadované polohy použít místo I2C mormální PWM signál a měřit/počítat si šířku pulsu (ale tady taky moc nevěřím že by to bylo stabilní) a nebo zkusím, jestli by si s tím neporadil jiný procesor. Zajímavým kandidátem se zdá být PICAXE-08M2.
Cau,s PICAXE-08M2 sice nedelam ale myslis si ze tenhle 8pinovej PIC ma vetci vykon nez 16F1825 ?
serva nejsou moc haklivy na frekvenci impulzu, takze jestli je krmis 200Hz nebo 40Hz je za urcitych okolnosti sumak ...
skus trochu popsat co to ma delat a jak cca casove narocny je to
preruseni musi bejt samozrejme co nejkratsi
serva nejsou moc haklivy na frekvenci impulzu, takze jestli je krmis 200Hz nebo 40Hz je za urcitych okolnosti sumak ...
skus trochu popsat co to ma delat a jak cca casove narocny je to
preruseni musi bejt samozrejme co nejkratsi
- Jeejda_teda_puvodne
- Příspěvky: 142
- Registrován: 08 dub 2012, 02:00
Naposledy upravil(a) Jeejda_teda_puvodne dne 25 říj 2016, 13:08, celkem upraveno 1 x.
- Jeejda_teda_puvodne
- Příspěvky: 142
- Registrován: 08 dub 2012, 02:00
Naposledy upravil(a) Jeejda_teda_puvodne dne 25 říj 2016, 13:09, celkem upraveno 1 x.
A na akom kompilery to robis? free hitec? Optimalizacia je na rychlost,velkost kodu? Rutiny z MSSP su dostatocne rychle aj z kruhovym bufferom,nevidim problem ho dat do mainu.A co mas vlastne v maine? A ake velke a ako casto chodia spravy po i2c? Velmi malo informacii... Tebe staci update kazdych 100ms,wdt nepreteka? ![Rolling Eyes :roll:](./images/smilies/icon_rolleyes.gif)
![Rolling Eyes :roll:](./images/smilies/icon_rolleyes.gif)
Už druhý krát strihám a furt je to krátke
VirtualMan:
Pic neovládám, jako stará škola jedu v asembleru na AVR, ale:
obsluha několika serv s taktem 40Hz a jedna sériová linka musí být zívačka pro jakýkoliv procesor.
Priorita přerušení se projeví v momentě, kdy se naráz setkají dvě přerušení.
Každý procesor je má seřazené podle priorit, u některých se dají priority měnit.
Přerušit přerušení lze taky, to už ale vyžaduje velmi dobrou kontrolu nad kódem.
Hlavně v přerušení se nedělaj matematický orgie typu sqrt, výpočet odchylky apod., to se řeší v mainu.
Dále neznám způsob exekuce intu na PICu, ale zaráží mě, jak je to napsané, že se musí testovat nějaké bity. Problém bych viděl v provedení
if (front == rear) return kdy ukončí celý INT při souběhu požadavků a na timer se nedostane, to ale hádám.
Pic neovládám, jako stará škola jedu v asembleru na AVR, ale:
obsluha několika serv s taktem 40Hz a jedna sériová linka musí být zívačka pro jakýkoliv procesor.
Priorita přerušení se projeví v momentě, kdy se naráz setkají dvě přerušení.
Každý procesor je má seřazené podle priorit, u některých se dají priority měnit.
Přerušit přerušení lze taky, to už ale vyžaduje velmi dobrou kontrolu nad kódem.
Hlavně v přerušení se nedělaj matematický orgie typu sqrt, výpočet odchylky apod., to se řeší v mainu.
Dále neznám způsob exekuce intu na PICu, ale zaráží mě, jak je to napsané, že se musí testovat nějaké bity. Problém bych viděl v provedení
if (front == rear) return kdy ukončí celý INT při souběhu požadavků a na timer se nedostane, to ale hádám.