PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Port.dll & High Resolution Timer machen Probleme



bwirmer
06.04.2005, 18:27
Ich schreibe gerade ein VB6 (Sorry ;) )-Programm, dass die Signale einer Wählscheibe über den Com-Port einliest. Da die Abtastrate des Standard-Timers zu gering ist, bin ich auf einen High-Resolution-Timer umgestiegen. Der funktioniert auch prima, jedoch verweigert die Port.dll ohne Fehlermeldung ihren Dienst, sobald ich einen solchen Timer im Projekt initialisiere (seltsamerweise erst bei der kompilierten Exe - beim Testen funktioniert alles einwandfrei). Hat jemand eine Ahnung woran das liegt und/oder gibt es port.dll-Alternativen mit denen es klappen könnte?

Gruß,
Benedikt

commander7
06.04.2005, 21:18
hallo bwirmer,
ich habe zwar kein lösungsansatz für dich, aber ich habe ein ähnliches problem. Ich brauche auch in VB6 oder VB .NET einen Timer der schneller als 1ms eingestellt werden kann. Wie funktioniert das mit dem High-Resolution Timer, habe mich mal in der Hilfe versucht schlau zu machen, bin aber gescheitert.

gruss commander7

bwirmer
06.04.2005, 21:55
hallo bwirmer,
Ich brauche auch in VB6 oder VB .NET einen Timer der schneller als 1ms eingestellt werden kann

Das geht nicht, allerdings betrügt dich der normale VB-Timer. Er schafft nur ca. 50ms, auch wenn du 1ms eingibst. Der High Resolution Timer schafft hingegen echte 1ms Auflösung ;)

Am komfortabelsten ist der CCRP-Timer (http://ccrp.mvps.org/index.html?controls/ccrptimer6.htm). Installiere ihn einfach nach Anleitung, füge deinem Projekt das Modul hinzu (Verweise...) und verwende ihn folgendermaßen:


private WithEvents Timer1 As ccrpTimer

Private Sub Form_Load()
Set Timer1 = New ccrpTimer
With Timer1
.EventType = TimerPeriodic ' Es gibt auch einmalige Aktionen und Countdown
.Interval = 1
.Stats.Frequency = 1
.Enabled = True
End With
End Sub

Private Sub Timer1_Timer(ByVal Milliseconds As Long)
'Hier kommen die Befehle rein!
End Sub

just4fun
06.04.2005, 23:25
Am komfortabelsten ist der CCRP-Timer (http://ccrp.mvps.org/index.html?controls/ccrptimer6.htm).

Hi bwirmer,

ich programmiere nicht in VB, sondern in C++ mit dem C++ - Builder 3.0 (alt, aber läuft).
Kennst du zufällig auch einen High Resolution Timer für den Builder?
Am liebsten natürlich als Package. :-)

Habe im Netz noch so keinen richtigen als Freeware gefunden.
1 echte ms Auflösung reicht mir bereits.

Blackbird
07.04.2005, 08:29
Timer oder Zeitmessung?



class timer
{
public:
// Konstruktoren
timer ();

// Methoden
void start ();
long double stop ();

inline long double getlast () const;

private:
// Konstruktoren
timer (const timer&);

// Operatoren
timer& operator = (const timer&);

// Variablen
LARGE_INTEGER m_Timer;
long double m_Measurement;

};


timer::timer ()
:
m_Measurement(0)
{
m_Timer.QuadPart = 0;
}

void timer::start ()
{
if(!QueryPerformanceCounter(&m_Timer))
throw;
}

long double timer::stop ()
{
LARGE_INTEGER EndTime;
if(!QueryPerformanceCounter(&EndTime))
throw;

EndTime.QuadPart -= m_Timer.QuadPart;

LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency);

m_Measurement = EndTime.QuadPart / static_cast<long double>(Frequency.QuadPart);

return(m_Measurement);
}

long double timer::getlast () const
{
return(m_Measurement);
}

aus dem Cplusplus-Forum (http://www.c-plusplus.de/forum/index.php).

Blackbird

just4fun
07.04.2005, 19:24
Timer oder Zeitmessung?[/code]
aus dem Cplusplus-Forum (http://www.c-plusplus.de/forum/index.php).


Einen Timer suche ich.

Ich möchte alle 1ms (oder länger) meinen Motor einen Schritt vorwärts steuern, und dabei noch ein paar kurze Sachen ausführen.
Das ganze sollte daher idealerweise Event-gesteuert sein, so wie bei dem Standard-Timer (der ja aber nur echte 50 ms liefert). :-(

bwirmer
07.04.2005, 20:15
Habe mich mal umgeschaut und bin auf die inpout32.dll gestoßen und möchte diese in der Hoffnung, dass diese DLL mit HighResolutionTimern funktioniert, ausprobieren. Weiß jemand, wie man damit den Com-Port ansteuert? Ich habe bisher nur Anleitungen für den Parallelport gefunden.

Blackbird
08.04.2005, 06:47
@just4fun,
Versuch es mal mit dem Multimedia-Timer, der ist wirklich auf die Millisekunde genau:

timeBeginPeriod
timeEndPeriod
timeGetDevCaps
timeGetSystemTime
timeGetTime
timeKillEvent
TimeProc
timeSetEvent


Alternativ kannst Du Dir aus dem High-Performance-Counter auch einen Timer bauen. Einfach in einem eigenen Thread warten, bis die Zeit um ist und eine Message senden oder einen Event setzen.

Das ist aber nicht das Problem - das Problem wird sein, so zeitgenau aus dem PC/Notebook heraus etwas steuern zu können!
Da hängen immer noch die Treiber für den Parallelport/Serialport mit den Geräte-Managern dazwischen.

Blackbird

just4fun
08.04.2005, 15:04
@Blackbird


Das ist aber nicht das Problem - das Problem wird sein, so zeitgenau aus dem PC/Notebook heraus etwas steuern zu können!

OK, werde ich mir mal anschauen.
Danke!

Ist mir natürlich klar, dass 1 ms echt sehr kurz ist.
Aber es kommt mir weniger auf die Genauigkeit, als auf die hohe Geschwindigkeit an. Und selbst wenn die Hardware dahinter "nur" 10 ms schafft, ist dass immerhin schon 5x schneller, als der olle 50ms-Standard-Timer im CppBuilder.

Blackbird
11.04.2005, 12:43
Nochwas zum Knobeln :-k

Wenn man Impulse an der seriellen oder parallelen Schnittstelle ausgibt (also timergesteuert ein Pin ein- und ausschaltet), so kann der eine oder andere Impuls mal länger werden, wenn Windows gerade damit beschäftigt ist, den Screensaver zu aktivieren, die Netzwerkkarte zu aktivieren und und und...
Das kann man eindämmen, wenn man die eigenen Prozesspriorität hochsetzt (z.B.: SetThreadPriority()) und/oder mit Critical Sections arbeitet (InitializeCriticalSection(), LeaveCriticalSection(), ...).

Ein "Restrisiko" bleibt aber immer.

Alternativ gibt es doch noch eine Möglichkeit, exakte, gleichbleibend genaue Impulse zu erzeugen, die NICHT von Windows ab und zu verlängert werden - allerdings ist da ein wenig Hardware erforderlich:

Wenn man den Sende-Puffer der seriellen Schnittstelle groß genug macht und man den immer randvoll lädt, so kommen exakt im Takt der Baudrate die Bytes an TxD raus. Hier ein USART angeschlossen (z.B: HD6402, COM8017, ...) und man hat an jedem der 5 bis 8 Datenpins im Takt der Baudrate eine Änderung.
Stellt man z.B.: folgende Parameter ein:
9600,8P2 (12 Bits gesamt pro 'Byte')
so ergibt das 1,250 ms / gesendeten Byte
d.h.: wenn Du nur das Bit 1 benutzt, und folgende Bytes in den Sende-Puffer schreibst (Bitdarstellung, x ist beliebiges bit):
xxxxxxx0, xxxxxxx1, xxxxxxx1, xxxxxxx0, xxxxxxx1, xxxxxxx1, xxxxxxx0
so erscheint an Bit 1 des UARTS folgende Impulsfolge:
1,25ms Low, 2,5ms High, 1,25ms Low, 2,5ms High, 1,25ms Low

Die übrigen 7 Bit kann man auch noch benutzen.
Mit anderen Baudraten ergeben sich auch andere Zeiten - z.B.: 115200,5N1 ergibt 60.7639 us/Byte. Das ist übrigens die Pulsbreite für das DCC-Format der Modelleisenbahn.

Blackbird

bwirmer
11.04.2005, 13:00
Jepp, Windows und Co sind schlimm - entweder man muss auf QNX o.ä. umsteigen, oder ein bisschen Hardware einsetzen...

Das Problem ist übrigens gelöst. Zwar weiß ich immer noch nicht genau, warum - aber wenn man den Timer vor der Port.dll initialisiert, funktioniert das Programm - umgekehrt nicht.

just4fun
11.04.2005, 18:05
Auch kein schlechter Tipp!
Zur Zeit hänge ich aber am Parallelport, da ich dort so schöne viele Leitungen habe.
Ich muss mal schauen, wann ich mich an die "Verschnellerung" durch den Multimediatimer wage und schauen, was es effektiv bringt.
Wie gesagt: Es ist mir nicht so wichtig, ob ein Motorstepper-Impuls dann 1,5 oder 1 ms lang ist. Ist natürlich nicht so schön, dürfte aber für meine Zwecke wohl ausreichen.

Aber dennoch vielen Dank für die guten Tipps und die Anregungen!
Wird weiter in meinem Kopf arbeiten...

Ist ist n klasse Forum hier! Bin jedes mal wieder begeistert. =P~
Hab nur leider viel zu wenig Zeit... :-(

Blackbird
12.04.2005, 06:26
@bwirmer,

Linux, Unix, SunOS sind nicht besser - sind eben alles keine Echtzeit-OS.
pSOS+, VxWorks sind es aber. Alternativ kann man auch DOS (ja, echtes, altes DOS!) mit der Betriebssystem-Erweiterung DESQView 386 nehmen. Die ist (fast) echtzeitfähig und multitasking ist sie auch.

Blackbird

bwirmer
12.04.2005, 13:30
Linux, Unix, SunOS sind nicht besser
Das meinte ich mit Windows & CO



sind eben alles keine Echtzeit-OS.


QNX aber schon ;)

http://www.openqnx.com

Achja, Windows CE scheint auch ein Echtzeit-OS zu sein :o

Skilltronic
12.04.2005, 21:57
Hallo

Ein PC besitzt für die zeitliche Steuerung einen PIT, einen programmierbaren Intervalltimer, der mit einem Takt von 1,193180 Mhz läuft und den man sowohl auslesen und damit Zeiten theoretisch bis auf unter 1µs genau messen, als auch selbst einstellen und damit die 55ms-Auflösung der übergeordneten Timer verbessern kann. Letzteres geht aber unter Windows nur eingeschränkt. Für exakte zeitliche Steuerung ist es sowieso das beste, man fährt seinen Rechner mit einer Startdiskette unter echtem DOS hoch.

Ichj habe so schon z.B. über den COM-Port und einem TSOP mittels eines QuickBasic-Programms Signale von einer IR-Fernbedienung eingelesen, deren Impulse deutlich unter 1ms lang waren.

Hier ein paar Links zum PIT:

http://www.franksteinberg.de/SOURCE/TIMING.TXT
http://www.sharpmz.org/mz-700/8253ovview.htm
http://ivs.cs.uni-magdeburg.de/bs/lehre/sose99/bs1/aufgaben/aufgabe3/timer.shtml

Gruss
Skilltronic

Blackbird
13.04.2005, 06:33
@Skilltronic,
absolut richtig.
Der "PIT" ist auch unter W95/98 noch erreichbar. Aber ab WinNT/2k/XP/ME nicht mehr. Nur mit einem eigenen Treiber. Oder man verwendet die Funktionen QueryPerformanceCounter(...) und QueryPerformanceFrequency(...) (funktionieren auch unter W95/98 ), die eben genau diesen Counter des 8253 auslesen. In den Chipssätzen der Mainbords gibt es den (Uralt-)IC 8253 nicht mehr. Aber seine Funktionalität ist aus Kompatibilitätsgründen in den Chipsätzen mit enthalten. Genauso wie die von 16550 und anderen.

Meine Antworten bezogen sich auch nur auf C/C++-Code für W32-Systeme, nicht auf Basic (für 16Bit-Systeme), weil der Zugriff auf Hardware-Addressen in W32-Systemen gesperrt ist. Deshalb auch mein Vorschlag, DOS zu nutzen. Dann hat man auch alle Vorteile der hardwarenahen Programmierung, die Du genannt hast.

@bwirmer,
WindowsCE ist kein Echtzeitsystem. Nur ein abgespecktes 32Bit-Windows, das aus genau diesem Grund recht schnell ist.

Hier einmal zum Verständnis das Hauptmerkmal eines Echtzeit-OS:
Jedes von außen eintreffende Ereignis (z.B.: an einem Port) muß nach einer durch die Programmierung festgelegten Zeit (abhängig vom Code und vom Maschinentakt) zu einer Reaktion an einem anderen Port in IMMER der gleichen Zeit führen, egal, was der Prozesser/Rechner gerade macht. Ob das Minuten oder Microsekunden sind, spielt dabei gar keine Rolle - es muß nur immer die gleiche (vorausberechnete) Zeit sein, egal, ob der Rechner gerade die Datenbank abgleicht, das Netzwerk durchsucht, im IDLE-Modus rumrennt oder sonstwas macht.

Naja, egal wie, für unsere (Amateuer-)Anwendungen gibt es eine Menge Möglichkeiten, mit vorhandenen PCs und OS quasi Echtzeitanwendungen, auch für kurze Reaktionszeiten zu "bauen". Das hat der Thread hier schön zusammengefaßt.

Blackbird

bwirmer
13.04.2005, 11:22
@bwirmer,
WindowsCE ist kein Echtzeitsystem. Nur ein abgespecktes 32Bit-Windows, das aus genau diesem Grund recht schnell ist.

Stimmt, bin meinen aufgeschnappten Informationen nocheinmal genau nachgegangen. Allerdings ist CE schon ziemlich nah dran (http://www.windowsfordevices.com/articles/AT6761039286.html) und mit dem normalen Windows nicht unbedingt zu vergleichen - das trifft wohl eher für XP Pocket zu.

Das Prozesse bei einem Echtzeitsystem jederzeit zu 100% deterministisch sein müssen, ist klar - und Windows ist da strukturell einfach anders aufgebaut.