/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Præcision af _sleep() timeren og bittest?
Fra : Kasper Vibe Grevsen


Dato : 15-12-01 17:05

Hejsa,

til styring af en saftevandsautomat har jeg lavet følgende delayløkke i
Visual C++:

// #includes og #defines ikke med i denne kodesnip

#define Noedstop_L 16 // bit nummer 5
const int interval=10, saftTid=300; // saftTid 300
millisekunder
DigitalOutput( SAFT+VAND ); // Åbner ventiler
for( int i=0; i<saftTid/interval; ++i) // Delay saftTid +
overhead
{
_sleep(interval);
if( !(DigitalInput() & Noedstop_L) ) // Hvis nødstop aktiveres
fastholdes løkken
--i; // så
påfyldning kan genoptages. Ventiler lukkes aut.
// af
nødstop HW.
}
DigitalOutput( 0 ); // Lukker
ventiler


Hver indgang på i/o-kortet svarer til en bit ud af otte, der læses samtidigt
med DigitalInput().
Hvis jeg forstår det ret vil !(DigitalInput() & Noedstop_L) kun være sandt,
når Noedstop_L er aktiv (lav)?

Mit andet spørgsmål går på præcissionen af _sleep() kaldet. Jeg har læst at
mange timere bruger BIOSs 55 ms tick, men gælder det også for sleep-timeren?
Altså skal jeg sætte interval = 55/n for at få bedst præcision?
Jeg ved godt at overhead i løkken, accesstid på kortet og reaktionstid på
ventilerne sætter en grænse, men det kan jo ligesågodt blive bedst muligt.


mvh.
Kasper


---
Denne mail er kontrolleret for virus med AVG. Sidst opdateret 4/12-01.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.307 / Virus Database: 168 - Release Date: 11-12-01



 
 
Martin Dyring (16-12-2001)
Kommentar
Fra : Martin Dyring


Dato : 16-12-01 14:42

"Kasper Vibe Grevsen" <kaspervg@mail1.stofanet.dk_> wrote in message
news:3c1b74d7$0$333$ba624c82@nntp02.dk.telia.net...
> Hejsa,
>
> til styring af en saftevandsautomat har jeg lavet følgende delayløkke i
> Visual C++:

[snip]

> Hver indgang på i/o-kortet svarer til en bit ud af otte, der læses
samtidigt
> med DigitalInput().
> Hvis jeg forstår det ret vil !(DigitalInput() & Noedstop_L) kun være
sandt,
> når Noedstop_L er aktiv (lav)?

Hvis nødstoppet er "omvendt" (dvs. inaktivt når bit 5 er høj på input og
aktivt når den er lav) så er det korrekt.

> Mit andet spørgsmål går på præcissionen af _sleep() kaldet. Jeg har læst
at
> mange timere bruger BIOSs 55 ms tick, men gælder det også for
sleep-timeren?
> Altså skal jeg sætte interval = 55/n for at få bedst præcision?
> Jeg ved godt at overhead i løkken, accesstid på kortet og reaktionstid på
> ventilerne sætter en grænse, men det kan jo ligesågodt blive bedst muligt.

Nu er saftvand jo ikke en eksakt videnskab :) - men jeg vil foreslå du
kigger på QueryPerformanceFrequency og QueryPerformanceCounter hvis du har
brug for mere præcision. Såfremt den maskine du afvikler på ikke skal bruges
til så meget andet vil jeg foreslå du laver en løkke der busy-looper vha.
Q.P.Counter istedet for at bruge noget Sleep()-lignende. Med Sleep() kan du
næsten være helt sikker på at din tråd opgiver sit timeslice og regner med
at kernen vækker den engang. På den måde vil du mister en del præcision i
din timing (med mindre du sætter din tråd til at køre med
realtime-prioritet).

--
Mvh,
Martin Dyring



Dragon (05-01-2002)
Kommentar
Fra : Dragon


Dato : 05-01-02 02:00

Hej Martin, tak for dit svar. Min computer led desværre en total
nedsmeltning så derfor skriver jeg først igen nu ;-(

> > til styring af en saftevandsautomat har jeg lavet følgende delayløkke i
> > Visual C++:

> Hvis nødstoppet er "omvendt" (dvs. inaktivt når bit 5 er høj på input og
> aktivt når den er lav) så er det korrekt.
>
Ja, det er derfor signalet hedder Noedstop_L og ikke bare Noedstop. Vi fik
heldigvis det hele til at virke så det var lækkert.

> > Mit andet spørgsmål går på præcissionen af _sleep() kaldet.
>
> Nu er saftvand jo ikke en eksakt videnskab :) - men jeg vil foreslå du
> kigger på QueryPerformanceFrequency og QueryPerformanceCounter
> hvis du har brug for mere præcision.

Ok, jeg endte med at nøjes med _sleep() loopet, men for sjovs skyld målte
jeg eksekveringstiden ved 60 udførsler af 4000 ms delayet og 60 udførsler af
et 800 ms loop. Alle lå indenfor -0,01% til 0,23% hhv. -0,01% til 0,70%.

konstruktionen var noget a la
get RDTSCstarttid
for-loop x 20
{ for loop x 80 hhv. 400
{ _sleep(10);
if( DigitalInput()&0 ) //Betingelse altid falsk
--i;
}
get RDTSCsluttid
}

En ting jeg undrede mig over var at første udførelse af yderste for-loop tog
0,23% hhv. 0,70% længere tid end de følgende, men det må skyldes at
instruktionerne ligger i cachen derefter.

Endelig dividerede jeg det gennemsnitlige antal clockcycli for 4000 ms
delayet med antallet for 800 ms loopet og fik en faktor 5,0013584, hvilket
var rigelig præcist til vores krav om +/-10% af påfyldningsvolumin.


mvh
Kasper



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste