Python:"while"太慢了,实际执行时sleep(0.25)变成了sleep(3)
Python: "while" is too slow, and sleep(0.25) becomes sleep(3) in actual execution
我是 运行 Python Raspberry Pi 3 上的程序,我想每 0.25 秒从 DS18B20 传感器记录一次温度。
早些时候,当程序很简单并在 shell 上显示温度时,它非常快并且没有问题。不幸的是,由于程序本身现在包括记录到一个文件,我每 2 秒或 3 秒就会收到一个日志。
如何确保 0.25 秒的记录间隔。
我已经分享了下面的代码:
#This program logs temperature from DS18B20 and records it
#Plots the temperature-time plot.
import os
import sys
#import matplotlib.pyplot as plt
from re import findall
from time import sleep, strftime, time
from datetime import *
#plt.ion()
#x = []
#y = []
ds18b20 = ''
def setup():
global ds18b20
for i in os.listdir('/sys/bus/w1/devices'):
if i != 'w1_bus_master1':
ds18b20 = i
# Reads temperature data from the Temp sensor
# This needs to be modified for use with max31855 and K-type thermocouples
def read():
# global ds18b20
location = '/sys/bus/w1/devices/' + ds18b20 + '/w1_slave'
tfile = open(location)
text = tfile.read()
tfile.close()
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = temperature / 1000
return temperature
#Loop for logging - sleep, and interrupt to be configured.
def loop():
while True:
if read() != None:
print "Current temperature : %0.3f C" % read()
#sleep(0.25)
func()
def write_temp(temperature,file_name):
with open(file_name, 'a') as log:
log.write("{0},{1}\n".format(datetime.now().strftime("%d-%m-%Y %H:%M:%S"),str(temperature)))
arg = sys.argv[1]
filename1 = str(arg) + "-" + datetime.now().strftime("%d-%m-%Y-%H-%M-%S")+".csv"
def func():
temperature = read()
#sleep(0.25)
write_temp(temperature,filename1)
#graph(temperature)
#For plotting graph using MatPlotLib
#Comment out this function during foundry trials to avoid system slowdown
#Check system resource usage and slowdown using TOP or HTOP
#def graph(temperature):
# y.append(temperature)
# x.append(time())
# plt.clf()
# plt.scatter(x,y)
# plt.plot(x,y)
# plt.draw()
#Interrupt from command-line
def destroy():
pass
if __name__ == '__main__':
try:
setup()
func()
loop()
except KeyboardInterrupt:
destroy()
我已经注释掉了我认为占用大量资源的部分,但我仍然无法管理少于 2 秒的任何内容。我得到的结果如下:
输出:
27-09-2016 12:18:41,23.0
27-09-2016 12:18:43,23.062
27-09-2016 12:18:46,23.125
27-09-2016 12:18:48,23.187
27-09-2016 12:18:50,23.187
27-09-2016 12:18:53,23.562
27-09-2016 12:18:55,25.875
27-09-2016 12:18:58,27.187
27-09-2016 12:19:00,27.5
- 只打开一次日志文件(并在程序退出时将其关闭)
- 不要总是重新读取传感器的温度。你打电话给
read()
太频繁了。
- 减少一般开销并简化您的调用。
我无法完全测试这个,但像这样的东西可以工作:
import os
import sys
import time
from datetime import datetime
def read_temp(dev):
'''Reads temperature from sensor and returns it as float.'''
loc = '/sys/bus/w1/devices/' + dev + '/w1_slave'
with open(loc) as tf:
return float(tf.read().split('\n')[1].split(' ')[9][2:]) / 1000.0
def write_temp(t, logfile):
'''Writes temperature as .3 float to open file handle.'''
logfile.write('{0},{1:.3f}\n'.format(datetime.now().strftime('%d-%m-%Y %H:%M:%S'), t))
def loop(dev, logfile):
'''Starts temperature logging until user interrupts.'''
while True:
t = read_temp(dev)
if t:
write_temp(t, logfile)
print('Current temperature: {0:.3f} °C'.format(t))
sys.stdout.flush() # Flush. Btw, print is time-consuming!
time.sleep(.25)
if __name__ == '__main__':
# Take the first match for a device that is not 'w1_bus_master1'
dev = [d for d in os.listdir('/sys/bus/w1/devices') if d != 'w1_bus_master1'][0]
# Prepare the log filename
fname = str(sys.argv[1]) + "-" + datetime.now().strftime("%d-%m-%Y-%H-%M-%S")+".csv"
# Immediately open the log in append mode and do not close it!
logfile = open(fname, 'a')
try:
# Only pass device and file handle, not the file name.
loop(dev, logfile)
except KeyboardInterrupt:
# Close log file on exit
logfile.close()
我是 运行 Python Raspberry Pi 3 上的程序,我想每 0.25 秒从 DS18B20 传感器记录一次温度。
早些时候,当程序很简单并在 shell 上显示温度时,它非常快并且没有问题。不幸的是,由于程序本身现在包括记录到一个文件,我每 2 秒或 3 秒就会收到一个日志。
如何确保 0.25 秒的记录间隔。
我已经分享了下面的代码:
#This program logs temperature from DS18B20 and records it
#Plots the temperature-time plot.
import os
import sys
#import matplotlib.pyplot as plt
from re import findall
from time import sleep, strftime, time
from datetime import *
#plt.ion()
#x = []
#y = []
ds18b20 = ''
def setup():
global ds18b20
for i in os.listdir('/sys/bus/w1/devices'):
if i != 'w1_bus_master1':
ds18b20 = i
# Reads temperature data from the Temp sensor
# This needs to be modified for use with max31855 and K-type thermocouples
def read():
# global ds18b20
location = '/sys/bus/w1/devices/' + ds18b20 + '/w1_slave'
tfile = open(location)
text = tfile.read()
tfile.close()
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = temperature / 1000
return temperature
#Loop for logging - sleep, and interrupt to be configured.
def loop():
while True:
if read() != None:
print "Current temperature : %0.3f C" % read()
#sleep(0.25)
func()
def write_temp(temperature,file_name):
with open(file_name, 'a') as log:
log.write("{0},{1}\n".format(datetime.now().strftime("%d-%m-%Y %H:%M:%S"),str(temperature)))
arg = sys.argv[1]
filename1 = str(arg) + "-" + datetime.now().strftime("%d-%m-%Y-%H-%M-%S")+".csv"
def func():
temperature = read()
#sleep(0.25)
write_temp(temperature,filename1)
#graph(temperature)
#For plotting graph using MatPlotLib
#Comment out this function during foundry trials to avoid system slowdown
#Check system resource usage and slowdown using TOP or HTOP
#def graph(temperature):
# y.append(temperature)
# x.append(time())
# plt.clf()
# plt.scatter(x,y)
# plt.plot(x,y)
# plt.draw()
#Interrupt from command-line
def destroy():
pass
if __name__ == '__main__':
try:
setup()
func()
loop()
except KeyboardInterrupt:
destroy()
我已经注释掉了我认为占用大量资源的部分,但我仍然无法管理少于 2 秒的任何内容。我得到的结果如下:
输出:
27-09-2016 12:18:41,23.0
27-09-2016 12:18:43,23.062
27-09-2016 12:18:46,23.125
27-09-2016 12:18:48,23.187
27-09-2016 12:18:50,23.187
27-09-2016 12:18:53,23.562
27-09-2016 12:18:55,25.875
27-09-2016 12:18:58,27.187
27-09-2016 12:19:00,27.5
- 只打开一次日志文件(并在程序退出时将其关闭)
- 不要总是重新读取传感器的温度。你打电话给
read()
太频繁了。 - 减少一般开销并简化您的调用。
我无法完全测试这个,但像这样的东西可以工作:
import os
import sys
import time
from datetime import datetime
def read_temp(dev):
'''Reads temperature from sensor and returns it as float.'''
loc = '/sys/bus/w1/devices/' + dev + '/w1_slave'
with open(loc) as tf:
return float(tf.read().split('\n')[1].split(' ')[9][2:]) / 1000.0
def write_temp(t, logfile):
'''Writes temperature as .3 float to open file handle.'''
logfile.write('{0},{1:.3f}\n'.format(datetime.now().strftime('%d-%m-%Y %H:%M:%S'), t))
def loop(dev, logfile):
'''Starts temperature logging until user interrupts.'''
while True:
t = read_temp(dev)
if t:
write_temp(t, logfile)
print('Current temperature: {0:.3f} °C'.format(t))
sys.stdout.flush() # Flush. Btw, print is time-consuming!
time.sleep(.25)
if __name__ == '__main__':
# Take the first match for a device that is not 'w1_bus_master1'
dev = [d for d in os.listdir('/sys/bus/w1/devices') if d != 'w1_bus_master1'][0]
# Prepare the log filename
fname = str(sys.argv[1]) + "-" + datetime.now().strftime("%d-%m-%Y-%H-%M-%S")+".csv"
# Immediately open the log in append mode and do not close it!
logfile = open(fname, 'a')
try:
# Only pass device and file handle, not the file name.
loop(dev, logfile)
except KeyboardInterrupt:
# Close log file on exit
logfile.close()