Řízení RC serva PICem - servo se cuká. Proč?

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
VirtualMan
Příspěvky: 63
Registrován: 18 bře 2005, 01:00
Bydliště: Brno

Řízení RC serva PICem - servo se cuká. Proč?

#1 Příspěvek od VirtualMan »

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.

Uživatelský avatar
kulikus
Příspěvky: 2484
Registrován: 10 pro 2009, 01:00
Kontaktovat uživatele:

#2 Příspěvek od kulikus »

Servsa jsou obvyle napájená z baterie. Pokud to máš z adaptéru, máš dobře vyhlazené napájení?

Uživatelský avatar
VirtualMan
Příspěvky: 63
Registrován: 18 bře 2005, 01:00
Bydliště: Brno

#3 Příspěvek od VirtualMan »

No, já to teď napájím z takového toho 5V MiniUSB adaptéru. Je to spínaný zdroj, tak jsem to nijak nevyhlazoval. Dám tam elyt, ale předpokládám, že na výstupu z toho zdroj nějaký je.

Uživatelský avatar
forbidden
Příspěvky: 8808
Registrován: 14 úno 2005, 01:00
Bydliště: Brno (JN89GF)
Kontaktovat uživatele:

#4 Příspěvek od forbidden »

Je obsluha přerušení správně napsaná? Nenastane během ní třeba další přerušení od něčeho jinýho? Co kouknout na výstup osciloskopem?

Uživatelský avatar
VirtualMan
Příspěvky: 63
Registrován: 18 bře 2005, 01:00
Bydliště: Brno

#5 Příspěvek od VirtualMan »

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...)

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
}

Uživatelský avatar
forbidden
Příspěvky: 8808
Registrován: 14 úno 2005, 01:00
Bydliště: Brno (JN89GF)
Kontaktovat uživatele:

#6 Příspěvek od forbidden »

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.

Uživatelský avatar
VirtualMan
Příspěvky: 63
Registrován: 18 bře 2005, 01:00
Bydliště: Brno

#7 Příspěvek od VirtualMan »

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

Uživatelský avatar
Mendor
Příspěvky: 223
Registrován: 16 dub 2008, 02:00
Bydliště: Kladno

#8 Příspěvek od Mendor »

Použij řadu PIC 18F, ta už priority má.

Uživatelský avatar
VirtualMan
Příspěvky: 63
Registrován: 18 bře 2005, 01:00
Bydliště: Brno

#9 Příspěvek od VirtualMan »

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.

Uživatelský avatar
MiloPS3
Příspěvky: 259
Registrován: 07 srp 2010, 02:00

#10 Příspěvek od MiloPS3 »

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

Uživatelský avatar
Jeejda_teda_puvodne
Příspěvky: 142
Registrován: 08 dub 2012, 02:00

#11 Příspěvek od Jeejda_teda_puvodne »

Naposledy upravil(a) Jeejda_teda_puvodne dne 25 říj 2016, 13:08, celkem upraveno 1 x.

Uživatelský avatar
jankop
Příspěvky: 679
Registrován: 04 dub 2007, 02:00
Kontaktovat uživatele:

#12 Příspěvek od jankop »

Nikdy jsem se servem nepracoval. Když jsem potřeboval opakovaně zapínat přístroj v záruce, který se automaticky po 8 hodinách vypnul, tak jsem koupil nejlacinější modelářský servo a napsal program. Zapojil to a naprosto žádný problém. Faktem je, že jsem to psal v assembleru.

Uživatelský avatar
Jeejda_teda_puvodne
Příspěvky: 142
Registrován: 08 dub 2012, 02:00

#13 Příspěvek od Jeejda_teda_puvodne »

Naposledy upravil(a) Jeejda_teda_puvodne dne 25 říj 2016, 13:09, celkem upraveno 1 x.

Uživatelský avatar
Burajko
Příspěvky: 1803
Registrován: 21 srp 2009, 02:00

#14 Příspěvek od Burajko »

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? :roll:
Už druhý krát strihám a furt je to krátke

Jenda_KL
Příspěvky: 1173
Registrován: 10 zář 2008, 02:00
Bydliště: Kadaň
Kontaktovat uživatele:

#15 Příspěvek od Jenda_KL »

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.

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“