在rPi3B+;上使用100%CPU的简单python脚本;
我有raspberry pi型号3b+和HC-SR04超声波距离传感器(还有一对ds18b20和一对DHT21,但我认为它们与我的问题无关) 我已经找到了一个python脚本,可以从中进行测量,并根据我的需要对其进行了修改——主要是进行几次时间跨度的读取,从中取一个平均值,将值映射到0到100之间,作为百分比,并将其提交到grafana和domoticz的inflow数据库 守则:在rPi3B+;上使用100%CPU的简单python脚本;,python,raspberry-pi,Python,Raspberry Pi,我有raspberry pi型号3b+和HC-SR04超声波距离传感器(还有一对ds18b20和一对DHT21,但我认为它们与我的问题无关) 我已经找到了一个python脚本,可以从中进行测量,并根据我的需要对其进行了修改——主要是进行几次时间跨度的读取,从中取一个平均值,将值映射到0到100之间,作为百分比,并将其提交到grafana和domoticz的inflow数据库 守则: #source: https://tutorials-raspberrypi.com/raspberry-pi-u
#source: https://tutorials-raspberrypi.com/raspberry-pi-ultrasonic-sensor-hc-sr04/
#Libraries
import RPi.GPIO as GPIO
import time
from influxdb import InfluxDBClient
import sys
# https://www.domoticz.com/wiki/Domoticz_API/JSON_URL%27s#Python
import requests
client = InfluxDBClient(database='pellet')
series = []
#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)
#set GPIO Pins
GPIO_TRIGGER = 23
GPIO_ECHO = 22
#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
def distance():
# set Trigger to HIGH
GPIO.output(GPIO_TRIGGER, True)
# set Trigger after 0.01ms to LOW
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
StartTime = time.time()
StopTime = time.time()
# save StartTime
while GPIO.input(GPIO_ECHO) == 0:
StartTime = time.time()
# save time of arrival
while GPIO.input(GPIO_ECHO) == 1:
StopTime = time.time()
# time difference between start and arrival
TimeElapsed = StopTime - StartTime
# multiply with the sonic speed (34300 cm/s)
# and divide by 2, because there and back
distance = (TimeElapsed * 34300) / 2
return distance
def pellet(dist):
# zmierzona odleglosc
# dist = distance()
# do zmierzenia poziom maksymalny
# 63 - do pokrywy
in_min = 63
# do zmierzenia poziom minimalny
in_max = in_min + 100
#wyjscie jako procent, od 0 do 100
out_min = 100
out_max = 0
# map z arduino: https://www.arduino.cc/reference/en/language/functions/math/map/
return (dist - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
def loop():
# nie wiecej jak 200 iteracji
loop = 200
# suma
total = 0
# tabelka z pojedynczmi wynikami
measurements = []
# liczba pomiarow do zrobienia
counter = 10
counter1 = 0
# czas pomiedzy pomiarami
sleep =30
#
while loop > 0:
loop -= 1
time.sleep(sleep)
# koniec, jesli wykonano liczbe pomiarow
if counter == 0:
#print(total/10)
return pellet(total/10), measurements
break
if loop == 0 and counter1 != 0:
return pellet(total/counter1), measurements
break
if loop == 0 and (counter1 == 0 or total == 0):
GPIO.cleanup()
sys.exit()
dist = distance()
# jesli wynik jest zly
if dist < 63 or dist > 163:
print("nie ok")
continue
counter -= 1
measurements.append(dist)
counter1 += 1
total += dist
print("total po ",counter1 , "sek: ", total, "dist: ", dist)
print(total/10)
#return total/10
if __name__ == '__main__':
try:
#dist = distance()
#print ("Measured Distance = %.1f cm" % dist)
#print (pellet(dist))
loop=loop()
print("avg :", loop[0])
#print("measurs :", loop[1])
#print("test :", loop[1][2])
if (1):
point = {
"measurement": "pellet",
"tags": {
"location": "piwnica",
"type": "hc-sr04"
},
"fields": {
"value": loop[0],
"raw_measurement1": loop[1][0],
"raw_measurement2": loop[1][1],
"raw_measurement3": loop[1][2],
"raw_measurement4": loop[1][3],
"raw_measurement5": loop[1][4],
"raw_measurement6": loop[1][5],
"raw_measurement7": loop[1][6],
"raw_measurement8": loop[1][7],
"raw_measurement9": loop[1][8],
"raw_measurement10": loop[1][9]
}
}
series.append(point)
client.write_points(series)
url = 'http://localhost:8080/json.htm?type=command¶m=udevice&nvalue=0&idx=13&svalue='+str(loop[0])
r = requests.get(url)
GPIO.cleanup()
# Reset by pressing CTRL + C
except KeyboardInterrupt:
print("Measurement stopped by User")
GPIO.cleanup()
#来源:https://tutorials-raspberrypi.com/raspberry-pi-ultrasonic-sensor-hc-sr04/
#图书馆
将RPi.GPIO导入为GPIO
导入时间
从influxdb导入InfluxDBClient
导入系统
# https://www.domoticz.com/wiki/Domoticz_API/JSON_URL%27s#Python
导入请求
client=InfluxDBClient(数据库='pellet')
系列=[]
#GPIO模式(板/车身控制模块)
GPIO.setmode(GPIO.BCM)
#设置GPIO引脚
GPIO_触发器=23
GPIO_回波=22
#设置GPIO方向(输入/输出)
GPIO.setup(GPIO_触发器,GPIO.OUT)
GPIO.setup(GPIO_ECHO,GPIO.IN)
定义距离():
#将触发器设置为高
输出(GPIO_触发器,真)
#将0.01毫秒后的触发器设置为低
睡眠时间(0.00001)
GPIO.output(GPIO_触发器,False)
StartTime=time.time()
StopTime=time.time()
#节省启动时间
当GPIO.input(GPIO_回波)==0时:
StartTime=time.time()
#节省到达时间
当GPIO.input(GPIO_回波)==1时:
StopTime=time.time()
#开始和到达之间的时差
时间经过=停止时间-开始时间
#乘以声速(34300厘米/秒)
#除以2,因为这里和后面
距离=(经过的时间*34300)/2
返回距离
def颗粒(距离):
#奥德莱格洛斯兹米尔佐纳酒店
#距离=距离()
#多兹米尔泽尼亚·波齐奥姆·马克西马尔尼
#63-do pokrywy
in_min=63
#zmierzenia poziom Minimanny酒店
英寸最大值=英寸最小值+100
#wyjscie jako procent,od 0 do 100
out_min=100
out_max=0
#z arduino地图:https://www.arduino.cc/reference/en/language/functions/math/map/
返回(距离输入最小值)*(输出最大值-输出最小值)/(输入最大值-输入最小值)+输出最小值;
def loop():
#nie wiecej jak 200 iteracji
循环=200
#苏玛
总数=0
#tabelka z pojedynczmi wynikami
测量值=[]
#里兹巴·波米罗·多兹罗比尼亚酒店
计数器=10
计数器1=0
#波米亚拉米
睡眠=30
#
当循环>0时:
循环-=1
时间。睡眠(睡眠)
#科尼克,杰斯利·维科纳诺·利茨贝·波米亚罗
如果计数器==0:
#打印(总计/10)
返回弹丸(总数/10),测量值
打破
如果循环==0且计数器为1!=0:
返回弹丸(总数/计数器1),测量值
打破
如果循环==0且(计数器1==0或总计==0):
GPIO.cleanup()
sys.exit()
距离=距离()
#jesli wynik jest zly
如果dist<63或dist>163:
打印(“nie ok”)
持续
计数器-=1
测量值。附加(dist)
计数器1+=1
总+=距离
打印(“采购订单总额”,计数器1,“瑞典克朗:”,总计,“地区:”,地区)
打印(总计/10)
#返回总数/10
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
尝试:
#距离=距离()
#打印(“测量距离=%.1f厘米”%dist)
#印刷品(颗粒(区))
loop=loop()
打印(“平均值:”,循环[0])
#打印(“测量:”,循环[1])
#打印(“测试:”,循环[1][2])
如果(1):
点={
“测量”:“颗粒”,
“标签”:{
“地点”:“小鱼”,
“类型”:“hc-sr04”
},
“字段”:{
“值”:循环[0],
“原始测量1”:循环[1][0],
“原始测量2”:循环[1][1],
“原始测量3”:循环[1][2],
“原始测量4”:循环[1][3],
“原始测量5”:循环[1][4],
“原始测量6”:循环[1][5],
“原始测量7”:循环[1][6],
“原始测量8”:循环[1][7],
“原始测量9”:循环[1][8],
“原始测量10”:循环[1][9]
}
}
系列。附加(点)
客户端。写入点(系列)
url='1〕http://localhost:8080/json.htm?type=command¶m=udevice&nvalue=0&idx=13&svalue='+str(循环[0])
r=请求。获取(url)
GPIO.cleanup()
#按CTRL+C键重置
除键盘中断外:
打印(“用户停止测量”)
GPIO.cleanup()
问题是我注意到CPU温度曲线图升高,有许多短的谷值达到了大约正确的温度
当我使用ssh连接到pi并运行htop时,我发现这个脚本使用了100%的cpu
但最奇怪的是,从昨天开始,脚本每15分钟在crontab中运行一次,从14:30开始,从今天11:00左右开始提高CPU温度
我不是开发人员或程序员,我只是从网络上复制代码,所以我不知道这是否是代码的一部分(但为什么在21小时后?),或者是什么,为什么,以及如何调试和修复它
所以这不仅仅是环境问题,因为圆周率在阁楼上,大约5到10度
谢谢您的帮助。这里:
while GPIO.input(GPIO_ECHO) == 0:
StartTime = time.time()
这句话不停地说:“如果pin为0,请节省时间,如果pin为0,请节省时间,如果pin为…”。每次检查后,您都需要等待一段时间
while GPIO.input(GPIO_ECHO) == 0:
time.sleep(0.001) # 1 ms
StartTime = time.time()
检查本身可能需要~us,因此这将减少99%的CPU使用率。您可能希望对pin==1的情况执行相同的操作,具体取决于您需要的时间准确性。此处:
while GPIO.input(GPIO_ECHO) == 0:
StartTime = time.time()
这句话不停地说:“如果pin为0,请节省时间,如果pin为0,请节省时间,如果pin为…”。每次检查后,您都需要等待一段时间
while GPIO.input(GPIO_ECHO) == 0:
time.sleep(0.001) # 1 ms
StartTime = time.time()
检查本身可能需要~us,因此这将减少C
def distance():
MAX_READ_ATTEMPTS = 10000 #this is a random value I chose. You will need to fine-tune it based on actual hardware performance
# set Trigger to HIGH
GPIO.output(GPIO_TRIGGER, True)
# set Trigger after 0.01ms to LOW
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
# lets not have any unneeded code here, just in case
# save StartTime
while GPIO.input(GPIO_ECHO) == 0 and retry_counter < MAX_READ_ATTEMPTS:
retry_counter += 1
StartTime = time.time()
# maximum number of retries reached, returning with error condition
if retry_counter == MAX_READ_ATTEMPTS:
return -1
reatry_counter = 0
# save time of arrival
while GPIO.input(GPIO_ECHO) == 1 and retry_counter < MAX_READ_ATTEMPTS:
retry_counter += 1
StopTime = time.time()
# maximum number of retries reached, returning with error condition
if retry_counter == MAX_READ_ATTEMPTS:
return -1
# time difference between start and arrival
TimeElapsed = StopTime - StartTime
# multiply with the sonic speed (34300 cm/s)
# and divide by 2, because there and back
distance = (TimeElapsed * 34300) / 2
return distance