stř 21.03.2018 18:57
volatile uint16_t prev_time;
volatile uint16_t XXX;
byte icpPin = 8;
void setup() {
Serial.begin(115200);
pinMode(icpPin,INPUT);
TCCR1A = 0x00;
TCCR1B = 0x02;
TIMSK1 = _BV(ICIE1);
}
ISR(TIMER1_CAPT_vect) {
uint16_t duration = (ICR1 - prev_time);
prev_time = ICR1;
if (! bit_is_set(TCCR1B ,ICES1)) {
XXX = duration;
}
TCCR1B ^= _BV(ICES1);
}
void loop() {
Serial.println(XXX); // tohle zrovna dobrý není :-(
}
stř 21.03.2018 23:20
čtv 22.03.2018 22:50
// servo cteni:
namespace {
int puls_uS = 1500;
unsigned long actual_uS;
}
void setup() {
pinMode(2, INPUT_PULLUP); // vstup PWM
pinMode(3, OUTPUT); // servo na ověření výstupu
Serial.begin(9600); // jen na zkoušku, to tu nebude
}
void loop() {
cti_puls();
pulz(puls_uS);
Serial.println(puls_uS); // jen na zkoušku, to tu nebude
}
void pulz(int pulz_uS) { // generování impulzu pro servo
actual_uS = micros() + pulz_uS;
digitalWrite(3, 1); // začátek servoimpulzu
while (micros() < actual_uS ) { } // tohle snad nepoužívá přerušení
digitalWrite(3, 0); // konec servoimpulzu
}
void cti_puls() { // načtení délky příchozího pulzu
while (digitalRead(2) == 1){ } // čeká na nulu
while (digitalRead(2) == 0){ } // čeká na signál
actual_uS = micros(); // dočkal se
while (digitalRead(2) == 1){ } // čeká na konec pulzu
puls_uS = micros() - actual_uS; // načte délku pulzu
}
pát 23.03.2018 0:11
No já bych se u podobných úloh taky přerušením vyhýbal (píšu to pořád dokola - přerušení jen když je opodstatněné). Zůstává mně ale utajeno, proč se vyhýbáš třeba čtení pulsu (pulseIn), když už teda nechceš používat knihovnu servo. (A tu bych v tomto případě asi použil také, protože m.j. posílá impuls s vhodným opakováním sama - pokud by se to teda s něčím nehádalo, což může být při více servech problém.)jyrry píše:No a nakonec jsem si to zkusil "po strojařsku" ...
pát 23.03.2018 8:01
To je šité na robotická serva, pro "naše" se musí hlídat ten "teoretický" úhel (45° - 135°), ne délka v mikrosekundách (1000-2000).http://navody.arduino-shop.cz/arduino-projekty/servo-motor.html píše:Úhel se pohybuje nejčastěji v rozsahu 0° až 180°. Nastavení tohoto úhlu se provádí zasláním impulsu o určité délce. Neutrální poloha (90°) odpovídá obvykle délce impulsu 1,5ms. Délka 0,5ms odpovídá úhlu 0° a impuls délky 2,5ms nastavuje úhel 180°. Impulsy se posílají motoru pravidelně každých 20ms.
pát 23.03.2018 12:08
Pokud to tak je, leze ti do čtení přerušení z ostatního kódu. Uzavři pulseIn() mezi cli() a sei(). Určitě je to přesnější než tvoje smyčka (teď jsem to i ověřil - pro sichr).jyrry píše:Hm, to pulseIn jsem zatím neobjevil ale teď to zkouším. Funguje ale řízené servo je nervoznější než s tím mým dřevním principem čtení ....
čtv 05.04.2018 21:14
stř 11.04.2018 23:42
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
int puls_us = 1000;
void setup() {
pwm.begin();
pwm.setPWMFreq(50);
delay(10);
}
void loop() {
pwm.setPWM(0, 0, float (puls_us/5.109));
delay(500);
}
pon 23.11.2020 4:29
pon 23.11.2020 6:15
// servo revers:
int neutral_uS = 1500;
int puls_uS = 1500;
int hystereze = 20;
int puls1_uS = 1500;
int ramec_uS = 20000;
byte pocet_imp = 0;
const byte LED = 1;
const byte PWM = 2;
const byte servo1 = 3;
void setup() {
pinMode(LED, OUTPUT); // LEDka
pinMode(PWM, INPUT); // vstup PWM
pinMode(servo1, OUTPUT); // servo 1
attachInterrupt(0, ctipuls, RISING);
}
void loop() {
pocet_imp++;
if (pocet_imp > 3) puls_uS = neutral_uS;
if (puls_uS > neutral_uS + hystereze) digitalWrite(LED, HIGH);
if (puls_uS < neutral_uS - hystereze) digitalWrite(LED, LOW);
puls1_uS = 2 * neutral_uS - puls_uS;
pulz(puls1_uS, servo1);
delayMicroseconds(ramec_uS - puls_uS);
}
void pulz(int pulz_uS, byte servo) {
noInterrupts();
digitalWrite(servo, HIGH);
delayMicroseconds(pulz_uS);
digitalWrite(servo, LOW);
interrupts();
}
void ctipuls() {
unsigned long aktual_uS = micros();
long newpuls_uS;
while (digitalRead(2) == HIGH) {
}
newpuls_uS = micros() - aktual_uS;
if (newpuls_uS < 900) newpuls_uS = puls_uS; // osetreni delky
if (newpuls_uS > 2100) newpuls_uS = puls_uS; // osetreni delky
puls_uS = newpuls_uS;
pocet_imp = 0;
}
pon 23.11.2020 11:29
Fakt se ti to zdá jako základ pro výuku na téma - co se servem?jyrry píše:Tohle mám uložené od mých pokusů s arduinem....
pon 23.11.2020 21:16
úte 24.11.2020 0:01
YenyaKas píše:... neutrál je 1520 µs, ne 1500.
úte 24.11.2020 1:19