主要采用RS485通讯
1、风速采集
首先要查询传感器在主机上的端口号和波特率(正常为4800),代码如下:
port_list = list(serial.tools.list_ports.comports())
if len(port_list) == 0:
print("无可用串口!")
else:
for i in range(0, len(port_list)):
print(port_list[i])
port_num = 'COM' + input('Port Number = COM:')
根据端口返回的二进制代码转换成十六进制代码,转成十进制,最后根据产品说明书量程数据转换成正常风速
在根据风力等级表转成对应的风力等级
全部代码
import serial
import time
import serial.tools.list_ports
def wind_speed():
temp_send = '01 03 00 00 00 02 C4 0B'
ser = serial.Serial(port_num, 4800)
# 发送的数据转为2进制b'\x01\x03\x00\x00\x00\x02\xc4\x0b'
temp_send = bytes.fromhex(temp_send)
#print(temp_send)
while True:
if ser.is_open:
#print('port open ok')
ser.write(temp_send)
time.sleep(1)
# 获取返回的缓冲data,获取的是buffer_data的长度 9
buffer_data = ser.in_waiting
#print(buffer_data, 'buffer_data')
if buffer_data:
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
return_data = ser.read(buffer_data)
#print('返回的数据2进制:', return_data)
# 二进制转换为16进制:010304010802307b79
return_data_hex = str(return_data.hex())
#print('返回的数据转换为16进制:', return_data_hex)
# 对返回的数据进行解析,16进制转成10进制
wind_speed = int(return_data_hex[6:10], 16)/10
local_time = time.localtime()
now_time = time.strftime("%Y/%m/%d %H:%M:%S", local_time)
with open('D:\\风速.txt', 'a',encoding='utf-8') as file:
##with open('D:\\desktop\\python_study\\python_exe\\电流信号处理\\风速.txt', 'a',encoding='utf-8') as file:
if wind_speed <= 0.3:
file.write(str(now_time))
file.write('\t无风,风速为:')
file.write(str(wind_speed))
file.write('m/s\n')
print(now_time,'\t','无风', wind_speed, 'm/s')
elif 0.3 <= wind_speed <=1.5:
file.write(str(now_time))
file.write('\t一级软风,风速为:')
file.write(str(wind_speed))
file.write('m/s\n')
print(now_time,'\t','1级软风', wind_speed, 'm/s')
elif 1.6 <= wind_speed <=3.3:
file.write(str(now_time))
file.write('\t二级软风,风速为:')
file.write(str(wind_speed))
file.write('m/s\n')
print(now_time, '\t', '2级软风', wind_speed, 'm/s')
elif 3.4 <= wind_speed <=5.4:
file.write(str(now_time))
file.write('\t三级微风,风速为:')
file.write(str(wind_speed))
file.write('m/s\n')
print(now_time, '\t', '3级微风', wind_speed, 'm/s')
elif 5.5 <= wind_speed <=7.9:
file.write(str(now_time))
file.write('\t四级和风,风速为:')
file.write(str(wind_speed))
file.write('m/s\n')
print(now_time, '\t', '4级和风', wind_speed, 'm/s')
elif 8.0 <= wind_speed <=10.7:
print(now_time, '\t', '5级清劲风', wind_speed, 'm/s')
elif 10.8 <= wind_speed <=13.8:
print(now_time, '\t', '6级强风', wind_speed, 'm/s')
elif 13.9 <= wind_speed <=17.1:
print(now_time, '\t', '7级疾风', wind_speed, 'm/s')
elif 17.2 <= wind_speed <=20.7:
print(now_time, '\t', '8级大风', wind_speed, 'm/s')
elif 20.8 <= wind_speed <=24.4:
print(now_time, '\t', '9级烈风', wind_speed, 'm/s')
time.sleep(1)
if __name__ == '__main__':
port_list = list(serial.tools.list_ports.comports())
if len(port_list) == 0:
print("无可用串口!")
else:
for i in range(0, len(port_list)):
print(port_list[i])
port_num = 'COM' + input('Port Number = COM:')
wind_speed()
2、风向采集
跟风速采集类似,要先对准北方,然后根据旋转角度得出风向
全部代码:
import serial
import time
temp_send = '01 03 00 00 00 02 C4 0B'
Port_number = input('请输入端口号(COM5/COM6/COM7):')
ser = serial.Serial(Port_number, 4800)
# 发送的数据转为2进制b'\x01\x03\x00\x00\x00\x02\xc4\x0b'
temp_send = bytes.fromhex(temp_send)
#print(temp_send)
while True:
if ser.is_open:
#print('port open ok')
ser.write(temp_send)
time.sleep(1)
# 获取返回的缓冲data,获取的是buffer_data的长度 9
buffer_data = ser.in_waiting
#print(buffer_data, 'buffer_data')
if buffer_data:
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
return_data = ser.read(buffer_data)
#print('返回的数据2进制:', return_data)
# 二进制转换为16进制:010304010802307b79
return_data_hex = str(return_data.hex())
#print('返回的数据转换为16进制:', return_data_hex)
# 对返回的数据进行解析,16进制转成10进制
wind_direction = int(return_data_hex[6:10], 16)
local_time = time.localtime()
now_time = time.strftime("%Y/%m/%d %H:%M:%S", local_time)
if wind_direction == 0:
print(now_time, '\t', '北风')
elif wind_direction == 1:
print(now_time, '\t', '东北风')
elif wind_direction == 2:
print(now_time, '\t', '东风')
elif wind_direction == 3:
print(now_time, '\t', '东南风')
elif wind_direction == 4:
print(now_time, '\t', '南风')
elif wind_direction == 5:
print(now_time, '\t', '西南风')
elif wind_direction == 6:
print(now_time, '\t', '西风')
elif wind_direction == 7:
print(now_time, '\t', '西北风')
time.sleep(2)
3、温湿度采集
代码
#!/usr/bin/env python
import RPi.GPIO as GPIO
import numpy as np
import time
DHTPIN = 17 # 引脚号17
GPIO.setmode(GPIO.BCM) # 以BCM编码格式
def read_dht11_dat():
GPIO.setup(DHTPIN, GPIO.OUT)
GPIO.output(DHTPIN, GPIO.LOW)
# 给信号提示传感器开始工作,并保持低电平18ms以上
time.sleep(0.02) # 这里保持20ms
GPIO.output(DHTPIN, GPIO.HIGH) # 然后输出高电平
GPIO.setup(DHTPIN, GPIO.IN)
# 发送完开始信号后得把输出模式换成输入模式,不然信号线上电平始终被拉高
while GPIO.input(DHTPIN) == GPIO.LOW:
continue
# DHT11发出应答信号,输出 80 微秒的低电平
while GPIO.input(DHTPIN) == GPIO.HIGH:
continue
# 紧接着输出 80 微秒的高电平通知外设准备接收数据
# 开始接收数据
j = 0 # 计数器
data = [] # 收到的二进制数据
kk = [] # 存放每次高电平结束后的k值的列表
while j < 40:
k = 0
while GPIO.input(DHTPIN) == GPIO.LOW: # 先是 50 微秒的低电平
continue
while GPIO.input(DHTPIN) == GPIO.HIGH: # 接着是26-28微秒的高电平,或者 70 微秒的高电平
k += 1
if k > 100:
break
kk.append(k)
if k < 8: # 26-28 微秒时高电平时通常k等于5或6
data.append(0) # 在数据列表后面添加一位新的二进制数据“0”
else: # 70 微秒时高电平时通常k等于17或18
data.append(1) # 在数据列表后面添加一位新的二进制数据“1”
j += 1
print("sensor is working.")
print('初始数据高低电平:\n', data ) # 输出初始数据高低电平
print('参数k的列表内容:\n', kk ) # 输出高电平结束后的k值
m = np.logspace(7, 0, 8, base=2, dtype=int) # logspace()函数用于创建一个于等比数列的数组
# 即[128 64 32 16 8 4 2 1],8位二进制数各位的权值
data_array = np.array(data) # 将data列表转换为数组
# dot()函数对于两个一维的数组,计算的是这两个数组对应下标元素的乘积和(数学上称之为内积)
humidity = m.dot(data_array[0:8]) # 用前8位二进制数据计算湿度的十进制值
humidity_point = m.dot(data_array[8:16])
temperature = m.dot(data_array[16:24])
temperature_point = m.dot(data_array[24:32])
check = m.dot(data_array[32:40])
print(humidity, humidity_point, temperature, temperature_point, check)
tmp = humidity + humidity_point + temperature + temperature_point
# 十进制的数据相加
if check == tmp: # 数据校验,相等则输出
return humidity, temperature
else: # 错误输出错误信息
return False
def main():
print("Raspberry Pi DHT11 Temperature test program\n")
time.sleep(1) # 通电后前一秒状态不稳定,时延一秒
while True:
result = read_dht11_dat()
if result:
humidity, temperature = result
print("humidity: %s %%, Temperature: %s ℃" % \
(humidity, temperature))
print('\n')
time.sleep(1)
if result == False:
print("Data are wrong,skip\n")
time.sleep(1)
def destroy():
GPIO.cleanup()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
destroy()