| Naam |
Bericht |
DeeP
|
Beste COers,
Ik wil gaan beginnen met het aansturen van de paralelle poort in visual studio 2005. Het programma wordt geschreven in C# en zal gebruikt worden voor de aansturing van mijn freesmachine. Op het moment gebruik ik Mach3 voor de aansturing alleen voldoet dit niet meer aan mijn eisen, waardoor ik zelf een programma wil gaan schrijven.
Voor de stappenmotoren heb ik een pulserend signaal van minimaal 40khz nodig (per motor, liefst 5x). De poort kan dit wel aan omdat dit al wordt gedaan in Mach3.
Ik vraag mij alleen af hoe dit is te realiseren? Hoe krijg ik nou een stabiele blokgolf uit de poort? Een timer in C# gaat maar tot 1ms wat 1Khz betekend. Hoe is dit op te lossen?
Groeten Danny
|
Boudie
|
Google even op "real time clock" of "clock ticks".
De interne timer, die je met de meeste besturingssystemen kan uitlezen, heeft een resolutie van 1 microseconde.
Of je daar een stabiele blokgolf mee kunt maken is echter nog maar de vraag, want je OS heeft meer te doen dan alleen maar de printerpoort aansturen. Hij reageert bijvoorbeeld ook op het bewegen van je muis.
Je zou een externe schakeling kunnen maken die je via de printerpoort aanstuurt en die de opwekking van de blokgolf voor z'n rekening neemt. Hardstikke stabiel en voor zoiets heeft je OS tijd zat.
|
free_electron
|
heel waarschijnlijk gebruikt mach3 een speciale driver.
waarschijnlijk ene systeemdriver die in hoge prioriteit loopt en die dus inderdaad eerste prioriteit krijgt...
probleem is : dergelijke driver schrijven.
Professioneel ElectronenTemmer - 8 April 08 : 7.355.303
|
DeeP
|
De rtc zou inderdaad heel goed kunnen werken, dit ga ik eens verder onderzoekwn denk ik. De driver scrijven is punt één maar ik denk dat het programma zelf moeilijker is.
Is er verder geen andere mogelijkheid? Eventueel andere timers?
|
free_electron
|
de driver zal het moeilijkste zijn....
dat moet een kernel mode driver zijn ( .sys) en is zeer moeilijk te debuggen
Professioneel ElectronenTemmer - 8 April 08 : 7.355.303
|
Jan Arjen
|
@DeeP:
Ik heb (in c#) een programma gemaakt die de deurbel vervangt en m'n elektriciteits-verbruik meet.
Ik monitor hiervoor de parallele poort, en om het geheel te testen heb ik ook een event-generator gebouwd die getimed energy-pulsen afgeeft. En hier kom ik er tot mijn verbijstering achter dat het soms wel 12ms kan duren voordat de eventhandler aangeroepen wordt! Wanneer ik echter rechtstreeks m'n verbruik meet en bijv. de kookplaat aanzet op vol vermogen, is het verschil stukken kleiner. Ik denk dat in zowel het sturen van een output pin en het lezen van de status een verschil kan optreden van zo'n 5ms. Nu maakt het voor mijn toepassing niet zoveel uit, dit verschil maar ik kan me voorstellen dat het voor stappenmotoren beroerder is.
|
timmie
|
in het .net framework 3.5 zijn er 2 timermodules beschikbaar de gene die jij gebruikt heeft een resolutie van 1mS de andere volgens mij lager maar nagel me er niet op vast.
en dan nog je zult windows nog steeds wijs moeten maken dat hij exacte timing moet aanhouden(niet windows sterkste kant)
DMX interface
|
Sponcebert
|
met 12 mS ben je al een hele goeie. Dat de timers werken met getallen in milliseconde wil niet zeggen dat deze ook zo nauwkeurig werken ! Onder windows gebeurt er veel ( netwerk etc ) wat toch prioriteit krijgt.
|
timmie
|
systemdrivers schrijven dan heb je nog kans van slagen
verder alle processen en threads killen die niet hoeven te draaien.
DMX interface
|
free_electron
|
neen. der is weer een misverstand in het spel.
de RESOLUTIE van de timer in windows is 1 milliseconde .
De hardware timer die erachter zit zelf telt in stappen van ongeveer 11 milliseconde ( heeft te maken met de allereerste pc. die had een 8254 programmable timer. kanaal 2 daarvan was verbonden aan de clockgenerator voor de isa bus die op een ntsc kristal ( 3.58 MHz ) draaide ( eigenlijk de helft daarvan ) de counter was geprogrammeerd om over te lopen om de 9.98 milliseoncen en daarbij een hardware interrupt te genereren.
De systeemticks hedentendage worden nog steeds aan dezelfde snelheid opgewekt ( er is ene mogelijkheid tegenwoordig om te scalen met en factor 10, en ik geloof dat windows dat ook kan doen, maar je moet het wel VRAGEN , het gebeurt niet automatisch )
dus : die HARDWARE teller verhoogt met 1 elke TICK die er optreedt.
windows heeft echter en software layer erbovenop die iets anders doet.
telkens er een interrupt komt wordt de huidige HARDWARE stand uitgelezen , vergeleken met de vorige gekende hardware stand. De Delta daartussen wordt vermenigvuldigd met te tijd van 1 hardwaretick en dat resultaat wordt teruggegeven.
zelfs als je volgas de systeemtimer in windows leest zal je zien dat die schommelt. dat komt omdat windows niet op alle hardware pulsen reageert. in high priority taken wordt de hardware interrupt even stilgelegd. er verstrijken dus meerdere hardware pulsen vooraleer windows 'luistert' . vandaar gaan ze de hardware counter lezxen , de delta bepalen tussen de laatste keer dattie gelezen werd en de huidige stand , en dat vermenigvuldigen met de tijdsconstante. zo weet je toch hoevele tijd er verstreken is.
het lezen van de systeemtick geeft dus altijd een juist resultaat tot op de milliseconde. het interval waartussen gelezen wordt kan geweldig schommelen !
maak een programmatje wat volgas de timer kan lezen en afprinten op het scherm.
het kan zjin dat je dit ziet
1
2
2
4
12
13
15
als je 15 ziet : dan ben je op dat ogenblik er inderdaad in geslaagd te timer te lezen. en was de verstreken tijd 15 milliseconden sedert het starten van de timer. maar het punt waarop jij gelezen hebt kan best op 14 of op 16 of 16 milliseconden geweest zijn. het kan ook zijn dat jous leesopdracht 'gestalld' was omdat er gewoonweg andere zaken prioriteit hadden.
( jij wou lezen op 5 milliseconden maar jouw thread was in sleep tot aan 12 ... )
de software timers werken op dezelfde manier.
als je in visual studio ( taal pseelt geen rol) een timer object maakt die om de 40 milliconden moet firen : op het moment dat je de timer start slaan ze de huidige tickcount op. wanneer de (tickcount > tick_count_at_start + interval )roepen ze jouw event aan.
als jouw event handler meer tijd in beslag neemt dan het interval dan zal je een tick missen ! je bent op dat moment 'blind'
die timers werken dus niet op het princiepe van : we wachten hier totdat x=y. HEt princiepe is , we wachten totdat er meer tijd verstreken is dan het opgegeven minimum. en we proberen zo dicht mogelijk tegen dat minimum het event af te vuren.. maar er is geen garantie !!
Professioneel ElectronenTemmer - 8 April 08 : 7.355.303
|
timmie
|
@Free en wanneer men de Timer api van win gebruikt(dan bedoel ik degene die normaal zou worden gebruikt voor audio/video)
zou je dan nix beters kunnen behalen?
DMX interface
|
Boudie
|
DeeP:
Onderstaande functie is te gebruiken om clock ticks uit te lezen. Let op dat in geval van hyperthreading en multicore-systemen minder betrouwbare uitlezingen plaatsvinden. Die zijn wel te corrigeren (of te vermijden) maar dat is niet simpel.
Google op "rdtsc" en je weet alles.
code:
extern __inline__ unsigned long long int rdtsc()
{
unsigned long long int x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
Deze gebruik ik zelf om circa 130.000x / seconde de parallele poort uit te lezen.
(AMD Athlon X2 3800 met Linux kernel 2.6.18.2-34-default)
Overigens dwaalt dit wat af van elektronica. Mijn eerdere suggestie om een externe schakeling de timing te laten verzorgen ligt meer op CO-gebied. 
En werkt, denk ik, het best...
|
free_electron
|
wat boudie doet is inderdaad rechtstreeks de counter uitlezen van de 8254. ik vrees dat dat onder windows niet lukt. Dat kan alleen gedaan wordne door een process wat in ring 0 draait ... user space kan daar niet komen volgens mij.
En zoals timmie al schreef : de audio/video drivers haken in op die counter.( Dat is een echte hardware counter ) alhoewel de meeste audiokaarten tegenwoordig interne buffers hebben en gewoon requests doen voor een volgend blok data, en intern de timing verzorgen in de audiokaart. Software voor audio is niet meer time citical.
ditto voor video...
Professioneel ElectronenTemmer - 8 April 08 : 7.355.303
|
SparkyGSX
|
Ik ken niet alle details van de interne werking van windows, maar het verhaal van FE klopt wel met wat ik weet (of denk te weten). Sowieso kan een user-mode programma in windows nooit timing verwachten die op meer dan 10ms nauwkeurig is, want dat is de standaard interval van je timeslices.
De driver die Mach3 e.d. gebruiken, gaat waarschijnlijk tussen windows en de hardware zitten, om op die manier op de timer interrupts te kunnen reageren.
Nog los van dit verhaal, is het schrijven van een motion controller niet echt eenvoudig, maar wel te doen als je weet wat je doet (dus weet hoe een motion controller zou moeten werken, en veel van de interne werking van de machine weet).
Wat me handiger lijkt, is een ISA kaart ontwerpen (of PC104, dat is ISA in een andere formfactor), en daar met microcontrollers of FPGA's de pulsen genereren. Je zou het zo "simpel" kunnen maken dat je hier een stuk geheugen op onderbrengt, met een slimme codering dat door discrete hardware gebruikt wordt. Dit geheugen vul je vervolgens vanuit je software, waarbij de hardware voor de timing zorgt.
Maar... waarom windows? Dit soort dingen zijn een stuk eenvoudiger met andere besturingssystemen, of zelfs helemaal zonder besturingssysteem. Windows is alles behalve geschikt voor zulke dingen.
|
free_electron
|
ik zou dat onder dos schrijven. geen gedoe met een operating systeem wat in de weg komt zitten ...
ISA ... dat wordt een probleem ..... vindt maar een moederbord wat dat nog heeft..
een PC104 bord zou de oplossing zijn inderdaad.
anders een PCI kaartje dan maar ...
de timeslice is 10mS omdat de hardware timer tickt op die kadans. windows herrekent de timer kadans naar echte time. ( der is een functie voor om de echte time stand op te vragen van de systemtimer ( dus niet de tijd uit de klok ) ik geloof dat een echte tick om de 9.98 milliseconden is. ( komt door da manier waarop ze afdelen , en de inkomende frequntie voor die 8254.
Onder DOS heb je direct toegang tot die timer ( er zijn 3 kanalen. van kanaal 1 moet je afblijven !!! die wordt gebruikt voor dram refresh .... touch en die ! ) [Bericht gewijzigd door free_electron op 28 augustus 2008 00:55:41]
Professioneel ElectronenTemmer - 8 April 08 : 7.355.303
|
SparkyGSX
|
PCI is toch een stuk lastiger te interfacen dan ISA, zoals aan de hardware- als de softwarekant.
Ik heb zelf nog wel een aardige voorraad moederborden (met processors en geheugen) waar ISA sloten op zitten. PC104 wordt steeds minder gebruikt, het wordt steeds meer PC104+ (=PCI sloten), en er is niet erg gemakkelijk aan te komen. Aan geschikte PC's op marktplaats e.d. geen gebrek.
Eigenlijk vindt ik het wel jammer dat de ISA bus helemaal verdwenen is, want hij was erg gemakkelijk te interfacen, en als zodanig een goed leerobject. Met PCI, die ook al in rap tempo uitgefaseerd wordt, zit je eigenlijk al aan een FPGA of een speciaal IC vast (zie daar maar eens aan te komen).
Ik krijg nostalgische herinneringen aan het rommelen met de PIC (programmable interval controller) onder DOS. Dat kanaal voor de DRAM refresh kun je best gebruiken, als je dan zelf de originele interrupt routine maar regelmatig aanroept.
Ik dacht dat de hardware timer onder windows harder liep dan 10ms, want als ik zelf een stukje software schrijf die steeds slaapt tot de volgende timeslice, krijg ik een interval van 10ms. Dat betekend (lijkt me) dat er een volledige ronde langs alle actieve threads is geweest.
Anyway, ik zou zelf ook voor DOS kiezen, of misschien een flink gestripte linux kernel.
|
Sponcebert
|
Even een tip over DOS, boot dan wel onder DOS en geen Windows DOS box of windows zonder grafische schil. Je krijgt dan dezelfde ellende.
|
free_electron
|
quote:
tzal een serieus gestripte moeten zijn.. dat ding zit ok altijd vanalles te doen achter jouw rug.
het voordeel van dos is , dat eenmaal je programma geladen in geheugen , dos niks meer doet. je programma controleert nu.
het engie wat nog gebeurt is de refreshcycles maar dat zijn bios functions.
Professioneel ElectronenTemmer - 8 April 08 : 7.355.303
|
Boudie
|
Dat strippen is al voor je gedaan: RTLinux (Real Time Linux).
|
timmie
|
* timmie toch maar eens gezocht op "Creating a windows drivers"
en zij het niet dat windows een Framework heeft voor UMDF en KMDF(user mode en kernel mode drivers).
nu geloof ik niet dat dit kattepis is. maar misschien/waarschijnlijk wel de enige redelijk haalbare oplossing
DMX interface
|
DeeP
|
hmm na een weekje niet meer gekeken te hebben zijn er toch nog serieuze reacties geplaats. Onder dos lijkt het mij een beetje jammer vanwege de lage afwerking van de grafische interface.
Dus vandaar dat ik het ook via windows wil doen. Gewoon vertrouwd in c# en met een mooie gui. Het is een programma voor mijn freesmachine dus ik zou graag wel willen zien wat ik ga frezen, welk toerental van de spindle, feedsnelheden en dergelijke. Dus dos vind ik persoonlijk niet echt geschikt.
Ik wil tijd steken in eventuele drivers en dergelijke voor windows. Dus over het besturings systeem is eigenlijk geen discussie lijkt mij ??
|
Jan Arjen
|
Ik zou persoonlijk voor een combo gaan:
Een c# applicatie voor de gui, welke dan
(via seriele poort oid) commando's verstuurd
naar een pic/avr. Deze kan dan met de
gestuurde instellingen realtime pulsen
genereren en eventueel status berichten
terug sturen.
|
DeeP
|
quote: Op 15 september 2008 12:24:53 schreef Jan Arjen:
Ik zou persoonlijk voor een combo gaan:
Een c# applicatie voor de gui, welke dan
(via seriele poort oid) commando's verstuurd
naar een pic/avr. Deze kan dan met de
gestuurde instellingen realtime pulsen
genereren en eventueel status berichten
terug sturen.
en nu probeer jij eens een 0 - 40khz (misschien nog meer) te genereren met een pic. Je hebt dus 80000 timer interrupts nodig om die 40khz te maken. Maar wat doe je met 39khz, hoe ga je die genereren??
Precies, dit is iets waar ik al een hele tijd over na zit te denken. Als jij mij een oplossing kan geven, doe ik het ook liever op die manier .. maar helaas is de oplossing bij mij nog niet gekomen.
|
free_electron
|
ik zou dat in een fpga doen.
je kan daar registers genoeg in maken.
die kloksnelheid, zoveel stappen in die richting. de microstep machine kan je meteen mee in de fpga goeten. en 18245 erachter als powerstage en vooruit maar.
de fpga knoop je aan een ftdi245 en huppekee
Professioneel ElectronenTemmer - 8 April 08 : 7.355.303
|
timmie
|
zou het niet haalbaar zijn om die pulsen naar buiten te brengen in een aparte thread met real time voorrang.
en dat je nadat het zijn werk heeft gedaan de thread weer kilt?
DMX interface
|