Ovládání KM z LPT PC

petr213
Příspěvky: 122
Registrován: 7. 3. 2008, 8:57
Bydliště: Uherský Brod

4. 2. 2009, 7:56

Já jsem to vyhrabal z jednoho starého Amára. Kdysi dávno jsem to zkoušel. Pivař moc nejsu ( u nás je špíš ta trnková ) ale když bude cesta okolo ...
Pupik
Příspěvky: 248
Registrován: 7. 12. 2008, 6:09
Bydliště: Ostrava
Kontaktovat uživatele:

5. 2. 2009, 4:48

Zkus ten odkaz http://www.electroweb.wz.cz/jaknalpt.html jsou tam i nejake zdrojaky, treba objevis jeste neobjevene ;)
Jo jeste malickost treba ji uz vis, kdyz budes chtit rosvitit vic pinu, musis ty hodnoty scitat. Pokud se jedna o cteni portu 0x379 tak ten pozadovany pin musis logicky vymaskovat.
zavadils
Příspěvky: 22
Registrován: 27. 1. 2009, 4:14
Kontaktovat uživatele:

22. 11. 2010, 6:49

Nepříšel náhodou někdo jak generovat impulzy ve visual basicu řádově v mikrosekundách. V milisekundách mi to chodí parádně. Motory se točí, ale je to dost malá frekvence. Budu rád za každé info. Díkes
Uživatelský avatar
Radek-B
Příspěvky: 2137
Registrován: 13. 9. 2006, 11:09
Bydliště: V:Karlovice
Kontaktovat uživatele:

22. 11. 2010, 7:25

A neni basic na generovani mikrosekund ponekud pomaly ? Nebude to tim ?

RADEK
modernizace/repase CNC strojů a zařízení
automatizace/konstrukce
franc
Příspěvky: 1
Registrován: 22. 11. 2010, 8:55

22. 11. 2010, 9:28

Ahoj!
Já používám na ovládání malých krokových motorků QBASIC pod DOSem. Výstup z LPT portu, pin 2 a 3, připojím na IO ULN2803. Používím krokové motory s 5 nebo 6 vývody. Zapojení je z knihy "Ovládání LPT pod WIN".
Program v QBASICu:
1 ba=&H378:rem LPT 1
2 t(0)=3:t(1)=2:t(2)=0:t(3)=1
3 FOR a = 1 TO 1000:rem pocet kroku
4 FOR m=0 TO 3
5 OUT(ba), t(m)
6 FOR r = 1 TO 200:NEXT r:rem rychlost
7 NEXT m
8 NEXT a
HonzaCh
Příspěvky: 286
Registrován: 21. 11. 2006, 8:57
Bydliště: Ostrava

22. 11. 2010, 10:31

zavadils píše:Nepříšel náhodou někdo jak generovat impulzy ve visual basicu řádově v mikrosekundách. V milisekundách mi to chodí parádně. Motory se točí, ale je to dost malá frekvence. Budu rád za každé info. Díkes
Ono ten VB asi nebude to pravé ořechové. Interpretovaný jazyk plus Widle plus spousta balastu, než se ten OUT procedí všema vrstvama Windows až ke skutečné instrukci OUT.

Můžeš zkusit optimalizaci -- vyházet z cyklů všechny výpočty a jiné zbytečnosti (jako kreslení po obrazovce) -- a nastavit výkonnému vláknu nebo aspoň celému programu co nejvyšší prioritu (realtime). Moc od toho ale nečekej, kdyby to bylo tak snadné, nebyl by MACH u mnohých na indexu (a rozhodně citlivý na konfiguraci PC a widlí).

Můžeš zkusit ten DOS (ale čistý DOS, ne okno DOSu ve woknech) a případně nějaký překládaný jazyk (C/Pascal/asembler...). Ale to bude asi mimo Tvou mísu, jinak by ses asi neptal...

HTH,
H.
zavadils
Příspěvky: 22
Registrován: 27. 1. 2009, 4:14
Kontaktovat uživatele:

23. 11. 2010, 2:22

HonzaCh píše:
zavadils píše:Nepříšel náhodou někdo jak generovat impulzy ve visual basicu řádově v mikrosekundách. V milisekundách mi to chodí parádně. Motory se točí, ale je to dost malá frekvence. Budu rád za každé info. Díkes
Ono ten VB asi nebude to pravé ořechové. Interpretovaný jazyk plus Widle plus spousta balastu, než se ten OUT procedí všema vrstvama Windows až ke skutečné instrukci OUT.

Můžeš zkusit optimalizaci -- vyházet z cyklů všechny výpočty a jiné zbytečnosti (jako kreslení po obrazovce) -- a nastavit výkonnému vláknu nebo aspoň celému programu co nejvyšší prioritu (realtime). Moc od toho ale nečekej, kdyby to bylo tak snadné, nebyl by MACH u mnohých na indexu (a rozhodně citlivý na konfiguraci PC a widlí).

Můžeš zkusit ten DOS (ale čistý DOS, ne okno DOSu ve woknech) a případně nějaký překládaný jazyk (C/Pascal/asembler...). Ale to bude asi mimo Tvou mísu, jinak by ses asi neptal...

HTH,
H.

Vyhazovat z cyklů asi nic nemusím. protože bez nějaký zpomalovací prodlevy to vygenereje frekvenci větší než je schopen pobrat KM. Našel jsem nějakou funkci "QueryPerformanceCounter", ale nevím jak ji rozchodit.
Uživatelský avatar
robokop
Site Admin
Příspěvky: 22915
Registrován: 10. 7. 2006, 12:12
Bydliště: Praha
Kontaktovat uživatele:

23. 11. 2010, 2:25

mel jsem kdysi program kterej byl pod dosem a stejne to nebylo uplne ono
pri psani na klavesnici to samozrejme kolisalo atd...

chce to nejake prostredi s exaktnim casovanim kde se vyhradi pevny casovy usek na zpracovani rizeni KM a druhy usek na graficke rozhrani, zpracovani vstupu atd...

to ti zaruci vpodstate pouze hardware
jednocipovy mikroprocesor nebo hradlove pole
mrkni treba na arduino mozna to bezezbytku vyresi to co potrebujes a bude to jiste bez zadneho hazardu!
Vsechna prava na chyby vyhrazena (E)
HonzaCh
Příspěvky: 286
Registrován: 21. 11. 2006, 8:57
Bydliště: Ostrava

23. 11. 2010, 11:15

zavadils píše:Vyhazovat z cyklů asi nic nemusím. protože bez nějaký zpomalovací prodlevy to vygenereje frekvenci větší než je schopen pobrat KM. Našel jsem nějakou funkci "QueryPerformanceCounter", ale nevím jak ji rozchodit.
  1. Tak to jsem nějak mimo. Zájem byl o mikrosekundy s tím, že milisekundy chodí, ale to je pro Tebe příliš pomalé a chceš/potřebuješ rychlejc, a včil je to rychlý až moc? :o :o :o

    Mimochodem, běžných 200 kroků na otáčku krát třeba 300RPM (5ot/s) ~ 1kHz (1ms perioda impulsů, změna úrovně signálu co 500μs). Když dojde na mikrokrokování, musí to být adekvátně rychlejší.

    Windows (a jeho preemptivní multitasking a další složitosti) Ti nezaručí rovnoměrné rozložení pulsů na výstupu. Někde tu byl obrázek s notami na buben, které generuje někomu MACH (pokud si vzpomínám). I PC lze donutit k řízení, ale bez těch Windows, dokonce bez klasického DOSu. Průchodnější je většinou spíš ten zmíněný mikrořadič.
  2. Co je na QueryPerformanceCounter podle popisu na MSDN složitého? Zavolat s adresou 64bitového integeru (ve VC knihovnách deklarováno jako union)... Akorát to existuje jen pro Win2000 a novější.

    Jak se to dělá ve VB snad najdeš v helpu, stisknout <F1> je rychlejší, než psát příspěvek. Tenhle jazyk neznám, ale na uvedeném odkazu je přímo ukázka kódu ve VB6, stačí to jen obkreslit! :roll: A kde jinde samostatně hledat informaci, než u zdroje, což je v případě microsoftích produktů kupodivu profláknutně známá Microsoft Developer Network na webu Microsoftu, kterou najde jako jeden z prvích hitů i konkurenční Google??? :-( I s překladem Ti google pomůže, a i když to není Vrchlický, na porozumnění to při spojení s originálem snad stačí.
  3. Nějakých funkcí je ve Win32 API šest půlek. Bez dalšího má tvrzení
    zavadils píše:Našel jsem nějakou funkci "QueryPerformanceCounter",...
    nevalnou informační hodnotu, se skutečným použitím této fce Ti těžko můžeme pomoct.
H.
zavadils
Příspěvky: 22
Registrován: 27. 1. 2009, 4:14
Kontaktovat uživatele:

24. 11. 2010, 1:28

HonzaCh píše:
zavadils píše:Vyhazovat z cyklů asi nic nemusím. protože bez nějaký zpomalovací prodlevy to vygenereje frekvenci větší než je schopen pobrat KM. Našel jsem nějakou funkci "QueryPerformanceCounter", ale nevím jak ji rozchodit.
  1. Tak to jsem nějak mimo. Zájem byl o mikrosekundy s tím, že milisekundy chodí, ale to je pro Tebe příliš pomalé a chceš/potřebuješ rychlejc, a včil je to rychlý až moc? :o :o :o

    Mimochodem, běžných 200 kroků na otáčku krát třeba 300RPM (5ot/s) ~ 1kHz (1ms perioda impulsů, změna úrovně signálu co 500μs). Když dojde na mikrokrokování, musí to být adekvátně rychlejší.

    Windows (a jeho preemptivní multitasking a další složitosti) Ti nezaručí rovnoměrné rozložení pulsů na výstupu. Někde tu byl obrázek s notami na buben, které generuje někomu MACH (pokud si vzpomínám). I PC lze donutit k řízení, ale bez těch Windows, dokonce bez klasického DOSu. Průchodnější je většinou spíš ten zmíněný mikrořadič.
  2. Co je na QueryPerformanceCounter podle popisu na MSDN složitého? Zavolat s adresou 64bitového integeru (ve VC knihovnách deklarováno jako union)... Akorát to existuje jen pro Win2000 a novější.

    Jak se to dělá ve VB snad najdeš v helpu, stisknout <F1> je rychlejší, než psát příspěvek. Tenhle jazyk neznám, ale na uvedeném odkazu je přímo ukázka kódu ve VB6, stačí to jen obkreslit! :roll: A kde jinde samostatně hledat informaci, než u zdroje, což je v případě microsoftích produktů kupodivu profláknutně známá Microsoft Developer Network na webu Microsoftu, kterou najde jako jeden z prvích hitů i konkurenční Google??? :-( I s překladem Ti google pomůže, a i když to není Vrchlický, na porozumnění to při spojení s originálem snad stačí.
  3. Nějakých funkcí je ve Win32 API šest půlek. Bez dalšího má tvrzení
    zavadils píše:Našel jsem nějakou funkci "QueryPerformanceCounter",...
    nevalnou informační hodnotu, se skutečným použitím této fce Ti těžko můžeme pomoct.
H.
1. rychlý je to právě bez použití zpomalování, ale s použitím delay nebo sleep v milisekundách je to už moc pomalé.

2. k funkci QueryPerformanceCounter jsem v MSDN příklad našel, to mě taky napadlo, ale jen tak to obšlehnout a tvrdit že je to jednoduchý, když neznám visual basic no nevím. Propblém je, že při použítí této funkce mi to vrátí jako nejmenší rozlišovací schopnot stejně 1 ms. Což mi nic nepomůže. Takže nevím jestli někdo ví jak přesně tuto funkci použít přesně, tak mi klidně může písnout. Díkes
HonzaCh
Příspěvky: 286
Registrován: 21. 11. 2006, 8:57
Bydliště: Ostrava

24. 11. 2010, 2:52

zavadils píše:1. rychlý je to právě bez použití zpomalování, ale s použitím delay nebo sleep v milisekundách je to už moc pomalé.
Aha I. To už je informace.
zavadils píše:2. k funkci QueryPerformanceCounter jsem v MSDN příklad našel, to mě taky napadlo, ale jen tak to obšlehnout a tvrdit že je to jednoduchý, když neznám visual basic no nevím. Propblém je, že při použítí této funkce mi to vrátí jako nejmenší rozlišovací schopnot stejně 1 ms. Což mi nic nepomůže. Takže nevím jestli někdo ví jak přesně tuto funkci použít přesně, tak mi klidně může písnout. Díkes
Aha II.

To je přesně to, co jsem psal v bodu 3. QueryPerformanceCounter() je sama o sobě na použití jednoduchá fce s jediným parametrem a obšlehnout její volání z MSDNka (jak jinak si přeložit Našel jsem…ale nevím jak ji rozchodit. — ona totiž chodí, je součástí jádra) je jednoduché a za tím si stojím i bez znalosti VB. Ale až teď jsme se dozvěděli nějaký kontext.

Na její použití pro čekání potřebuješ i "brášku" — QueryPerformanceFrequency(). Ta ti řekne, jak rychle ty interní hodiny tikají, z čehož se dá zjistit, jakému času odpovídá změna čítače (counter) o jedničku (t=1/f).

Když tohle víš, můžeš si spočítat, jaká změna odpovídá požadovanému čekání (delta=f*dobaCekaniVSekundach); na začátku čekání zavoláš QueryPerformanceCounter, a pak periodicky znovu voláš QueryPerformanceCounter tak dlouho, dokud absolutní hodnota rozdílu obou stavů čítače (modulo 2^64) nepřesáhne spočítanou.

Zanese se tam jistá chyba (volání fce a výpočet na počátku i v cyklu něco trvá). Je třeba taky řešit, jak se použitý jazyk chová při přetečení počítání v 64 bitech (ve VB ten typ CURRENCY).

Obecně se to dá optimalizovat počítáním v celočíselné aritmetice a případně předvypočtením koncového stavu (netřeba odčítat, jen porovnávat, ale zase je nutno ošetřit přetečení), ale to už do značné míry závisí na použitém programovacím jazyku (a ten Tvůj VB neznám).

V každém případě je celý princip téhle dvojice fcí včetně kompenzace chyby způsobené voláním téhle fce naznačen v onom zmíněném VB6 Code Snippet-u pro QueryPerformanceFrequency().

HTH,
H.
Uživatelský avatar
Krutor
Sponzor fora
Příspěvky: 1019
Registrován: 2. 12. 2008, 8:58
Bydliště: Moravské Bránice
Kontaktovat uživatele:

24. 11. 2010, 9:41

Napsal jsem si ve Visual C++ vlastní interpolátor pro řízení CNC soustruhu. Na Athlonu 1.8 GHz mi to chodí na 40 kHz (mám 800 kroků na otáčku, stoupání šroubu 4 mm, zvládlo to tedy rychlost 200 mm/s (12 m/min). Zrychlení 800 mm/s^2. Stále ladím, ale zdá se, že to funguje. Video bude snad o Vánocích. Nechci vás nudit bohapustým přejížděním suportu sem a tam, chci předvést pořádné "šponobraní". Jenže to bych nesměl mít elektroniku v krabici od bot.

1) Pokud je VB interpretovaný, tak to je utopie. Musí to být zkompilované do *.exe
2) Pomáhám si takovou prasárnou, že program sám sobě nastaví tzv. "realtime" prioritu. Skutečné realtime to asi není, ale vzhledem k tomu, že PC se v tu chvíli jeví jako mrtvé, tak bych věřil tomu, že se systém opravdu maximální možnou měrou věnuje mému procesu.
3) Funkce "sleep" naprosto nevyhovuje, má rozlišení 1 ms. Je opravdu nutno použít QueryPerformanceCounter, ideálně obalit si to do vlastní funkce, která vrací čas v sekundách jako desetinné číslo (double).
4) Rozlišení tohoto časovače je značně degradováno ve chvíli, kdy aplikace běží v módu ladění (debug). To je pak rozlišení časovače nedostatečné. Jakmile ladění vypnu (mód release), tak to sviští jedna báseň.

Jinak přeju hodně štěstí a zábavy :-) Já už to po chvilkách píšu 3 roky. A třeba takový zrychlený pohyb po kružnici, to už mi dalo docela zabrat. A to prosím ovládám jen 2 osy současně. Klobouk dolů před lidmi, kteří napsali Mach nebo EMC.
Petr Spáčil
zavadils
Příspěvky: 22
Registrován: 27. 1. 2009, 4:14
Kontaktovat uživatele:

25. 11. 2010, 6:13

HonzaCh píše:
zavadils píše:1. rychlý je to právě bez použití zpomalování, ale s použitím delay nebo sleep v milisekundách je to už moc pomalé.
Aha I. To už je informace.
zavadils píše:2. k funkci QueryPerformanceCounter jsem v MSDN příklad našel, to mě taky napadlo, ale jen tak to obšlehnout a tvrdit že je to jednoduchý, když neznám visual basic no nevím. Propblém je, že při použítí této funkce mi to vrátí jako nejmenší rozlišovací schopnot stejně 1 ms. Což mi nic nepomůže. Takže nevím jestli někdo ví jak přesně tuto funkci použít přesně, tak mi klidně může písnout. Díkes
Aha II.

To je přesně to, co jsem psal v bodu 3. QueryPerformanceCounter() je sama o sobě na použití jednoduchá fce s jediným parametrem a obšlehnout její volání z MSDNka (jak jinak si přeložit Našel jsem…ale nevím jak ji rozchodit. — ona totiž chodí, je součástí jádra) je jednoduché a za tím si stojím i bez znalosti VB. Ale až teď jsme se dozvěděli nějaký kontext.

Na její použití pro čekání potřebuješ i "brášku" — QueryPerformanceFrequency(). Ta ti řekne, jak rychle ty interní hodiny tikají, z čehož se dá zjistit, jakému času odpovídá změna čítače (counter) o jedničku (t=1/f).

Když tohle víš, můžeš si spočítat, jaká změna odpovídá požadovanému čekání (delta=f*dobaCekaniVSekundach); na začátku čekání zavoláš QueryPerformanceCounter, a pak periodicky znovu voláš QueryPerformanceCounter tak dlouho, dokud absolutní hodnota rozdílu obou stavů čítače (modulo 2^64) nepřesáhne spočítanou.

Zanese se tam jistá chyba (volání fce a výpočet na počátku i v cyklu něco trvá). Je třeba taky řešit, jak se použitý jazyk chová při přetečení počítání v 64 bitech (ve VB ten typ CURRENCY).

Obecně se to dá optimalizovat počítáním v celočíselné aritmetice a případně předvypočtením koncového stavu (netřeba odčítat, jen porovnávat, ale zase je nutno ošetřit přetečení), ale to už do značné míry závisí na použitém programovacím jazyku (a ten Tvůj VB neznám).

V každém případě je celý princip téhle dvojice fcí včetně kompenzace chyby způsobené voláním téhle fce naznačen v onom zmíněném VB6 Code Snippet-u pro QueryPerformanceFrequency().

HTH,
H.

Tak jsem použíl toto:

Dim Ctr1 As Currency, Ctr2 As Currency
QueryPerformanceCounter Ctr1
QueryPerformanceCounter Ctr2
mOverhead = Ctr2 - Ctr1
QueryPerformanceFrequency mFrequency
QueryPerformanceCounter mStart
QueryPerformanceCounter mStop
mElapsed = ((mStop - mStart - mOverhead) / mFrequency) * 1000
Debug.Print "----------------------------------------------------"
Debug.Print Time
Debug.Print "mStart= "; mStop
Debug.Print "mStop= "; mStart
Debug.Print "mOverhead= "; mOverhead
Debug.Print "mFrequency= "; mFrequency
Debug.Print "Elapsed="; Format$(mElapsed, "0.0000")

a Výsledek je:
----------------------------------------------------
19:12:19
mStart= 2254702287,3732
mStop= 2254702287,3231
mOverhead= 0,1111
mFrequency= 261209
Elapsed=-0,0002

Chápu to dobře, že to tedy dokáže vygenerovat cca 261 kHz?
HonzaCh
Příspěvky: 286
Registrován: 21. 11. 2006, 8:57
Bydliště: Ostrava

26. 11. 2010, 2:09

zavadils píše:Tak jsem použíl toto:

Dim Ctr1 As Currency, Ctr2 As Currency
QueryPerformanceCounter Ctr1
QueryPerformanceCounter Ctr2
mOverhead = Ctr2 - Ctr1
QueryPerformanceFrequency mFrequency
QueryPerformanceCounter mStart
QueryPerformanceCounter mStop
mElapsed = ((mStop - mStart - mOverhead) / mFrequency) * 1000
Debug.Print "----------------------------------------------------"
Debug.Print Time
Debug.Print "mStart= "; mStop
Debug.Print "mStop= "; mStart

Debug.Print "mOverhead= "; mOverhead
Debug.Print "mFrequency= "; mFrequency
Debug.Print "Elapsed="; Format$(mElapsed, "0.0000")

a Výsledek je:
----------------------------------------------------
19:12:19
mStart= 2254702287,3732
mStop= 2254702287,3231
mOverhead= 0,1111
mFrequency= 261209
Elapsed=-0,0002

Chápu to dobře, že to tedy dokáže vygenerovat cca 261 kHz?
Obávám se, že a) ne, b) si úplně nerozumíme.

QueryPerformanceCounter nic negeneruje.

Celý ten cirkus okolo QueryPerformanceCounter (dále jen QPC, kdo se s tím má psát) Ti umožní zjistit víceméně přijatelně přesně dobu, která uplynula mezi voláními. Pokud je to podporováno HW (prý od dob Pentia), QPC vrátí obsah speciálního registru procesoru (TSC, Time Stamp Counter), který je nezávisle na nějakém programu inkrementován každý hodinový cyklus (viz třeba TSC na Wiki). Nic víc.

Taková informace se dá použít k relativně přesnému časování nějaké operace pomocí vloženého čekání v cyklu. Víš, jak má něco trvat (třeba délka STEPu na LPT) a přepočteš to na tiky TSC (čili změnu čísla z QPC); zapamatuješ si "čas" (QPC), něco užitečného uděláš (například spočítáš a pošleš novou hodnotu na port) a dále čekáš, dokud se TSC (jehož hodnotu opakovaně zjišťuješ pomocí volání QPC) nedopočítá k požadované. Pak můžeš pokračovat (nová doba, nový začátek, nová práce, čekání…). Pokud budeš užitečně pracovat moc dlouho, žádné čekání nenastane, ale to znamená, že nestíháš.

Máš tam chybku (přehozený start a stop u debug.print-ů), ale to není důležité. Taky tam chybí jejich deklarace, netuším, co si tam ten v-bastlík pro mStart apod. domyslel. Podle hodnoty mFrequency asi nějakou blbost, takovou šunku snad nemáš. (Mmch, měla by se testovat úspěšnost volání třeba u té frekvence, ať se potvrdí, že to HW opravdu podporuje.)

To, co jsi napsal, teoreticky musí "vracet" vždy 0 (hodnota Elapsed), protože režii odečítáš a mezi voláním nic neděláš stejně jako u "vypočítávání" režie. Prakticky tam nastávají drobné odchylky v závislosti na tom, "co se ve widlích zrovna děje" (systémová přerušení, ostatní úlohy). Konec konců, Tobě ukázka vygenerovala čas (uplynulo mínus 2 mikrosekundy!) :D.

Ve skutečnosti může být i hodnota režie (mOverhead) špatně, pokud mezi voláními QPC s Ctr1 a Ctr2 nastane přepnutí mezi úlohami (task switch; navenek to nepozáš). (Windows mají preemptivní multitasking: zjednodušeně, když úloze dojde přidělený čas, násilně ji přeruší a k lízu se zas na chvilku pustí jiná — kvůli tomu jsem Ti kdysi radil zvednout prioritu na realtime a Krutor to pak potvrdil [Vsuvka pro něj: Není to prasárna; já bych to rozdělil na aspoň 2 vlákna a prioritu zvednul na RT jen tomu, co ovládá port.].) Navíc u víceprocesorových čí vícejádrových strojů má každé jádro svoje počítadlo TSC (tj. by se to mělo vázat k jednomu zvolenému pomocí SetThreadAffinityMask), viz ta Wiki nebo MSDN.

Jen pro informaci, u mého Intel DualCore 2,4GHz (QueryPerformanceFrequency dává 2400040000) je u přeloženého kódu režie cca 250-260ns. Tzn. frekvence volání QPC by mohla být teoreticky skoro 4MHz. Ale to by nesmělo nastat přepnutí mezi úlohami a pod. a hlavně — nic užitečného bych mezi tím neudělal.

H.
Odpovědět

Zpět na „Krokové motory“