阿库娅很不错,下一秒就是你的了

独自生活许久,免不了会有孤独感,孤独的特征之一就是自己吐槽自己(´⊙ω⊙`),在某些事情变的不可挽回之前,有个会唱歌(放歌),会跳舞(放视频),能交流(词库尬聊)的纸片人相伴,或许会更加不可挽回吧。

咱的智能家居系统,无论是不是虚拟美少女,至少要能养成。大厂的生态哪有自己亲手养大的放心,哪怕是个智障。

我又不是智障

# 网关部分

# 食材

根据需求,项目大体分为两个阶段。第一阶段,改造现有设备然后接入树莓派 4B,通过 Web 应用实现远程控制,调研中转到 Google Home 的方法(到此为止了)。第二阶段替换掉 Google Home,为树莓派加持先进的 ML (Magic Learning) 技术,实现 AI (Artificial Idiot) 中枢。主要技术指标如下。

  • 美少女皮 + 自定义唤醒词
  • 开源技术确保安全
  • 一键自毁

先不管有生之年的技术指标,第一阶段主要用到的开源软件有这么几个。

  • 后端

    • Raspbian Buster (arm64)
    • Flask
    • OpenCV 4.2
    • MariaDB 10.4
    • Nginx
  • 前端

    • Jinja2
    • Bootstrap 4

推荐的开发工具。

  • 宇宙第二 PyCharm
  • 宇宙第一 VS Code
  • 世界一流 Keil C51

为避免消化不良,还需掌握如下技巧。

  • 对硬件一知半解
  • 擅长使用搜索引擎
  • 擅长通过推倒墙娘解锁新姿势

# 应用架构

网关硬件就用树莓派,主要提供 REST API,配合 Web 界面进行交互,实现远程控制设备。也可接入第三方服务,比如 Google home(嘤语学习好助手)。

为了快速上线,后端咱就用了 Python。框架采用 Flask,是一个采用模块化设计理念的 Web 应用框架,也被称为微框架。Flask 没太多默认配置,可以通过 Flask-extension 引入如 MySQL ORM,模板引擎,表单和身份验证等插件。程序使用 MVC 分层架构,便于协作开发和后续扩展,同样为了加速,暂时使用 Jinja2 模板生成器糊出来的前端。

# 数据库

MariaDB 是 MySQL 在 MySQL 的基础上改进的关系型数据库,在提升性能的同时保持与 MySQL 的完全兼容,仅需简单卸载 MySQL 并安装 MariaDB 即可。

参见 E-R 图,config表保存传感器节点的状态,包括传感器类型,环境数据最大值和最小值,传感器或执行器状态,上次动作源等。sensor表保存传感器历史数据,外键连接config表。camera表保存连续运动的发生时间和截图路径。user表储存用户信息,包括登录名称,用户邮箱,密码等数据。

# 运动检测

OpenCV 已经实现了多种常见的检测算法。MOG 算法是一个背景分割算法,以混合高斯模型为基础。此算法使用多个高斯分布混合计算对背景像素建模,指定权重为像素点 RGB 值在整个序列中的持续时间。若一个 RGB 值属于背景像素点,那么它的持续时间相对于运动像素长,相应的权重也更高。

MOG2 是 MOG 算法的改进。它为每一个像素点单独计算高斯分布,这样能更好的适应由于亮度,噪点等外部参数发生变化而引起的场景变化。

GMG 算法结合了贝叶斯分割法和静态背景估算法,使用图像序列的一些帧建立背景模型,然后通过贝叶斯估计 (Bayesian Estimation) 识别前景。这是一种自适应算法,更新出现的图像帧具有更高的权重,从而适应光照变化。此外,还可以利用如开闭运算之类的形态学算法,除去无用的噪音。

运动检测流程如上图所示,相关算法由 OpenCV 实现。

# 节点部分

初号机目前的机能有些稚嫩,只能做到温度检测,运动检测,远程监控,自动控制,远程控制等功能。不过第一版只是试验品,咱就先来介绍下当前的硬件施工进度,以及软硬件联合测试的方法。

# 施工标准

标准体验至少需要准备如下硬件,更敷衍的体验只需一个带摄像头的电脑。大部分模块桃饱网有成品,没有的也可以根据 PCB 用面包板凑合下。

  • Raspberry Pi 4B ×1
  • PI Camera ×1
  • 8051 MCU ×1
  • 1-Wire temp sensor DS18B20 ×1
  • ZigBee CC2530 SoC ×3

# MCU

节点主控可以选 8051/AVR ATmega8/STM32,其中,8051 有存储空间少,处理性能差,耗能高等众多优点,本来是不会选的。不过手边有几片 8051,就直接回收利用了。

其他的还有 ZigBee,传感器模块。其中,MCU 运行控制程序,处理和保存数据。传感器负责环境参数的感知和转换。ZigBee 负责与其他节点或网关通信,实现指令和数据的双向传输。

# 温度传感器

DS18B20 温度传感器使用 1-Wire 总线协议通信。控制线路需要一个上拉电阻,因为所有器件通过一个三态或漏极开路端口连接到总线。微处理器使用每个设备唯一的 64 位代码识别和寻址总线上的设备。每个设备都有唯一的地址,总线上的设备数量实际上是无限的。

DS18B20 温度传感器定义了读写指令,响应指令和复位指令。除响应指令外,同步信号均由 MCU 产生。为了确保可靠的数据传输,同一时间只能有一个信号存在于 1-Wire 总线上。数据的传输符合单总线协议,按照初始化配置、ROM 指令、工作指令的顺序进行操作,其所有的指令和数据都是从低位开始发送到高位。

# ZigBee

ZigBee 和 IEEE 802.15.4 经常被混用,但实际上他们是完全不同的概念。IEEE 802.15.4 标准由 IEEE 组织制定和支持。它定义了小区域低功耗无线通信的媒体访问层(MAC)和物理层(PHY)规范。由于没有定义多跳传输,地址分配,和应用层互操作协议,有些通信协议基于 802.15.4,对其进行了一些修改和扩充,例如 6LoWPAN,Tiny O/S、ZigBee 等。

ZigBee 通过建立网络层来支持点对点多跳网络,建立安全层来增强网络安全,还建立了应用层来实现应用程序互操作。传感器节点的 ZigBee 模块使用网状路由,即单播发送。数据包通过 Mesh 路由发送,发送方知道接收方是否收到完整数据。网状路由最多可以经过 30 个节点来传输数据。

咱这里用的是成品模块(DL-LN3X),支持串口通信,只需指定节点的地址和数据,即可发送到目的节点,中间的过程 CC2530 中烧录的程序会安排的很好。

# 温度采集

温度节点控制程序使用 C 语言实现,程序运行在 8051 MCU 上,如下图,每隔 1s 上传一次温度信息,或者在上位机请求时立即上传温度信息。

# PCB

PCB 的设计对于最终系统的整体性能和电路设计一样重要。PCB 板形尺寸确定在 50mm*50mm 以内,完成总体布局后,开始放置组件。组件位置是否合理,将直接关系到电路是否可靠。

在 PCB 布局中,先按照功能模块划分区域,然后考虑各模块的相对位置。任何高频模拟信号或高精度数字信号都应该尽可能保持距离,原则上所有敏感区域利用 GND 相互隔离,信号路径尽可能短。

# 测试

# 运行环境

在树莓派上安装 Raspbian Buster 系统。应用基于 Python 开发,使用了大量第三方 Library,可使用 virtualenv 创建一个 Python 3 虚拟环境,执行 pip 命令安装所有依赖包。

$ pip install -r requirements.txt

运动捕捉相关功能使用 OpenCV 实现,PyPi 预编译的 OpenCV 4 可能缺少部分功能(目前够用了),如果你闲得慌呢,下面是编译安装的方法。把 opencv 和扩展库 opencv_contrib 的源代码 Clone 到本地,进入 Python 3 虚拟环境,安装 numpy 和编译工具,使用 CMake 来构建编译配置。

$ cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
    -D ENABLE_NEON=ON \
    -D ENABLE_VFPV3=ON \
    -D BUILD_TESTS=OFF \
    -D OPENCV_ENABLE_NONFREE=ON \
    -D INSTALL_PYTHON_EXAMPLES=OFF \
    -D BUILD_EXAMPLES=OFF ..

确认配置无误后,键入 make -j4 开始编译,-j4 参数指定 4 个核心用于编译。在 2G 内存的 Raspberry Pi 4B 上,编译大约需要 1 小时,结束后使用 make install 完成 OpenCV 4 的安装。OpenCV 默认安装在全局的 site-packages 目录中,创建个符号链接到 Python 3 虚拟环境来使用 OpenCV。

# 数据库

安装 MariaDB,使用 flask-migrate 恢复数据库结构。

$ python manage.py db init
$ python manage.py db migrate
$ python manage.py db upgrade

# 开动吧

Python 这语言,怎么写都跑的起来。根目录下的 gate.py 是网关软件的入口文件,使用如下命令启动程序测试外网访问。在生产环境部署时,还需使用 Nginx 反向代理,以提高系统的稳定性和安全性。

$ which python
/home/xxx/umr-dive/venv/bin/python
$ export Env=Dev
$ sudo -E /home/xxx/umr-dive/venv/bin/python gate.py -i 0.0.0.0 -o 80

目前为止还算顺利,现在咱有了个能用的智能家居,至于别的需求,后续再慢慢扩展。但愿不会成为有生之年系列。

更新:接入了涂鸦,配合 Google home 用的很爽。

# Tips

  • 如果没有公网 IP,还需要搭建内网穿透服务。
  • 上述操作启动的是测试服务器,生产环境还需使用 Nginx 反向代理。
  • 客户端需支持现代浏览器,比如最新版 Chrome,Firefox,Safari 等。
  • 传感器节点采用模块化设计,可更换任意使用标准接口的传感器。

# Reference

项目源码 (opens new window)

OpenCV – Stream video to web browser/HTML page (opens new window)

Install OpenCV 4 on Raspberry Pi 4 and Raspbian Buster (opens new window)

未完待续。

网关部分
食材
应用架构
数据库
运动检测
节点部分
施工标准
MCU
温度传感器
ZigBee
温度采集
PCB
测试
运行环境
数据库
开动吧
Tips
Reference