Toon posts:

[VC6.0] uit polling lus springen.

Pagina: 1
Acties:

Verwijderd

Topicstarter
Momenteel gebruik ik een oneindige lus om de LPT te scannen.
Hoe zou ik nu iets kunnen schrijven dat ik bv door een knopdruk uit die lus zou kunnen springen. (Het probleem dat ik nu ondervind, is dat ik op geen knoppen kan drukken tijdens die lus.)

code:
1
2
3
4
5
6
7
8
9
10
11
BYTE poortstatus;
BYTE S3[2];  // array om slechts iets uitgevoerd mag worden op stijgende flank.
                    //moet van de vorm [0,1] zijn. 
BYTE S6[2];
while(1)
{
poortStatus=scanLPT();
UpdateBYTES(poortStatus,S3,S6);
opdrachten(S3,S6);
Sleep(10); //om de 10 ms een scan uitvoeren
}

  • bramseltje
  • Registratie: September 2001
  • Laatst online: 23-07 23:59
Misschien is het verstandiger dit pollen met een timerevent te doen. Er is ongetwijfeld een timer component in VC aanwezig (zit in C++ builder, de borland versie ook) waarmee je dit ook kan doen.

Je geeft al aan dat je nergens op kan klikken als ie in de lus zit, en da's dan waarschijnlijk omdat je niet multi-threaded programmeert 8-) Begin ik zelf ook niet aan hoor, begrijp me niet verkeerd! :P Dus als je dan toch ergens op wil kunnen klikken zul je die poll in een OnTimer Event moeten afhandelen...

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Als je dit in je mainthread doet worden er logischerwijs geen windowsmessages afgehandeld. Er zijn 2 oplossingen voor. De netste is om deze lus in een 2e thread uit te voeren waar je door middel van een Event object uit kan springen:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
HANDLE  g_Thread;
HEVENT  g_ThreadShutdown;

DWORD WINAPI MyPollerThread(LPVOID lpParameter)
{
BYTE poortstatus;
BYTE S3[2];  // array om slechts iets uitgevoerd mag worden op stijgende flank.
                    //moet van de vorm [0,1] zijn. 
BYTE S6[2];

// Run until we are requested to stop, wait 10ms
while(WaitForSingleObject(g_ThreadShutdown, 10) == WAIT_TIMEOUT)
  {
  poortStatus=scanLPT();
  UpdateBYTES(poortStatus,S3,S6);
  opdrachten(S3,S6);
  }
// Succesful thread shutdown
return 0;
}

int main()
{
DWORD l_Dummy;

// Create event object, then launch thread
g_ThreadShutdown = CreateEvent(NULL, FALSE, FALSE, NULL);
g_Thread = CreateThread(NULL, 0, MyPollerThread, NULL, 0, &l_Dummy);

// Do rest of program
...
}

void ShutdownThread()
{
// Set the event, then wait for the thread to be finished
SetEvent(ThreadShutdown);
WaitForSingleObject(g_Thread, INFINITE);
}

De 2e methode is iets minder netjes maar voorkomt wel dat je multithreaded moet met alle rotzooi van dien.

Je kunt tijdens die eindeloze loop namelijk gewoon window messages blijven processen als volgt:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
MSG  l_Message; 
BYTE poortstatus;
BYTE S3[2];  // array om slechts iets uitgevoerd mag worden op stijgende flank.
                    //moet van de vorm [0,1] zijn. 
BYTE S6[2];

while(true)
  {
  poortStatus=scanLPT();
  UpdateBYTES(poortStatus,S3,S6);
  opdrachten(S3,S6);
  Sleep(10); //om de 10 ms een scan uitvoeren

  // Process all pending messages
  while(PeekMessage(&l_Message, NULL, 0, 0, PM_REMOVE)) 
    { 
    TranslateMessage(&l_Message); 
    DispatchMessage(&l_Message); 
    } 
  }

Nadeel van deze aanpak is dat je geen enkele garantie hebt dat er iedere 10 seconden wordt gepold (event processing kan theoretisch minuten duren).

* curry684 had wat tijd over vanavond... O-)

Professionele website nodig?


Verwijderd

Topicstarter
Wow thanx, hier ben ik zeker wat mee.
'k zal dit vlug eens bestuderen.
_/-\o_

Verwijderd

Topicstarter
Nog een vraagje aan curry684:

Ik heb eerst methode2 geprobeerd (makkelijkste ;) ) , Nu deze is niet bruikbaar omdat de tijdsintervallen tussen de polls te groot zijn.

Nu porbeer ik methode 1 werkend te krijgen, maar dit is de 1ste keer dat ik van die Threads zou gebruiken in mijn progje.

Ik gebruik nu een Dialog Based Apllication.
Vanuit een apart venster (met klasse ChardwareControl)zou ik die poll lus met een knop druk willen uitvoeren en met een andere knop druk stoppen.
Waar voeg ik nu
HANDLE g_Thread;
HEVENT g_ThreadShutdown
toe?
In de header-file ??
Daar worden blijkbaar wat foutmeldingen gegeven.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je kunt natuurlijk ook de parameter van Sleep () omlaag brengen :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 14 March 2003 @ 11:30:
Ik heb eerst methode2 geprobeerd (makkelijkste ;) ) , Nu deze is niet bruikbaar omdat de tijdsintervallen tussen de polls te groot zijn.
Daarom zei ik: "Nadeel van deze aanpak is dat je geen enkele garantie hebt dat er iedere 10 milliseconden wordt gepold (event processing kan theoretisch minuten duren)." :)
Ik gebruik nu een Dialog Based Apllication.
Vanuit een apart venster (met klasse ChardwareControl)zou ik die poll lus met een knop druk willen uitvoeren en met een andere knop druk stoppen.
Waar voeg ik nu
HANDLE g_Thread;
HEVENT g_ThreadShutdown
toe?
In de header-file ??
Daar worden blijkbaar wat foutmeldingen gegeven.
In de headerfile instantieer je nooit dingen. For the sake of example had ik er globale variabelen van gemaakt, maar je dient ze netjes op te bergen op een correcte plek waar beide threads erbij kunnen. Je lijkt op dit moment nog bezig met C dus dan is niets mis met een globale variabele in je .c file :)

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 14 maart 2003 @ 11:30:
Ik heb eerst methode2 geprobeerd (makkelijkste ;) ) , Nu deze is niet bruikbaar omdat de tijdsintervallen tussen de polls te groot zijn.
Hoe belangrijk is die interval trouwens? Mag die ook 1 of 5ms zijn of moet ie altijd verplicht 10ms zijn?

Zo ja dan zul je de pollerthread op time critical priority moeten zetten, zo nee kun je gewoon zoals .oisyn zegt met de singlethreaded approach gaan en de Sleep veranderen in 1ms wait (dat zal resulteren in hoofdzakelijk delays van 1-10ms met sporadische peaks naar enkele tientallen ms).

Professionele website nodig?


Verwijderd

Topicstarter
Als ik dit in mijn .C zet krijg ik volgende melding:
code:
1
error C2501: 'HEVENT' : missing storage-class or type specifiers

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

heb je windows.h geinclude? :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Graag na de #include <windows.h> zetten :)

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 14 March 2003 @ 11:43:
[...]

Hoe belangrijk is die interval trouwens? Mag die ook 1 of 5ms zijn of moet ie altijd verplicht 10ms zijn?
.
Die timing is niet zo belangrijk. mag wat meer of minder zijn. Het is de bedoeling van een knopdruk (stijgende flank) op de lpt te detecteren. (Stijgende flank : eerste poll ingang laag, tweed poll ingang hoog.) (Knop is hardware matig ontdenderd.)

Verwijderd

Topicstarter
curry684 schreef op 14 March 2003 @ 11:46:
Graag na de #include <windows.h> zetten :)
Die stond er idd niet in, maar foutmelding blijft. :'(

Verwijderd

Topicstarter
code:
1
2
3
4
5
6
7
8
9
--------------------Configuration: Prog - Win32 Debug--------------------
Compiling...
hardwareControl.cpp
D:\: error C2146: syntax error : missing ';' before identifier 'g_ThreadShutdown'
D:\: error C2501: 'HEVENT' : missing storage-class or type specifiers
D:\: fatal error C1004: unexpected end of file found
Error executing cl.exe.

hardwareControl.obj - 3 error(s), 0 warning(s)

Deze meldingen krijg ik als ik
HANDLE g_Thread;
HEVENT g_ThreadShutdown;
invoeg in mijn .cpp file
Lijkt wel of ie HEVENT niet kent.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Eeps mijn totale excuses... find/replace HEVENT door HANDLE.

[mental note]
* curry684 schrijft code voor GoT-postings altijd in notepad of direct in de browser, nooit garantie dat het compileert dus ;)

[ Voor 54% gewijzigd door curry684 op 14-03-2003 12:19 ]

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 14 maart 2003 @ 11:43:
[...]
zo nee kun je gewoon zoals .oisyn zegt met de singlethreaded approach gaan en de Sleep veranderen in 1ms wait (dat zal resulteren in hoofdzakelijk delays van 1-10ms met sporadische peaks naar enkele tientallen ms).
Hoe implementeer ik dan die wait. Deze herkent ie niet (of typ ik weer verkeerd?)
code:
1
2
3
wait(10);
-> geeft volgende error:
: error C2065: 'wait' : undeclared identifier

of moet hier weer een bepaalde header geincluded worden. (windows.h is aanwezig)

[ Voor 4% gewijzigd door Verwijderd op 14-03-2003 12:22 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sleep aanroepen met 1 als argument natuurlijk

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 14 March 2003 @ 11:49:
Die timing is niet zo belangrijk. mag wat meer of minder zijn. Het is de bedoeling van een knopdruk (stijgende flank) op de lpt te detecteren. (Stijgende flank : eerste poll ingang laag, tweed poll ingang hoog.) (Knop is hardware matig ontdenderd.)
Sja we kunnen ook nog aan de botergeile singlethreaded variant met waitable timers beginnen, houd je vast :)
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
LARGE_INTEGER l_Timeout;

HANDLE l_Timer;
MSG    l_Message;  
BYTE   poortstatus; 
BYTE   S3[2];  // array om slechts iets uitgevoerd mag worden op stijgende flank. 
                    //moet van de vorm [0,1] zijn.  
BYTE   S6[2]; 

l_Timer            = CreateWaitableTimer(NULL, FALSE, NULL); 
l_Timeout.QuadPart = -10 * 10000;    // 10ms in 100ns intervals
while(true) 
  { 
  // Every iteration should last 10ms
  SetWaitableTimer(l_Timer, &l_Timeout, 0, NULL, NULL, FALSE);

  poortStatus=scanLPT(); 
  UpdateBYTES(poortStatus,S3,S6); 
  opdrachten(S3,S6); 

  // Process all pending messages 
  while(WaitForSingleObject(l_Timer, 0) == WAIT_TIMEOUT)
    {
    if(PeekMessage(&l_Message, NULL, 0, 0, PM_REMOVE))
      {  
      TranslateMessage(&l_Message);  
      DispatchMessage(&l_Message);  
      }  
    else
      {
      // All pending messages done, now wait for the timer
      WaitForSingleObject(l_Timer, INFINITE);
      break;
      }
    }
  }

Professionele website nodig?


Verwijderd

Topicstarter
.oisyn schreef op 14 March 2003 @ 12:35:
Sleep aanroepen met 1 als argument natuurlijk
|:( Dacht dat je een functie wait bedoelde. |:(

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Curry: is een MsgWaitForMultipleObjects () niet handiger? :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

.oisyn schreef op 14 maart 2003 @ 13:16:
Curry: is een MsgWaitForMultipleObjects () niet handiger? :)
True, maar ik probeerde het nog op een begrijpelijk niveau te houden.... :)

In ieder geval:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
HANDLE l_Timer; 
MSG    l_Message;   
BYTE   poortstatus;  
BYTE   S3[2];  // array om slechts iets uitgevoerd mag worden op
               // stijgende flank. moet van de vorm [0,1] zijn.   
BYTE   S6[2];  

l_Timer            = CreateWaitableTimer(NULL, FALSE, NULL);  
l_Timeout.QuadPart = -10 * 10000;    // 10ms in 100ns intervals 
while(true)  
  {  
  // Every iteration should last 10ms 
  SetWaitableTimer(l_Timer, &l_Timeout, 0, NULL, NULL, FALSE); 

  poortStatus=scanLPT();  
  UpdateBYTES(poortStatus,S3,S6);  
  opdrachten(S3,S6);  

  // Process all pending messages  
  while(MsgWaitForMultipleObjects(1, &l_Timer,
                    FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0 + 1)
    { 
    if(PeekMessage(&l_Message, NULL, 0, 0, PM_REMOVE)) 
      {   
      TranslateMessage(&l_Message);   
      DispatchMessage(&l_Message);   
      }   
    } 
  }

* curry684 mag weer eens met z'n threadjes en eventjes spelen :Y)

[ Voor 4% gewijzigd door curry684 op 14-03-2003 13:59 . Reden: layout ]

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 14 March 2003 @ 13:51:
[...]
True, maar ik probeerde het nog op een begrijpelijk niveau te houden.... :)
Voor mensen met minder programeer ervaring. (Zoals mezelf) :)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 14 March 2003 @ 13:55:
[...]

Voor mensen met minder programeer ervaring. (Zoals mezelf) :)
Die ervaring krijg je vanzelf als je de 5 of zo wild verschillende varianten die ik tot nu toe heb gepost minutieus gaat analyseren :)

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 14 March 2003 @ 12:53:
[...]

Sja we kunnen ook nog aan de botergeile singlethreaded variant met waitable timers beginnen, houd je vast :)
Jihaaa, dit is wat ik wilde. THX _/-\o_

en het werkt nog ook. :*)

Bedankt voor de assistentie.
Nogmaals _/-\o_

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 14 March 2003 @ 14:06:
Jihaaa, dit is wat ik wilde. THX _/-\o_

en het werkt nog ook. :*)

Bedankt voor de assistentie.
Nogmaals _/-\o_
Zet maar een credit in je sourcecode/documentatie/verslag O-)

btw. waitable timers werken niet onder Win95, wel onder WinME/98/NT/2k/XP, even onthouden dus.

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 14 maart 2003 @ 14:09:
[...]
Zet maar een credit in je sourcecode/documentatie/verslag O-)
Zal ik zeker doen.
btw. waitable timers werken niet onder Win95, wel onder WinME/98/NT/2k/XP, even onthouden dus.
OK, bedankt voor de tip. De toepassing moet onder Win98SE draaien, dus dat zal wel lukken.
THX
Pagina: 1