昉·星光系列课程15:昉·星光开发板智能家居远程控制

昉·星光系列课程15:昉·星光开发板智能家居远程控制

本次课程为昉·星光开发板IoT开发系列课程的第十五讲,将带领同学们在昉·星光开发板上,结合使用温度传感器和MQTT,实现远程信息发布和控制。
本次课程,在昉·星光开发板V1和V2上,操作步骤相同。

一、学习目标

  • 学习昉·星光开发板通过MQTT发布温度传感器的温湿度值,在手机端实时获取发布的温湿度值,并通过手机端,控制开发板连接的LED灯的亮度。

二、准备工作

在开始本次课程的实际操作之前,同学们需要做好一些准备工作,课程中涉及到的硬件如下:

  • 开发板:昉·星光开发板
  • 温度传感器:SHT30温度传感器
  • LED:单色LED模块
  • 杜邦线:若干

三、远程控制原理

在本次课程中,远程控制是基于MQTT协议进行的。
MQTT协议是基于发布/订阅模式的物联网通信协议,凭借简单易实现、支持 QoS、报文小等特点,占据了物联网协议的半壁江山。

通过MQTT协议,在星光开发板上程序中,我们可以将采集到的传感器信息,发布到MQTT服务端,其他应用可以通过订阅对应的信息,从而得到发布的信息。同样的,其他应用也可以将控制指令消息,发布到MQTT服务端,星光开发板上的程序收到对应的控制指令消息后,再控制外部设备。

四、实物连线

首先,参考下图,将温度传感器和LED到昉·星光开发板:

实物连接如下:

注意:
应根据实际使用的传感器,确定供电电压。本次课程中使用的模块使用5V供电电压。

五、代码编写

在本次课程中,SHT30温湿度传感器的使用,在 昉·星光系列课程3:昉·星光开发板温湿度传感器使用 中已有详细的讲解,请预先阅读该课程了解。
另外,赛昉还提供了 应用指南 (Python) - 使用昉·星光2使LED以PWM频率闪烁,演示了如何使用PWM控制LED,本课程中的PWM控制即参考该应用指南,请预先查看了解。

然后,我们编写如下的程序 iot_test.py:

# -*- coding: utf-8 -*-
# file: ~/projects/iot/iot_test.py

import random
import time
import json

from paho.mqtt import client as mqtt_client
from sensirion_i2c_driver import I2cConnection
from sensirion_i2c_sht.sht3x import Sht3xI2cDevice
from sensirion_i2c_driver.linux_i2c_transceiver import LinuxI2cTransceiver
import VisionFive.gpio as GPIO

GPIO.setmode(GPIO.BCM)		#set pin numbering system
led_pin = 36
led_brightness = 0
GPIO.setup(led_pin, GPIO.OUT)
p = GPIO.PWM(led_pin, 1000)
p.start(0)
p.ChangeDutyRatio(0)

# 打开SHT3X设备
i2c_transceivervice = LinuxI2cTransceiver('/dev/i2c-0')
sht3x = Sht3xI2cDevice(I2cConnection(i2c_transceivervice))

broker = 'broker-cn.emqx.io'
port = 1883
topic_base = "/vf2/iot"
# generate client ID with pub prefix randomly
client_id = f'vf2-iot-client-{random.randint(0, 1000)}'

is_connected = False

def connect_mqtt():
    def on_connect(client, userdata, flags, rc):
        global is_connected
        if rc == 0:
            is_connected = True
            print("Connected to MQTT Broker!")
        else:
            print("Failed to connect, return code %d\n", rc)

    client = mqtt_client.Client(client_id)
    client.on_connect = on_connect
    client.connect(broker, port)
    return client

def publish(client):
    while True:
        # 读取温湿度值
        temperature, humidity = sht3x.single_shot_measurement()

        # 打印当前数据的数据和计算结果
        print("{:0.2f} °C , {:0.2f} %RH, {:d}".format(
            temperature.degrees_celsius,
            humidity.percent_rh, led_brightness))

        msg = json.dumps({
            "temperature": format(temperature.degrees_celsius,'.1f'),
            "humidity": format(humidity.percent_rh,'.0f'),
            "brightness": led_brightness
            })

        topic = "%s/report" % topic_base
        result = client.publish(topic, msg)
        # result: [0, 1]
        status = result[0]
        if status == 0:
            print(f"Send `{msg}` to topic `{topic}`")
        else:
            print(f"Failed to send message to topic {topic}")

        time.sleep(5)

def subscribe(client: mqtt_client):
    def on_message(client, userdata, msg):
        global led_brightness
        print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
        json_data = json.loads(str(msg.payload.decode()))

        if 'led' in json_data:
            led_brightness = int(json_data['led'])
            if led_brightness>100:
                led_brightness = 100
            elif led_brightness<0:
                led_brightness = 0
            p.ChangeDutyRatio(led_brightness)
            print("Set LED brightness to %d" % led_brightness)

    topic = "%s/cmd" % topic_base
    client.subscribe(topic)
    client.on_message = on_message

def run():
    client = connect_mqtt()
    client.loop_start()
    while not is_connected:
        time.sleep(1)
    subscribe(client)
    publish(client)

if __name__ == '__main__':
    run()

在上述代码中,我们线连接到mqtt服务,然后使用led_brightness保存当前LED亮度值,从SHT30读取到了温度值,然后通过mqtt发布温湿度和亮度数据到 /vf2/iot/report 主题下。同时,向mqtt订阅 /vf2/iot/cmd 主题,接受控制指令消息,收到消息后,根据消息体(json格式)中的led值,来控制LED的亮度。

mqtt部分的核心调用:

  • connect_mqtt():连接到mqtt服务
  • publish():循环读取传感器数据,然后进行发布
  • subscribe(): 订阅控制指令消息,收到消息后进行对应的处理

在上述代码中,为了方便大家测试,使用的mqtt服务是 EMQX 提供的公共服务 broker-cn.emqx.io,可以直接连接使用。如果是在正式应用场合中使用,可以自己搭建mqtt服务器确保安全。

六、运行效果

要运行以上的程序,还需要安装相应的支持库,具体如下:

# 安装扩展库
sudo pip install sensirion-i2c-sht
sudo pip install VisionFive.gpio
sudo pip3 install -i https://pypi.doubanio.com/simple paho-mqtt

编写完成后,运行 iot_test.py,就可以开始进行远程信息接受和查看测试了。

python3 iot_test.py

七 手机控制

通过前面的步骤,我们已经可以通mqtt来获取传感器的信息,以及控制星光开发板连接的LED了。
在此基础上,我们可以在手机上安装Mqtt Dashboard应用,从而实现手机端查看传感器信息和控制了。
MqttDashboard下载地址:https://play.google.com/store/apps/details?id=com.app.vetru.mqttdashboard&hl=zh_CN

下载完成后,首先添加消息服务:

然后,添加对应的控件,来显示传感器的信息显示和控制:

温度、湿度、LED亮度信息使用文本控件:

控制使用使用按钮控件:

参考半亮,设置好全亮{led:100}、熄灭{“led”:0}

做好以上设置以后,在主界面,就能收到星光开发板通过mqtt发送的消息,并呈现到对应的控件上。
点击半亮、全亮、熄灭按钮,就能通过mqtt发布控制指令到星光开发板,从而控制LED亮度。

八、总结

在本次课程中,我们学习了结合使用MQTT协议与星光开发板进行通用,获取上报的传感器数据,并下发控制指令控制LED的亮度。
要进行物联网开发,MQTT协议是重要基础之一。MQTT协议广泛应用于物联网、移动互联网、智能硬件、车联网、电力、能源等领域,既能作为网关在设备侧接入通信,也能作为设备-云端的通信协议。

九、课后作业

  • 了解MQTT的知识
  • 结合其他传感器和模块,进行传感器信息的发布,以及控制风扇电机的运转。
  • 参考本次课程的实例程序,在其他电脑或者支持Python的开发板上,编写Python程序,实现对星光开发板发布信息的接受,并通过发布指令控制星光开发板。

十、参考资料

2 Likes