Servoreverz s ATtiny85
Moderátor: Moderátoři
- Dumitru
- Příspěvky: 254
- Registrován: 11 pro 2015, 00:00
- Bydliště: Slovensko,Bratislava
- Kontaktovat uživatele:
Fuse : LOW 0xE2
HIGH 0xDF
- Přílohy
-
- Ebastlirna_reverz2.hex
- (345 bajtů) Staženo 109 x
Proč mi nemůže všechno chodit hned ?!!
Jen tak na okraj, kámoš přeložil ten test přetečení Timeru 1 na PlatformIO a ta nestabilita 4us tam je taky. A na ATmega328P na Timeru 2 není, stejně jako není při překladu na Arduino Ide. Na vyvracení tvých dalších tvrzení nemám náladu ani čas.
Ten A51 code, (nevím, k čemu by mě měl být) určitě žádnej reverz servosignálu dělat nebude, možná tak kopii vstupního signálu.
Proč mi nemůže všechno chodit hned ?!!
- nostalcomp
- Příspěvky: 169
- Registrován: 09 lis 2022, 00:00
Tak jsem si to po roce znovu pustil a funguje to. Vůbec není nutné měřit délku vstupního servopulsu. Stačí jen čekat na hrany a generovat jeho doplněk do 3ms. K odčasování těch 3ms mi stačí 8-bitový timer s autoreloadem (ale šlo by to i bez něj) a inkrementačním kmitočtem 1MHz. Na náběžku vstupního servopulsu spustím časování, na sestupku nahodím reverzní servopuls a po dočasování 3ms ho zase shodím a čekám na další náběžku. Díky tomu, že timer pořád dokola odměřuje pevný interval 3mS, dá se snadno korigovat nepřesnost vznikající jeho obsluhou. Zkouším 2 analogová serva velikosti standard a micro. Funguje to parádně. Serva se při stabilním vstupním servopulsu ani nehnou. Ani při přiložení prstu na výstupní páku není cítit žádné chvění, či nepokoj. Prostě špalek funguje. Jak ty jsi s tím reverzem dopadl?
PIC16F54 mám zapájenou v redukci na DIL28 a o víkendu se ho chystám na Xeltecu napíct.
Zdroják mám v jiným PC. Už je to rok a tak ho doufám ještě najdu.
edit: Našel, snad je to ono aspoň to má nejnovější datum a čas.
Kód: Vybrat vše
// chodí s možností krokového nastavení středu neutrálu reverz serva
// ATtiny 84, s ATtiny 85 to nezvládá časovač.
volatile uint16_t pulseWidth;
volatile int8_t offset = 0;
ISR(INT0_vect) {
uint16_t startTime = TCNT1; // Uložení počáteční hodnoty časovače
while ((PINB & (1 << PINB2)) > 0); // Čekání na sestupnou hranu vstupu
uint16_t endTime = TCNT1; // Uložení konečné hodnoty časovače
if (endTime > startTime) { // test přetečení 16 bitů časovače
pulseWidth = endTime - startTime;
} else {
// Časovač přetekl
pulseWidth = (0xFFFF - startTime) + endTime + 1; // +1 protože časovač přetekl na nulu a pokračoval
}
// pulseWidth = pulseWidth; // Úprava hodnoty při použití prescaleru 8
pulseWidth = pulseWidth / 8; // Úprava hodnoty při použití prescaleru 1
pulseWidth = 3000 - pulseWidth; // Reverzace a kompenzace středu výstup serva
pulseWidth += offset; // Aplikace offsetu
// Generování výstupního pulzu na PA5
PORTA |= (1 << PORTA5); // Začátek výstupního pulzu
delayMicroseconds(pulseWidth); // Délka výstupního pulzu
PORTA &= ~(1 << PORTA5); // Konec výstupního pulzu
}
void setup() {
DDRA |= (1 << DDA5); // Nastavení PA5 jako výstup
DDRA &= ~(0x0F); // PA0-PA3 jako vstupy pro DIP přepínač
PORTA |= 0x0F; // Povolení pull-up odporů na PA0-PA3
DDRB &= ~(1 << DDB2); // Nastavení PB2 jako vstup
PORTB |= (1 << PORTB2); // Zapnutí pull-up rezistoru na PB2
// Nastavení časovače 1
TCCR1A = 0;
TCCR1B = (1 << CS10); // Prescaler 1, 8 MHz při 8 MHz systémovém taktu
// TCCR1B = (1 << CS11); // Prescaler 8, 1 MHz při 8 MHz systémovém taktu
// Povolení externího přerušení na PB2 (INT0)
MCUCR = (1 << ISC00) | (1 << ISC01); // Přerušení na vzestupnou hranu
GIMSK = (1 << INT0); // Povolení přerušení INT0
sei(); // Povolení globálních přerušení
}
void loop() {
uint8_t dipValue = (PINA & 0x0F); // Čtení hodnoty DIP přepínače
offset = (int8_t)(dipValue - 5); // Výpočet offsetu (-8 až 7)
offset *= 10; // krok po 10 mikrosekundách
delay (500);
}
Proč mi nemůže všechno chodit hned ?!!