基于Domoticz智能家居系统(十八)移植MySensors终端框架代码到Keil-MDK并用STM32+NRF24L01作个简单无线继电器

本文详细介绍了如何将MySensors终端框架移植到Keil-MDK,使用STM32F107VC和NRF24L01创建无线继电器。内容涵盖硬件连接、代码移植关键点、MySensors框架的基本流程及通信时序,还提供了代码示例和编译指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

移植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,注册的过程则稍有不同。

(1)、初始化和对其他节点建立连接的大概流程
Created with Raphaël 2.2.0 应用程序调用进入_begin() ,初始化无线设备; transportInitialise():初始化传输层状态机,把状态机切换到stInit状态,获取/指定节点ID和父节点原始ID; 进入transportWaitUntilReady(): 进入transportProcess(),在此处理接收到的消息数据 调用transportUpdateSM(), 如果状态有变化则更新状态机(初始时,状态为stInit) 进入stInitUpdate(),对节点ID可用性进行确认 进入transportProcessFIFO(); transportAvailable() 判断是否接收到数据 指定的父节点ID是否可用? 切换状态机到stParent,运行stParentTransition(), 在该函数中会发送一个 I_FIND_PARENT_REQUEST 消息, 请求目标父节点回复; 然后进入stParentUpdate(),寻找父节点(等待连接目标返回信息) 是否已经找到父节点? 如果(parentNodeId != AUTO)为真, 则表示找到,否则没找到父节点 切换状态机到stID,进入stIDUpdate()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值