Vítejte na Elektro Bastlírn?
Nuke - Elektro Bastlirna
  Vytvořit účet Hlavní · Fórum · DDump · Profil · Zprávy · Hledat na fóru · Příspěvky na provoz EB

Vlákno na téma KORONAVIRUS - nutná registrace


Nuke - Elektro Bastlirna: Diskuzní fórum

 FAQFAQ   HledatHledat   Uživatelské skupinyUživatelské skupiny   ProfilProfil   Soukromé zprávySoukromé zprávy   PřihlášeníPřihlášení 

Zákmity na rotačním encoderu
Jdi na stránku 1, 2  Další
 
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Miniaturní počítače (Arduino, Raspberry a další)
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
chromnikl



Založen: Apr 21, 2021
Příspěvky: 39

PříspěvekZaslal: po květen 15 2023, 20:36    Předmět: Zákmity na rotačním encoderu Citovat

Zdravím, řeším takový problém,
mám zařízení viz foto:
Jedná se o laserový efekt stavěný z toho, co bylo doma.
Pomocí encoderu chci sledovat polohu paprsku.
Zatím chci pouze čítat pulzy a po každém otočení - to jest 16 náběžných hran, je chci vynulovat.
Bohužel program nefunguje. i pokud je proměnná tik > 16 tak stále jede dále.
Představa je cca 2000 RPM - aby byl paprsek stabilní a neblikal. To je cca 530 impulzů za sekundu.

mezní frekvence je cca 10 kHz, takže tady by problém být neměl.
Nejsem si jistý kvalitou vstupního signálu, ale i kdyby to byly zákmity, tak by je to mělu nulovat správně.

Zde je blok kódu, který nefunguje.


kód:

int interruptPin = 2;
int tik = 0;
void setup()
{
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blik, FALLING);
  Serial.begin(9600);
}
void blik()
{
  tik ++;
  Serial.println(tik);
  return tik;
}

void loop()
{
 if (tik > 16) {
tik = 0;
 Serial.println(tik);}
}



Nějaký nápad
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Cowley



Založen: Feb 04, 2005
Příspěvky: 3290

PříspěvekZaslal: po květen 15 2023, 21:24    Předmět: Citovat

Ladíš program na správné (stejné) desce, jako je nastavena v IDE?

A co znamená: "Jede dále" ? Proč by neměl?
Vždyť nevoláš "DetachInterrupt"

Ještě zruš Serial.print uvnitř void blik().

Zaveď si proměnnou byte tisk=0;

Uvnitř void blik()
{ tik++; //pripocti
tisk=1; //nastav tisk
}

Do loop pak přidej
If (tisk ==1) //došlo ke změně
{Serial.println(tik); //vypiš kolik je tik
tisk=0; //jen jednou
}
If(tik >16) // víc jak 16?
{
tik = 0; //vynuluj
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
samec



Založen: Dec 19, 2017
Příspěvky: 4135

PříspěvekZaslal: út květen 16 2023, 0:12    Předmět: Citovat

blik je void, nemá mať return tik.
tik má byť volatile.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mahoney



Založen: Oct 26, 2019
Příspěvky: 381

PříspěvekZaslal: út květen 16 2023, 4:32    Předmět: Citovat

2chromnikl: Taky by chtělo vědět co je to za enkodér (foto nějak chybí), to máš nějaký optický s tvarovačem výstupních impulsů, nebo mechanický (když jsi vlákno nazval tak, jak jsi ho nazval…)?

A ještě drobný detail, když máš v interruptu komunikaci po serialu rychlostí 9600bd, tak ho určitě nevypíšeš 530x za vteřinu (s tím, co se pak ještě děje v pc), to z toho inrerruptu časově skoro nevylezeš … zvýšil bych té lince rychlost.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
chromnikl



Založen: Apr 21, 2021
Příspěvky: 39

PříspěvekZaslal: út květen 16 2023, 7:55    Předmět: Citovat

Zdravím, nějak se mi nepovedlo vložit obrázky, zde jsou:

https://ctrlv.cz/JLc1 tady je foto encoderu.
Je to nějaký čínský modul, takže o tvarování nemůže být řeč.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
chromnikl



Založen: Apr 21, 2021
Příspěvky: 39

PříspěvekZaslal: út květen 16 2023, 8:15    Předmět: Citovat

Tady je upravený kód.

Ve finále se to nebude odesílat po ser. lince, to je jen pro lazení.

kód:


const byte interruptPin = 2;

volatile int tik = 0;
void setup() {
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blik, CHANGE);
  Serial.begin(9600);
}
void blik(){
  Serial.println(tik);
  tik ++;
 
}
 
void loop() {
 if (tik == 16){
  Serial.println(tik);
  tik = 0;
  }
}
 
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mahoney



Založen: Oct 26, 2019
Příspěvky: 381

PříspěvekZaslal: út květen 16 2023, 8:27    Předmět: Citovat

Tohle ale není enkodér, to co jsi vytvořil je ekvivalent inkrementu. Dej odkaz na ten čínský modul, nějakou elektroniku tam vidím, nemůžeme říci jistě že tvarování impulsu tam není ošetřené. Jak jsi vlastně vydedukoval, že tě trápí zrovna zákmity? Osciloskopem?

To že máš sériovou linku jen pro ladění na věci nic nemění, jde o to že je potřeba si uvědomovat souvislosti a dělat věci pořádně (používat to správným způsobem). Přerušovací rutiny mají obecně být co nejkratší, a tvá tráví ~50 % celkového procesorového času na jednom jediném řádku (a přitom stačí jen zvýšit rychlost linky). A nebo jinak, v interruptu přeci vůbec nepotřebuješ dělat nějaký výpis, nech tam jenom
kód:
tik++
, jestli se to napočítá přeci vidíš v hlavní smyčce (a nebo si dej na nějaký pin ledku a ovládej ji místo té linky, pokud to chceš vidět).

Naposledy upravil Mahoney dne út květen 16 2023, 8:52, celkově upraveno 1 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Celeron



Založen: Apr 02, 2011
Příspěvky: 17736
Bydliště: Nový Bydžov

PříspěvekZaslal: út květen 16 2023, 8:52    Předmět: Citovat

Já bych do toho zatím přerušení netahal nožná ani nebude potřeba. Udělej si jednoduchej prográmek kterej čte signál z toho optickýho incrementu. A jen bych to co vstoupí do Arduina hned poslal na jinej port a kouknul na to osciloskopem jak na vstupním portu, tak na výstupním jestli tam jsou nějaký zákmity či ne. A zároveň tak můžeš vyzkoušet, kolik otáček to zvládne snímat.
U mechanickýho n-codéru s dvouma kontaktama se s tvarováním moc nemažou, dávají se pouze dvě keramiky 10N proti zemi. Když s ním něco ladím, i bez těch kondíků to krokuje správně. Ale používám knihovnu rotary.h. Moc jsem nezkoumal, jestli a jak tam mají zákmity ošetřený.

_________________
Jirka

Proč mi nemůže všechno chodit hned ?!!
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
bdn



Založen: Jan 16, 2020
Příspěvky: 468

PříspěvekZaslal: út květen 16 2023, 19:17    Předmět: Citovat

@chromnikl
funkce Serial.print je "pomalá" ve srovnání s rychlostí 530 impulzů /s. Tvůj program ti nebude vypisovat správně proměnnou tik. A už vůbec nevolej Serial.print uvnitř přerušení !
Nevím co má program dělat, co má být výsledná hodnota?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mahoney



Založen: Oct 26, 2019
Příspěvky: 381

PříspěvekZaslal: út květen 16 2023, 19:30    Předmět: Citovat

Zatím jenom zkouší napočítat těch 16 otvorů, co má na tom 3D printed kole, ale jelikož mu tam stejně chybí alespoň kontrolní otvor na celou otáčku + čidlo, nebo něco na těch rotujících zrcátkách, tak to stejně nebude mít jak zkontrolovat (teoreticky by mohl mít hallovu sondu na té desce motoru zespodu, ale nevím). To by ale nevadilo, mě by spíš zajímalo jak vydedukoval, že má na optickém čidle zákmity.


cut.jpg
 Komentář:
 Velikost:  157.71 kB
 Zobrazeno:  74 krát

cut.jpg


Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
chromnikl



Založen: Apr 21, 2021
Příspěvky: 39

PříspěvekZaslal: út květen 16 2023, 20:08    Předmět: Citovat

Zdravím, závoru používám tuto:
https://www.gme.cz/v/1508304/modul-opticke-zavory-s-lm393

Co se týče zákmitů, pokud ručně pootočím o jeden "krok", na seriovou linku mi to vypíše třeba 30 pulzů.

Program mám tady.
kód:

const byte interruptPin = 2;
const byte Led = 13;

volatile int tik = 0;
void setup() {
  pinMode(interruptPin, INPUT_PULLUP);
  pinMode(Led, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blik, RISING);
  Serial.begin(9600);
}
void blik(){
  tik ++;
}
void loop() {
 Serial.println(tik) ;
 if (tik > 16){
  tik = 0;
  digitalWrite(Led,HIGH);
  } else{digitalWrite(Led,LOW);}
}
 


Teď to pracuje tak jak chci - počítá to, ale pulzy nesedí, při jednom posunutí o jednu dírku, naskočí třeba 20 pulzů.

Co se týče hlídání pozice, vždy jednou za otáčku projde laser přes fotodiodu, z toho určuju začátek jednoho otočení.

Jak signál vytvarovat, aby nedocházelo k zákmitům? Změna řešení toho kola? Menší dírky?

Díky .
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mahoney



Založen: Oct 26, 2019
Příspěvky: 381

PříspěvekZaslal: út květen 16 2023, 20:40    Předmět: Citovat

Neříkej tomu zákmity, zákmity mohou mít jen mechanické kontakty (myslel jsem, že ti to dojde). Jsou to nejspíš odrazy, máš to kolo lesklé a otvory nejsou rovnoměrné, projeď je jehlovým pilníkem abys je zarovnal, a plochy těch kol polep něčím matným (nebo nastříkej matnou černou barvou ze spreje, ale aby ti chytla na plast, musíš předtím ještě použít primer na plasty). Další věc je, že když máš snímání optozávorou, tak i když je infračervená, musíš ji zastínit od okolního osvětlení, může reagovat na něco zvnějšku. Další věc je stínění vedení se signálem od závory, máš dole pod tím motor a ten má cívky a magnety (motor z CD/DVD ROM je oběžka, takže rotují magnety), obyčejný drát taky může něco pochytat, je to v podstatě anténa a ten Atmel vedle má na vstupech poměrně velký vstupní odpor, je to CMOS obvod, takže ti to klidně může sejmout taky.

Jinak podobné kolo lze koupit hotové přímo k té závoře: https://www.ebay.de/itm//292360097717


Naposledy upravil Mahoney dne út květen 16 2023, 20:51, celkově upraveno 2 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
nixdorf



Založen: May 06, 2017
Příspěvky: 570

PříspěvekZaslal: út květen 16 2023, 20:42    Předmět: Citovat

Ak dochádza k falošným odpalom, možno by to šlo spraviť i softwarovo, ale nebude to rýchle... Vyskúšaj nasledovné - toto čaká min. 1ms od odpalu. Ak to bude až príliš hluché a pomalé, zmeň tú tisícku na niečo menšie; ak to stačiť nebude, tak ju zvýš.
Kód počíta s tým, že je pin 2 prizemňovaný, skús ten inkrement zapojiť tak. Ak to nie je možné, nahraď INPUT_PULLUP na INPUT, FALLING na RISING a "== LOW" na "== HIGH".

kód:
const byte interruptPin = 2;
const byte Led = 13;
byte tick_count = 0;

volatile unsigned long us_tick = 0;

void setup()
{
  pinMode(Led, OUTPUT); 
  digitalWrite(Led, LOW);

  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blik, FALLING);

  Serial.begin(9600);
}

void blik()
{
  us_tick = micros();
}

void loop()
{
  if (us_tick && (micros() - us_tick > 1000))
  {   
    us_tick = 0;

    if (digitalRead(interruptPin) == LOW)
    {
      tick_count++;

      if (tick_count == 16)
      {
        digitalWrite(Led, HIGH);
      }
      else if (tick_count > 16)
      {
        tick_count = 1;
        digitalWrite(Led, LOW);
      }

      Serial.println(tick_count);
    }
  }
}


//edit: bdn má pravdu, předsedo Very Happy Dik, opravené. Ano, micros pretečie každých ~71min


Naposledy upravil nixdorf dne st květen 17 2023, 8:12, celkově upraveno 1 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
bdn



Založen: Jan 16, 2020
Příspěvky: 468

PříspěvekZaslal: st květen 17 2023, 6:46    Předmět: Citovat

@nixdorf
zajímavé minimalistické řešení, ale pozor na micros() je zde jedno nebezpečí:
1/ Pokud přijde přerušení blink() v době, kdy bude hodnota micros() blízko přetečnení např. N=(0xFFFFFFFF - 800);
2/ potom výraz (micros() > us_tick + 1000) bude okamžitě pravdivý, tj. ( N> (0xFFFFFFFF-800) + 1000), tj. (N>200);

Řešení: závorka "sčítání", by se měla nahradit "odečítáním"
// původně
(micros() > us_tick + 1000)
// nově
(micros()- us_tick > +1000)

Zdroj: http://www.gammon.com.au/forum/?id=12127
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mahoney



Založen: Oct 26, 2019
Příspěvky: 381

PříspěvekZaslal: st květen 17 2023, 8:47    Předmět: Citovat

Slušně vychovanej člověk čekačky vůbec nepoužívá, a přerušovací rutiny píše v assembleru Very Happy

(samozřejmě si dělám srandu, díky za tip Smile )
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Miniaturní počítače (Arduino, Raspberry a další) Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra.
Nemůžete odpovídat na témata 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 hlasovat v tomto fóru.
Nemůžete připojovat soubory k příspěvkům
Můžete stahovat a prohlížet přiložené soubory

Powered by phpBB © 2001, 2005 phpBB Group
Forums ©
Nuke - Elektro Bastlirna

Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.


PHP-Nuke Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Čas potřebný ke zpracování stránky 0.14 sekund