Hej har en for loop som skall läsa av ett i/o kort som sitter i datorn. Mitt problem är att jag vill läsa av kortet ca 20 gånger så att jag får ett medelvärde men kortet hinner inte med . Har provat med sleep men när man sätter sleep (1) så blir det inte en millisekund Det går att lösa ganska fult, med en waiting-loop. Det kommer ta upp datorns kapacitet under tiden. Annars ska det finnas någon sleep-funktion i WinAPI. Sök på "sleep winapi" på google, så hittar du nog något. Testa detta enkla trix. Som jag har förstått det behöver man använda QueryPerformanceCounter för att få så bra upplösning. Kör på tekniken i Niklas andra exempel men med QueryPerformanceCounter istället. Se http://support.microsoft.com/kb/q172338/ för mer info. QueryPerformanceCounter Igen Vad är det för I/O kort eller vad är det för sorts värde den tar reda på? Kortet är ett Advanthech pci 1711 finns på elfa Ok på det då förstår jag. Som du har skrivit kommer du ju inte åt resultatet. Det kommer inte att funka därför att x Om det är ett antal pulser så borde det väl vara ett heltal du får från FrequencyValue? Hur gick det sedan ? Jag hittade en funtion till kortet få en loop att räkna långsammare
Private Sub ScanTimer_Timer()
Dim x As Double
Dim i As Integer
Dim buffer As Double
buffer = 0
For i = 1 To 20
x = DAQCounter1.FrequencyValue 'Läser av i/o kort
buffer = buffer + x
Next i
x = buffer / i
End SubSv: få en loop att räkna långsammare
Waiting loop ser ut som:
<code>
for i = 1 to 20
...
for j=1 to wait_iterations
x=x 'meningslös operation för att få tiden att gå
next j
next i
</code>
Eller, för mer kontroll:
<code>
for i = 1 to 20
...
t = timer
do while (timer-t)<minimum_time
x=x 'meningslös operation för att få tiden att gå
loop
next i
</code>Sv:få en loop att räkna långsammare
Om inte detta funkar så får du använda 2 Timer:s .
Hur lång tid tror du behövs för att läsa 20 gånger och få kortet att svara korrekt ?
Testa detta först. Sen en annan sak du bör ha X Global så du kan läsa av den
utan för Timern.
<code>
Private Sub ScanTimer_Timer()
Dim x As Double
Dim i As Long
Dim buffer As Double
buffer = 0
For i = 1 To 20
x = DAQCounter1.FrequencyValue 'Läser av i/o kort
buffer = buffer + x
DoEvents
Next i
x = buffer / i
MsgBox x
End Sub
</code>
Vad har du för värde på ScanTimer Interval ?Sv: få en loop att räkna långsammare
/JohanSv:få en loop att räkna långsammare
Mmmm. det kan kanske vara något, men det är inte helt lätt att se vad han skall läsa av.
Skrev ett tips om detta för några år sedan.
[QueryPerformanceCounter]
Men det verkar som han vill göra saker långsammare, QueryPerformanceCounter
är till för att gör snabba avläsningar.Hans For Loop verkar gå för fort.
Tror fortfarande att ett vanligt DoEvent hjälper honom.
Alternativ kör en Timer som loop ex. Timer.Interval = 100 då kan han Scanna 20 ggr ~ 2 sek. Sv: få en loop att räkna långsammare
roade mig med att spåna kring ditt problem.Så här skulle du också kunna testa.
<code>
Sub ScanTimer_Timer()
Dim x As Double
Dim i As Long
Dim buffer As Double
buffer = 0
For i = 1 To 20
x = DAQCounter1.FrequencyValue 'Läser av i/o kort
Do Until x <> 0
DoEvents
Loop
buffer = buffer + x
x = 0
Next i
x = buffer / i
MsgBox x
End Sub
</code>
Sen måste jag tycka att konstruktionen är lite konstigt.Hur plockar du ut svaret
Dvs x i x= buffer/i som iofs borde vara x = buffer\i
Och ! Varför ligger koden i en TimerSv: få en loop att räkna långsammare
DAQCounter1.FrequencyValue
Låter som någon sorts frekvensvärde från en räknare?
Innehåller FrequencyValue räknade pulser?
I så fall hur ofta uppdateras det värdet?
Nollställs FrequencyValue när värdet läses av?
Är det så att du vill summera 20 mätvärden och dividera det med tiden under vilket dessa togs?
Sv:få en loop att räkna långsammare
Jag har en pulsgivare Heidenhain ROD 426 1500 pulser/varv
Jag vill läsa av pulsgivaren ca 5 gånger /sek men värdet ska vara medelvärde av 20 mätningar pga vissa störningar Sv:få en loop att räkna långsammare
Då bör det räcka med min lösning med DoEvents i Forsatsen.
<code>
For i = 1 To 20
x = DAQCounter1.FrequencyValue 'Läser av i/o kort
buffer = buffer + x
DoEvents
Next i
</code>
Eller ?Sv: få en loop att räkna långsammare
är en Lokal variabel i ScanTimer som du inte når från utsidan.
Vill att du testar båda dessa varianter. DVS visa resultatet i en Label.
<code>
Private Sub ScanTimer_Timer()
Dim x As Double
Dim i As Long
Dim buffer As Double
buffer = 0
For i = 1 To 20
x = DAQCounter1.FrequencyValue 'Läser av i/o kort
buffer = buffer + x
Next i
Label1.Caption = buffer \ i
DoEvents
End Sub
</code>
Eller om inte det funkar
<code>
Private Sub ScanTimer_Timer()
Dim x As Double
Dim i As Long
Dim buffer As Double
buffer = 0
For i = 1 To 20
x = DAQCounter1.FrequencyValue 'Läser av i/o kort
buffer = buffer + x
DoEvents
Next i
Label1.Caption = buffer \ i
DoEvents
End Sub
</code>
Jag tror att exempel 1 kommer att funka. Sv: få en loop att räkna långsammare
En enkel lösning är att använda en listbox. Du får då oxå se historik:
Private Sub ScanTimer_Timer()
Dim sum As Double
Dim index As Long
Dim Value As Double
Value = DAQCounter1.FrequencyValue 'Läser av i/o kort
List1.AddItem Value
List1.ItemData(List1.NewIndex) = Value
List1.TopIndex = List1.NewIndex
Do While (List1.ListCount > MaxItems)
List1.RemoveItem 0
Loop
For index = 0 To List1.ListCount - 1
sum = sum + List1.ItemData(index)
Next
Label1.Caption = FormatNumber(sum / List1.ListCount, 2)
End Sub
Annars kan du använda en array:
Private Const MaxItems As Long = 20
Private ItemsSum As Long
Private ItemsStart As Long
Private ItemsCount As Long
Private Items(MaxItems) As Double
Private Sub ScanTimer_Timer()
Dim Avg As Double
Dim Value As Double
Value = DAQCounter1.FrequencyValue 'Läser av i/o kort
Avg = Process(Value)
Label1.Caption = FormatNumber(Avg, 2)
End Sub
Private Function Process(Value As Double) As Double
Dim index As Long
If ItemsCount = MaxItems Then
index = ItemsStart
ItemsSum = ItemsSum - Items(ItemsStart)
ItemsStart = (ItemsStart + 1) Mod MaxItems
Else
index = ItemsCount
ItemsCount = ItemsCount + 1
End If
Items(index) = Value
ItemsSum = ItemsSum + Value
Process = ItemsSum / ItemsCount
End Function
Sv:få en loop att räkna långsammare
Skulle vara klädsamt med lite FeedBackSv: få en loop att räkna långsammare
gatePeriod så jag behövde bara sätta den på 20 ms sä lästes pulsgivaren under 20 ms.
så då funkade det