Servoreverz s ATtiny85
Napsal: 14 kvě 2024, 13:41
Potřebuju pro kámoše udělat servoreverz do modelu. Vím, dá se to koupit na Alíku ale nebude to hned a taky není k zahození se něco naučit.
Takže 0,8-2,2ms, co se opakuje každých 20ms otočit při 0,8 ms na 2,2ms a naopak.
Tak jsem zplichtil pár řádků. Je to funkční ale nepoužitelný, výstupní servo nepravidelně trochu kolísá kolem středový polohy. Nejdřív jsem si myslel, že se pere přerušení se servoknihovnou a tak jsem to zkusil bez přerušení a knihovny a ono to bylo stejné. Připojil jsem na výstup servoreverzu zajícočítač a bylo to jasné, výstup kolísal o 0,008 - 0,017ms. Prostě při použitý koncepci měření a generování výstupu záleží na tom, kam se změna vstupního portu trefí do milis procesoru. Teoreticky chyba 2 milis při vzestupné a 2 milis pri sestupné hraně, takže klidně 4milis. No a při generování výstupního signálu to samé a to celé na druhou. Z toho je těch 8-17 milisekund kolísání. No je to jasný, bylo by potřeba aby milis běžel 5-10 x rychleji. Jenže jak na to? Když použiju na měření interní časovač, nahodím ho při vzestupné a zastavím při sestupné hraně, mám délku vstupního impulzu. Ale je tam jeden problém, u Tiny85 s krystalem 8MHz se dá nejrychleji plnit časovač 1us. Takže žádný výrazný zpřesnění se asi konat nebude.
Tak nevím, co s tím...
Takže 0,8-2,2ms, co se opakuje každých 20ms otočit při 0,8 ms na 2,2ms a naopak.
Tak jsem zplichtil pár řádků. Je to funkční ale nepoužitelný, výstupní servo nepravidelně trochu kolísá kolem středový polohy. Nejdřív jsem si myslel, že se pere přerušení se servoknihovnou a tak jsem to zkusil bez přerušení a knihovny a ono to bylo stejné. Připojil jsem na výstup servoreverzu zajícočítač a bylo to jasné, výstup kolísal o 0,008 - 0,017ms. Prostě při použitý koncepci měření a generování výstupu záleží na tom, kam se změna vstupního portu trefí do milis procesoru. Teoreticky chyba 2 milis při vzestupné a 2 milis pri sestupné hraně, takže klidně 4milis. No a při generování výstupního signálu to samé a to celé na druhou. Z toho je těch 8-17 milisekund kolísání. No je to jasný, bylo by potřeba aby milis běžel 5-10 x rychleji. Jenže jak na to? Když použiju na měření interní časovač, nahodím ho při vzestupné a zastavím při sestupné hraně, mám délku vstupního impulzu. Ale je tam jeden problém, u Tiny85 s krystalem 8MHz se dá nejrychleji plnit časovač 1us. Takže žádný výrazný zpřesnění se asi konat nebude.
Tak nevím, co s tím...
Kód: Vybrat vše
#include <Servo_ATTinyCore.h>
Servo myServo; // servo objekt
volatile unsigned long startPulse, endPulse;
volatile bool isHigh = false;
// Interupt rutina
ISR(PCINT0_vect) { // servo vstup
if (digitalRead(PB2) == HIGH) {
startPulse = micros(); // ulož si začátek pulzu
isHigh = true; // je vzestupná
} else if (isHigh) {
endPulse = micros(); // ulož si konec pulzu
isHigh = false;
}
}
void setup() {
pinMode(PB2, INPUT); // pin vstupu impusů
GIMSK |= _BV(PCIE); // povolit interupt při změně stavu PB2
PCMSK |= _BV(PCINT2); // povolit přerušení pro pin PB2
pinMode(PB1, OUTPUT); // PB1 jako výstup
myServo.attach(PB1); // přiřaď servo na pin PB1
}
void loop() {
unsigned long pulseLength = endPulse - startPulse; // spočítej délku servoimpulzu
unsigned long outputPulse = map(pulseLength, 800, 2200, 2200, 800); // Reverz mapa
myServo.writeMicroseconds(outputPulse); // řízení reverzovaného serva
delay(17); // zpoždění pro opakování po cca 20 ms
}