Lesson 1 quick start
文章目录
课程github仓库: microsoft/IoT-For-Beginners: 12 Weeks, 24 Lessons, IoT for All! (github.com)
1. Intro
1.1 实验环境
微软这个iot课程提供了arduino、树莓派、模拟器三种实验选项。本笔记先用模拟器环境过一遍。
安装web服务环境:
- Node.js (nodejs.org)
- docsify,执行
npm i docsify-cli -g
安装即可;
在IoT-For-Beginners根目录下执行docsify serve
,就能访问http://localhost:3000
了。
参考virtual-device.md,安装模拟器环境:
- Python >= 3.6
- https://github.com/CounterFit-IoT/CounterFit,执行
pip install CounterFit
即可。
安装后执行counterfit.exe
即可启动web服务,默认访问http://127.0.0.1:5000/
,端口可以改变(--port PORT
)。因为这个模拟器是python实现的,注意两点:
-
养成使用虚拟环境的好习惯:
python -m venv CounterFit
; -
有兼容性问题,我用python3.7.9搭建的环境如下:
$ pip freeze > requirements.txt
$ pip list
Package Version
---------------------- -----------
beautifulsoup4 4.9.3
bidict 0.22.0
certifi 2021.10.8
charset-normalizer 2.0.12
click 7.1.2
colorama 0.4.4
CounterFit 0.1.3.dev30
counterfit-connection 0.1.0.dev5
counterfit-shims-grove 0.1.4.dev5
dnspython 1.16.0
eventlet 0.30.2
Flask 1.1.4
Flask-SocketIO 5.0.1
greenlet 1.1.2
idna 3.3
importlib-metadata 4.11.3
itsdangerous 1.1.0
Jinja2 2.11.3
lxml 4.6.3
MarkupSafe 2.0.1
pip 20.1.1
python-engineio 4.3.2
python-socketio 5.6.0
requests 2.27.1
setuptools 47.1.0
six 1.16.0
soupsieve 2.3.2.post1
typing-extensions 4.2.0
urllib3 1.26.9
Werkzeug 1.0.1
zipp 3.8.0
Web界面如下(注意右上角的未连接状态):
1.2 什么是 “物联网(IoT)”?
任何能够与周围物理世界交互的设备。
两种关键设备:
- 传感器 从世界中收集数据,例如:测量速度、温度或地点。
- 执行器 将电信号转换成现实世界的交互,例如:触发开关,打开灯,发出声音或将控制信号传送到其它硬件,例如,打开电源插座。
IoT还包括:
- 云服务:处理传感器数据,或者将请求转发给执行器;
- 边缘设备(edge devices):没有或不需要联网,自己处理与响应传感器的数据;
IoT开发的关注点之一:了解需要收集的数据、怎么收集它,怎么利用它来作出决策,以及如果有必要的话,怎么利用这些决策来和物理世界交互。
应用举例:
- 消费者物联网,如智能音箱;
- 商业物联网,如商店的摄像头、
- 工业物联网(IIoT),农业互联网;
- 基础设施物联网,类似智慧城市。
1.3 IoT设备
开发者套件通常有两种:微控制器(microcontrollers)和单板机(single-board computers)
微控制器
微控制器,简称MCU,包括:
- CPU;
- RAM和程序存储器;
- IO,如传感器或执行器。
使用模拟器完成实验后,可以买个 Seeed studios 的Wio Terminal ,一个兼容Arduino的微控制器,它包含传感器、执行器、Wi-Fi 和一个屏幕。
通常用 C 或 C++ 来为微控制器写程序,后续环境可以用vsc+PlatformIO 扩展,或者Arduino IDE。
单板机
可理解为功能齐全的计算机,可以用任何编程语言来为它写程序。我们通常用 Python 为物联网设备写程序。
最有名的就是树莓派。后续学习树莓派时可以用vsc+RemoteSSH扩展。
1.4 Hello World
源码位于1-getting-started\lessons\1-introduction-to-iot\code\
,这里有wio、树莓派、和counterfit三种源码,树莓派和counterfit虚拟设备都是python环境,只是counterfit多了连接硬件的逻辑。Wio的c源码可以参考wio-terminal.md。
这里只看counterfit源码:
from counterfit_connection import CounterFitConnection
CounterFitConnection.init('127.0.0.1', 5000)
print('Hello World!')
Vscode里执行前,先配一下python环境:
- ctrl+shift+p选择counterfit虚拟环境里的python.exe;
- 新开terminal
Ctrl+F5执行,如果web界面的状态编未connected,就说明成功了。
2. A deeper dive into IoT
2.1 IoT应用组件
当然就是Internet和Thing。
先看一下两种Internet:
- 云服务;
- Mesh网络,比如蓝牙通过hub建立一片mesh网络;
关于Thing,在上一节说过,并不一定非要联网(即edge边缘设备),这样可以快速处理局域网内的数据,比如智能音箱的语音唤醒功能,再高级点的功能可能会内置AI。
2.2 微控制器详解
CPU
需要理解的一些概念
clock tick
ALU
The faster the ticks, the more power consumed and more heat generated.
The Wio Terminal for example has a CPU that runs at 120MHz or 120,000,000 cycles per second.
微控制器通常没有要散热器。
一些cpu有多种工作频率,通过切换来延长硬件寿命,比如苹果M1,有4种工作频率。
Memory
两种:
- Non-volatile Program memory;
- random-access memory (RAM).
MCU的RAM通常是KB级的,比如WIO有192KB。而现在的PC,众所周知,RAM是GB级的。
MCU的程序存储器,是MB级的,比如WIO有4M,和PC的GB/TB差远了。
IO
Microcontrollers need input and output (I/O) connections to read data from sensors and send control signals to actuators. They usually contain a number of general-purpose input/output (GPIO) pins. These pins can be configured in software to be input (that is they receive a signal), or output (they send a signal).
Frameworks and operating systems
因为CPU和内存的原因,MCU不能运行操作系统。
每种芯片都有自己的api和文档,通过交叉编译后把符合芯片结构的程序烧录进芯片,比如Arduino的程序就是setup和loop,即事件循环,或者说消息循环。
You would write your setup code in the
setup
function, such as connecting to WiFi and cloud services or initializing pins for input and output. Your loop code would then contain processing code, such as reading from a sensor and sending the value to the cloud. You would normally include a delay in each loop, for example, if you only want sensor data to be sent every 10 seconds you would add a delay of 10 seconds at the end of the loop so the microcontroller can sleep, saving power, then run the loop again when needed 10 seconds later.
有些MCU也支持RTOS,比如Arduino FreeRTOS。
2.3 单板机
以 树莓派为例,它有三种型号:
- full size version
- the smaller Pi Zero
- a compute module that can be built into your final IoT device.
Raspberry Pi OS, 是Debian Linux的衍生版本(能用apt)。
3. Interact with the physical world with sensors and actuators
This lesson introduces two of the important concepts for your IoT device - sensors and actuators.
3.1 sensors
Lesson 1 quick start
文章目录
课程github仓库: microsoft/IoT-For-Beginners: 12 Weeks, 24 Lessons, IoT for All! (github.com)
1. Intro
1.1 实验环境
微软这个iot课程提供了arduino、树莓派、模拟器三种实验选项。本笔记先用模拟器环境过一遍。
安装web服务环境:
- Node.js (nodejs.org)
- docsify,执行
npm i docsify-cli -g
安装即可;
在IoT-For-Beginners根目录下执行docsify serve
,就能访问http://localhost:3000
了。
参考virtual-device.md,安装模拟器环境:
- Python >= 3.6
- https://github.com/CounterFit-IoT/CounterFit,执行
pip install CounterFit
即可。
安装后执行counterfit.exe
即可启动web服务,默认访问http://127.0.0.1:5000/
,端口可以改变(--port PORT
)。因为这个模拟器是python实现的,注意两点:
-
养成使用虚拟环境的好习惯:
python -m venv CounterFit
; -
有兼容性问题,我用python3.7.9搭建的环境如下:
$ pip freeze > requirements.txt
$ pip list
Package Version
---------------------- -----------
beautifulsoup4 4.9.3
bidict 0.22.0
certifi 2021.10.8
charset-normalizer 2.0.12
click 7.1.2
colorama 0.4.4
CounterFit 0.1.3.dev30
counterfit-connection 0.1.0.dev5
counterfit-shims-grove 0.1.4.dev5
dnspython 1.16.0
eventlet 0.30.2
Flask 1.1.4
Flask-SocketIO 5.0.1
greenlet 1.1.2
idna 3.3
importlib-metadata 4.11.3
itsdangerous 1.1.0
Jinja2 2.11.3
lxml 4.6.3
MarkupSafe 2.0.1
pip 20.1.1
python-engineio 4.3.2
python-socketio 5.6.0
requests 2.27.1
setuptools 47.1.0
six 1.16.0
soupsieve 2.3.2.post1
typing-extensions 4.2.0
urllib3 1.26.9
Werkzeug 1.0.1
zipp 3.8.0
Web界面如下(注意右上角的未连接状态):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a9ufs7mN-1652011480341)(lesson1.assets/CounterFit.png)]
1.2 什么是 “物联网(IoT)”?
任何能够与周围物理世界交互的设备。
两种关键设备:
- 传感器 从世界中收集数据,例如:测量速度、温度或地点。
- 执行器 将电信号转换成现实世界的交互,例如:触发开关,打开灯,发出声音或将控制信号传送到其它硬件,例如,打开电源插座。
IoT还包括:
- 云服务:处理传感器数据,或者将请求转发给执行器;
- 边缘设备(edge devices):没有或不需要联网,自己处理与响应传感器的数据;
IoT开发的关注点之一:了解需要收集的数据、怎么收集它,怎么利用它来作出决策,以及如果有必要的话,怎么利用这些决策来和物理世界交互。
应用举例:
- 消费者物联网,如智能音箱;
- 商业物联网,如商店的摄像头、
- 工业物联网(IIoT),农业互联网;
- 基础设施物联网,类似智慧城市。
1.3 IoT设备
开发者套件通常有两种:微控制器(microcontrollers)和单板机(single-board computers)
微控制器
微控制器,简称MCU,包括:
- CPU;
- RAM和程序存储器;
- IO,如传感器或执行器。
使用模拟器完成实验后,可以买个 Seeed studios 的Wio Terminal ,一个兼容Arduino的微控制器,它包含传感器、执行器、Wi-Fi 和一个屏幕。
通常用 C 或 C++ 来为微控制器写程序,后续环境可以用vsc+PlatformIO 扩展,或者Arduino IDE。
单板机
可理解为功能齐全的计算机,可以用任何编程语言来为它写程序。我们通常用 Python 为物联网设备写程序。
最有名的就是树莓派。后续学习树莓派时可以用vsc+RemoteSSH扩展。
1.4 Hello World
源码位于1-getting-started\lessons\1-introduction-to-iot\code\
,这里有wio、树莓派、和counterfit三种源码,树莓派和counterfit虚拟设备都是python环境,只是counterfit多了连接硬件的逻辑。Wio的c源码可以参考wio-terminal.md。
这里只看counterfit源码:
from counterfit_connection import CounterFitConnection
CounterFitConnection.init('127.0.0.1', 5000)
print('Hello World!')
Vscode里执行前,先配一下python环境:
- ctrl+shift+p选择counterfit虚拟环境里的python.exe;
- 新开terminal
Ctrl+F5执行,如果web界面的状态编未connected,就说明成功了。
2. A deeper dive into IoT
2.1 IoT应用组件
当然就是Internet和Thing。
先看一下两种Internet:
- 云服务;
- Mesh网络,比如蓝牙通过hub建立一片mesh网络;
关于Thing,在上一节说过,并不一定非要联网(即edge边缘设备),这样可以快速处理局域网内的数据,比如智能音箱的语音唤醒功能,再高级点的功能可能会内置AI。
2.2 微控制器详解
CPU
需要理解的一些概念
clock tick
ALU
The faster the ticks, the more power consumed and more heat generated.
The Wio Terminal for example has a CPU that runs at 120MHz or 120,000,000 cycles per second.
微控制器通常没有要散热器。
一些cpu有多种工作频率,通过切换来延长硬件寿命,比如苹果M1,有4种工作频率。
Memory
两种:
- Non-volatile Program memory;
- random-access memory (RAM).
MCU的RAM通常是KB级的,比如WIO有192KB。而现在的PC,众所周知,RAM是GB级的。
MCU的程序存储器,是MB级的,比如WIO有4M,和PC的GB/TB差远了。
IO
Microcontrollers need input and output (I/O) connections to read data from sensors and send control signals to actuators. They usually contain a number of general-purpose input/output (GPIO) pins. These pins can be configured in software to be input (that is they receive a signal), or output (they send a signal).
Frameworks and operating systems
因为CPU和内存的原因,MCU不能运行操作系统。
每种芯片都有自己的api和文档,通过交叉编译后把符合芯片结构的程序烧录进芯片,比如Arduino的程序就是setup和loop,即事件循环,或者说消息循环。
You would write your setup code in the
setup
function, such as connecting to WiFi and cloud services or initializing pins for input and output. Your loop code would then contain processing code, such as reading from a sensor and sending the value to the cloud. You would normally include a delay in each loop, for example, if you only want sensor data to be sent every 10 seconds you would add a delay of 10 seconds at the end of the loop so the microcontroller can sleep, saving power, then run the loop again when needed 10 seconds later.
有些MCU也支持RTOS,比如Arduino FreeRTOS。
2.3 单板机
以 树莓派为例,它有三种型号:
- full size version
- the smaller Pi Zero
- a compute module that can be built into your final IoT device.
Raspberry Pi OS, 是Debian Linux的衍生版本(能用apt)。
3. Interact with the physical world with sensors and actuators
This lesson introduces two of the important concepts for your IoT device - sensors and actuators.
3.1 sensors
Sensors convert whatever they sense into an electrical signal that can be interpreted by an IoT device. How this electrical signal is interpreted depends on the sensor, as well as the communication protocol used to communicate with the IoT device.
举例:温度传感器、光感,按钮、相机、加速度计、麦克风。
Types
Sensors are either analog or digital.
模拟传感器,以电位表为例,传感器通过指针的旋转角度计算点位,模拟信号经过模数转换器(ADC)编码为数字信号(0/1),传送给IoT设备。
IoT devices are digital - they can’t work with analog values, they only work with 0s and 1s.
Arduino库提供了 analogRead
函数。
数字传感器已经越来越普及,这样就不必给设备加上ADC了,不过也有些高级点的数字传感器有自己的ADC,比如数字温度传感器。
最简单的数字传感器应该是开关了,只有on/1和off/0两种状态。
the GPIO pins on a Raspberry Pi work on 3.3V, and read a return signal above 1.8V as a 1, below 1.8V as 0.
有的数字传感器也支持其它功能,比如加密。
CounterFit亮度传感器实验
参考文档:virtual-device-sensor.md
Create a light sensor:
- In the Create sensor box in the Sensors pane, drop down the Sensor type box and select Light.
- Leave the Units set to NoUnits
- Ensure the Pin is set to 0
- Select the Add button to create the light sensor on Pin 0
import time
from counterfit_connection import CounterFitConnection
from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor
CounterFitConnection.init('127.0.0.1', 5000)
light_sensor = GroveLightSensor(0) # pin 0
while True:
light = light_sensor.light
print('Light level:', light)
time.sleep(1)
运行python后,这个模拟器要这么玩:
- 设置value, 或者勾选random;
- 点击set
3.2 Actuator
Actuator convert an electrical signal from your IoT device into an interaction with the physical world such as emitting light or sound, or moving a motor.
举例:LED、喇叭、步进电机(Stepper motor)、继电器(Relay)、以及屏幕。
Types
和传感器一样,也是模拟和数字两种。
Analog actuators take an analog signal and convert it into some kind of interaction, where the interaction changes based off the voltage supplied.
模拟执行器,比如可变亮度的灯。IoT设备通过DAC(模数转换器)把数字信号转换为电压数,执行器就可以提供不同伏特的电压。
另一种数模转换方法是 脉冲宽度调制(Pulse-Width Modulation, PWM),具体参考课件。
数字执行器,一个简单的例子就是不可变亮度的灯泡。
CounterFit数字传感器LED实验
参考virtual-device-actuator.md
这个实验在传感器实验的基础上来实现,当光感亮度小于300时,led就亮。
Create an LED:
- In the Create actuator box in the Actuator pane, drop down the Actuator type box and select LED.
- Set the Pin to 5
- Select the Add button to create the LED on Pin 5
import time
from counterfit_connection import CounterFitConnection
from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor
from counterfit_shims_grove.grove_led import GroveLed
CounterFitConnection.init('127.0.0.1', 5000)
light_sensor = GroveLightSensor(0)
led = GroveLed(5)
while True:
light = light_sensor.light
print('Light level:', light)
if light < 300:
led.on()
else:
led.off()
time.sleep(1)
可以把光感亮度上限设置为600,即LED等有50%的概率亮。
4. Connect your device to the Internet
4.1 简介
IoT devices typically connect to a single cloud IoT service using a standard communication protocol, and that service is connected to the rest of your IoT application, from AI services to make smart decisions around your data, to web apps for control or reporting.
从传感器收集数据并发送给云服务的过程叫做遥测,telemetry。
IoT devices can receive messages from the cloud. Often the messages contain commands:
- perform an action either internally (such as reboot or update firmware)
- using an actuator (such as turning on a light).
4.2 通信协议
IoT里应用最广泛的通信协议就是基于发布/订阅模型的MQTT。其它协议还有AMQP 、 HTTP/HTTPS.
实验
上一节的实验其实就是很简单的夜间路灯,只不过在实际中,为了避免某个灯被遮住导致误判,需要所有灯的光感都认为天黑了,才能亮灯。
本节的实验,则是在上一节的基础上引入MQTT broker,可以自己搭建,也可以使用test.mosquitto.org,
安装依赖库:
python -m pip install paho-mqtt
如果设备是wio,则需要一些arduino库,比如WiFi ,还有mqtt客户端库 PubSubClient。
客户端名称需要有一个guid,避免使用test.mosquitto.org时和其它客户端冲突,可以在Generate GUIDs online (guidgen.com)生成,也可以命令行里执行vs的uuidgen.exe工具。
连接mqtt的逻辑如下
import paho.mqtt.client as mqtt
id = '<ID>'
client_name = id + 'nightlight_client'
mqtt_client = mqtt.Client(client_name)
mqtt_client.connect('test.mosquitto.org')
mqtt_client.loop_start()
print("MQTT connected!")
MQTT
可以参考之前的笔记:
4.3 遥测实验
Telemetry is the act of gathering data from sensors and sending it to the cloud.
Although the name is Message Queueing (initials in MQTT), it doesn’t actually support message queues. This means that if a client disconnects, then reconnects it won’t receive messages sent during the disconnection, except for those messages that it had already started to process using the QoS process. Messages can have a retained flag set on them. If this is set, the MQTT broker will store the last message sent on a topic with this flag, and send this to any clients who later subscribe to the topic. This way, the clients will always get the latest message.
MQTT also supports a keep alive function that checks if the connection is still alive during long gaps between messages.
课件提供了一个恒温器的例子,帮助理解。
要发送的数据和web一样,一般是json形式。Arduino需要ArduinoJson库,python需要json库。
发布端
源码位于 code-commands/server
import json
import time
import paho.mqtt.client as mqtt
id = '<ID>'
client_telemetry_topic = id + '/telemetry'
server_command_topic = id + '/commands'
client_name = id + 'nightlight_server'
mqtt_client = mqtt.Client(client_name)
mqtt_client.connect('test.mosquitto.org')
mqtt_client.loop_start()
def handle_telemetry(client, userdata, message):
payload = json.loads(message.payload.decode())
print("Message received:", payload)
command = { 'led_on' : payload['light'] < 300 } # =======是否亮灯===========
print("Sending message:", command)
client.publish(server_command_topic, json.dumps(command))
mqtt_client.subscribe(client_telemetry_topic)
mqtt_client.on_message = handle_telemetry
while True:
time.sleep(2)
订阅端
源码位于code-commands/virtual-device/nightlight
import time
from counterfit_connection import CounterFitConnection
from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor
from counterfit_shims_grove.grove_led import GroveLed
import json
import paho.mqtt.client as mqtt
CounterFitConnection.init('127.0.0.1', 5000)
light_sensor = GroveLightSensor(0)
led = GroveLed(5)
id = '<ID>'
client_telemetry_topic = id + '/telemetry'
server_command_topic = id + '/commands'
client_name = id + 'nightlight_client'
mqtt_client = mqtt.Client(client_name)
mqtt_client.connect('test.mosquitto.org')
mqtt_client.loop_start()
def handle_command(client, userdata, message):
payload = json.loads(message.payload.decode())
print("Message received:", payload)
if payload['led_on']:
led.on()
else:
led.off()
mqtt_client.subscribe(server_command_topic)
mqtt_client.on_message = handle_command
while True:
light = light_sensor.light
print('Light level:', light)
mqtt_client.publish(client_telemetry_topic, json.dumps({'light' : light}))
time.sleep(5)
把两端的id改成相同的guid,先执行哪个都可以,订阅端响应如下:
python .\app.py
Light level: 219
Message received: {'led_on': True}
Light level: 201
Message received: {'led_on': True}
Light level: 67
Message received: {'led_on': True}
Light level: 44
Message received: {'led_on': True}
响应的,收到True时,web界面的led灯会亮。
4.4 失联处理
如果订阅端失联了,那要看具体逻辑:
- 有些指令会覆盖前面的指令,比如关机;
- 有些指令会按队列执行,比如远控机器人。
Sensors convert whatever they sense into an electrical signal that can be interpreted by an IoT device. How this electrical signal is interpreted depends on the sensor, as well as the communication protocol used to communicate with the IoT device.
举例:温度传感器、光感,按钮、相机、加速度计、麦克风。
Types
Sensors are either analog or digital.
模拟传感器,以电位表为例,传感器通过指针的旋转角度计算点位,模拟信号经过模数转换器(ADC)编码为数字信号(0/1),传送给IoT设备。
IoT devices are digital - they can’t work with analog values, they only work with 0s and 1s.
Arduino库提供了 analogRead
函数。
数字传感器已经越来越普及,这样就不必给设备加上ADC了,不过也有些高级点的数字传感器有自己的ADC,比如数字温度传感器。
最简单的数字传感器应该是开关了,只有on/1和off/0两种状态。
the GPIO pins on a Raspberry Pi work on 3.3V, and read a return signal above 1.8V as a 1, below 1.8V as 0.
有的数字传感器也支持其它功能,比如加密。
CounterFit亮度传感器实验
参考文档:virtual-device-sensor.md
Create a light sensor:
- In the Create sensor box in the Sensors pane, drop down the Sensor type box and select Light.
- Leave the Units set to NoUnits
- Ensure the Pin is set to 0
- Select the Add button to create the light sensor on Pin 0
import time
from counterfit_connection import CounterFitConnection
from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor
CounterFitConnection.init('127.0.0.1', 5000)
light_sensor = GroveLightSensor(0) # pin 0
while True:
light = light_sensor.light
print('Light level:', light)
time.sleep(1)
运行python后,这个模拟器要这么玩:
- 设置value, 或者勾选random;
- 点击set
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5CxK5jZm-1652011398722)(lesson1.assets/virtual-sensor.png)]
3.2 Actuator
Actuator convert an electrical signal from your IoT device into an interaction with the physical world such as emitting light or sound, or moving a motor.
举例:LED、喇叭、步进电机(Stepper motor)、继电器(Relay)、以及屏幕。
Types
和传感器一样,也是模拟和数字两种。
Analog actuators take an analog signal and convert it into some kind of interaction, where the interaction changes based off the voltage supplied.
模拟执行器,比如可变亮度的灯。IoT设备通过DAC(模数转换器)把数字信号转换为电压数,执行器就可以提供不同伏特的电压。
另一种数模转换方法是 脉冲宽度调制(Pulse-Width Modulation, PWM),具体参考课件。
数字执行器,一个简单的例子就是不可变亮度的灯泡。
CounterFit数字传感器LED实验
参考virtual-device-actuator.md
这个实验在传感器实验的基础上来实现,当光感亮度小于300时,led就亮。
Create an LED:
- In the Create actuator box in the Actuator pane, drop down the Actuator type box and select LED.
- Set the Pin to 5
- Select the Add button to create the LED on Pin 5
import time
from counterfit_connection import CounterFitConnection
from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor
from counterfit_shims_grove.grove_led import GroveLed
CounterFitConnection.init('127.0.0.1', 5000)
light_sensor = GroveLightSensor(0)
led = GroveLed(5)
while True:
light = light_sensor.light
print('Light level:', light)
if light < 300:
led.on()
else:
led.off()
time.sleep(1)
可以把光感亮度上限设置为600,即LED等有50%的概率亮。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hi8BuIL1-1652011398724)(lesson1.assets/virtual-led.png)]
4. Connect your device to the Internet
4.1 简介
IoT devices typically connect to a single cloud IoT service using a standard communication protocol, and that service is connected to the rest of your IoT application, from AI services to make smart decisions around your data, to web apps for control or reporting.
从传感器收集数据并发送给云服务的过程叫做遥测,telemetry。
IoT devices can receive messages from the cloud. Often the messages contain commands:
- perform an action either internally (such as reboot or update firmware)
- using an actuator (such as turning on a light).
4.2 通信协议
IoT里应用最广泛的通信协议就是基于发布/订阅模型的MQTT。其它协议还有AMQP 、 HTTP/HTTPS.
实验
上一节的实验其实就是很简单的夜间路灯,只不过在实际中,为了避免某个灯被遮住导致误判,需要所有灯的光感都认为天黑了,才能亮灯。
本节的实验,则是在上一节的基础上引入MQTT broker,可以自己搭建,也可以使用test.mosquitto.org,
安装依赖库:
python -m pip install paho-mqtt
如果设备是wio,则需要一些arduino库,比如WiFi ,还有mqtt客户端库 PubSubClient。
客户端名称需要有一个guid,避免使用test.mosquitto.org时和其它客户端冲突,可以在Generate GUIDs online (guidgen.com)生成,也可以命令行里执行vs的uuidgen.exe工具。
连接mqtt的逻辑如下
import paho.mqtt.client as mqtt
id = '<ID>'
client_name = id + 'nightlight_client'
mqtt_client = mqtt.Client(client_name)
mqtt_client.connect('test.mosquitto.org')
mqtt_client.loop_start()
print("MQTT connected!")
MQTT
可以参考之前的笔记:
4.3 遥测实验
Telemetry is the act of gathering data from sensors and sending it to the cloud.
Although the name is Message Queueing (initials in MQTT), it doesn’t actually support message queues. This means that if a client disconnects, then reconnects it won’t receive messages sent during the disconnection, except for those messages that it had already started to process using the QoS process. Messages can have a retained flag set on them. If this is set, the MQTT broker will store the last message sent on a topic with this flag, and send this to any clients who later subscribe to the topic. This way, the clients will always get the latest message.
MQTT also supports a keep alive function that checks if the connection is still alive during long gaps between messages.
课件提供了一个恒温器的例子,帮助理解。
要发送的数据和web一样,一般是json形式。Arduino需要ArduinoJson库,python需要json库。
发布端
源码位于 code-commands/server
import json
import time
import paho.mqtt.client as mqtt
id = '<ID>'
client_telemetry_topic = id + '/telemetry'
server_command_topic = id + '/commands'
client_name = id + 'nightlight_server'
mqtt_client = mqtt.Client(client_name)
mqtt_client.connect('test.mosquitto.org')
mqtt_client.loop_start()
def handle_telemetry(client, userdata, message):
payload = json.loads(message.payload.decode())
print("Message received:", payload)
command = { 'led_on' : payload['light'] < 300 } # =======是否亮灯===========
print("Sending message:", command)
client.publish(server_command_topic, json.dumps(command))
mqtt_client.subscribe(client_telemetry_topic)
mqtt_client.on_message = handle_telemetry
while True:
time.sleep(2)
订阅端
源码位于code-commands/virtual-device/nightlight
import time
from counterfit_connection import CounterFitConnection
from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor
from counterfit_shims_grove.grove_led import GroveLed
import json
import paho.mqtt.client as mqtt
CounterFitConnection.init('127.0.0.1', 5000)
light_sensor = GroveLightSensor(0)
led = GroveLed(5)
id = '<ID>'
client_telemetry_topic = id + '/telemetry'
server_command_topic = id + '/commands'
client_name = id + 'nightlight_client'
mqtt_client = mqtt.Client(client_name)
mqtt_client.connect('test.mosquitto.org')
mqtt_client.loop_start()
def handle_command(client, userdata, message):
payload = json.loads(message.payload.decode())
print("Message received:", payload)
if payload['led_on']:
led.on()
else:
led.off()
mqtt_client.subscribe(server_command_topic)
mqtt_client.on_message = handle_command
while True:
light = light_sensor.light
print('Light level:', light)
mqtt_client.publish(client_telemetry_topic, json.dumps({'light' : light}))
time.sleep(5)
把两端的id改成相同的guid,先执行哪个都可以,订阅端响应如下:
python .\app.py
Light level: 219
Message received: {'led_on': True}
Light level: 201
Message received: {'led_on': True}
Light level: 67
Message received: {'led_on': True}
Light level: 44
Message received: {'led_on': True}
响应的,收到True时,web界面的led灯会亮。
4.4 失联处理
如果订阅端失联了,那要看具体逻辑:
- 有些指令会覆盖前面的指令,比如关机;
- 有些指令会按队列执行,比如远控机器人。