综合案例2.0-智能风扇
最新案例教程点击下方链接跳转,CSDN已停止更新
点
击
跳
转
简介
日常生活中,我们经常需要一些通过风扇降温的场景,比如说机房,电脑主机等等。人为的去打开或者关闭风扇,调节档位,操作起来不是很方便。本案例通过一个温度传感器实时的采集当前温度,然后依据温度值,动态调节风扇速度。
本案例通过一个温度传感器实时采集当前温度,然后依据温度值,动态的调节风扇的转速和开关,同时我们可以通过手机app实时的控制风扇转速所对应的温度档位,实现对风扇的远程控制,既能方便我们控制风扇,也能有效的节能,绿色环保。
AHT10温湿度传感器
- 模块说明
产品型号 | AHT10 |
---|---|
供电电压 | 1.8-3.6V(DC) |
测量范围(湿度) | 0~99.9%RH |
测量范围(温度) | -40~+85℃ |
湿度精度 | ±2%RH(25℃) |
温度精度 | ±0.3℃ |
分辨率 | 温度:0.1℃,湿度:0.1%RH |
输出信号 | I2C信号 |
电机模块
这类模块集成了驱动芯片,我们不必分开购买马达、扇叶和L9110模块。通过PWM脉冲宽度来调节电机转速。
电机上有四个接口:
-
VCC:电源正极,接树莓派的 5V 接口。
-
GND:电源负极,接树莓派任意一个 GND 口。
-
INA 和 INB :两个控制口。驱动的核心就落在两个输入引脚上。
INA 为高电平,INB 为低电平时——正转; INA 为低电平,INB 为高电平时——反转。 单独只接其中一个接口也能控制
准备
本案例需要的硬件
器材 | 数量 |
---|---|
HaaS506开发板 | 1 |
AHT10温湿度传感器 | 1 |
电机模块 | 1 |
SIM卡 | 1 |
杜邦线 | 若干 |
硬件连接图
代码流程
1、连接阿里云平台。
2、开机上传一次内置的温度阈值,并持续读取并上传当前温湿度传感器读取的温度数值
3、设置云端回调,接收来自云端的数据,更改程序中的判断数值
功能实现
1、物联网平台开发
第一次使用物联网平台的读者,需要开通实例后使用物联网平台功能。也可以使用免费的公共实例进行开发,在阿里云物联网平台中,左上角选择‘华东2-上海’,点击‘公共实例’,即可开通。
1、平台产品创建可参考haas506 2.0开发教程-aliyunIoT
2、创建产品属性(添加物模型)
- 选择产品功能定义–编辑草稿
- 添加自定义功能
- 添加标识符与数据类型(标识符要与代码一致)
- 点击发布上线
- 点击确定
2、设备端开发
-
第一次使用开发板的读者可以按照haas5062.0开发教程-导学篇搭建开发环境。
-
搭建完后复制以下代码到Visual Studio Code,复制产品证书到代码相应位置。
-
2.2版本获取IMEI号接口有更新,需要更改以下内容(Ctrl+F 查找modem)
# 获取设备的IMEI 作为deviceName 进行动态注册
deviceName = modem.info.getDevImei()
...
- main.py
# coding=utf-8
from ahtx0 import AHT10
from driver import PWM
import network
import ujson
import utime as time
import modem
from aliyunIoT import Device
import kv
# 警报开关以及时间段控制
gear1_temp = 22
gear2_temp = 27
gear3_temp = 32
FLAG_CUR_TEMP = "temp"
FLAG_GEAR1 = "gear1"
FLAG_GEAR2 = "gear2"
FLAG_GEAR3 = "gear3"
cur_gear = 0
#当iot设备连接到物联网平台的时候触发'connect' 事件
def on_connect(data):
global module_name,default_ver,productKey,deviceName,deviceSecret,on_trigger,on_download,on_verify,on_upgrade
print('***** connect lp succeed****')
data_handle = {}
data_handle['device_handle'] = device.getDeviceHandle()
#当连接断开时,触发'disconnect'事件
def on_disconnect():
print('linkkit is disconnected')
#当iot云端下发属性设置时,触发'props'事件
def on_props(request):
global FLAG_GEAR1, FLAG_GEAR2, FLAG_GEAR3,FLAG_CUR_TEMP,gear1_temp, gear2_temp, gear3_temp,temp
params=request['params']
data_all=eval(params)
if FLAG_GEAR1 in data_all :
gear1_temp = data_all[FLAG_GEAR1]
value_gears()
if FLAG_GEAR2 in data_all :
gear2_temp = data_all[FLAG_GEAR2]
value_gears()
if FLAG_GEAR3 in data_all :
gear3_temp = data_all[FLAG_GEAR3]
value_gears()
if FLAG_CUR_TEMP in data_all:
temp = data_all[FLAG_CUR_TEMP]
upload_temp()
#当iot云端调用设备service时,触发'service'事件
def on_service(id,request):
print('clound req id is {} , req is {}'.format(id,request))
#当设备跟iot平台通信过程中遇到错误时,触发'error'事件
def on_error(err):
print('err msg is {} '.format(err))
#网络连接的回调函数
def on_4g_cb(args):
global g_connect_status
pdp = args[0]
netwk_sta = args[1]
if netwk_sta == 1:
g_connect_status = True
else:
g_connect_status = False
#网络连接
def connect_network():
global net,on_4g_cb,g_connect_status
#NetWorkClient该类是一个单例类,实现网络管理相关的功能,包括初始化,联网,状态信息等.
net = network.NetWorkClient()
g_register_network = False
if net._stagecode is not None and net._stagecode == 3 and net._subcode == 1:
g_register_network = True
else:
g_register_network = False
if g_register_network:
#注册网络连接的回调函数on(self,id,func); 1代表连接,func 回调函数 ;return 0 成功
net.on(1,on_4g_cb)
net.connect(None)
else:
print('网络注册失败')
while True:
if g_connect_status:
print('网络连接成功')
break
time.sleep_ms(20)
#动态注册回调函数
def on_dynreg_cb(data):
global deviceSecret,device_dyn_resigter_succed
deviceSecret = data
device_dyn_resigter_succed = True
# 连接物联网平台
def dyn_register_device(productKey,productSecret,deviceName):
global on_dynreg_cb,device,deviceSecret,device_dyn_resigter_succed
key = '_amp_customer_devicesecret'
deviceSecretdict = kv.get(key)
print("deviceSecretdict:",deviceSecretdict)
if isinstance(deviceSecretdict,str):
deviceSecret = deviceSecretdict
if deviceSecretdict is None or deviceSecret is None:
key_info = {
'productKey': productKey ,
'productSecret': productSecret ,
'deviceName': deviceName
}
# 动态注册一个设备,获取设备的deviceSecret
#下面的if防止多次注册,当前若是注册过一次了,重启设备再次注册就会卡住,
if not device_dyn_resigter_succed:
device.register(key_info,on_dynreg_cb)
def upload_date(key_value):
data_str=ujson.dumps(key_value)
data={
'params':data_str
}
device.postProps(data)
value_data.clear()
value_data = {}
def upload_temp():
global value_data,temp,FLAG_CUR_TEMP
value_data[FLAG_CUR_TEMP]=temp
upload_date(value_data)
def value_gears():
global FLAG_GEAR1,FLAG_GEAR2,FLAG_GEAR3,gear1_temp, gear2_temp, gear3_temp,value_data
value_data[FLAG_GEAR1]=gear1_temp
upload_date(value_data)
value_data[FLAG_GEAR2]=gear2_temp
upload_date(value_data)
value_data[FLAG_GEAR3]=gear3_temp
upload_date(value_data)
#电机控制
def control(gear):
if not isinstance(gear,int):
raise ValueError("gear is not an int object")
if not gear in range(4):
raise ValueError("gear must be in range 0-3")
if gear == 0:
duty= 0
if gear == 1:
duty= 33
if gear == 2:
duty= 66
if gear == 3:
duty= 99
param = {'freq':3000, 'duty': duty }
pwm_pwm.setOption(param)
if __name__ == '__main__':
ICCID=None
g_connect_status = False
net = None
device = None
deviceSecret = None
deviceName = None
#替换下列产品信息
###################################
productKey = "a1A9j0EmrQr"
productSecret = "21ATZN5PR2iuv08w"
###################################
device_dyn_resigter_succed = False
# 连接网络
connect_network()
# 获取设备的IMEI 作为deviceName 进行动态注册
#2.2版本改为
#deviceName = modem.info.getDevImei()
deviceName = modem.getDevImei()
#获取设备的ICCID
ICCID=modem.sim.getIccid()
#初始化物联网平台Device类,获取device实例
device = Device()
if deviceName is not None and len(deviceName) > 0 :
#动态注册一个设备
dyn_register_device(productKey,productSecret,deviceName)
else:
print("获取设备IMEI失败,无法进行动态注册")
while deviceSecret is None:
time.sleep(0.2)
print('动态注册成功:' + deviceSecret)
key_info = {
'region' : 'cn-shanghai' ,
'productKey': productKey ,
'deviceName': deviceName ,
'deviceSecret': deviceSecret ,
'keepaliveSec': 60,
}
#打印设备信息
print(key_info)
#device.ON_CONNECT 是事件,on_connect是事件处理函数/回调函数
device.on(device.ON_CONNECT,on_connect)
device.on(device.ON_DISCONNECT,on_disconnect)
device.on(device.ON_PROPS,on_props)
device.on(device.ON_SERVICE,on_service)
device.on(device.ON_ERROR,on_error)
device.connect(key_info)
#主程序
time.sleep(2)
value_gears()
print('start work')
#初始化温度传感器
a=AHT10()
#set mode(℃ or F)
a.set_mode(0)
#初始化电机模块
pwm_pwm = PWM()
pwm_pwm.open("pwm_pwm")
while True:
time.sleep_ms(200)
temp = a.temperature() #获取温度信息
print('cur temp is {}'.format(temp))
upload_temp()
if temp <= gear1_temp and cur_gear != 0:
cur_gear = 0
control(cur_gear)
print('fan change to gear {}'.format(cur_gear))
elif temp > gear1_temp and temp <= gear2_temp and cur_gear != 1:
cur_gear = 1
control(cur_gear)
print('fan change to gear {}'.format(cur_gear))
elif temp > gear2_temp and temp <= gear3_temp and cur_gear != 2:
cur_gear = 2
control(cur_gear)
print('fan change to gear {}'.format(cur_gear))
elif temp > gear3_temp and cur_gear != 3:
cur_gear = 3
control(cur_gear)
print('fan change to gear {}'.format(cur_gear))
ahtx0.py
import utime as time
from driver import I2C
#CONSTANTS
AHT10_ADDRESS = 0x38 # 0111000 (7bit address)
AHT10_READ_DELAY_MS = 75 # Time it takes for AHT to collect data
AHT_TEMPERATURE_CONST = 200
AHT_TEMPERATURE_OFFSET = 50
KILOBYTE_CONST = 1048576
CMD_INITIALIZE = bytearray([0xE1, 0x08, 0x00])
CMD_MEASURE = bytearray([0xAC, 0x33, 0x00])
FARENHEIT_MULTIPLIER = 9/5
FARENHEIT_OFFSET = 32
class AHT10:
def __init__(self, mode=0, address=AHT10_ADDRESS):
self.i2c = I2C()
self.i2c.open('aht10')
self.address = address
writeBuf=bytearray(4)
writeBuf[0]=self.address
writeBuf[1]=CMD_INITIALIZE[0]
writeBuf[2]=CMD_INITIALIZE[1]
writeBuf[3]=CMD_INITIALIZE[2]
self.i2c.write(writeBuf)
self.readings_raw = bytearray(8)
self.results_parsed = [0, 0]
self.mode = mode # 0 for Celsius(摄氏度), 1 for Farenheit(华氏度)
def read_raw(self):
writeBuf=bytearray(4)
writeBuf[0]=self.address
writeBuf[1]=CMD_MEASURE[0]
writeBuf[2]=CMD_MEASURE[1]
writeBuf[3]=CMD_MEASURE[2]
self.i2c.write(writeBuf)
time.sleep_ms(AHT10_READ_DELAY_MS)
readBuf=bytearray(6)
readBuf[0]=AHT10_ADDRESS
self.i2c.read(readBuf)
self.readings_raw[0]=readBuf[0]
self.readings_raw[1]=readBuf[1]
self.readings_raw[2]=readBuf[2]
self.readings_raw[3]=readBuf[3]
self.readings_raw[4]=readBuf[4]
self.readings_raw[5]=readBuf[5]
self.results_parsed[0] = self.readings_raw[1] << 12 | self.readings_raw[2] << 4 | self.readings_raw[3] >> 4
self.results_parsed[1] = (self.readings_raw[3] & 0x0F) << 16 | self.readings_raw[4] << 8 | self.readings_raw[5]
def humidity(self):
self.read_raw()
return (self.results_parsed[0] / KILOBYTE_CONST) * 100
def temperature(self):
self.read_raw()
if self.mode is 0:
return (self.results_parsed[1] / KILOBYTE_CONST) * AHT_TEMPERATURE_CONST - AHT_TEMPERATURE_OFFSET
else:
return ((self.results_parsed[1] / KILOBYTE_CONST) * AHT_TEMPERATURE_CONST - AHT_TEMPERATURE_OFFSET) * FARENHEIT_MULTIPLIER + FARENHEIT_OFFSET
def set_mode(self, mode):
if mode==0 or mode==1:
self.mode = mode
else:
raise ValueError('Mode must be either 0 for Celsius or 1 Farenheit')
- board.json
{
"name": "haas506",
"version": "1.0.0",
"io": {
"ADC0": {
"type": "ADC",
"port": 0,
"sampling": 12000000
},
"ADC1": {
"type": "ADC",
"port": 1,
"sampling": 12000000
},
"pwm_pwm": {
"type": "PWM",
"port": 39
},
"pwm_lpg": {
"type": "PWM",
"port": 3
},
"aht10": {
"type": "I2C",
"port": 1,
"addrWidth": 7,
"freq": 400000,
"mode": "master",
"devAddr": 56
},
"serial1": {
"type": "UART",
"port": 0,
"dataWidth": 8,
"baudRate": 115200,
"stopBits": 1,
"flowControl": "disable",
"parity": "none",
"timeout": 1000
},
"serial2": {
"type": "UART",
"port": 1,
"dataWidth": 8,
"baudRate": 9600,
"stopBits": 1,
"flowControl": "disable",
"parity": "none",
"timeout": 1000
},
"serial3": {
"type": "UART",
"port": 2,
"dataWidth": 8,
"baudRate": 115200,
"stopBits": 1,
"flowControl": "disable",
"parity": "none",
"timeout": 1000
}
},
"debugLevel": "ERROR",
"repl": "enable",
"replPort": 0
}
调试
1、串口调试工具log,网络连接成功–动态注册成功–重复打印当前温度,模式更改时打印更改的模式
2、云端有数据传入,打开实时刷新,显示数据会自动更新。
3、物联网应用开发
以下是物联网应用开发流程,接下来按以下流程介绍移动端应用的开发。
3.1新建‘普通项目’
- 使用阿里云IoTStudio创建项目。
- 在项目管理新建空白项目
3.2关联产品和设备
3.3新建‘移动应用’
点击上图红框中的‘组件’,就可以看到可用的组件列表。各组件的使用说明请参考组件说明
3.4页面设计
按顺序将组件从上到下拖到中间画布区
文本组件设置
开关组件设置
- 配置数据源
- 配置交互
同样的方法,配置其他两个数字框
- 数字框三
实时曲线组件设置
3.5预览和发布上线
在页面‘’保存‘’并点击‘预览’进行预览。
手机扫描二维码,可以在手机进行设置并查看实时温度数据。