Autor |
Zpráva |
ellet
|
Napsal: stř 21.03.2018 17:57 |
|
Mazák
|
|
|
Registrován: 12.2.2016 Příspěvky: 1975 Bydliště: Vysočina, ČR
|
Tak ať je to komplet, ještě (trochu zjednodušená) funkční verze podle YenyaKase, t.j.bez nulování čítače. Při použití Arduino Mini Pro 3,3V (8MHz) vrací cca 1000 - 2000. Kód: 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í :-( }
|
|
Nahoru |
|
|
|
|
|
jyrry
|
Napsal: stř 21.03.2018 22:20 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20822 Bydliště: Rakovník, CZ Obrázky: 0
|
No, jestli tomu porozumím tak to někde použiju Ale samozřejmě dík, pokusím se
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
jyrry
|
Napsal: čtv 22.03.2018 21:50 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20822 Bydliště: Rakovník, CZ Obrázky: 0
|
No a nakonec jsem si to zkusil "po strojařsku" A taky to funguje. Pro potřeby udělátek jako servospínač, řízení pumovnice a pod. to myslím stačí přebohatě: Kód: // 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 }
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
ellet
|
Napsal: čtv 22.03.2018 23:11 |
|
Mazák
|
|
|
Registrován: 12.2.2016 Příspěvky: 1975 Bydliště: Vysočina, ČR
|
jyrry píše: No a nakonec jsem si to zkusil "po strojařsku" ... 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.)
|
|
Nahoru |
|
|
jyrry
|
Napsal: pát 23.03.2018 7:01 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20822 Bydliště: Rakovník, CZ Obrázky: 0
|
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í (stále pochroustává). Na té servo.h knihovně mi trochu vadí tohle: 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.
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). Rámec (20ms) mi vlastně ohlídá ten vstupující PWM signál a nemusím ho tedy nijak hlídat. Prostě načtu délku pulzu, pak vyšlu svůj (případně postupně své, je-li jich víc jako v "pumovnici") a zbytek času čekám na nový příchozí puls. Netluče se mi tedy rámec vstupu a můj. Nebo se to musí nějak synchronizovat?
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
ellet
|
Napsal: pát 23.03.2018 11:08 |
|
Mazák
|
|
|
Registrován: 12.2.2016 Příspěvky: 1975 Bydliště: Vysočina, ČR
|
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í .... 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). Ta servo knihovna není někdy ideální. Problém ms versus úhel ale nechápu. Používám ve výpočtech co je výhodnější (většinou vycházím z délky pulsu). U tak jednoduchý úlohy jako je pumovnice se ale bez knihovny snadno obejdeš (a nakonec i na čtení pulsu by stačily dvě polohy a ještě je můžeš i vynechávat - záleží na požadavcích).
|
|
Nahoru |
|
|
jyrry
|
Napsal: čtv 05.04.2018 20:14 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20822 Bydliště: Rakovník, CZ Obrázky: 0
|
Zase si trošku hraju, dorazily nové zásilky Příloha:
čtení_a_tisk_PWM.jpg [ 106.66 KiB | Zobrazeno 14439 krát ]
Příloha:
čtení_a_tisk_PWM_2.jpg [ 105.3 KiB | Zobrazeno 14432 krát ]
Jo, jasně, jsou to us, ne ms...
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
jyrry
|
Napsal: stř 11.04.2018 22:42 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20822 Bydliště: Rakovník, CZ Obrázky: 0
|
Další hračka... Dopracoval jsem se k tomu že přes to nemůžu/neumím řídit serva přímo časem; převádím mikrosekundy na poměrné délky PWM, vlastně nastavuji šířku impulzu v rámci: Kód: #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); } Tu konstantu 5.109 jsem vyšetřil zkusmo, měřením délky impulzu... Skáče to podle ní, nejde rozlišit kratší čas v mikroseknundách...
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
guchar
|
Napsal: pon 23.11.2020 3:29 |
|
Mazák
|
|
Registrován: 7.5.2015 Příspěvky: 7414 Bydliště: ČR Obrázky: 8
|
Obraceč výchylky serva s Arduinem Prolétl jsem 1 až 7 tohoto vlákna a žádný příspěvek zde nemám. To je dobře i špatně současně. Pro Arduino Nano R3 si chci napsat obraceč výchylek. Po vyzkoušení a nějaké době hraní si jej přepsat do finálního provedení HW. Kritériem pro výběr konečné podoby není na 1. místě její velikost (rozměry HW). Vybraná varianta by neměla být zbytečně drahá a zápis SW by neměl vyžadovat vybavení navíc. Zdá se, že pro pokusy i konečnou verzi bude použit "Arduino Nano R3, ATmega328P Klon". U té ceny zase rozdíly deseti korun nejsou podstatné. Pokud jsem se do Arduina zapojil bylo asi to jinde. Podle všeho zde " Procesory a jiné vychytávky Téma: PWM servosignál - Arduino - převod na STEP/DIR" http://www.rcmania.cz/viewtopic.php?f=41&t=80225&start=90Ten SW by měl být jednoduchý, ale aspoň částečně univerzální nebo jednoduše upravitelný pro různá serva. Pokud se pamatuji na čtení a generování délky rámce a impulzu, lze jít více cestami a není to zcela bez potíží. Pro začátek by se asi jako parametry dosadily obvyklé konstanty dané konkrétním servem a soupravou.
|
|
Nahoru |
|
|
jyrry
|
Napsal: pon 23.11.2020 5:15 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20822 Bydliště: Rakovník, CZ Obrázky: 0
|
Tohle mám uložené od mých pokusů s arduinem. Už ani nevím proč tam třeba mám tu LEDku... Kód: // 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; }
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
ellet
|
Napsal: pon 23.11.2020 10:29 |
|
Mazák
|
|
|
Registrován: 12.2.2016 Příspěvky: 1975 Bydliště: Vysočina, ČR
|
jyrry píše: Tohle mám uložené od mých pokusů s arduinem.... Fakt se ti to zdá jako základ pro výuku na téma - co se servem? Ještě bych doplnil, jako někdy hodící se funkčnost, načíst koncové body, ale jen v případě, že se v omezeném čase po zapnutí, páka pohybuje (min - max).
|
|
Nahoru |
|
|
YenyaKas
|
Napsal: pon 23.11.2020 20:16 |
|
Mazák
|
|
|
Registrován: 17.1.2017 Příspěvky: 1339 Bydliště: Brno
|
Já bych dělal hardwarový input capture. A teda někde jsem viděl že neutrál je 1520 µs, ne 1500.
_________________ Sky Surfer; HK Paraglide; DYI: samokřídlo Ita, elektrovětroň Kaze, delta Quasar3D; FlySky i6
|
|
Nahoru |
|
|
jyrry
|
Napsal: pon 23.11.2020 23:01 |
|
Moderátor serveru
|
|
|
Registrován: 28.2.2005 Příspěvky: 20822 Bydliště: Rakovník, CZ Obrázky: 0
|
YenyaKas píše: ... neutrál je 1520 µs, ne 1500. Jak u které značky. Gr/SJ HoTT má 1500.
_________________ jyrry.webnode.cz
|
|
Nahoru |
|
|
guchar
|
Napsal: úte 24.11.2020 0:19 |
|
Mazák
|
|
Registrován: 7.5.2015 Příspěvky: 7414 Bydliště: ČR Obrázky: 8
|
O možnost 1500 nebo 1520 jsem už někde zakopl. Ba to někomu nějak vadilo. Neexistuje někde přehled existujících Tmin, Tstřed a Tmax (stačil by i jen pro analogová). A pro různé výrobce pevný versus pohyblivý rámec (mimo pulsů kanálů tam býval ZAČÁTEK synchro puls) Pro ty pevné jejich trvání (opakovací kmitočet)? Ono těch možností z dob FM modulace a kodér/dekodér bylo víc. Jako první úlovek mám - Sunday, November 11, 2012 - How To Read RC Receiver PPM Stream RCArduino - Arduino Projects, Libraries and Tutorials http://rcarduino.blogspot.com/2012/11/how-to-read-rc-receiver-ppm-stream.htmlÚlovek 2 Zjištění (kontrola) hodnot pro konkrétní RC TX Reading Remote Control Receiver Values with Arduino (Ryan Boland, April 14, 2016) https://ryanboland.com/blog/reading-rc-receiver-values
|
|
Nahoru |
|
|
Kdo je online |
Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 10 návštevníků |
|
Nemůžete zakládat nová témata v tomto fóru Nemůžete odpovídat v tomto fóru Nemůžete upravovat své příspěvky v tomto fóru Nemůžete mazat své příspěvky v tomto fóru Nemůžete přikládat soubory v tomto fóru
|
|
|