Switch to full style
Nabíječky, zdroje, přístroje
Odeslat odpověď

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

pát 09.03.2018 7:47

Nie je lacný, ale dobrý:
https://www.topmodelcz.cz/index.php?&desktop_back=eshop&action_back=&id_back=0&desktop=eshop&action=zbozi_detail&id=18257

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

úte 13.03.2018 22:08

Ahoj slowake,
děkuju za odkaz. Vypadá že tester toho umí hodně, ale jestli jsem dobře hledal, tak rychlost přeběhu umí jen v 4 nebo 6 stupních. To je nejspíš málo.

Jirka

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

stř 14.03.2018 13:07

Medved74 píše:Ahoj slowake,
děkuju za odkaz. Vypadá že tester toho umí hodně, ale jestli jsem dobře hledal, tak rychlost přeběhu umí jen v 4 nebo 6 stupních. To je nejspíš málo.

Jirka

Áno, rýchlosť oscilácie serv sa dá nastaviť v šiestich stupňoch.

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

čtv 15.03.2018 20:01

Chlapci, vy ste tu taky šikovný v programovaní: nejako som sa dokopal k tomu, aby som cyklovanie serva strčil do prerušenia ( keďže vykresľovanie dispeja je príííšerne pomalé ), ale občas mi servo ako keby zakmitne. Nehodili by ste očkom po tom mojom kóde, či tam nemám nejakú vyloženú kravinu?
Malo by to bežať na Timer2 a keďže je len 8-bitový, tak interrupt beží na 1ms a 20ms z toho robím cez premennú citac .

Servotester SETUP píše:void setup() {

// set up Timer 2
TCCR2A = 0; // normal operation
TCCR2B = bit(WGM22) | bit (CS22); // CTC, scale to clock / 256
OCR2A = 124; // compare A register value (256 * clock speed / 125)
TIMSK2 = bit (OCIE2A); // interrupt on Compare A Match

...


Servotester INTERRUPT ROUTINE píše:ISR(TIMER2_COMPA_vect)
{ // zaciatok prerusenia
noInterrupts();
citac++;
if ( citac >= 20)
{
citac = 0;
static boolean state = false;
state = !state; // toggle
digitalWrite (LED, state ? HIGH : LOW);

if( val <= 0)
outservo = map(val, -100, 0, MinRange, MidRange); // scale it to use it with the servo (value between 0 and 180)
if( val > 0)
outservo = map(val, 0, 100, MidRange, MaxRange); // scale it to use it with the servo (value between 0 and 180)
myservo.writeMicroseconds(outservo); // set servo to mid-point
...
...
interrupts();
} // koniec prerusenia

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

pát 16.03.2018 22:30

Jak je definována val? Je to globální proměnná? Jak je plněna?

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

sob 17.03.2018 8:14

Mně celkem funguje (viz. název vlákna) toto:
Kód:
// servo rozsah a rychlost pohybu @ Arduino nano:
  int dir = 1;
  unsigned int min_uS = 1000;
  unsigned int max_uS = 2000;
  unsigned int puls2_uS = 1500;
  unsigned int wide_uS = 500;
  static unsigned int neutral_uS = 1500;
  static unsigned long period_uS = 20000;
     
  void setup() {
  pinMode(2, OUTPUT); // servo 1 @ pin 2 (servo s pohybem dle poťáku - klasický servotester)
  pinMode(3, OUTPUT); // servo 2 @ pin 3 (servo s rozkmitem a rychlostí dle poťáků)
  pinMode(4, OUTPUT); // servo 3 @ pin 4 (servo s trvalým neutrálem)
  pinMode(A1, INPUT); // potak1 @ pin A1
  pinMode(A5, INPUT); // potak2 @ pin A5
  }

void loop() {
  unsigned long aktual_uS = micros();
  unsigned int puls1_uS = analogRead(A1) + min_uS;
  unsigned int step_ = ( puls1_uS - min_uS ) / 10;
  wide_uS = analogRead(A5)/2;
  puls2_uS = puls2_uS + dir * step_;
  if (puls2_uS >= (neutral_uS + wide_uS) || puls2_uS <= (neutral_uS - wide_uS)) {
    puls2_uS = puls2_uS - dir * step_; 
    dir = -1 * dir;
  }
  pulz(puls1_uS, 2);
  pulz(puls2_uS, 3);
  pulz(neutral_uS, 4);
  while (micros() - aktual_uS <= period_uS){ }
  }

void pulz(int pulz_uS, byte servo) {
  unsigned long out_uS = micros();
  digitalWrite(servo, HIGH);
  while (micros() - out_uS <= pulz_uS){}
  digitalWrite(servo, LOW);
  }

Jasně, jde to udělat jinak a lépe ale mně na tom baví to že i tak to funguje :-)
No a chtěl jsem nepotřebovat tu knihovnu servo.h

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

sob 17.03.2018 9:33

https://www.arduino.cc/reference/en/lan ... roseconds/

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

sob 17.03.2018 18:39

Nevím co tam všechno máš ale TCCR2B bit WGM22 dle datasheetu ATmega328, nastavuje režim 4 (rezervováno) asi by mělo být:
TCCR2A | = (1 << WGM21); // režim 2, CTC
TCCR2B | = (1 << CS22);
Nemusí to být ale tím. Používat přerušení ve vyšších programovacích jazycích bývá problém. Je potřeba znát, které funkce používají rovněž přerušení a to z fragmentu kódu ani poznat nelze. A zákaz přerušení v přerušení by bylo další téma.

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

sob 17.03.2018 20:47

Chlapci, díky za všetky pripomienky, konečne to chodí jak má, HURÁÁÁ.
Takže po poradí:
ellet píše:Nevím co tam všechno máš ale TCCR2B bit WGM22 dle datasheetu ATmega328, nastavuje režim 4 (rezervováno) asi by mělo být:
TCCR2A | = (1 << WGM21); // režim 2, CTC
TCCR2B | = (1 << CS22);
...
A zákaz přerušení v přerušení by bylo další téma.

Zákaz prerušení som tam dal ako posledný zúfalý pokus zabrániť nejakým hazardom, ale na funkci rostlináře to nemělo vliv, blblo to aj predtým. Už je odtiaľ preč
Ten setup pre Timer2 som vybádal z nejakých tutoriálov v hodne vyskej nočnej hodine, chodilo to. Do datasheetu som bol lenivý pozerať. Ten Tvoj setup bol brutál rýchly, takže som na rýchlo spravil prienik z môjho a Tvojho setupu a vzniklo toto:
Timer2 SETUP píše:...
TCCR2A = (1 << WGM21); // režim 2, CTC
TCCR2B = bit (CS22)| bit (CS21)| bit (CS20);
OCR2A = 155; // approx 10ms
TIMSK2 = bit (OCIE2A); // interrupt on Compare A Match
...

Asi sa budem musieť predsa len pozrieť do datasheetu, keďže osciloskop doma nemám, ergo či prerušenie beží na 1ms ( 20ms s citac ) zatiaľ odhadujem len tak okometricky pohľadom na LEDku, akože mohla by blikať 25x za sekundu :mrgreen:
Trochu som si upravil ten program od jyrry, napriek tom, že by sa tuším delay nemal používať v interrupte, tak to beží:
pulz píše:void pulz(int pulz_uS, byte servo) {
unsigned long out_uS = micros();
digitalWrite(servo, HIGH);
delayMicroseconds(pulz_uS);
digitalWrite(servo, LOW);
}

S
while (micros() - out_uS <= pulz_uS){}
to nebežalo :roll:
Inak si myslím, že problém bol kdesi medzi Servo.h a mojím prerušením, z času na čas sa proste nemali radi...
Keď sa dokopem k nejakému videu, tak sem dám, že by ste videli, čo som páchal.
Ešte raz vďaka.
Naposledy upravil ddano007 dne sob 17.03.2018 21:27, celkově upraveno 2

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

sob 17.03.2018 21:07

ddano007 píše:Ten Tvoj setup bol brutál rýchly, takže som na rýchlo spravil prienik z môjho a Tvojho setupu a vzniklo toto...
Co jsem napsal bylo míněno jen jako oprava dvou řádků a to tak aby bylo zachováno tvoje nastavení (/64). Nic jsem nepočítal (taky nevím jaký používáš "hodiny") ale hlavně že to chodí! A datasheet je fakt základ. :)
A ještě - delay() a delayMicroseconds() není, z hlediska přerušení, jedno a totéž. (Popsáno na www.arduino.cc)

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

sob 17.03.2018 23:03

Chlapci, akým spôsobom sa handluje v Arduine prerušenie: nuluje sa požiadavka na prerušenie pri vbehnutí do prerušenia, alebo pri vybehnutí z prerušenia?
Dôvod mojej otázky: Timer2 mi beží na 1ms a generuje prerušenie. Napočítam 20 prerušení a cez delayMicroseconds generujem stále v prerušení až, povedzme, 2500us pulz pre servo. Ergo za tú dobu sa mi 2x reloadne Timer2 a nastaví flag prerušenia.
Ak sa požiadavka na prerušenie nuluje na konci obsluhy prerušenia, tak je to OK, ale ak na začiatku, tak vyletím z prerušenia a idem doň zas. Aká je správna odpoveď?

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

sob 17.03.2018 23:45

Mas to zhruba naopak ako by to malo byt, zaciatok pulzu by mal byt "zvonka" prerusenia, potom si nastavis timer na prislusnu dobu a ked pride prerusenie tak impulz ukoncis

ak mas delay v preruseni (nechapem preco, nevidim dovod, ale to je tvoj problem), musis si byt isty ze stihas, znamena ze za dobu pulzu ti dalsie nepride (to sa da ale potom je zase otazka naco to prerusenie vlastne mas ked si vlastne mohol cakat) ... a pokial by si to urobil spravne multiprocesorovo, to znamena ze kriticke veci vyriesis prve, potom povolis prerusenia a az potom zacnes robit delay, tak narazis na problem ze ti bude servami trhat ked ti tam niekde v impulze vznikne prerusenie

mimichodom ked si pozries servo library, zistis ze sa tam dost vela robi s casovacmi a preruseniami, takze ak to chces kombinovat z inymi preruseniami od casovacov, treba si dat pozor

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

ned 18.03.2018 0:05

1, prerusenie potrebujem, aby som casoval 20ms mimo hlavnu slucku, kde mam obsluhu displeja, ktora trva desatiny sekundy.
2, podla datasheetu pri vleteni do interruptu zablokuju vsetky prerusenia a odblokuju az s reti. Pokial to v prgrame nie je zmenene.
3, to, ze pocas interruptu sa mi reloadne Timer2 nie je problem, len neviem, kedy sa nuluje interfupt flag pre Timer2; na zaciatku obsluhy prerusenia, ci na konci?

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

ned 18.03.2018 10:10

Nebudu ti to kritizovat, protože bych měl pocit, že bych měl vytvořit něco lepšího a to se mně teď nehodí.
Jdeš na to moc rychle a nechce se ti moc číst manuál, jak píšeš. A to není dobrá kombinace. Protože se jedná o programování v reálném čase, není to úplně triviální záležitost a přerušení by mělo být vždycky co nejkratší. (Promiň trochu kritiky)
Ale k tvé otázce. Odpověď je v datasheetu ale možná trochu skrytá, proto tedy ještě odpovím. Mazání příznaků přerušení je hardwarová záležitost a proto nemůže být automaticky provedena jinde než vstupem do přerušení. Návrat z přerušení je assemblerovskou instrukci reti, která z hlediska přerušení pouze povolí globální přerušení. Můžeš ale ovlivnit příznakové bity před koncem rutiny sám. Je tam drobné riziko, mohlo by dojít k události nastavující flag ještě před výstupem z rutiny.
(Chce to literaturu, hezky to ve svých knížkách popisuje David Matoušek. Čím dřív, tím líp. Zápal ti nechybí, stejně si ji koupíš :) )

Re: Servotester s nastavením rozsahu i rychlosti přeběhu

ned 18.03.2018 11:18

Navrhuji ispirovat se tu: https://manuals.velleman.eu/category.php?id=98

Jsou tam knihovny k řízení serv v robotovi. Umí to až osmnáct serv najednou.

Aktivuješ potřebný počet serv a přiřadiš je na výstupní piny. Tím pádem už mají PPM. Pak je tam rutina, kterou nastavíš cílovou polohu ve stupních serv, které mají popojet. A pak rutina, kterou když spustíš s parametrem doba v milisekundách tak serva přemístí patřičnou rychlostí do požadovaných poloh.

A z toho už si jednoduše sestavíš jakýkoliv pohyb jakoukoliv rychlostí.
Odeslat odpověď