Dobrý den,
Rozhodl jsem se, že se naučím pracovat se servem, našel jsem kód pochopil princip ovládání, a dokonce se mi podařilo servo rozchodit.
Problém je v tom, že se chová celkem nepředvídatelně
klidně mi 10x provede bez problému cyklus 0°, 90°, 180°, a potom se začně kousat, vrčet, ale následně třeba znovu naběhne zpátky, jindy se procesor zastaví, nebo jen přepíná LED.
Zde je kód:
Mám takový vtíravý pocit, že do serva by měl jít ten signál trvale a ne, že mu pošleš 50 pulzů a pak to celé 2 vteřiny stojí. Ono je totiž docela pravděpodobný, že servo během těch 50 pulzů nestihne přestavit pozici…
A mimochodem, snaž se vyhnout příkazům delay o délce kolem 1 ms a výše. Procesor pak má soustu práce s delayema a nemá čas na nic jínýho. Na testování je to samozřejmě jedno. Jinak místo toho použij nějaké časovače a přerušení a procesoru zbyde spoustu času na nějakou rozumnější práci, než čekání.
servo se ovlada impulzama o delce cca 1-2ms, co servo to samozrekme odchylka , sou ale serva co zvladnou i vic,
ten pulz: 1ms je sinchronizace a zbytek natoceni, frekvence cca 50Hz, takze kazdejch 20ms by mel bejt impulz o nastaveni , nektery zvladaj i rychlejsi posilani ,
pokud neni zadnej pulz servo stoji,musi ale bejt log 0 na vstupu
pokud nastavis log 1 a pretahnes to pres 2 ms tak to dela bordel,servo jede za roh na dorazy a pak samozrejme klesa napeti (pokud nemas tvrdej zdroj) a muze se resetovat procesor atd
kondiky…
RA0 = 1;
__delay_us(500); tohle je co ??
co tohle…
Děkuji za Vaše reakce.
Reaguji na MiloPS3:
Kód jsem musel upravit tak, aby mi to kompilátor vzal následovně;
[code]#define _XTAL_FREQ 20000000
#include <xc.h>
#pragma config FOSC = HS #pragma config WDTE = OFF #pragma config PWRTE = OFF #pragma config BOREN = OFF #pragma config LVP = OFF #pragma config CPD = OFF #pragma config WRT = OFF #pragma config CP = OFF
void main()
{
TRISA0 = 0;
while(1)
{
unsigned int i,j;
unsigned int pulz = 1200;
for(j=0;j<5;j++)
{
for(i=0;i<25;i++)
{
RA0 = 1;
__delay_us(pulz);
RA0 = 0;
__delay_us(20000);
}
pulz+=100;
}
for(j=0;j<5;j++)
{
for(i=0;i<25;i++)
{
RA0 = 1;
__delay_us(pulz);
RA0 = 0;
__delay_us(20000);
}
pulz-=100;
}
}
}
[/code]
Ovšem kompilátor mi vyhazuje chybu u
__delay_us(pulz);
main.c:26: error: (1387) inline delay argument must be constant
Zřejmě mu tam vadí proměnná.
Ještě mi nešlo int16 a while(true). Používám kompiler XC8
Zdravím, než takhle složitě laborovat, udělal bych si malý přípravek s 555, který bude posílat puls 1.5 ms s periodou 20 ms. Přidat malý poti, abych mohl puls měnit o ca 0.3 ms. To vše pro napětí ca 4 až 5V. Servo s tím musí naprosto spolehlivě fungovat. Nešetřil bych blokovací kondy a elyty v napájení, rovněž zdroj musí bez poklesu pod 0.2V zvládnout 2A proudu. Jinak osciloskop zkontrolovat napájení, pulsy, zkrátka vše možné. Bez možnosti změřit sám nebo u někoho je vše časově a psychycky hodně náročné.
Četl jsem, že příkazy __delay vytěžují procesor.
Proto jsem se snažil najít nějaký příklad s použitím některého ze tří timerů.
Jeden z nejjednodušších kódů pro začátek jsem našel zde: microcontrollerboard.com/pic-timer0-tutorial.html
Pro začátek bych chtěl jen blikat s LED diodou, jenže nevím, na jaké místo do kódu na výš uvedené adrese zařadit RD0 = 1 popř. 0
Nemohli by jste mi poradit, nebo mě odkázat na nejjednodušší program s použitím timeru?
Děkuji!
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
}[/code]
Bohužel, nefunguje to, ale nejsem si zde jist pár věcmi:
T0CS = 0; //pro práci s interním oscilátorem
Tam bych asi měl nastavit něco jiného, když používám 20MHz externí krystal, že? Navíc, PIC16F877A podle mně dostupných informací interním oscilátorem nedisponuje.
Prescaleru rozumím, o tom jsem se dočetl v příručce microchip, ale nevím, co přesně nastavuje bit T0SE.
Toto je v tutoriálu Microchip:
Mám všechna nastavení správně? Musí být povolen Watchdog timer?
Děkuji!