Switch to full style
Dneska se procesory objevují všude, pokud máte nějaký nápad, či udělát, tak se neváhejte pochlubit.
Odeslat odpověď

Re: Arduino a servo

stř 21.03.2018 18:57

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í :-(
}

Re: Arduino a servo

stř 21.03.2018 23:20

No, jestli tomu porozumím tak to někde použiju :?
Ale samozřejmě dík, pokusím se :-)

Re: Arduino a servo

čtv 22.03.2018 22:50

No a nakonec jsem si to zkusil "po strojařsku" :mrgreen:
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
}

Re: Arduino a servo

pát 23.03.2018 0:11

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.)

Re: Arduino a servo

pát 23.03.2018 8:01

Hm, to pulseIn jsem zatím neobjevil :oops: 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?

Re: Arduino a servo

pát 23.03.2018 12:08

jyrry píše:Hm, to pulseIn jsem zatím neobjevil :oops: 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).

Re: Arduino a servo

čtv 05.04.2018 21:14

Zase si trošku hraju, dorazily nové zásilky :-D
čtení_a_tisk_PWM.jpg
čtení_a_tisk_PWM_2.jpg

Jo, jasně, jsou to us, ne ms... :|

Re: Arduino a servo

stř 11.04.2018 23:42

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... :?

Re: Arduino a servo

pon 23.11.2020 4:29

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=90

Ten 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.

Re: Arduino a servo

pon 23.11.2020 6:15

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;
  }

Re: Arduino a servo

pon 23.11.2020 11:29

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).

Re: Arduino a servo

pon 23.11.2020 21:16

Já bych dělal hardwarový input capture. A teda někde jsem viděl že neutrál je 1520 µs, ne 1500.

Re: Arduino a servo

úte 24.11.2020 0:01

YenyaKas píše:... neutrál je 1520 µs, ne 1500.

Jak u které značky. Gr/SJ HoTT má 1500.

Re: Arduino a servo

úte 24.11.2020 1:19

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
Odeslat odpověď