Python 如何从文件中读取字符串,将其转换为int,将值存储在内存中,然后访问值并在屏幕上打印?
我需要使用Raspberry Pi 3和Python读取DS18B20传感器的温度读数。 问题是传感器的刷新率(~1秒) 我需要从sys/bus/w1/devices/28-041670f43bff/w1_从机读取数据,并使用我得到的整数在直接连接到GPIO的7段显示器上显示温度(不使用任何硬件多路复用-i2c…等) 为了显示两位数的温度,我需要非常快地打开和关闭数字(比传感器刷新更快) 这是用于获取整数温度的一小段代码:Python 如何从文件中读取字符串,将其转换为int,将值存储在内存中,然后访问值并在屏幕上打印?,python,sensors,temperature,Python,Sensors,Temperature,我需要使用Raspberry Pi 3和Python读取DS18B20传感器的温度读数。 问题是传感器的刷新率(~1秒) 我需要从sys/bus/w1/devices/28-041670f43bff/w1_从机读取数据,并使用我得到的整数在直接连接到GPIO的7段显示器上显示温度(不使用任何硬件多路复用-i2c…等) 为了显示两位数的温度,我需要非常快地打开和关闭数字(比传感器刷新更快) 这是用于获取整数温度的一小段代码: def temperature(): with open ("/
def temperature():
with open ("/sys/bus/w1/devices/28-041670f43bff/w1_slave") as q:
r=q.read()
temp=r[69:71]
t=int (temp)
return t
但我需要每秒多次调用此函数,以便在7段显示器上获得良好的显示效果
我是这样想的:
#the temperature() function returns a two digit int
while True:
GPIO.output(31,0)
GPIO.output(temp[temperature()/10], 1) # temp is a dictionary used to know which segments to light up to show numbers
time.sleep(0.0005)
GPIO.output(31,1)
GPIO.output(37,0)
GPIO.output(temp[temperature()%10], 1)
time.sleep(0.0005)
GPIO.output(37,1)
但是这个代码只会使一个数字亮起,等等~1秒,亮起另一个数字,等等~1秒……等等
任何关于如何实现这一点的想法都是非常受欢迎的。与其自己实现这一功能,不如使用解决这一特定代码的库。在这种情况下,我建议您使用传感器。您可以在以下位置找到文档: 您可以使用以下方式进行安装:
pip install w1thermsensor
它确实支持DS18B20,并且在自述文件中提供了与您的用例的精确模拟
从包的文档中:
from w1thermsensor import W1ThermSensor
sensor = W1ThermSensor()
temperature_in_celsius = sensor.get_temperature()
temperature_in_fahrenheit = sensor.get_temperature(W1ThermSensor.DEGREES_F)
temperature_in_all_units = sensor.get_temperatures([
W1ThermSensor.DEGREES_C,
W1ThermSensor.DEGREES_F,
W1ThermSensor.KELVIN
])
在许多情况下,特别是对于流行的硬件设备,您会发现python中已经有了可用的库,这将使您能够快速编写适合自己特殊需要的代码
注:根据以下链接中的技术讨论,如果DS18B20设置为12位温度分辨率,温度转换将需要750毫秒,或3/4秒。如果将硬件设置为9位分辨率,则硬件中的转换时间为93.75毫秒。我怀疑这是每秒一次问题的根源
在这个问题中有一些关于这个问题的讨论:
有关configDS18B20实用程序,请参阅第二个答案
分辨率设置为9位时,您可以调整源代码中的w1thermsensor
重试延迟\u秒
/重试\u尝试
值组合,并获得所需的值。我不清楚重试延迟是否对设备的实际轮询有任何影响。看起来它是用来查找设备的。不过,正如我所说,这个时间间隔可能会影响对单个设备的轮询。我只是没有充分阅读源代码,看它何时何地发挥作用
新年快乐 您不应该自己实现此功能,而应该使用解决代码中这一特定部分的库。在这种情况下,我建议您使用传感器。您可以在以下位置找到文档: 您可以使用以下方式进行安装:
pip install w1thermsensor
它确实支持DS18B20,并且在自述文件中提供了与您的用例的精确模拟
从包的文档中:
from w1thermsensor import W1ThermSensor
sensor = W1ThermSensor()
temperature_in_celsius = sensor.get_temperature()
temperature_in_fahrenheit = sensor.get_temperature(W1ThermSensor.DEGREES_F)
temperature_in_all_units = sensor.get_temperatures([
W1ThermSensor.DEGREES_C,
W1ThermSensor.DEGREES_F,
W1ThermSensor.KELVIN
])
在许多情况下,特别是对于流行的硬件设备,您会发现python中已经有了可用的库,这将使您能够快速编写适合自己特殊需要的代码
注:根据以下链接中的技术讨论,如果DS18B20设置为12位温度分辨率,温度转换将需要750毫秒,或3/4秒。如果将硬件设置为9位分辨率,则硬件中的转换时间为93.75毫秒。我怀疑这是每秒一次问题的根源
在这个问题中有一些关于这个问题的讨论:
有关configDS18B20实用程序,请参阅第二个答案
分辨率设置为9位时,您可以调整源代码中的w1thermsensor
重试延迟\u秒
/重试\u尝试
值组合,并获得所需的值。我不清楚重试延迟是否对设备的实际轮询有任何影响。看起来它是用来查找设备的。不过,正如我所说,这个时间间隔可能会影响对单个设备的轮询。我只是没有充分阅读源代码,看它何时何地发挥作用
新年快乐 我会将显示例程放入自己的线程中,这样您就不必在主循环中考虑它了。下面的代码应该演示这个概念。将“testing”设置为False,以查看它是否与您的硬件一起工作
#!/usr/bin/python
import time
import threading
import Queue
import random
# Set this to False to read the temperature from a real sensor and display it on a 7-digit display.
testing = True
def temperature_read(q):
# Read the temperature at one second intervals.
while True:
if testing:
r = '-' * 69 + '%02d' % (random.randrange(100)) + 'blahblah' * 4
else:
r = open('/sys/bus/w1/devices/28-041670f43bff/w1_slave', 'r').read()
print r
# The temperature is represented as two digits in a long string.
# Push the digits into the queue as a tuple of integers (one per digit).
q.put((int(r[69]), int(r[70])))
# Wait for next reading.
# (Will w1_slave block until the next reading? If so, this could be eliminated.)
time.sleep(1.0)
def temperature_display(q):
# Display the temperature.
# Temperature is two digits, stored separately (high/low) for more efficient handling.
temperature_h = temperature_l = 0
while True:
# Is there a new temperature reading waiting for us?
if not q.empty():
temperature = q.get()
# If it's None, we're done.
if temperature is None:
break
# Load the two digits (high and low) representing the temperature.
(temperature_h, temperature_l) = temperature
if testing:
print 'displayH', temperature_h
time.sleep(0.05)
print 'displayL', temperature_l
time.sleep(0.05)
else:
GPIO.output(31,0)
GPIO.output(temperature_h, 1) # temp is a dictionary used to know which segments to light up to show numbers
time.sleep(0.0005)
GPIO.output(31,1)
GPIO.output(37,0)
GPIO.output(temperature_l, 1)
time.sleep(0.0005)
GPIO.output(37,1)
# Clean up here. Turn off all pins?
# Make a queue to communicate with the display thread.
temperature_queue = Queue.Queue()
# Run the display in a separate thread.
temperature_display_thread = threading.Thread(target=temperature_display, args=(temperature_queue,))
temperature_display_thread.start()
# Run the reader.
try:
temperature_read(temperature_queue)
except:
# An uncaught exception happened. (It could be a keyboard interrupt.)
None
# Tell the display thread to stop.
temperature_queue.put(None)
# Wait for the thread to end.
temperature_display_thread.join()
为了支持另一个读取(传输),我只是将它放在读取循环中,而不是为它添加另一个线程。我更改了队列以便您可以轻松地将其移动到另一个线程,但我怀疑您会添加更多输入,因此这可能是一种合理的方法,除非一个线程的读取频率需要有很大的不同。(即使这样,也可以在循环中使用计数器进行操作。)
这是一个版本,每十次只读取一次温度,但每次读取传输。我想你会看到如何轻松地调整它以满足你的需要
我会为每个阅读器创建单独的线程,但这会使线程管理相当复杂
#!/usr/bin/python
import time
import threading
import Queue
import random
# Set this to False to read the temperature from a real sensor and display it on a 7-digit display.
testing = True
def observe(q):
count = 0
while True:
# Only read the temperature every tenth time.
if (count % 10 == 0):
# Make a temperature reading.
if testing:
r = '-' * 69 + '%02d' % (random.randrange(100)) + 'blahblah' * 4
else:
r = open('/sys/bus/w1/devices/28-041670f43bff/w1_slave', 'r').read()
print 'temperature ->', r
# The temperature is represented as two digits in a long string.
# Push the digits into the queue as a tuple of integers (one per digit).
q.put(('temperature', int(r[69]), int(r[70])))
# Make a transmission reading.
if testing:
r = random.randrange(1,6)
else:
r = 0 # Put your transmission reading code here.
print 'transmission ->', r
q.put(('transmission', r))
# Wait for next reading.
if testing:
time.sleep(0.5)
else:
time.sleep(0.1)
count += 1
def display(q):
# Display the temperature.
# Temperature is two digits, stored separately (high/low) for more efficient handling.
temperature_h = temperature_l = transmission = 0
while True:
# Is there a new temperature reading waiting for us?
if not q.empty():
reading = q.get()
# If it's None, we're done.
if reading is None:
break
elif reading[0] == 'temperature':
# Load the two digits (high and low) representing the temperature.
(x, temperature_h, temperature_l) = reading
elif reading[0] == 'transmission':
(x, transmission) = reading
if testing:
print 'displayH', temperature_h
time.sleep(0.05)
print 'displayL', temperature_l
time.sleep(0.05)
print 'transmission', transmission
time.sleep(0.05)
else:
GPIO.output(31,0)
GPIO.output(temperature_h, 1) # temp is a dictionary used to know which segments to light up to show numbers
time.sleep(0.0005)
GPIO.output(31,1)
GPIO.output(37,0)
GPIO.output(temperature_l, 1)
time.sleep(0.0005)
GPIO.output(37,1)
# Clean up here. Turn off all pins?
# Make a queue to communicate with the display thread.
readings_queue = Queue.Queue()
# Run the display in a separate thread.
display_thread = threading.Thread(target=display, args=(readings_queue,))
display_thread.start()
# Observe the inputs.
try:
observe(readings_queue)
except:
# An uncaught exception happened. (It could be a keyboard interrupt.)
None
# Tell the display thread to stop.
readings_queue.put(None)
# Wait for the thread to end.
display_thread.join()
我会将显示例程放入它自己的线程中,这样您就不必在主循环中考虑它。下面的代码应该演示这个概念。将“testing”设置为False,以查看它是否与您的硬件一起工作
#!/usr/bin/python
import time
import threading
import Queue
import random
# Set this to False to read the temperature from a real sensor and display it on a 7-digit display.
testing = True
def temperature_read(q):
# Read the temperature at one second intervals.
while True:
if testing:
r = '-' * 69 + '%02d' % (random.randrange(100)) + 'blahblah' * 4
else:
r = open('/sys/bus/w1/devices/28-041670f43bff/w1_slave', 'r').read()
print r
# The temperature is represented as two digits in a long string.
# Push the digits into the queue as a tuple of integers (one per digit).
q.put((int(r[69]), int(r[70])))
# Wait for next reading.
# (Will w1_slave block until the next reading? If so, this could be eliminated.)
time.sleep(1.0)
def temperature_display(q):
# Display the temperature.
# Temperature is two digits, stored separately (high/low) for more efficient handling.
temperature_h = temperature_l = 0
while True:
# Is there a new temperature reading waiting for us?
if not q.empty():
temperature = q.get()
# If it's None, we're done.
if temperature is None:
break
# Load the two digits (high and low) representing the temperature.
(temperature_h, temperature_l) = temperature
if testing:
print 'displayH', temperature_h
time.sleep(0.05)
print 'displayL', temperature_l
time.sleep(0.05)
else:
GPIO.output(31,0)
GPIO.output(temperature_h, 1) # temp is a dictionary used to know which segments to light up to show numbers
time.sleep(0.0005)
GPIO.output(31,1)
GPIO.output(37,0)
GPIO.output(temperature_l, 1)
time.sleep(0.0005)
GPIO.output(37,1)
# Clean up here. Turn off all pins?
# Make a queue to communicate with the display thread.
temperature_queue = Queue.Queue()
# Run the display in a separate thread.
temperature_display_thread = threading.Thread(target=temperature_display, args=(temperature_queue,))
temperature_display_thread.start()
# Run the reader.
try:
temperature_read(temperature_queue)
except:
# An uncaught exception happened. (It could be a keyboard interrupt.)
None
# Tell the display thread to stop.
temperature_queue.put(None)
# Wait for the thread to end.
temperature_display_thread.join()
为了支持另一个读取(传输),我只是将它放在读取循环中,而不是为它添加另一个线程。我更改了队列以便您可以轻松地将其移动到另一个线程,但我怀疑您会添加更多输入,因此这可能是一种合理的方法,除非一个线程的读取频率需要有很大的不同。(即使在那时,