嵌入式C++、STM32、ROS系统和MQTT协议通讯:智能农业灌溉系统项目设计思路(代码示例)

news2024/9/8 22:54:43

目录

项目概述

系统设计

硬件设计

软件设计

系统架构图

代码实现

1. STM32微控制器代码

1.1 STM32初始化代码

1.2 读取土壤湿度

1.3 MQTT数据发送

1.4 接收控制命令

1.5 主循环

2. ROS系统代码

2.1 创建ROS节点

2.2 控制水泵的逻辑

3. ROS与MQTT的集成

3.1 安装ros_mqtt

3.2 在ROS中配置MQTT

项目总结

项目总结

项目优点

后续改进方向

参考文献


项目概述

随着全球水资源短缺问题的日益严重,智能灌溉系统的开发与应用显得尤为重要。本文介绍一种基于STM32微控制器土壤湿度传感器的智能灌溉系统。该系统利用MQTT协议将数据上传至ROS(Robot Operating System)系统,进而实现自动化精准灌溉。通过实时监测土壤湿度和天气预报信息,系统能够根据设定的阈值自动控制水泵,实现水资源的节约和农作物的高效灌溉。

系统设计

硬件设计

  1. STM32微控制器:作为系统的核心,负责数据采集、处理和控制。
  2. 土壤湿度传感器:实时监测土壤的湿度状况,输出模拟或数字信号。
  3. MQTT通信模块:如ESP8266或SIM800L,用于将数据发送到ROS系统。
  4. 水泵:根据控制信号自动灌溉。
  5. 电源模块:为各个硬件组件提供稳定的电源。

软件设计

  1. STM32固件

    • 读取土壤湿度传感器数据。
    • 通过MQTT协议将数据发送到ROS系统。
    • 接收ROS系统发送的灌溉控制命令。
  2. ROS系统

    • 接收来自STM32的数据。
    • 根据设定的阈值和天气预报信息,判断是否启动水泵。
    • 控制水泵的开关状态。

系统架构图

代码实现

本文将详细介绍STM32和ROS系统的代码实现,包括每块代码的注释和说明。

1. STM32微控制器代码

1.1 STM32初始化代码

首先,初始化STM32微控制器及其外设。

#include "stm32f4xx_hal.h"
#include "mqtt_client.h" // MQTT客户端库

// 初始化系统
void System_Init(void) {
    HAL_Init(); // 初始化HAL库
    SystemClock_Config(); // 配置系统时钟
    MX_GPIO_Init(); // 初始化GPIO
    MX_USART2_UART_Init(); // 初始化串口
    MQTT_Init(); // 初始化MQTT客户端
}
  • HAL_Init(): 初始化硬件抽象层。
  • SystemClock_Config(): 配置系统时钟。
  • MX_GPIO_Init(): 初始化GPIO端口。
  • MX_USART2_UART_Init(): 初始化串口通信。
  • MQTT_Init(): 初始化MQTT客户端。
1.2 读取土壤湿度

读取土壤湿度传感器的值并转换为百分比。

// 读取土壤湿度
float Read_Soil_Moisture(void) {
    uint32_t adc_value = HAL_ADC_GetValue(&hadc1); // 获取ADC值
    float moisture_percentage = (adc_value / 4095.0) * 100; // 将ADC值转换为百分比
    return moisture_percentage; // 返回湿度值
}
  • HAL_ADC_GetValue(&hadc1): 获取ADC通道的值。
  • 将ADC值转换为湿度百分比,假设ADC值范围为0-4095。
1.3 MQTT数据发送

通过MQTT将土壤湿度数据发送到服务器。

// 发送土壤湿度数据到MQTT服务器
void Send_Data(float moisture) {
    char message[50];
    snprintf(message, sizeof(message), "{\"moisture\": %.2f}", moisture); // 将湿度值格式化为JSON
    MQTT_Publish("farm/soil/moisture", message); // 发送MQTT消息
}
  • 功能:将土壤湿度数据以JSON格式发送到MQTT Broker。
  • 代码说明
    • snprintf用于将浮点数moisture格式化为JSON字符串,确保在消息中包含适当的湿度值。
    • MQTT_Publish函数将格式化后的消息发送到主题"farm/soil/moisture",以便ROS系统可以接收和处理。

1.4 接收控制命令

处理接收到的MQTT消息,根据指令控制水泵的开关状态。

// 处理接收到的MQTT消息
void MQTT_Message_Handler(char *topic, char *message) {
    // 判断是否是水泵控制指令
    if (strcmp(topic, "farm/control/pump") == 0) {
        if (strcmp(message, "ON") == 0) {
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); // 打开水泵
            printf("Pump is ON\n"); // 输出调试信息
        } else if (strcmp(message, "OFF") == 0) {
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); // 关闭水泵
            printf("Pump is OFF\n"); // 输出调试信息
        }
    }
}
  • 功能:根据接收到的MQTT消息控制水泵的状态。
  • 代码说明
    • strcmp函数用于比较消息主题和内容。
    • HAL_GPIO_WritePin用于控制水泵的GPIO引脚,GPIO_PIN_1对应于水泵的控制引脚。
    • 输出调试信息以便于观察水泵的状态。

1.5 主循环

在主循环中,系统会定期读取土壤湿度并发送数据,同时检查是否有新的MQTT消息。

int main(void) {
    System_Init(); // 初始化系统
    while (1) {
        float moisture = Read_Soil_Moisture(); // 读取土壤湿度
        Send_Data(moisture); // 发送数据到MQTT

        // 检查是否有新消息并处理
        MQTT_Check_For_Messages(); // 检查MQTT消息
        HAL_Delay(60000); // 每60秒读取一次湿度
    }
}
  • 功能:主循环中定时读取土壤湿度并发送数据,同时处理MQTT消息。
  • 代码说明
    • Read_Soil_Moisture()函数用于获取当前的土壤湿度。
    • Send_Data(moisture)将湿度数据发送到MQTT Broker。
    • MQTT_Check_For_Messages()检查是否有新的MQTT消息,并调用相应的处理函数。
    • HAL_Delay(60000)使主循环每60秒执行一次。

2. ROS系统代码

接下来,我们将实现ROS系统的代码,处理从STM32接收到的土壤湿度数据,并根据设定阈值控制水泵。

2.1 创建ROS节点

在ROS中,我们需要创建一个节点用于接收和处理从STM32发送的土壤湿度数据,并根据设定的阈值控制水泵的状态。

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def callback(data):
    # 解析接收到的湿度数据
    moisture_data = data.data
    moisture = float(moisture_data.split(":")[1].strip("}"))  # 解析JSON格式数据
    control_pump(moisture)  # 根据湿度值控制水泵

def control_pump(moisture):
    threshold = 30.0  # 设定的湿度阈值
    if moisture < threshold:
        publish_command("ON")  # 湿度低于阈值,启动水泵
    else:
        publish_command("OFF")  # 湿度高于阈值,停止水泵

def publish_command(command):
    pub = rospy.Publisher('farm/control/pump', String, queue_size=10)  # 创建发布者
    pub.publish(command)  # 发布水泵控制命令
    rospy.loginfo("Published command: %s", command)  # 输出信息到日志

if __name__ == '__main__':
    rospy.init_node('irrigation_controller', anonymous=True)  # 初始化ROS节点
    rospy.Subscriber('farm/soil/moisture', String, callback)  # 订阅湿度数据主题
    rospy.spin()  # 保持节点运行
  • 功能:创建一个ROS节点,接收土壤湿度数据,并根据湿度值控制水泵的开关。
  • 代码说明
    • rospy.init_node('irrigation_controller', anonymous=True): 初始化一个名为irrigation_controller的ROS节点。
    • rospy.Subscriber('farm/soil/moisture', String, callback): 订阅farm/soil/moisture主题,用于接收来自STM32的湿度数据,并在接收到数据时调用callback函数。
    • rospy.spin(): 保持节点运行,等待回调函数处理消息。

2.2 控制水泵的逻辑

control_pump函数中,我们根据读取到的土壤湿度值决定水泵的开关状态。

def control_pump(moisture):
    threshold = 30.0  # 设定的湿度阈值
    if moisture < threshold:
        publish_command("ON")  # 湿度低于阈值,启动水泵
    else:
        publish_command("OFF")  # 湿度高于阈值,停止水泵
  • 功能:根据湿度值判断是否需要启动或停止水泵。
  • 代码说明
    • 定义一个湿度阈值(例如30.0%),如果湿度低于阈值,则发送"ON"命令启动水泵;如果湿度高于阈值,则发送"OFF"命令停止水泵。

3. ROS与MQTT的集成

为了让ROS能够处理MQTT消息,我们可以使用ros-mqtt库将ROS与MQTT连接。这样,ROS就可以接收来自STM32的消息,并根据逻辑处理发送控制指令。

3.1 安装ros_mqtt

在ROS环境中安装ros_mqtt库:

sudo apt-get install ros-<your_ros_distro>-mqtt

替换<your_ros_distro>为你的ROS版本,例如noeticmelodic

3.2 在ROS中配置MQTT

为了让ROS能够通过MQTT协议接收和发送消息,我们需要设置MQTT客户端,并在ROS节点中进行必要的配置。

import paho.mqtt.client as mqtt

# MQTT连接回调
def on_connect(client, userdata, flags, rc):
    rospy.loginfo(f"Connected to MQTT Broker with result code {rc}")
    client.subscribe("farm/soil/moisture")  # 订阅湿度数据主题

# MQTT消息处理回调
def on_message(client, userdata, msg):
    rospy.loginfo(f"Received message: {msg.payload.decode()}")
    moisture_data = msg.payload.decode()  # 将消息内容解码为字符串
    callback(moisture_data)  # 调用之前定义的callback函数处理消息

if __name__ == '__main__':
    rospy.init_node('irrigation_controller', anonymous=True)  # 初始化ROS节点

    # 配置MQTT客户端
    mqtt_client = mqtt.Client()  # 创建MQTT客户端实例
    mqtt_client.on_connect = on_connect  # 设置连接回调
    mqtt_client.on_message = on_message  # 设置消息处理回调

    # 连接到MQTT Broker
    mqtt_client.connect("broker.hivemq.com", 1883, 60)  # 连接到MQTT Broker

    # 启动MQTT客户端循环
    mqtt_client.loop_start()  # 启动阻塞循环以处理网络流量

    # 订阅ROS主题
    rospy.Subscriber('farm/soil/moisture', String, callback)  # 订阅湿度数据主题

    rospy.spin()  # 保持节点运行
    mqtt_client.loop_stop()  # 停止MQTT客户端循环
  • 功能:设置MQTT客户端以便与MQTT Broker连接并处理消息。
  • 代码说明
    • on_connect(client, userdata, flags, rc): 当与MQTT Broker连接成功后会调用该函数,可以在这里进行主题订阅。
    • on_message(client, userdata, msg): 当接收到MQTT消息时,该函数将被调用,可以在这里处理消息内容并调用callback函数。
    • mqtt_client = mqtt.Client(): 创建一个MQTT客户端实例。
    • mqtt_client.connect("broker.hivemq.com", 1883, 60): 连接到MQTT Broker,使用HiveMQ公共测试Broker。
    • mqtt_client.loop_start(): 启动MQTT循环,处理网络流量和消息。

项目总结

本文介绍了一种基于STM32微控制器和土壤湿度传感器的智能灌溉系统。通过MQTT协议将数据上传至ROS系统,实现了自动化精准灌溉。系统能够根据实时的土壤湿度和设定的阈值控制水泵的开关,节约水资源,提高灌溉效率。

项目优点

  1. 精准灌溉:系统可根据实时土壤湿度调整灌溉计划,避免水资源浪费。
  2. 实时监测:通过MQTT协议,能够实时监测土壤湿度,并快速响应。
  3. 易于扩展:系统架构清晰,可根据需求增加其他传感器(如气象传感器)实现更智能的灌溉管理。

后续改进方向

  1. 天气预报集成:集成天气预报API,进一步优化灌溉计划。
  2. 手机应用:开发手机应用,用户可以实时监控土壤湿度和水泵状态。
  3. 数据分析:收集数据进行分析,优化长期灌溉策略。

参考文献

  1. MQTT协议简介: MQTT - The Standard for IoT Messaging
  2. ROS官方文档: Documentation - ROS Wiki
  3. STM32微控制器文档: https://www.st.com/en/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus.html
  4. Paho MQTT Python客户端文档: Eclipse Paho | The Eclipse Foundation

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1957612.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 执行计划详解

文章目录 一. 概念二. 语法三. 详解各字段1. id2. select_type3. table4. partitions5. type6. possible_keys与key7. key_len8. ref9. rows10. filtered11. Extra 一. 概念 有了慢查询后&#xff0c;需要对慢查询语句进行分析。一条查询语句经过MySQL查询优化器后&#xff0c…

最全国内13家DNS分享 解决网页被恶意跳转或无法打开问题

腾讯 DNS (DNSPod) 腾讯 DNS 是由 DNSPod 提供的公共免费 DNS 服务。DNSPod 已被腾讯收购&#xff0c;现在属于腾讯公司所有。该 DNS 服务稳定性和连通性良好&#xff0c;经测试在海外也可以使用。 DNSPod 提供了 IPv4、IPv6 DNS 和 DoT/DoH 服务。 IPv4 地址: 119.29.29.29…

fastapi教程(五):中间件

一&#xff0c;什么是中间件 中间件是一种软件组件&#xff0c;它在请求到达应用程序处理程序之前和/或响应发送回客户端之前执行操作。 请求从客户端发出。 请求首先经过Middleware 1。 然后经过Middleware 2。 请求到达FastAPI路由处理器。 响应从路由处理器返回。 响应经过…

精品PPT | 云原生大数据平台构建及落地实践.pptx

1、监控和可观测性的关系及渊源 2、当前阶段落地可观测性的挑战在哪里 3、落地好一个可观测系统的三大要素 4、面向故障处理过程的可观测性体系建设案例 5、思考&#xff1a;人工智能2.0对可观测性技术和产品演进的影响

鸿蒙开发—黑马云音乐之Music页面

目录 1.外层容器效果 2.信息区-发光效果 3.信息区-内容布局 4.播放列表布局 5.播放列表动态化 6.模拟器运行并配置权限 效果&#xff1a; 1.外层容器效果 Entry Component export struct MuiscPage {build() {Column() {// 信息区域Column() {}.width(100%)// .backgroun…

环形链表 II - 力扣(LeetCode)C语言

142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; (点击前方链接即可查看题目) 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达…

制造企业选型MES管理系统时需要关注的地方

在当今制造业全面拥抱数字化转型的浪潮中&#xff0c;MES管理系统解决方案的角色日益凸显&#xff0c;成为提升生产效率、优化资源配置的关键工具。对于制造企业而言&#xff0c;选择一款合适的MES管理系统不仅关乎当前的生产管理需求&#xff0c;更直接影响到企业未来的竞争力…

【React】详解classnames工具:优化类名控制的全面指南

文章目录 一、classnames的基本用法1. 什么是classnames&#xff1f;2. 安装classnames3. 导入classnames4. classnames的基本示例 二、classnames的高级用法1. 动态类名2. 传递数组3. 结合字符串和对象4. 结合数组和对象 三、实际应用案例1. 根据状态切换类名2. 条件渲染和类名…

【权威发布】第二届机械电子工程与软件工程国际会议(MEESE 2024)

第二届机械电子工程与软件工程国际会议 2024 International Conference on Mechanical and Electronic Engineering and Software Engineering 【1】会议简介 第二届机械电子工程与软件工程国际会议是一个专注于机械电子工程与软件工程领域交叉融合的国际盛会。会议旨在汇聚全球…

Vue3可媲美Element Plus Tree组件研发之重命名节点

在上一节《移除节点》基础上继续迭代JuanTree的功能&#xff0c;我们将实现节点重命名的功能。 实现效果&#xff1a; 可以对现有节点进行编辑&#xff0c;点回车或失去焦点完成编辑&#xff0c;如果输入为空&#xff0c;会恢复为原来的值。同时支持对新增的节点自动启用编辑功…

花几千上万学习Java,真没必要!(三十四)

1、泛型类&#xff1a; 测试代码&#xff1a; 创建一个Box类; package settest.com; public class Box<T> { // T stands for "Type" - T是一个占位符&#xff0c;用于表示具体的类型 // 类的内部可以使用T作为类型声明变量 private T t; // 构造方法&am…

ROS中使用rqt_plot快速实现数据可视化

对数据进行可视化有很多好处&#xff0c;比如可以帮助我们快速判断机器人运动轨迹是否平滑。 一般来说&#xff0c;我们会将数据保存为文件&#xff0c;然后进行绘图&#xff0c;但是在ROS中&#xff0c;有一个很好用的工具&#xff0c;叫rqt_plot&#xff0c;用它可以快速实现…

力扣高频SQL 50题(基础版)第二十四题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第二十四题1729.求关注者的数量题目说明实现过程准备数据实现方式结果截图 力扣高频SQL 50题&#xff08;基础版&#xff09;第二十四题 1729.求关注者的数量 题目说明 表&#xff1a; Followers ----------------…

Maven已经导入Junit包,但是还是无法使用注解

Maven已经导入Junit包&#xff0c;但是还是无法使用注解 背景&#xff1a; 导入了Junit的依赖 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></d…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第六十五章 Linux I2C驱动实验

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

Qt编写自定义控件:跑马灯文本控件

#ifndef RUNNINGTEXTWIDGET_H #define RUNNINGTEXTWIDGET_H#include <QWidget>enum Direction {North 0, //上South, //下West, //左East //右 };class RunningTextWidget : public QWidget {Q_OBJECT public:explicit RunningTextWidget(QWidget *parent nullptr);…

第二期:集成电路(IC)——智能世界的微观建筑大师

嘿&#xff0c;小伙伴们&#xff01;&#x1f44b; 我是你们的老朋友小竹笋&#xff0c;一名热爱创作和技术的工程师。上一期我们聊了聊AI芯片&#xff0c;这次我们要深入到更微观的层面&#xff0c;来探究集成电路&#xff08;IC&#xff09;的世界。准备好一起探索了吗&#…

50+受高度近视屈光参差与白内障阻碍,巫雷院长一场手术“均衡”双眼

周女士双眼近视度数一直差异很大&#xff0c;这么多年从未看清。“这次”是因为发现视力逐渐下降检查得知并发性白内障&#xff0c;以屈光性白内障手术得以一次性治疗多个问题。 周女士小时候就近视了&#xff0c;那时家里不重视&#xff0c;且自己觉得戴眼镜“不好”&#xf…