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
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
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.
Heippa!
Grez@:
Please explain...using iron wire!
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.
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.
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.
Heippa!
Tässä vaiheessa olisi mielenkiintoista saada nähdä myös alkuperäisen kysysjän kommentteja...
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.
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.
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.
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.
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ää ;)
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...
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.
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.
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
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
Aihe on jo aika vanha, joten et voi enää vastata siihen.