如何从文件中读取字符串,将其转换为int,将值存储在内存中,然后访问该值并将其打印在屏幕上?
我需要使用Raspberry Pi 3和Python从DS18B20传感器读取温度读数。 问题是传感器(〜1秒) 我需要从sys/bus/w1/devices/28-041670f43bff/w1_slave
阅读和使用整数i得到显示直接连接到我的GPIO(不使用任何硬件复用的7段显示器上的温度的刷新速率 - I2C ....等)如何从文件中读取字符串,将其转换为int,将值存储在内存中,然后访问该值并将其打印在屏幕上?
为了显示一个两位数温度,我需要打开和关闭位真快(小于传感器刷新更快)
这用于小片的代码得到整数温度:
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秒〜.....等等上。
的如何做到这一点任何想法非常赞赏。
我会把显示程序放到它自己的线程中,这样你就不必在主循环中考虑它了。下面的代码应该证明这个概念。将“测试”设置为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):
while True:
# 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.
# (Will w1_slave block until the next reading? If so, this could be eliminated.)
time.sleep(1.0)
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()
这里有一个版本,只读取温度每第十次,但每一次读取传输。我想你会看到如何轻松调整这个来满足你的需求。
我会为每个读者制作单独的线程,但它会使线程管理变得复杂一些。
#!/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()
是的。这正是我所需要的。温度更新并正确显示。谢谢 –
你能告诉我如何添加另一个线程?我有另一段代码,就像一个齿轮(卡丁车换档)指示器(1 ... 2 ... 3 ... 4 ... 5 ... 4..3..etc),我想要与此同时在相同的4位7段显示器上运行。再次感谢你。 –
我在这里新来的,所以我不知道如果我这样做的权利... 我添加了传输到我的答案的代码。那样有用吗? –
而不是实现你自己的这个功能,你应该使用的库,在那里,地址代码的特定位本身。在这种情况下,我建议你使用W1ThermSensor。你可以找到的文档:
,您可以使用安装它:
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
])
在许多情况下,特别是对于流行的硬件设备,你会发现,目前已经提供给蟒蛇内使用库,并且将所有你快速继续写下你自己特定需求的独特代码。
注:根据以下链接的技术讨论,如果DS18B20设置为12位温度分辨率,温度转换将花费750毫秒或3/4秒。如果您将硬件设置为9位分辨率,则硬件中的转换时间为93.75毫秒。我怀疑这是你每秒一次的问题的根源。
https://www.maximintegrated.com/en/app-notes/index.mvp/id/4377
没有在这个问题上这个问题的一些讨论:
https://raspberrypi.stackexchange.com/questions/14278/how-to-change-ds18b20-reading-resolution
见第二个答案,关于configDS18B20效用。
设置为9位分辨率,你可以能够调整在源代码中的
w1thermsensor
RETRY_DELAY_SECONDS
/RETRY_ATTEMPTS
值组合,并得到你所需要的。我不清楚重试延迟是否会影响设备的实际轮询。它看起来像是在那里寻找设备。虽然,正如我所说的那样,间隔可能会影响轮询单个设备的。我只是没有仔细阅读源代码,看看它在什么时间和地点发挥作用。
新年快乐!
非常感谢你的这个想法。我将使用这个包。但是这个功能每秒钟左右只能显示一次温度。 –
@PinteaMihaita查看我更新的答案。你可以通过改变硬件本身的温度分辨率来解决这个问题,但是通过在你的软件中进行任何操作,不会改变硬件配置,你看起来不会比1秒更新好得多。即使如此,目前还不清楚这是否会有所帮助,根据我上面提到的来自raspberrypi.stackexchange.com的回答。不过,这是你最好的选择。祝你好运! –
谢谢。也会试图做到这一点。也许我可以更好地提高速度。谢谢 –
这是关于读取温度或运行GPIO的问题吗?关于读取温度FAST以运行GPIO的 –
。 –
我怀疑它是如此缓慢。你有计时吗?如果速度慢,你可以在每次读取前保持文件打开并寻找(0),但如果速度更快,我会感到惊讶。我问你是否有时间吗? –