Hallo,

Sommige mensen weten het misschien al, ik ben de laatste tijd een beetje aan het kloten met de lpt-poort.

Om te beginnen heb ik het artikel van deze website gebruikt. Helaas zijn (bijna) alle downloads niet meer beschikbaar en er staat maar een heel klein beetje info over het aansturen van de poort, bijna de helft is info over de poort zelf, nu is deze info ook nuttig maar niet echt super nuttig voor iemand die de poort wil aansturen tenminste, dat vind ik.

Ik heb ook mijn eigen module geschreven met de volgende functies:

  • Boolean omrekenen naar Bit (true wordt 1 en false wordt 0)
  • Decimaal omrekenen naar Byte
  • Byte omrekenen naar decimaal
  • Bit naar keuze hoog maken
  • Bit naar keuze laag maken
  • Byte op de lpt poort zetten
  • Alle uitgangen hoog
  • Alle uitgangen laag
  • Bit "togglen" (0 wordt 1 en 1 wordt 0)
  • Shift van rechts naar links hoog
  • Shift van rechts naar links laag
  • Shift van links naar rechts hoog
  • Shift van links naar rechts laag
  • Alle ingangen apart inlezen
  • Een Byte op de ingang lezen

To-Do:

  • Blokgolf met instelbare frequentie op instelbare Data-lijn
  • Pwm met instelbare Duty cycle op instelbare Data-lijn
  • Byte naar buiten sturen met instelbare frequentie en instelbare data-lijn

Ik zou graag het artikel willen uitbreiden met voorbeeld codes voor verschillende functies die ik heb geschreven en downloads en schema's (waarvan er ook een paar missen) willen vervangen/vernieuwen.

Nu zijn mijn vragen:
To Mod's : Is dit goed?
To All : Is hier behoefte aan?
To All : Hebben jullie nog aanvullingen op de lijst met functies hierboven?

Ik hoor lees jullie mening wel, Leime

Even voor de duidelijkheid (aangezien ik het was vergeten te melden) het gaat om Visual Basic!
Edit: Uitbreiden met ie... hoe verzin je het leime....

Rommelen met de parallelle poort van de PC? Damn, het is lang geleden dat ik dat gedaan heb. Ik kan me nog herinneren dat ik daarmee ooit een mooie ISA controller met VESA local bus om zeep heb geholpen, dus dat was nog in het 486 tijdperk.

Op Beyondlogic.org staat nog wel wat bruikbare informatie over de parallelle poort (en vele anderen).

Maar een beetje commentaar op je lijstje:

Hoe wil je een boolean omrekenen naar een bit? Wat bedoel je met decimaal omrekenen naar een byte? De term decimaal slaat alleen op de representatie.

Bit zetten, resetten, togglen, shiften met een nieuw bitje, enz. zijn naar mijn idee allemaal volkomen zinloos, als je de ingangen kunt lezen en de uitgangen kunt lezen en schrijven, met 16 of 32 bit integers of zo, kun je alles doen.

Als je echt meer wilt kunnen met de parallelle poort, zorg er dan voor dat je er zelf een interrupt handler aan kunt hangen zodat je de poort niet steeds hoeft te pollen, en interrupt driven met de systeemklok een pulstrein kunt genereren, zoals Mach3 en andere CNC besturingen voor windows doen.

1ste reactie op lijstje : Ik heb er toch achter gezet? Als een boolean false is converteer je die naar een o en als een boolean true is converteer je die naar een 1. decimaal naar byte betekent 255 converteren naar 11111111 enz.

2de reactie : Voor mensen die niet echt ervaring hebben met de lpt poort kan het makkelijk zijn lijkt mij.

3de reactie : Ben ik nog mee bezig (het is namelijk nog behoorlijk in ontwikkeling)

leime

Eerlijk gezegd komt het lijstje op mij over als misschien bruikbaar voor mensen zonder wezenlijke programmeer ervaring. Ik zie functies die ik waarschijnlijk zelf kan implementeren in minder code dan het aanroepen van die functie kost, en de functies waar je echt iets aan hebt, ontbreken nog.

Maar goed, dat is mijn persoonlijke mening, daar vroeg je om, dus die heb je gekregen. Het is zeker niet mijn bedoeling het af te kraken hoor, maar ik zie de toegevoegde waarde van die functies gewoon niet. Dat ze er zijn, wil natuurlijk niet zeggen dat je ze perse moet gebruiken, en in principe zitten ze natuurlijk niemand in de weg. Als er mensen zijn die wel graag met dergelijke functies werken, zijn ze beschikbaar.

Ik zie je reactie ook niet al afkraken hoor ;) Ik ben juist blij dat iemand commetaar geeft.

maar:

Op 23 juni 2009 13:47:25 schreef SparkyGSX:
en de functies waar je echt iets aan hebt, ontbreken nog.

Zoals? Interrupt ben ik nu mee bezig maar dat werkt nog niet precies hoe ik dat wil ;)

leime

Nou, eigenlijk voor de mogelijkheid om een callback te gebruiken voor veranderingen op de poort, als het even kan buiten de normale task scheduling om, zodat je snel kunt reageren.

De mogelijkheid om een of meerdere pulstreinen uit te sturen zou erg handig zijn.

Heb je eigenlijk al bekeken wat de maximale latency, realistisch haalbare frequentie en jitter van het geheel is? Welke frequentie kun je nog betrouwbaar op de uitgangen krijgen, en wat is de maximale frequentie op de ingangen voordat je pulsjes gaat missen?

Ik moet me wel bij Sparky aansluiten. Ik neem toch aan dat shiften, xorren (toggle), ORren, ANDen (bit aan/uit) etcetera in VB gewoon ook vrij rechtstreeks kan? Lijkt me stug dat daar alleen in C operatoren voor zijn.

In VB? Zeg dat dan meteen...

Als ik me goed herinner, kun je in VB niet bitshiften. Je kunt natuurlijk wel vermenigvuldigen met 2^x-1 om x posities naar links te shiften, en delen om naar rechts te shiften (let op de bizarre afronding van VB), maar VB kent "natuurlijk" ook geen unsigned 32-bit integer, als ik me goed herinner.

VB kent geen onderscheid tussen bitwise en logische operaties. Welke zombie dat bedacht heeft weet ik ook niet, maar elke AND, OR, NOT etc. is dus bitwise. Dit is ook de reden dat de waarde van checkbox.value die true is, altijd true zal blijven, hoe vaak je die ook inverteert. Dat was een klein foutje; true is daar 1, in plaats van -1. Als je alles bitwise inverteert, is 0 gelijk aan false, -1 gelijk aan true, en alle andere waarden zijn verboden.

Dit alles gaat overigens over VB6, ik heb lang geleden een stukje code in elkaar gedraaid voor binaire communicatie over de seriële poorten, en dat waren ook de dingen waar ik tegenaan gelopen ben. Aangezien het (gelukkig!) alweer een aantal jaar geleden is dat ik VB6 heb aangeraakt, zou ik er best wel ergens naast kunnen zitten hoor.

Dit is een reactie op Deze post

In mijn module maak ik gebruik van de io.dll van geekout
Ik heb de instructies makkelijker gemaakt en de ingang al helemaal. Inmiddels werkt de hardware interrupt. Ik ben nu bezig om deze op de achtergrond te laten uitvoeren.

Met pulstrein bedoel je gewoon een bepaalde reeks pulsen van een bepaalde frequentie? Of een byte op 1 datalijn (net zoiets als een streepjescode)?

En reactie op dat laatste:
Max frequentie uit zou ik niet weten, ik heb geen scoop oid, ik zal google eens informeren.
Max frequentie in weet ik ook niet, ik heb geen functiegenerator oid, ik zal google nog maar eens informeren.

leime

Dit is een reactie op Deze post

Heel stom.. Ben ik vergeten te vertellen dat het om VB gaat....

Ik heb ook de module zo gemaakt dat je wel kan shiften, tenminste dat noem ik shiften.


00000000
10000000
11000000
11100000
11110000
11111000
11111100
11111110
11111111

De 2de alinea: Zal eens testen wat je bedoeld

Leime

Op zich klopt die shift wel, maar over het algemeen shift je altijd een 0 in, en geen 1 als je naar rechts shift.

Met een pulstrein bedoel ik een blokgolf met een instelbare frequentie. Als je ook nog de duty-cycle zou kunnen instellen, kun je ook PWM signalen genereren en R/C servo's aansturen. Helemaal gaaf wordt het natuurlijk als je een array van bytes kunt opgegeven, die op instelbare frequentie naar buiten gestuurd worden; op die manier kun je ook een SPI master maken, of een functie generator als je een weerstandsladder met buffertjes of andere DAC aan de poort hangt.

Ik ben eigenlijk wel benieuwd naar je implementatie van die hardware interrupt, aangezien die io.dll daar, voor zover ik kan zien, geen mogelijkheden voor heeft.

Op 23 juni 2009 14:21:21 schreef leime:
Heel stom.. Ben ik vergeten te vertellen dat het om VB gaat....

Ik had dat geëxtraheerd uit het feit dat je het over het (VB en) printerpoort-artikel van CO had. Kennelijk een juiste aanname. VB is een crime als het ook maar iets harder wordt dan software.

@leime waaar haal jij een hardware interupt binnen? dat kan alleen op kmd nivo je kan hoogstens een callback krijgen vanuit de kernel maar dan werk je al via unsafe/unmanaged code.

@sparky: vb2005/2008 kent unsigned variabele, ook de unsigned 32bit integer die luistert naar de naam: UInt32

Daar heb je gelijk in, maar daarom zei ik er ook al bij dat het nog over VB6 ging. VB.NET is nauwelijks te vergelijken met VB6 en de andere voorgangers.

Ik heb een klein beetje met VB.NET gespeeld, maar niet met hardware en zo.

@timmie: Een mond voor maar ik begrijp er niets van..

Ik haal hem binnen met de printerpoort. De interrupt is alleen nog niet echt een interrupt, mijn programma staat in een do loop lus en zodra je een ingang hoog maakt spring je uit de do loop en dan kun je evt na een opdracht weer gewoon de do loop lus binnengaan.

@Jochem: Persoonlijk vind ik het wel meevallen, ik vind het leuk om ermee te werken.

@ Sparky: Bij het shiften kun je kiezen of je een 0 of een 1 wil shiften en je kunt kiezen welke kant op. Die blokgolf met instelbare frequentie, moet niet moeilijk zijn. Duty-cycle word lastig maar ik kan het altijd proberen. Die Byte's naar buiten sturen, kan ik eens proberen. Voor die interrupt zie de @ op timmie.

leime

edit: Ik heb even een blokje To-Do in de startport gezet.

was ik al bang voor.

als je toch een do-while lus hebt gooi dat ding in een aparte thread en gebruik events voor het "breaken"

Daar was ik al bang voor. Een hardware interrupt is echt wel even iets anders dan een loopje om een poortje te pollen.

Zonder scope en frequentieteller zul je nooit kunnen bepalen of je een goede pulsgenerator hebt gemaakt. Ik doel ook niet op een pulstrein van 5Hz of zo, maar meer richting 10 of zelfs 100kHz.

Maar kun je eens uitleggen dat jouw code nu precies toevoegt? Ik zie bij het lijstje van die io.dll ongeveer dezelfde functies staan als in jouw lijstje. Waarom zou iemand jouw code gebruiken, en niet gewoon direct die io.dll?

@sparky: dan zou je voor de pulsen nog wel de timerapi voor audio kunnen gebruiken

Iemand zou mijn module in combinatie met de io.dll kunnen gebruiken omdat ik alle instructies simpeler heb gemaakt. En waar heb vooral om gaat: Ik heb de boel zo gemaakt dat je de uitgangen los van elkaar kunt uitlezen dat kan met die io.dll niet.

De pulstrein werkt, je kunt hem instellen op een preciesie van 1 KHz maar ik moet nog meten of dit ook echt een nette blokgolf is. Dat doe ik waarschijnlijk in het weekend bij een vriend.

En de Interrupt werkt prima zolang je geen complexe programma's maakt.

Maar deze module is vooral bedoel voor mensen die geen ervaring hebben met programeren, deze kunnen dan met een beetje moeite waarschijnlijk wel binnen een dag een programma in elkaar flansen. Kijk, jij programmeert geloof ik behoorlijk veel, dus voor jou zal deze module niet echt nuttig zijn.

Ik ben blij met jullie reacties en uit jullie reacties kan ik halen dat jullie het nut er niet van inzien. Ik weet niet of jullie dat artikel wel eens gelezen hebben, want daar ging het eigenlijk om, die wil ik graag verbeteren/uitbreiden. Nu staat er alleen hoe je het SLEEP commando gebruikt en hoe je een poort hoog/laag maakt, iemand anders heeft bij de reacties nog moeten zeggen dat je eerst een module moet maken, kortom, ik vind persoonlijk dat dat artikel wel een opfris-beurt kan gebruiken.

Leime

Edit: Ik heb eens de interrupt pagina's van picbasic doorgelezen maar daar gebeurt het op bijna dezelfde manier hoor. (Of ik begrijp het niet)

een hardware interupt veroorzaakt een sprong van de plek waar de proccesor op dat moment bezig is naar de interuptvector.

wat je nu doet is gewoon checken of de status van de poort is veranderd das leuk maar het is geen interupt en als je pc druk bezig is met andere processen die misschien ook nog wel meer tijd krijgen dan dat van jou dan kna je data missen.

vandaar ook het idee om gebruik te maken van de timerapi of een thread die in high-priority draaid

bij de weg: een µC die op de seriele of usb poort zit kan meer en is waarschijnlijk makkelijker aan te passen naar eigen wensen.

pc zijde hoeft niet perse heel moelijk te zijn

ik zou me vooral concentreren op vb.net en de vb6 achterwege laten....

gebruik de io dll van logix4u . dat is de ENIGE stabiele en correcte implementatie ! de rest zijn vuile toeren.

shiften en roteren zit ingebakken in .net

je kan een mooi class maken die je dan kan instantieren.

dim lpt1 as printerport
lpt1.address = &h378
lpt1.d0 = true
lpt1.data = &h2F
lpt1.d3 = false

enzovoort.

je kan mooi properties maken voor al die dingen.
en als je computer meerdere poortne heeft can je meerdere instances maken van de class.

Voor interrupts voeg je aan de class een event toe.


Public Class printerport
    Private my_data As Byte
    Public Property d0() As Boolean
        Get
            Return CBool(my_data And 1)
        End Get
        Set(ByVal value As Boolean)
            If value = True Then
                Me.data = my_data Or 1
            Else
                Me.data = my_data and 254
            End If
        End Set
    End Property
    Public Property data() As Byte
        Get
            Return my_data
        End Get
        Set(ByVal value As Byte)
            my_data = value
            Select Case myport
                Case &H378, &H278, &H3BC
                    '       out(my_port, my_data)
                Case Else
                    Debug.Print(":: no port set.")
            End Select
        End Set
    End Property
    Private myport As Integer = 0
    Public Property port() As Integer
        Get
            Return myport
        End Get
        Set(ByVal value As Integer)
            myport = value
        End Set
    End Property
End Class

Voila hier heb je de basis al.

Let op de manier waarop ik de code maak. der zitten een aantal truuks in.
Bij het manipuleren van individuele bits lees ik van de interne variabele my_data. Maar ik schrijf het resultaat naar mijn eigen property me.data. op die manier hoef ik niet op 96 plaatsen de code te schrijven om de effectieve data op de poort te zetten. De property set trip op het wijzigen en doet dat voor mij. ik moet ook geen calls doen naar subroutines. Dit spaart tijd en maakt de code sneller.

Ook het foefelen met bits gebeurt op een speciale manier. ik reken alles zelf uit en plaats constanten in machinetaal wordt dat effectief 1 instructie.

ik doe in een select case statement de test op waar de poort staat.
eigenlijk kan je dat ook nog versnellen door de test in de property set van 'port' te doen en daar ene vlag te zetten. dan hoeft de select case maar 1 keer te lopen. spaart weer een aantal cycli uit.

Dergelijke bibliotheken moet je optimiseren voor snelheid.

ik heb ooit een gemodivifceerde val functie gemaakt (vval) die naast &h ook &b aankan.

je kan dingen doen zoals x = vval("&b1100100001010001")
dat maakt bitbanging makkelijker.

[Bericht gewijzigd door free_electron op (65%)]

Ik ken maar 2 methodes om directe I/O te kunnen doen vanuit een windows programma; ofwel door de port privilege bitmap aan te passen (belachelijk dat je daar bij kan, maar goed), of via een kernel driver. Ik ben wel met FE eens dat een kernel driver technisch gezien een veel betere oplossing is.

Overigens heb je die io.dll helemaal niet nodig om de port privilege bitmap aan te passen, dat heb ik lang geleden ook een keer zelf geschreven, en dat was niet eens echt moeilijk. Als ik me goed herinner, is de bitmap zelf read-only, maar de pointer naar de bitmap kun je wel overschrijven. Je maakt dus een blok geheugen aan wat groot genoeg is, zet alles op 0xFF (geloof ik) om jezelf toegang te geven tot alle poorten, en schrijft de pointer naar dat blok over de bestaande pointer.

Dat was nog wel in good-old C, dus niet in een van de .NET talen.

@Leime: hoe heb je die 1kHz blokgolf gemaakt? Eerlijk gezegd lijkt het me sterk dat dat een goede blokgolf is, aangezien de timeslice interval meestal zo'n 10ms is in windows.

Als je dit soort dingen goed wilt doen, zul je dat hele .NET verhaal overboord moeten gooien, en een kernel driver moeten schrijven in C of zo. Een kernel driver is echter geen kattepis, dan moet je echt wel weten waar je mee bezig bent. Daarbij zou ik daar, onder windows, niet aan beginnen tenzij je hele goede afspraken kunt maken met je apotheker voor flinke korting op grote partijen aspirine en paracetamol.

Ik heb het artikel over de parallelle poort zelf niet gelezen, en misschien heb je wel gelijk dat het verbeterd kan worden. Bedenk echter wel dat je daar een beetje laat mee bent; parallelle poorten worden steeds schaarser, en er staan al heel veel dergelijke tutorials op internet. Ik denk eigenlijk dat het ongeveer even zinnig is al een nieuwe tutorial gaan schrijven over het interfacen van de ISA bus.

Op 23 juni 2009 12:57:34 schreef leime:
Ik heb ook mijn eigen module geschreven met de volgende functies:

Das leuk, maar het is geen 'hoe werkt VB' artikel, het is een 'printerpoort en VB' artikel.

Ik ben met je eens dat het artikel wel eens een opfrisbeurt mag gebruiken, maar dan had ik toch wel graag wat duidelijkere schema's gezien om dingen met de poort aan te sturen (via transistor en optocoupler), en hoe je de boel moet aansluiten om wat in te lezen.
Het stukje VB dat laat zien hoe je het inleest in VB lijkt mij logisch, maar ik zie geen reden om er extra basisfunctie bij te stoppen. Het artikel is bedoeld om als module ergens aan toe te voegen, niet om op zichzelf te staan. Een klein testprogramma om wat uitgangen aan te sturen / in te lezen is genoeg.

Edit: Uitbreiden met ie... hoe verzin je het leime....

Geen idee, vertel eens? Meteen de wijziggen ook maar even goedgezet. :)

Aan de reacties te lezen in het denk ik het slimst om het artikel (van mij) gewoon in een pdfje te zetten en dan zet ik hier wel een link neer en een link op mijn site.

Leime

Eerlijk gezegd lijkt het me een stuk handiger en veiliger voor je PC om een uc'tje te pakken, en dan met een seriele verbinding de I/O-poorten van je uc te switchen.

Voordelen:
-minder risico op een stukke PC
-meer poorten
-meer features (A/D, etc.), want uiteindelijk wil je dat toch.