2015-07-20 207 views
1

我寫了一個腳本來從儀器中讀取數據並將數據寫入CSV文件。每次採樣之間的時間間隔可以由用戶設置。一秒採樣率很常見。我使用了time.sleep,並嘗試使用timeElapsed = timeEnd - timeBegin提取腳本的處理時間。問題是這不夠好。時間在流逝,所以不時有劇本跳過一秒鐘。在我的電腦上,它大約每2-3分鐘發生一次。所以我的問題是如何提高時間的準確性。每秒運行while循環

import csv 
import datetime 
import time 
import os.path 

no_of_meas = 200 
cur_meas = 1 
time_interval= 1 #time between each sample given in seconds, 1 second is the lowest recommended value 

with open('test.csv', 'a', newline='') as fp: 
    while cur_meas <= no_of_meas: 
     timeBegin = time.time() 
     cur_time = datetime.datetime.strftime(datetime.datetime.now(), '%H:%M:%S.%f') 
     a = csv.writer(fp, delimiter='\t') 
     data = [[cur_time, cur_meas]] 
     a.writerows(data) 
     fp.flush() #flush and os.fsync to be sure that data is written to disk 
     os.fsync(fp.fileno()) 
     print(', '.join(map(str, data))) 
     cur_meas += 1 
     timeEnd = time.time() 
     timeElapsed = timeEnd - timeBegin 
     time.sleep(time_inter-timeElapsed) 
+3

而不是睡覺,檢查當前時間是否大於或等於一段時間;這樣,錯誤不能累積。 –

+0

我認爲這是你想要的:http://stackoverflow.com/a/13151104/3881403 –

回答

0

由於您正在創建一個稍微關閉的新時間表,因此不應在每次調用時重置您的基準時間。您必須從全球時間基準上進行計算。你需要使用浮點數來確保Python不會做任何整數舍入。

就相關部分:

interval = 1.0 
start_time = time.time() 

with open('test.csv', 'a', newline='') as fp: 
    while cur_meas <= no_of_meas: 
     next_in = (start_time + (cur_meas - 1.0) * interval) - time.time() 
     if next_in > 0.0: 
      time.sleep(next_in) 
     # your measuring code. 

這樣,當電流測量所預期的,睡在那之前或立即繼續當已經達到時間的代碼將計算。

+0

謝謝你這個作品真的很好。我已經在兩臺電腦上運行了腳本,大約有62000個樣本,我沒有錯過任何一秒鐘,也沒有跳過任何秒鐘。 –

0

您需要將延遲基於實際時間而不是每次迭代延遲。以下是處理它的一種可能的替代方式,它不會長時間漂移,但會使用更多的CPU。

import time 

def tick(time_interval): 
    next_tick = time.time() + time_interval 
    while True: 
     time.sleep(0.2)  # Minimum delay to allow for catch up 
     while time.time() < next_tick: 
      time.sleep(0.2) 

     yield True 
     next_tick += time_interval 

time_interval = 1.0 
ticker = tick(time_interval) 

while cur_meas <= no_of_meas: 
    # Do measurement code 
    next(ticker) 

個別迭代將到下一個0.2s(或者你需要的罰款)。如果迭代延遲(例如,CPU負載),這將允許每隔0.2秒「追趕」,直到時間再次同步。

+0

這不適合我。我可能是因爲錯誤輸入了一些內容,但時間卻跳了很多。有些時候,我每秒鐘得到2-3個樣本,有時甚至會跳過一兩個樣本。 –

+0

您可以再次複製/粘貼,我發佈了一小段時間後做了一些修改。只有腳本凍結一秒鐘以上纔會出現2-3個樣本,它會每隔0.2秒打勾一次,直到抓住爲止。 –

+0

現在效果更好。它每秒採樣一次,準確度似乎相當不錯。 –