Ich weiß nicht ob mir jemand hier helfen kann aber ich versuchs einfach mal. Ich möchte mit dem Parallelport eine Messung machen. Ich habe mir eine Platiene zurecht gelötet, wo ich schon mal LED´s An und aus schalten kann. Nun mein Problem: Ich bekomme keine Daten IN den PC. Ich habe als Betriebssystem Win XP. In Borland c++ 6.0 habe ich mit eine Oberflache zum Ansteuern meiner Platiene Programmiert. Damit ich den Parallelport ansprechen kann, benutze ich die inpout32.dll. Leider kann ich nur Leienhaft mit der C++ Sprache umgehen und noch mit keiner andren. Wie sage ich in C++ das er an Port 0x378 den Pin 2 ( Data0) Einlesen soll? Das Ganze ist für eine Facharbeit und deswegen were ich über hilfe sehr dankbar. Gruss Testfahrer
Du mußt im Bios den Port umstellen, ansonsten ist es dir nur möglich, pin 10-15 einzulesen.
Und bevor du die Facharbeit abgibst, bitte Rechtschreibprogramm drüberlaufen lassen (Platiene, Leienhaft, were und 6-8 andere...)!
Hi, du musst auf dem Port 0x378+2 32 ausgeben, dann kannst du 0x378 als Eingang verwenden. Sei aber vorsichtig, bau lieber noch Angstwiderstände ein ;) HTH
@Helmut -dc3yc (dc3yc) Bist du ein spezialisierter Deutschlehrer. ...ein wenig unpassend?
@juppi: Ist doch peinlich, wenn man nicht mal den Jargon des Hobbys in seiner Landessprache beherrscht... @testfahrer: Mal an eine serielle Verbindung zum PC gedacht? Lässt sich wesentlich leichter handhaben. Außerdem gibt es eine Menge fertiger Software, z.B. zum Datenloggen - HTerm wäre hier mein Favorit.
Serielle Schnittstellen lassen sich außerdem noch mit USB-Dongle oder sogar mit Bluetooth nutzen. Parallelport ist ja sowas von out ;-)
>Parallelport ist ja sowas von out ;-)
Eben! OUT funktioniert ja, bloß IN nicht. ;-)
SCNR
Paul
Testfahrer wrote: > Ich weiß nicht ob mir jemand hier helfen kann aber ich versuchs einfach > mal. > > Ich möchte mit dem Parallelport eine Messung machen. Ich habe mir eine > Platiene zurecht gelötet, wo ich schon mal LED´s An und aus schalten > kann.acharbeit und deswegen were ich über hilfe sehr > dankbar. Aber pass auf, dass Du Vorsicht walten laesst. Wenn Du den Port lieferst ist meistens das ganze Mainboard geschrottet, da dann noch andere Peripherieeinheten daran glauben muessen.
@Juppi Nachdem dein erster Satz eine Frage darstellt, würde ich dahinter auch das korrekte Satzzeichen setzen ("?"). Nun zur Antwort: nein, bin ich nicht. Bin nur Inschinör. Aber einer, der seine erste Fremdsprache in Wort und Schrift einigermaßen beherrscht; die Muttersprache allerdings in Wort besser als in Schrift, weil sich Dialekt besser sprechen als schreiben lässt. Und wenn dann Worte wie "Platiene" oder "Wiederstand" auftauchen, kräuseln sich meine Fußnägel doch recht schmerzhaft.
lt. Wikipedia: "Nach dem Doppelpunkt wird in der deutschen Grammatik groß weiter geschrieben, wenn ein selbstständiger Satz folgt."
Zurück zum Thema: @Testfahrer: Schau mal im BIOS nach, wie der Parallel-Port konfiguriert ist. Hintergrund : Ursprünglich war diese Schnittstelle nur für die Datenausgabe (Drucken) gedacht. Später wurde sie als Dateneingang erweitert. Den Modus kann man im BIOS einstellen. Bei Normal/Standard/SPP ist nur eine Datenausgabe (unidirektional) möglich. Wenn auch eine Dateneingabe (bidirektional) möglich sein soll, muß Extended/EPP eingestellt sein. Es gibt auch noch den ECP-Modus, dieser benötig jedoch zusätzlich noch einen DMA-Kanal.
Danke für die Antworten bzw. Hilfen. ICh bin ein wenig weiter gekommen, ich kann nun die Basis Adresse des Parallelportes Auslesen. Diese liegt bei den meisten Rechenern auf Adr. 0x378 = #888. Ich benutzte eine DLL zum Ansprechen des Controllers, somit muss ich im BIOS nix einstellen. Nun hab ich aber noch immer das Problem, wenn ich die Data Register einlese kommt immer 0 Raus. Lese ich das Status Register, bekomme ich 126 und Lese ich das Control Register bekomme ich immer 204 heraus. Was sind das für Werte? Und meine Nächste Frage, wie Filter ich aus dem Data Register an welchem Data Pin des Sub 25 Steckers das Eingehende Signal Liegt? Pin 2 = Data0 Pin 3 = Data1 Pin 4 = Data2 Pin 5 = Data3 Pin 6 = Data4 Pin 7 = Data5 Pin 8 = Data6 Pin 9 = Data7
@GeraldB > Hintergrund : > Ursprünglich war diese Schnittstelle nur für die Datenausgabe (Drucken) > gedacht. Später wurde sie als Dateneingang erweitert Das stimmt so nicht ganz, es kommt darauf an wie man die Daten an der Schnittstelle einlesen will. Es gab schon immer das Signal für OutOfPaper oder Online - diese lassen sich Wunderbar als eingang nutzen, da sollte sogar die einstellung im Bios egal sein. Frage an Testfahrer: Kannst du ein paar Details zum anschluss sagen, an welchen Pins willst du als eingang Nutzen, wie viele eingänge brauchst du überhaupt?
Ich brauche nur 1 Pin ist sogar egal welcher. Es wird warscheinlich einer der Data Reihe werden. Was ich mir noch so überlegt habe, wie sieht es aus, MUSS im Controll Register nicht irgend ein Bit auf 1 sein, damit die Data Register als Eingang und nicht all Ausgang Gesetzt sind? WIe macht man denn so was?
So ich habe es nun hinbekommen eine Messaufnahme mit dem Parallelport zu machen. Leider ist das ergebniss nicht so wie ich es mir vorgestellt habe. Es heißt ja, das der Parallelport einen zeitliche Abgriff von 1 µs erlaubt. Das mag wohl sein, leider schafft mein schnellster PC, 2,1GHz CPU mit 400MHz Speichertakt, maximal 1,25 ms Pro Sample einer Messreihe. Das Signal welches ich aber messen möchte, liegt zwischen 10-12 µs. Nun such ich eine alternative diese Messung durchzuführen, und auch einen Messprotkoll zu haben. Das ganze natürlich ohne RISEN Kosten.
Da musst du halt eine externe Hardware benutzen. Ein Microcontroller mit meinetwegen serieller Schnittstelle. Der liest die Daten mit 1MHz in seinen Speicher und wenn der voll ist, schickt er sie zum PC. Kostet 5 Euro und bissl Programmieren.
> Es heißt ja, das der Parallelport einen zeitliche Abgriff von 1 µs > erlaubt. Ohne Betriebssystem oder auf Devicetreiberebene ist das locker möglich, auch sehr viel langsameren Rechnern. Sobald aber ein Betriebssystem wie Windows oder Linux dazukommt, wars das auch schon. Mit Hacks wie "giveio.sys" lässt sich zwar auch hier die Geschwindigkeit erhöhen, aber deterministisch oder zuverlässig ist das nicht. Die Druckerschnittstelle ist für Deine Aufgabe schlichtweg vollkommen ungeeignet. Nimm Dir den Rat von Christian zu Herzen, mit einem geeigneten µC kannst Du mit ziemlich wenig Aufwand auch mit höherer Genauigkeit Pulsdauern etc. messen.
Ersmal Dank für die Antworten. An supachris: Dann werd ich das wohl mit einem µIC machen müssen. Was brauch ich denn alles, damit ich mit dem Messen loslegen kann. Für deteijierte Infos wer ich sehr dankbar. MFG Testfahrer
@testfahrer Zeigt doch erstmal dein Programm, mehr als 1ms sollte schon drin sein. Eventuell kann man da ja noch etwas rausholen.
testfahrer wrote: > Ersmal Dank für die Antworten. > > An supachris: > > Dann werd ich das wohl mit einem µIC machen müssen. > Was brauch ich denn alles, damit ich mit dem Messen loslegen kann. > > Für deteijierte Infos wer ich sehr dankbar. Nö, Denken musst du schon alleine. Das geht mit nahezu jedem µC. Aber ich wette, du hast noch nie was damit gemacht. Dann wirds schwierig...
Hm Mein Programm ist um einiges zu gross fürs forum. Ist mit c++ Borland geschriegen. Und ja ich hab noch nie was mit µC´s gemacht. Ich komm aber bestimmt gut rein in die Theorie so als R u. F Techniker.
testfahrer (Gast) muss ja nicht das ganze Programm sein, es reicht ja die stelle die für das auslesen da ist, und warum sollt das Programm zu gross sein, ich glaube kaum das es ein paar MB quelltext sind - auch nicht mit borland.
Also mein QuellStext hat schon 1,3 MB. ;-) Hm Die reine einlese Schleife sieht so aus: do { x = x +1; mess = StrToInt(messintervall->Caption); erg = (inp32)(address); erg = erg -grd; Sleep (1); } while (x <1500); inp32 ist von meiner DLL zum Wert einlesen. address ist bei mir h379. Sleep muss ich haben, damit der Rechner nicht festhängt.
@testfahrer da kann man doch schon noch etwas machen do { x = x +1; mess = StrToInt(messintervall->Caption); # Viel zu langsam in der schleife # warum muss das hier sein? # für was ist mess überhaupt da? erg = (inp32)(address); erg = erg -grd; Sleep (1); #der Aufruf von Sleep mit 1(ms?) #wie willst du denn auf µs kommen wenn du schon 1ms wartest? } while (x <1500); also erstmal das StrToInt und messintervall->Caption weglassen und dann mal testen. Dann das Sleep(1) mal durch eine kleine schleife ersetzen. (mal ein wenig testet damit der optimierer es nicht wegschmeist) Ist zwar zum schluss reine Resourcenverschwendung aber für diese Problem fällt mir spontan nicht weiters ein. jetzt kann noch passiere das das Betriebsystem dir immer mal Zeit wegnimmt, das kann man noch ein wenig verbessern in dem man für diese Zeit den Thread als TimeCritial ausführt. float nix; for( x = 0; x < 10; ++x ) { nix = sqrt(x); };
Ich muss was verbessern. Ich habe den Sleep(1) Raus genommen. Der hat die Zeit auf 1m Sekunde begrenzt. Nun komm ich deutlich weiter runter. Aber noch nicht genug. Ich liege nun bei 250µs. Wie gesagt, ich brauch aber so ca. 10µs aufnahme möglichkeit. Den Treiber oder Dll welche ich benutze heißt INPOUT32.DLL. Mit giveio.sys ging die Messung nicht, den dafür ist das Signal irgenwie zu schwach.
@testfahrer hast du auch das StrToInt(messintervall->Caption) entfernt? > Den Treiber oder Dll welche ich benutze heißt INPOUT32.DLL. > Mit giveio.sys ging die Messung nicht, den dafür ist das Signal irgenwie > zu schwach. eine dll kann wohl kaum entschieden ob ein Bit schwach oder stark ist! Kann du bei dir Assembler einbauen in den Code? Wenn ja kann man damit den Overhead durch den dll aufruf einsparen.
nachtrag, schicke doch mal die wirkliche Schleife, in der Schleife wird das Ergebniss überhaupt nicht verwendet.
Also ich hab ersmal StrToInt(messintervall->Caption) rausgemacht. Wie kann ich mir nun genau anzeigenlassen, wieviel zeit er für die messung braucht, ich hab immer sekunden gezählt, wieviel er für 2000 Messproben in der sec braucht. Ich kahm auf 5500 für 2s. Hier das komplette Prog: ************************************************************************ mmess->Clear(); mmess->Lines->Add ("Dies ist eine 10 Sekunden Aufnahme mit 5500 Werten"); address = StrToInt (Edit1->Text); address = address +1; AnsiString zeit, tag, pin; byte erg; int x =0, grd; zeit = Time(); tag = Date(); mmess->Lines->Add ("Die Messung erfolgte am "+tag +" Um "+zeit); grd = (inp32)(address); do { x = x +1; erg = (inp32)(address); erg = erg -grd; if ( erg != 0) { mmess->Lines->Add ("1"); } else { mmess->Lines->Add ("0"); Neingp2->Checked=0; Neingp3->Checked=0; Neingp4->Checked=0; Neingp5->Checked=0; Neingp6->Checked=0; } if ( erg == 248) { pin = 15; Neingp2->Checked=0; Neingp3->Checked=0; Neingp4->Checked=0; Neingp5->Checked=0; Neingp6->Checked=1; } if ( erg == 240) { pin = 13; Neingp2->Checked=0; Neingp3->Checked=0; Neingp4->Checked=0; Neingp5->Checked=1; Neingp6->Checked=0; } if ( erg == 224) { pin = 12; Neingp2->Checked=0; Neingp3->Checked=0; Neingp4->Checked=1; Neingp5->Checked=0; Neingp6->Checked=0; } if ( erg == 128) { pin = 11; Neingp2->Checked=0; Neingp3->Checked=1; Neingp4->Checked=0; Neingp5->Checked=0; Neingp6->Checked=0; } if ( erg == 192) { pin = 10; Neingp2->Checked=1; Neingp3->Checked=0; Neingp4->Checked=0; Neingp5->Checked=0; Neingp6->Checked=0; } //Sleep (1); } while (x <5500); mmess->Lines->Add ("Die Messung erfolgte an Pin " +pin); Neingp2->Checked=0; Neingp3->Checked=0; Neingp4->Checked=0; Neingp5->Checked=0; Neingp6->Checked=0; *****************************************************************
Wieso machst du denn die gesamte Auswertung immer noch während der Messung? Mach doch mal 2 Schleifen. Die erste misst nur, schreibt alle Werte in einen Speicher, und die zweite macht die Auswertung der Ergebisse aus dem Speicher.
@Testfahrer ich muss mich Christian anschliesen, wenn man etwas Zeitkritischen macht, dann sollte man auch nur das nötigste machen. Mach der eine grosses Array und liese den Port in das array ein - mehr nicht. In einer 2.Schleife wertest du dann das Array aus. Hast du mal versucht nachzuvollziehen, was dein Rechner alles macht wenn du etwas mit mmess arbeitest - das ist doch bestimme eine MessageBox. Dabei werden haufenweise Nachrichten zwischen Windows und deinen Programm ausgetauscht, man sollte NIE ein ein solchen schleife die GUI ansprechen. Da waren ja meine messungen auf einen 286er schneller. unsigned char buffer[10*1024]=0; for( int i = 0; i < sizeof( buffer ); ++i ) { buffer[i] = (inp32)(address); } dann wirst du vermutlich das Problem haben, das es viel zu schnell ist, dann kannst du versuchen mit dummy schleifen die ganze sache zu verlangsamen oder ein größers Array zu nehmen, aber zu langsam dürfte das dann nicht mehr sein.
Nachtrag: um in etwas abschätzen zu können wie lange die Messung gedauert hat würde vor und hinter der Messschleife die Zeit ermitteln, aber die normalen Zeitfunktionen sind dafür bstimmt zu ungenau dafür gibt es QueryPerformanceCounter, dann kann man nur noch davon ausgehen das die Messerergebnisse gleichmäßig verteilt sind (was aber durch windows nicht ganz so sein wird). Wenn die kleine Scheife schnell genug ist könnte man auch versuche den wert von QueryPerformanceCounter für jeden Messwert zu speichern, müsste man mal testen ich kenn die overhead von QueryPerformanceCounter nicht.
> aber die normalen Zeitfunktionen sind dafür bstimmt zu ungenau
GetSystemTime/GetLocalTime liefert die Systemzeit auf 100 nsec genau.
Allerdings wird man die Schedulergranularität erkennen, die, wenn man
keine Gegenmaßnahmen ergreift, bei 10 msec liegt. Mit timeBeginPeriod
(einer Funktion aus der Multimedia-Unterstützung) kann die
Schedulergranularität auf 1 msec reduziert werden.
Also mess ist ein Memo Feld. Ich habe auch schon überlegt, erstmal ins Memo Speichern, und dann die Messwerte auswerten. Nur hab ich das Problem; Wie greife ich auf eine Bestimmte Zeile eines Memo zu? z.B. Ich möchte den Wert aus Line1 Auslesen durch Schleife jagen um 1 oder NULL aus dem Messergebnis zu machen, dann in ein 2tes Memofeld hinzufügen. Nun soll Line1 Gelöschtwerden, und die Restlichen Lines aufrücken. Mit Lines->Add(); wird eine Zeile hinzugefügt. Wie Lösche ich eine? Wie Lese ich eine Bestimmte aus?
Hallo, >Also mess ist ein Memo Feld. Ich habe auch schon überlegt, erstmal ins >Memo Speichern, und dann die Messwerte auswerten. Das ist der der völlig falsche weg, das memo feld gehört zu der GUI von Windows ist ist LANGSAM, mach es doch wie ich oben in dem Beispiel geschrieben habe in ein array und dann kannst du die werte bequem auslesen. @Rufus t. Firefly Also meine msdn sagt mir bei GetSystemTime, das dieStruktur nur ms enthalten kann, damit ist kann sie als min 1ms darstellen, mit QueryPerformanceCounter bekommt man es genauer hin. Das der Scheduler dazwischenfunkt ist klar, aber wenn innherhalb von 2 messungen kein Taskwechsel auftritt, dann kan man die Zeiten noch unterscheiden was bei GetSystemTime nicht mehr geht.
So ich hab es mit einem Array versucht. Das scheint echt schnell zu sein. Nun kommt aber ein NEUES Problem bei diesem Array. Und zwar ich bekomme IMMER nur den ersten wert in jede Zeile des Array´s. Hier mein Programm: int array[10000]; int i,j, grd; grd = (inp32)(address); for(i=0; i<10000; i++) { array[i] = (inp32)(address); } for(j=0; j<10000; j++) { i=0; i++; mmess->Lines->Add(array[i]); } Ich hab das mal mit "array[i] = random(50);" statt "array[i] = (inp32)(address)" da bekomm ich wirklich nur 10000 mal die 4 oder so. Woran kann das liegen?
i=0; i++; was erwartest du auch wenn du i auf 0 machst und danach +1 rechnest? eventuell mal mit for(j=0; j<10000; j++) { mmess->Lines->Add(array[j]); } testen
und warum hast das array auf int gemacht? ich hatte nicht ohne grund unsigned char geschrieben, ein port hat nur 1Byte warum sollte man dann 3Byte verschenken? immerhin sind das bei deiner größe schon 3kb zu viel. Ist zwar noch nicht der Tragisch, aber muss so eine Verschwendung denn sein?
Jo das lag an dem J hab das echt verpeilt. ;-) Ok hab auch das int ersetzt. nun weiß ich immer noch nicht wie lang ich wirklich brauch für eine Messung. Ich mach nun 100.000 Messungen und bekomme nur 2 recht kurze Ausschläge. ICh glaube es ist noch immer zu langsam. http://img3.imagebanana.com/img/imynvmwz/messtest.JPG
Was nur Spass. ;-) Bin nun am Ausmaskieren. damit ich nur Boolsche zustände als Messerg. bekomme. Danke erstmal für die geopferte Zeit.
Hat alles geklappt. Nun das Letzte was noch ist, ist die Sache mit der Zeit. Wie erfasse ich diese so genau wie möglich? mit Time(); bekommt man ja minimal nur die Sekunden.
@testfahrer Lies doch mal bitte die Kommentare genau durch, ich hatte doch oben extra noch geschrieben welche methoden es zur Zeitmessung gibt 1. du machst vor der Schleife die Abfrage der Zeit und nach der Schleife dann weisst du das die ergebnisse dezwischen liegen müssen und kannst sie gleic
@testfahrer Lies doch mal bitte die Kommentare genau durch, ich hatte doch oben extra noch geschrieben welche methoden es zur Zeitmessung gibt 1. du machst vor der Schleife die Abfrage der Zeit und nach der Schleife dann weisst du das die ergebnisse dezwischen liegen müssen und kannst sie gleichmässig verteilen. 2. du machst ein 2. Array wo du zu jeden messergebniss die Zeit speicherst das ist dann zwar etwas langsamer (sollte aber für deine zwecke noch schnell genug sein) kannst dafür aber genau sagen wenn welcher zustand war. Für die Zeitmessung stehen dir die GetSystemTime funktion aus der windows api zur verfügung die aber nur ms liefert, wenn es etwas genauer sein soll dann sollte man QueryPerformanceCounter verwenden, sie liefert mindestens ms kann aber abhängig vom prozessor auch genauer sein (kann aber auch probleme bei einen fehler im Bios und einen Dualcore system erzeugen) vorschlag für die Lösung 1 ZeitStart = GetSystemTime for ( ... ) { array[x] = messert } ZeitStop = GetSystemTime Dann weiss du wie welche zeit zwischen den messergebnissen vergangen ist. die Etwas schönere/langsamere lösung bei der du weiss wann welches ergebniss ermittelt wurden ist. unsigned char array1[10000] = {0}; LARGE_INTEGER array2[10000] = {0}; for( int x = 0; x < 10000; ++x ) { array1[x] = port; QueryPerformanceCounter( array2[x] ); } Damit hat du 2. Arrays, eines mit den messwerten und eines mit den zeiten dazu. QueryPerformanceCounter liefert keine wirkliche Zeit es liefert einfach eine Zahl die hochzählt, wie viel sei pro sec hochzählt bekommt man mit QueryPerformanceFrequency raus. Man kann sie auch nich in eine Zeit umrechnen aber man kann sagen der vom start der messung bis x sind so und so viele µs vergangen. Die Doku für die Funktionen findet man bei Microsoft in der MSDN. >Ich mach nun 100.000 Messungen und bekomme nur 2 recht kurze Ausschläge. >ICh glaube es ist noch immer zu langsam. Ich würde sagen ist es viel zu schnell, du unterschätzt die heutigen Computer. Für ihn ist eine ms eine Ewigkeit wenn man es richtig anstellt. Ich hatte da ganze schon zu Zeiten vom 286er mit 12Mhz gemacht und das war schon schnell genug. @Profieprogrammierer normalerweisse würde ich denn messwert und die Zeit in eine Stuktur/Klasse packen, 2Arrays geht für den zweck auch.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.