Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB.NET: VB5 ja LPT-portin lukeminen

Sivun loppuun

Jarmo [02.05.2009 08:10:56]

#

Taajuustieto lpt portin pinnistä 10
http://www.globu.net/pp/english/PP/ne555.htm
Tällaisessa osoitteessa tehty laskuri,kuka osaisi
kääntää kyseisen koodin vb5 lle
Käyttäisin sitä muuhunkin kuin lämpötilan tulkintaan
Jarmo

neau33 [03.05.2009 03:18:38]

#

Moikka Jarmo!

imppaa tämä pura ja kopioi inpout32.dll windowsin system32 hakemistoon

VBA-versio linkkisi koodiesimerkeistä...

Private Declare Function Inp Lib "inpout32.dll" _
Alias "Inp32" (ByVal PortAddress As Integer) As Integer

Private Type POINT_TYPE
   x As Double
   y As Double
End Type

Private data() As POINT_TYPE

Private Sub CommandButton1_Click()
   TextBox2.Text = _
   interpolar(GetFrequency)
End Sub

Private Sub UserForm_Activate()

  Dim lrow As Integer
  lrow = Sheets(1).UsedRange.Cells. _
  SpecialCells(xlCellTypeLastCell).Row
  For i = 1 To lrow
     ReDim Preserve data(i)
     data(i).x = Sheets(1).Cells(i, 1).Value
     data(i).y = Sheets(1).Cells(i, 2).Value
  Next i

End Sub

Private Function interpolar(num_var As Variant) As Variant

   Dim i As Integer
   Dim l As Variant
   Dim b As Boolean
   Dim x1 As Double, x2 As Double
   Dim y1 As Double, y2 As Double

   i = 1: l = 0: b = False

   Do While i < UBound(data) And b = False
      If num_var >= data(i + 1).y And _
      num_var <= data(i).y Then
         x1 = data(i).x
         y1 = data(i).y
         x2 = data(i + 1).x
         y2 = data(i + 1).y
         b = True
      End If
      i = i + 1
   DoEvents: Loop

   If b = True Then
     l = (x2 - x1) / (y2 - y1) * (num_var - y1) + x1
   End If

   interpolar = l

End Function

Private Function GetFrequency() As Double

   Dim ctd_pulse_h As Double
   Dim ctd_pulse_l As Double
   Dim system_reading_time As Single
   ctd_pulse_h = 0
   ctd_pulse_l = 0
   system_reading_time = Timer + 1

   Do While system_reading_time > Timer

      ByteRead = StatusPortRead(&H378) 'LPT1
      'For i = 0 To 7
         'If BitRead(ByteRead, i) = ...
         If BitRead(ByteRead, 7) = 1 Then
            ctd_pulse_h = ctd_pulse_h + 1
         End If
         If BitRead(ByteRead, 7) = 0 Then
            ctd_pulse_l = ctd_pulse_l + 1
         End If
      'Next i
   DoEvents: Loop

   GetFrequency = (ctd_pulse_h + ctd_pulse_l) / 2

End Function

Function StatusPortRead(BaseAddress) As Integer
   StatusPortRead = (Inp(BaseAddress + 1) Xor &H80)
End Function

Function BitRead(Variable, BitNumber) As Integer
   Dim BitValue As Integer
   BitValue = 2 ^ BitNumber
   BitRead = (Variable And BitValue) \ BitValue
End Function

Grez [03.05.2009 14:12:01]

#

Laskureita pitäisi kasvattaa vain, kun tila muuttuu, ei jokaisella kierroksella. Vertailemalla ctd_pulse_h ja ctd_pulse_l määrää nykyisellä koodilla saisi mitattavan signaalin "Duty Cyclen". Nykyisellään GetFrequency sen sijaan kertoo koneen kirjoitinportin lukunopeuden riippumatta syötetystä signaalista.

neau33 [03.05.2009 14:43:29]

#

Heippa!

Grez@:
Please explain...using iron wire!

Grez [03.05.2009 16:00:55]

#

No ihan yksinkertaisesti jos ajan tuon ohjelmasi koneessa, missä ei ole kytkettynä kirjoitinporttiin mitään, niin se sanoo taajuuden olevan 59200 Hz. Tästä voin päätellä, että koneeni pystyy lukemaan kirjoitinportin statuspinnien tilan noin 110000 - 120000 kertaa sekunnissa. Saisin suurinpiirtein saman 55000-60000 vastaukseksi, vaikka laittaisin koneen printteriporttiin tuon systeemin. Ja tarkoitushan oli mitata tajuutta jolla signaali tulee printteriporttiin, ei saada samaa lukua joka kerta.

Lisäksi jos katson mitä nuo muuttujat ovat tuolla GetFrequency funktion lopussa:

? ctd_pulse_h
113511
? ctd_pulse_l
0

Eli bitti on ollut "high" koko ajan, joka ei ole yllättävää, kun koneen kirjoitinporttiin ei ole mitään kytkettynä.

Ohessa toimiva taajuudenmittauskoodi
- vaatii myös inpout32.dll:n
- formilla label TaajuusLabel
- formilla commandbutton MittaaButton

Private Declare Function Inp Lib "inpout32.dll" _
Alias "Inp32" (ByVal PortAddress As Integer) As Integer

Private Const LPT1Base = &H378

Private Function GetFrequency() As Double
    Dim HalfPulses As Long   '= 0
    Dim EndReadingAt As Double
    Dim LastState As Boolean
    EndReadingAt = Timer + 1


    LastState = ReadAckBit(LPT1Base)
    Do While EndReadingAt > Timer
        If LastState <> ReadAckBit(LPT1Base) Then
            HalfPulses = HalfPulses + 1
            LastState = Not LastState
        End If
        DoEvents
    Loop

    GetFrequency = HalfPulses / 2

End Function
Function ReadAckBit(BaseAddress As Integer) As Boolean
    ReadAckBit = Inp(BaseAddress + 1) And 128
End Function
Private Sub MittaaButton_Click()
    TaajuusLabel.Caption = "Taajuus = " & GetFrequency()
End Sub

Yleisesti ottaen taajuuden mittaus printteriportin kautta on aika hölmöä ja resursseja tuhlaavaa*, eikä monissa nykykoneissa edes ole printteriporttia. Itse laittaisin joko lämpövastuksen joystick-porttiin tai sitten käyttäisin mikrokontrolleria joka mittaisi lämmön ja antaisi luvun suoraan vaikka sarjaporttiin tai USB:illa tai sitten laittaisin esim. digitaalisen onewire -lämpömittarin DS18S20 sarjaporttiin

* yks prosessori/ydin on kokonaan jumissa tuon inp-komennon aikana, joten esim. itselläni kun on kaksi ydintä, niin CPU-kulutus nousee 50%:iin tuon loopin ajaksi, vaikka siinä onkin doevents. Ja jos nykyprossu suorittaa yhtä komentoa n. 1/100 000 sekunnin nykykoneella, niin se on todella hidas komento.

groovyb [03.05.2009 23:52:42]

#

imho, ylipäätänsä helpommalla pääsee jos vaan vaihdat vb.nettiin, vaikka express versioon kun ilmaiseksi saa, ja sitten sarjaportin lukuun käytät serialport luokkaa suoraan.

ja tosiaan, mitään looppeja en myöskään itse suosittele. jos kyse on lämpötilan luvusta, pienemmät resurssit kuluu kun käytät vain timereita (ja suht pienellä intervallilla tulos on varmaankin sopiva)

suosittelisin että hommaisit sopivan admuuntimen sarjaporttiin jännite- tai virtamittausta varten, ja siihen lykkäisit lämpötila-anturin kiinni.

USB-vermeet ovat myös hyviä, käyppä vaikka kouluelektroniikan sivuilla ja metsästä USB- liitännän kokeilukortti
rakennussarjojen/vellemann k sarja. hinta taitaa olla 45e at the moment.

Grez [04.05.2009 03:37:37]

#

groovyb kirjoitti:

ja tosiaan, mitään looppeja en myöskään itse suosittele. jos kyse on lämpötilan luvusta, pienemmät resurssit kuluu kun käytät vain timereita (ja suht pienellä intervallilla tulos on varmaankin sopiva)

Ongelma on vaan siinä, että jos tulee esim. 1000 Hz taajuista pulssia vaikka 10% duty cyclellä, niin käytännössä porttia on pakko lukea vähintään 20000 kertaa sekunnissa luotettavan tuloksen saamiseksi. Siis joo, tippuuhan tuossa 20k vs 100k hz pollimisessa prossunkulutus 80%, mutta ei tuokaan ole optimiratkaisu, IMO.

Periaatteessa tietysti jos tuosta saisi printteriporttikeskeytyksen (niinkuin Ackista pitäisi saada) niin homma muuttuisi huomattavasti resurssiystävällisemmäksi. En sitten tiedä miten tuollainen on hyödynnettävissä Windowsissa - jos vaatii laiteajurin kirjoittamista, niin jäänee monilta väliin.

neau33 [04.05.2009 08:05:29]

#

Heippa!

Tässä vaiheessa olisi mielenkiintoista saada nähdä myös alkuperäisen kysysjän kommentteja...

groovyb [04.05.2009 14:47:59]

#

Grez, optimiratkaisu olisikin mielestäni tuo sopiva admuunnin, jonka puskurista lukisi mittadatat kertalaakilla aina jo valmiiksi keskiarvoistettuna.
näin ei tarvittaisi kuin se yksi datan luku. se olisi optimi, ja näin se yleensä tehdäänkin. miksi keskiarvoistaa itse kun, puskurit pc käyttöön tarkoitetuissa ad muuntimissa on jo yleensä itsestään. rajat tulee lähinnä ad muuntimen ja anturin tarkkuudessa. on turha tehdä muutenkaan mitään keskiarvoistuksia jos lukee 9 bittisellä lämpötila-anturilla lukeamia. (ja nämä 10-20e halvat anturit eivät paljon parempaan resoluutioon pysty)

jos -50C - +50C 9bitin lämpötila-anturia lukee, on pykälä mittauksessa vajaa 0.4 astetta, joka ei paljon aihetta keskiarvoistukselle anna. ja jos mittausalue on laajempi (kuten yleensä on), tarkkuus vaan heikkenee.

sarjaporttia tai lpt porttia käytettäessä datan luku on kaamean takkuista ja tehoja vievää, jolloin suurinopeuksinen luku ei vaan kannata suoraan. ja jos puskuroi itse, niin kannattaa katsoa että sarjaportin ja lpt portin max tiedonsiirtonopeudet ovat riittävät suurinopeuksisen datan lukuun. jos luet vaikka merkkijonoa, aika lyhyt saa olla että 100khz lukunopeus toteutuu 115000bps maksiminopeuden omaavasta sarjaportista.

Grez [04.05.2009 15:01:39]

#

Nuo taajuuksiin liittyvät kommenttini eivät tarkoittaneet, että pitäisi saada 100k näytettä lämpötilasta sekunnissa vaan että tuolla aloittajan kuvaamalla tavalla toteutetussa systeemissä pitää lukea printteriporttia suht tiiviiseen tahtiin, että saa edes sen yhden näytteen, eli signaalin taajuuden.

Itselläni on tällaisia juttuja varten pussillinen TO92-koteloisia DS18B20 -antureita pöytälaatikossa. Ne saa helposti sarjaporttiinkin kiinni, vaikka itse käytänkin lähinnä mikrokontrollerin kanssa niitä. Ja lämpötilan saa -55 - +125 °C välillä 1/16 °C resoluutiolla.

groovyb [04.05.2009 15:08:53]

#

Ok, no tuolla timerin käytöllä pystyy estämään ainakin täydellisen resurssikadon jonka sarjaportin luku loopilla aiheuttaa.
tuolla linkissäsi lukee että -10 - 85 astetta resoluutio +- 0.5 astetta?
itse käytän yleensä pt100:sia tai termopareja lämpötilan lukemiseen, nokevalilta saa hyviä muuntimia tähän.

Grez [04.05.2009 15:16:50]

#

Joo, kuten sanoin, niin kyllähän siinä voi esim. n. 80% säästää, jos pystyy ajamaan timeria esim. 1/20000s välein ja jos se riittää.

groovyb kirjoitti:

tuolla linkissäsi lukee että -10 - 85 astetta resoluutio +- 0.5 astetta?

Ei lue. Ihan aluksi erota toisistaan termit resoluutio ja tarkkuus. Kuten jo sanoin, niin mittausalue on -55°C - +125°C ja resoluutio nyt on itse valittavissa, 1/2 °C - 1/16 °C välillä. 1/2°C resoluutiolla saa reilut 10 näytettä sekunnissa ja resoluutiolla 1/16 °C saa reilun 1 näytteen sekunnissa.

Ja siis eihän toki tuo mikään ainoa vaihtoehto ole. Ajattelin vaan kysyjän tarpeeseen soveltuu luultavasti paremmin kuin esim. termopari, joita niitäkin kyllä löytyy.

groovyb [04.05.2009 16:25:11]

#

no tarkkuus rajoittaa sen resoluution. jos tarkkuus on +- 0.5 astetta, ei sen tarkempaan resoluution kannata edes mennä. ei ole väliä jos resoluutio mahdollistaa asteen pikkuosiin menemään mutta mittaus voi heittää puolella asteella suuntaan ja toiseen. 12bit mittauksella saa 2048 pykälää, jolloin mittausaskel on 0.09°C tuolla -55 ja 125°C välillä, ja jos tarkkuus on +- 0.5°C, ei tuota mittadataa voi käyttää, koska tulos voi olla -0.59°C ja 0.59°C välillä.
ainakaan suoraan. on eri asia kun sitten puskuroidaan, keskiarvoistetaan ja poistetaan piikit.

no, enivei, alkup. kysyjälle varmaan info riittää ;)

Grez [04.05.2009 16:29:24]

#

groovyb kirjoitti:

no tarkkuus rajoittaa sen resoluution

Resoluutio kyllä rajoittaa tarkkuuden, ei toisinpäin. Ainahan voit kalibroida sen itse, jolloin saat paremman tarkkuuden, kuin valmistajan lupaama +- 0.5 astetta.

groovyb kirjoitti:

jos tarkkuus on +- 0.5 astetta, ei sen tarkempaan resoluution kannata edes mennä.

Ei pidä paikkaansa. Usein on hyötyä tiedosta, että lämpötila on laskenut esim. 0,2 astetta, vaikka absoluuttisesti lämpötila tiedettäisiinkin vain 0,5 asteen tarkkuudella.

groovyb kirjoitti:

12bit mittauksella saa 2048 pykälää

2^12 = 4096.

Vähän paremmin ne faktat kohdalleen...

groovyb [04.05.2009 16:43:21]

#

kappas, pitäisi varmaan laskea sormilla :)

riippuu onko se absoluuttinen lämpötila vakio, vaiko kelluva 0.5 asteen heitolla suuntaan ja toiseen. jos heitto on vakio voidaan asia toki korjata offsetilla.

sama pätee myös tuohon ensimmäiseen resoluution rajoitukseen. eli jos heittoa on x astetta, ei kannata tarkempaan resoluutioon mennä. vaikka anturi sen mahdollistaisikin. jos heitto on vakio, niin sitte asia onkin aivan eri.
jos jos kalibrointi vain auttaisi asiaan maagisesti, ei tarvitsisi olla kalliita tarkkuusantureita, ainoastaan tarkkoja kalibrointilaitteita joilla saataisiin huonotkin anturit tarkoiksi, ja anturieroina olisi vain itse resoluutio.

Grez [04.05.2009 17:06:44]

#

groovyb kirjoitti:

riippuu onko se absoluuttinen lämpötila vakio, vaiko kelluva 0.5 asteen heitolla suuntaan ja toiseen. jos heitto on vakio voidaan asia toki korjata offsetilla.

No eihän tuossa nyt mitään 0,5°C "kohinaa" ole näytteissä. Jos olisi, niin eihän siinä resoluutiossa silloin mitään järkeä olisi. Nyt kuitenkin ilmeisesti valmistajan lupauksen max +- 0,5°C absoluuttisesta virheestä tietyllä välillä jotenkin omituisesti tarkoittavan, että se heittelisi näytteiden välillä tuon verran.

Kuten sanoit, tarkkuusmittareille on oma paikkansa - ei tuon anturin virhe ole absoluuttinen, eli ei sitä voi pysyvästi eliminoida kertakalibroinnilla. Tyypillinen drift rate 1000 tunnin aikana on 0,2°C. Silti tuollakin pystytään havainnoimaan lämpötilan vaihtelua käytännössä täydellä resoluutiolla, joten väite ettei tuon resoluutiosta olisi hyötyä ei vaan yksinkertaisesti pidä paikkaansa.

groovyb [04.05.2009 17:19:21]

#

no näinhän esim halvat paineanturit käyttäytyy,arvokkampikin jännitelähtöinen anturi sisältää kohinaa mV tasolla runsaasti, ja kun 5v jaetaa 12bit resoluutiolle, kohina on jo näkyvää. Ja kun kyseessä oli muutaman euron anturi, juuri tätä epäilin

Jarmo [05.05.2009 21:27:52]

#

Kiitos kaikille ,monipuolisesta palautteesta.

Tulen soveltamaan sitä vallan muuhun kuin lämpötilan tulkintaan,
555 piirin käyttö herätti mielenkiinnon
Nettisivulla sattui olemaan mulle sopivaa ideaa

Laitan koodin pätkän jo valmiiseen LPT koodiin
Vanha Compaq LT 5280 ssa ,ei ole peliporttia.
"Hitaasti mutta varmasti" Jarmo


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta