基于Domoticz智能家居系统(十八)移植MySensors终端框架代码到Keil-MDK并用STM32+NRF24L01作个简单无线继电器
移植MySensors终端框架代码到Keil-MDK并用STM32+NRF24L01作个简单无线继电器
前面一篇博文介绍了用Arduino IDE上如何用ESP8266和NRF24L01+模块作为MySensors系统的终端,Arduino IDE有它的特点和好处,比如可以安装第三方提供的各种库,或者第三方提供的各种开发板的板级支持包(BSP),可以通过某些工具,比如串口等等自动烧录固件,但是它也有很大的缺点,比如说它的IDE严重占用系统资源,因为它是用java开发的,运行一个软件实例已经导致系统很卡,如果开多个实例,同时看代码,那会导致系统死机;还有它似乎也不支持文件同步修改,也就是说如果我用source Insight等代码编辑器写的代码,不能同步过来,每次都需要重新打开这个IDE加载整个工程才行;还有一个最严重的缺点,那就是:它编译速度实在令人难以忍受。。。作为项目开发,如果有其他的编译器,请果断抛弃Arduino IDE!
本文将在MySensors 2.3.1 版本源代码基础之上,做些修改,直接用在STM32的开发板上,并用 Keil-MDK作为IDE进行编译。
Keil-MDK(Keil uVision5)版本号: MDK-ARM Plus Version 5.23
本人使用的STM32开发板是比较老旧的一个金牛板,芯片是STM32F107VC.
RF模块:NRF24L01+ 无线模块 功率加强版 2.4G 无线收发通信模块。
还有一个5V1路继电器模块 小体积 (高电平触发吸合)
一、硬件连接:
1、开发板与无线模块的连接(使用了STM32F107VC的SPI1接口)
STM32F107VC | NRF24L01+ 模块 |
---|---|
3V3 | VCC (NRF24L01+须3.3V供电) |
GND | GND |
PA3 | CE |
PA4 (SPI1_NSS) | CSN (CS) |
PA5 (SPI1_SCK) | SCK |
PA6 (SPI1_MISO) | MISO |
PA7 (SPI1_MOSI) | MOSI |
注意:本文不使用NRF24L01+的中断控制功能,故它的IRQ脚不接
2、开发板与继电器的连接
STM32F107VC | 继电器 |
---|---|
3V3 | VCC (改继电器模块可以接受3v到5v或者更宽的范围) |
GND | GND |
PB0 | S (或IN)(信号控制端) |
注意:本人使用的是比较便宜的继电器模块,没有光耦,直接跟STM32芯片的IO连接有安全上的风险,建议使用带光耦的模块。
二、关于MySensors代码移植
具体的移植比较麻烦,就不一点点写上来了。
挑几个重要的地方说吧。
1、本次移植做了很多精简
具体来说,去掉了做网关部分的代码,去掉了OTA(固件在线升级)部分的代码,去掉了加密、签名,只留最基本的通讯协议。留下的这部分,我们可以学习和熟悉MySensors的整个框架。有兴趣的朋友可以自己移植加密等部分。
2、代码中未实现的部分
本来MySensors框架需要用到存储芯片,用来存取节点ID和父节点ID等信息。但是我们在这次移植中为了简便,就省略了这部分代码,但在应用程序部分直接给定节点ID和父节点ID(默认为MY_PARENT_NODE_ID,默认初始值是255,表示尚未连接到父节点).。只要在正常任务运行之前,指定这两个ID,就不影响整体的运行。
3、主要的移植部分简介
首先说明一点:本次移植基于开发板使用FreeRTOS操作系统。但是,整个MySensors框架本质上是独立于操作系统的,移植过程大部分跟操作系统无关。如无操作系统(No OS),只要实现hwMillis、hwSleep、delay(ms)、delayMicroseconds(ms)函数,并写好NRF24模块的底层驱动,能够顺利收发数据就可以正常使用MySensors框架。
移植的文件 | 位置 | 功能 |
---|---|---|
MyHwSTM32F1.cpp | MySensors/hal/architecture/STM32F1/ | 实现STM32芯片上的几个最基本的函数,例如hwMillis(获取系统运行毫秒节拍数)、hwSleep(任务睡眠函数)、hwDebugPrint(打印调试信息函数)。 |
RF24.cpp | MySensors/hal/transport/RF24/driver/ | 实现NRF24L01+ 无线模块和STM32芯片的底层驱动(板子使用的是25Mhz晶振,运行主频是72Mhz)。 |
RF24.cpp | MySensors/hal/transport/RF24/ | 这部分属于进一步封装无线模块收发数据接口的适配层(这部分主要是是因为MySensors系统不只是针对NRF24模块控制,而是面向更多的无线模块,利用这层封装来适配这些模块)。 |
MyMessage.cpp | MySensors/core/ | 定义节点消息数据包结构,以及对数据值的读取处理等。每个数据包最长32字节(Byte),最短7字节。其中包括最基本的7字节消息头。payload(有效载荷)部分长度是0~25字节,最长25字节。具体请参考(Serial Protocol - 2.x 协议):https://www.mysensors.org/download/serial_api_20 |
MyTransport.cpp | MySensors/core/ | 传输层的实现,MySensors框架核心部分之一,主要按照通信协议对消息进行解析,实现一个控制通信状态的状态机机制,并通过解析后的消息来控制状态机。它有六个状态:stInit(初始化,获取节点ID、父节点ID等信息)、 stParent(寻找父节点)、 stID(确认终端ID合法性或请求向MySensors网关请求注册一个ID)、stUplink(把本节点连接到MySensors网关进行级联)、stReady(连接到MySensors网关成功,为更进一步无线数据传输功能准备就绪)、stFailure(连接MySensors网关失败)。另外,实现了节点之间发送消息、节点向网关或路由(即MySensors中继器)发送消息的函数,以及控制无线模块(例如但不限于NRF24无线模块)发送消息数据的底层实现。 |
MySensorsCore.cpp | MySensors/core/ | MySensors框架核心部分之二,主要是管理MySensors系统的整体运行,并封装常用的API函数。 |
4、MySensors框架运行的基本流程
注意:下面的流程主要是对指定的动态ID进行注册的过程。
如果是指定静态ID,注册的过程则稍有不同。