'''
oled温湿度报警,
可手动设定警戒值的报警装置,可以用于一些特定环境的温湿度控制
可以自己设定间隔时间
可以通过串口进行最高最低温度的设置等,省的设置一堆按钮显得乱
'''
from machine import Pin,PWM,I2C,Timer,UART
import time,machine,ssd1306,dht
uart1=UART(1,115200) #调用串口uart1
uart1.init(115200,bits=8,parity=None,stop=1) #初始化相关参数
Tim_S=Timer(0) #定时器对象,很怪,有了这个定时器,下面的蜂鸣器没有了短促的鸣叫。。。。。
key=Pin(27, Pin.OUT)
Buzzer= PWM(key) #定义蜂鸣器
Buzzer.duty(0) #控制蜂鸣器初始关闭状态
global data
data = dht.DHT22(Pin(15)) #实例化15号管脚,21被占用了
i2c = I2C(0, scl=Pin(22), sda=Pin(21)) #对应管脚
oled_width = 128
oled_height = 64 #画幅大小
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c) #调用,设置像素大小
i=0
space=3000 #默认三秒,可修改但是要为整型
point=['','.','..','...'] #动态表示在工作
Warn_tem_Max=29.0
Warn_tem_Min=26.0 #可修改为浮点型
Warn_hum_Max=60.0
Warn_hum_Min=40.0
L_Blue=Pin(2,Pin.OUT) #内置小灯,判断状态,命令设置成功闪亮
def Voice_On(): #开启调用
Buzzer.duty(512) #占空比
Buzzer.freq(2000) #频率
time.sleep(0.5)
Buzzer.duty(0)
time.sleep(0.5)
def Voice_Off(): #关闭调用
Buzzer.duty(0) #蜂鸣器关闭
def Open_Test(t):
data.measure() #先调用测量函数,获取温湿度
global temp
temp=data.temperature()
global humi
humi=data.humidity()
def max_or_min():
global tem_Max
global tem_Min
global hum_Max
global hum_Min
if int(temp)>tem_Max:
tem_Max=int(temp)
if int(temp)<tem_Min:
tem_Min=int(temp)
if int(humi)>hum_Max:
hum_Max=int(humi)
if int(humi)<tem_Max:
hum_Min=int(humi)
def Print():
global i
oled.text('Temp:'+str(temp), 0, 12)
oled.text('Max:'+str(tem_Max), 0, 26) #空一段,最大最小
oled.text('Min:'+str(tem_Min), 64, 26)
oled.text('Humi:'+str(humi), 0,40)
oled.text('Max:'+str(hum_Max), 0, 57)
oled.text('Min:'+str(hum_Min), 64, 57)
oled.text('working'+point[i%4], 25, 0)
oled.show()
time.sleep(0.2)
oled.fill(0)
i=i+1
def Is_Int(Dir): #异常处理。整型
try:
int(Dir)
return True
except ValueError:
pass
def Is_Float(Dir): #异常处理。浮点型
try:
float(Dir)
return True
except ValueError:
pass
def twink():
L_Blue.value(1)
time.sleep(0.5)
L_Blue.value(0)
time.sleep(0.5)
L_Blue.value(1)
time.sleep(0.5)
L_Blue.value(0)
time.sleep(0.5)
oled.fill(0) #清屏
oled.text('Welcome!', 10, 10) #欢迎界面
oled.show()
time.sleep(0.5)
oled.fill(0) #清屏
Open_Test(0) #先调用,才能全局改变下面的变量
Tim_S.init(period=space,mode=Timer.PERIODIC,callback=Open_Test)
#效果是到定义的时间就调用函数收集一下数据,但是程序依然在运行,到主函数后会因为未到指定时间
#而不启用收集函数,导致主函数出错,所以需要在定时器之前先调用一下函数,
#还有种办法,可以通过延时来达到等待函数运行后再去显示数据,但是因为后续会有自定义收集间隔
#所以如果通过延时来处理还需要让延时时间变量与间隔相同
#time.sleep(n)
tem_Max=int(temp) #控制空间,整数,大概
tem_Min=int(temp)
hum_Max=int(humi)
hum_Min=int(humi)
#主程序负责数据的对比,定时器外部中断优先,保障间隔的准确
while True: #循环获取温湿度
if Warn_tem_Min<temp<Warn_tem_Max and Warn_hum_Min<humi<Warn_hum_Max:
Voice_Off()
else:
Voice_On()
max_or_min()
Print()
#大概有几个口令:警报最大最小温度,湿度;采集时间间隔就这五个,
#注意判断类型,命令或类型不正确的不予理会,设置成功有闪灯提醒
if uart1.any()>0: #考虑放在定时器中,因为循环内很难监测到
Dir=uart1.read()
Dir=str(Dir) #转换为字符串型
#Dir=Dir.lower(),字符小写就涉及到回车的问题,无法转变,会异常,所以我可以提前切出来想要的部分
Dir=Dir[2:-3] #提前切掉b'...\n'这个东西,在让这个正常的字符串去变小写
if Dir.find('space')>=0:
Dir=Dir[5:]
if Is_Int(Dir)==True:
space=int(Dir)
Tim_S.init(period=space,mode=Timer.PERIODIC,callback=Open_Test)
twink()
elif Dir.find('tmax')>=0:
Dir=Dir[4:]
if Is_Float(Dir)==True:
Warn_tem_Max=float(Dir)
twink()
elif Dir.find('tmin')>=0:
Dir=Dir[4:]
if Is_Float(Dir)==True:
Warn_tem_Min=float(Dir)
twink()
elif Dir.find('hmax')>=0:
Dir=Dir[4:]
if Is_Float(Dir)==True:
Warn_hum_Max=float(Dir)
twink()
elif Dir.find('hmin')>=0:
Dir=Dir[4:]
if Is_Float(Dir)==True:
Warn_hum_Min=float(Dir)
twink()
#串口这部分也可以考虑写成函数,看起来能简洁些