首页 > 其他分享 >基于 STM32 和 Modbus 协议的公路隧道照明环境数据采集系统设计

基于 STM32 和 Modbus 协议的公路隧道照明环境数据采集系统设计

时间:2024-09-25 18:49:59浏览次数:3  
标签:STM32 HAL Modbus 采集 Init GPIO DHT11

一、项目概述

在现代高速公路的隧道照明系统中,实时监控环境参数(如照度、温度和湿度)是确保安全与高效运营的重要环节。本项目旨在设计一个多通道数据采集器,能够实时采集隧道内的照明及环境数据,并通过工业标准的 Modbus 协议将数据传输到上位机进行监控和分析。

技术栈关键词

  • 单片机: STM32

  • 传感器: BH1750(照度传感器),DHT11(温度湿度传感器)

  • 通信协议: Modbus

  • 数据传输: I²C(用于BH1750),单总线(用于DHT11)

二、系统架构

设计系统架构

系统架构的设计旨在满足数据采集的实时性和准确性需求。整体架构包括数据采集模块、数据处理模块和数据传输模块。STM32作为主控制器,负责协调各个模块的工作。

选择的硬件组件

  • STM32: 作为主控制器,具备强大的处理能力和丰富的外设接口。

  • BH1750: 精确的数字光照传感器,通过 I²C 协议进行通信。

  • DHT11: 低成本的温湿度传感器,通过单总线协议进行通信。

系统架构图

以下是系统架构图,清晰展示了各组件之间的关系和通信方式。

STM32 BH1750 DHT11 Modbus 发送读取照度命令 返回照度数据 发送读取温湿度命令 返回温湿度数据 发送数据到上位机 STM32 BH1750 DHT11 Modbus

三、环境搭建和注意事项

环境搭建

  1. 硬件准备:

    • STM32开发板(如STM32F103C8T6)

    • BH1750传感器模块

    • DHT11传感器模块

    • jumper线、面包板等

  2. 软件环境:

    • 开发环境: STM32CubeIDE

    • 库文件: STM32 HAL库、Modbus库、I²C库

  3. 注意事项:

  • 确保各传感器的电源电压符合要求。

  • 在连接传感器时注意I²C和单总线的引脚配置。

  • 使用外部上拉电阻确保数据传输的可靠性。

四、代码实现过程

在本节中,我们将详细介绍基于 STM32 和 Modbus 协议的公路隧道照明多通道数据采集器的代码实现过程。整个实现过程包括多个功能模块的设计与集成,我们将对每个模块的代码逻辑、工作流程、时序图等进行深入分析和说明。

1. 照度采集模块

1.1 模块概述

照度采集模块主要负责从 BH1750 传感器读取光照强度数据。BH1750 是一款高精度的数字光照传感器,支持 I²C 通信协议,具备快速响应能力,适合用于隧道照明的实时监控。

1.2 硬件连接
  • I²C 引脚配置:

  • SCL (时钟线) 连接到 STM32 的 I²C1_SCL

  • SDA (数据线) 连接到 STM32 的 I²C1_SDA

  • VCC 连接到 STM32 的 3.3V

  • GND 连接到 STM32 的 GND

1.3 代码实现

I²C 初始化

首先,我们需要初始化 I²C 总线,以便与 BH1750 进行通信。以下是 I²C 初始化的代码示例:

#include "stm32f1xx_hal.h"

I2C_HandleTypeDef hi2c1;

void MX_I2C1_Init(void) {
    hi2c1.Instance = I2C1;
    hi2c1.Init.ClockSpeed = 100000; // I²C 时钟频率
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    HAL_I2C_Init(&hi2c1);
}

读取照度数据

接下来,我们实现读取照度数据的函数。该函数会向 BH1750 发送读取命令,然后读取并返回光照强度值。

#define BH1750_ADDRESS 0x23 // BH1750 设备地址

float Read_Lux(void) {
    uint8_t cmd = 0x01; // 启动测量
    uint8_t data[2];
    
    // 发送启动命令
    HAL_I2C_Master_Transmit(&hi2c1, BH1750_ADDRESS, &cmd, 1, HAL_MAX_DELAY);
    
    // 延时等待转换
    HAL_Delay(180);
    
    // 读取数据
    HAL_I2C_Master_Receive(&hi2c1, BH1750_ADDRESS, data, 2, HAL_MAX_DELAY);
    
    // 计算照度值
    uint16_t lux = (data[0] << 8) | data[1];
    return (float)(lux / 1.2); // 转换为 lux
}

2. 温湿度采集模块

2.1 模块概述

温湿度采集模块主要负责与 DHT11 传感器进行通信,获取环境温度和湿度数据。DHT11 是一种低成本的数字温湿度传感器,适合用于环境监测。

2.2 硬件连接
  • 单总线连接:

    • DHT11 的 DATA 引脚连接到 STM32 的 GPIO 引脚(如 PA0),需要配置为输入输出模式。

    • VCC 连接到 STM32 的 3.3V

    • GND 连接到 STM32 的 GND

2.3 代码实现

DHT11 读取函数

以下是 DHT11 读取温度和湿度的函数实现,采用单总线协议进行通信。

#include "dht11.h"

// DHT11 读取温度和湿度
void Read_Temp_Humidity(float* temperature, float* humidity) {
    uint8_t data[5] = {0}; // 存储数据的数组
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 初始化 GPIO
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_0; // 假设 DATA 引脚连接到 PA0
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 向 DHT11 发送起始信号
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // 拉低信号线
    HAL_Delay(18); // 保持低电平18ms
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 拉高信号线
    HAL_Delay(20); // 等待 DHT11 反应

    // 设置信号线为输入
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // DHT11 响应信号
    while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)); // 等待连接
    while (!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)); // 等待 DHT11 拉低信号
    while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)); // 等待 DHT11 拉高信号

    // 读取 40 位数据
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 8; j++) {
            while (!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)); // 等待拉高
            HAL_Delay(30); // 等待 30us
            if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)) {
                data[i] |= (1 << (7 - j)); // 记录数据
            }
            while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)); // 等待拉低
        }
    }

    // 数据验证
    if (data[4] == (data[0] + data[1] + data[2] + data[3])) {
        *humidity = data[0]; // 湿度
        *temperature = data[2]; // 温度
    } else {
        *humidity = -1; // 错误
        *temperature = -1; // 错误
    }
}

3. 数据传输模块

3.1 模块概述

数据传输模块负责将采集到的照度、温度和湿度数据通过 Modbus 协议发送到上位机。Modbus 是一种广泛使用的通信协议,适用于工业设备之间的数据交换。

3.2 硬件连接
  • 串口连接:

    • 使用 STM32 的 USART 接口(如 USART1)连接到 Modbus 上位机。

    • TX 引脚连接到上位机的 RX,引脚连接为 RX。

3.3 代码实现

Modbus 初始化

首先,我们需要初始化 USART 以便进行数据传输。

#include "usart.h"

UART_HandleTypeDef huart1;

void MX_USART1_UART_Init(void) {
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 9600;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&huart1);
}

Modbus 数据发送

接下来,我们实现一个函数,用于通过 Modbus 协议发送数据。

#include "modbus.h"

// 发送 Modbus 数据
void Send_Data(float lux, float temperature, float humidity) {
    uint8_t buffer[32];
    int length = snprintf((char*)buffer, sizeof(buffer),
                          "Lux: %.2f, Temperature: %.2f, Humidity: %.2f\n", lux, temperature, humidity);
    
    // 通过 USART 发送数据
    HAL_UART_Transmit(&huart1, buffer, length, HAL_MAX_DELAY);
}

4. 主程序逻辑

在主程序中,我们将整合以上模块,实现数据的周期性采集和传输。

#include "main.h"

int main(void) {
    HAL_Init(); // 初始化 HAL 库
    SystemClock_Config(); // 配置系统时钟
    // 初始化 I2C 和 USART
    MX_I2C1_Init();
    MX_USART1_UART_Init();

    // 主循环
    while (1) {
        float lux = Read_Lux(); // 读取照度
        float temperature, humidity;
        Read_Temp_Humidity(&temperature, &humidity); // 读取温湿度

        // 发送数据到上位机
        Send_Data(lux, temperature, humidity);

        // 延时一段时间(例如 1 秒)
        HAL_Delay(1000);
    }
}

标签:STM32,HAL,Modbus,采集,Init,GPIO,DHT11
From: https://blog.csdn.net/qq_40431685/article/details/142530542

相关文章

  • 基于WebServer的工业数据采集系统
     一、项目框架及流程二、http简介HTTP协议是HyperTextTransferProtocol(超文本传输协议)的缩写,是用于WebBrowser(浏览器)到WebServer(服务器)进行数据交互的传输协议。HTTP是应用层协议HTTP是一个基于TCP通信协议传输来传递数据(HTML文件,图片文件,查询结果等)HTTP协议......
  • 基于STM32单片机的病人护理监测系统
    基于STM32单片机的病人护理监测系统0、毕业设计选题原则说明(重点)1、项目简介1.1系统功能1.2演示视频2、部分电路设计2.1STM32单片机核心板电路设计2.2DS18B20温度采集电路2.3MKB0805血压心率检测电路设计2.4、非接触式水位检测电路设计2.5、OLED显示电路设计3、单片机代码展......
  • 基于STM32单片机的厨房天然气蓝牙手机APP检测GSM短信报警系统
    基于STM32单片机的厨房天然气蓝牙手机APP检测GSM短信报警系统0、毕业设计选题原则说明(重点)1、项目简介1.1系统功能1.2演示视频2、部分电路设计2.1STM32单片机核心板电路设计2.2HC05蓝牙无线通信电路设计2.3sim900AGSM短信报警电路2.4、MQ-4天然气检测电路设计2.5、HC-SR505......
  • 基于STM32单片机的OneNet物联网云平台血压心率体温摔倒检测系统
    基于STM32单片机的OneNet物联网云平台血压心率体温摔倒检测系统0、毕业设计选题原则说明(重点)1、项目简介1.1、系统功能1.2、演示视频2、部分电路设计2.1、STM32单片机核心板电路设计2.2、ESP8266WIFI电路设计2.3、MKB0805血压心率检测电路设计2.4、ADXL345摔倒检测电路设计2.5、D......
  • 基于STM32单片机的OPENMV颜色识别小球追踪系统设计
    基于STM32单片机的OPENMV颜色识别小球追踪系统设计0、毕业设计选题原则说明(重点)1、项目简介1.1、系统功能1.2、演示视频2、部分电路设计2.1、STM32单片机核心板电路设计2.2、openmv使用说明2.3、stm32与openmv通信电路设计2.4、OLED液晶显示电路设计2.5、二维云台控制电路3、单片......
  • 基于STM32单片机的声音压力红外检测OneNET云平台防盗设计
    基于STM32单片机的声音压力红外检测OneNET云平台防盗设计0、毕业设计选题原则说明(重点)1、项目简介1.1系统功能1.2演示视频2、部分电路设计2.1STM32单片机核心板电路设计2.2HX711压力重力检测电路设计2.3ESP8266WIFI无线通信电路设计2.4、声音检测电路设计3、单片机代码展示3......
  • STM32CubeMX+usart+DMA+Modbus从机
    前言单片机型号STM32f103zet6使用USART1串口来实现DMA收发使用DMA1通道5,来传输USART1接收的数据使用DMA1通道4,来传输USART1发送的数据实现了Modbus从机协议(03和06功能)1.准备工作modbuspoll和modbusslave模拟软件下载链接:https://pan.baidu.com/s/1cX8HC-rm3gsM......
  • modbus 的 输入和输出
    modbus的输入和输出1.输入线圈输出线圈2.输入寄存器输出寄存器保持寄存器什么是线圈?线圈就是一种只能有0和1(或者开和关)两种状态的一种寄存器俗称线圈寄存器它一般用来表示或者控制设备元器件的开或关的状态在PLC中一般包括两种线圈:输入线圈和输出线......
  • 推荐一款Modbus转OPC UA协议软件
    在很多工业自动化领域OPCUA协议使用非常广泛,而很多PLC或其他控制系统RFID控制机、视觉控制器等采用Modbus协议比较多,这就存在不同系统因为使用不同协议而无法交付,下面我介绍一款软件可以完美解决Modbus和OPCUA协议无法通信问题。该软件是一款国内公司开发的纯国产软件,下载地......
  • modbus设备数据 转 profinet IO项目案例
    目录1案例说明12VFBOX网关工作原理13准备工作24设置网关采集MODBUS从站数据25用PROFINETIO协议转发数据86案例总结101案例说明设置网关采集Modbus设备数据把采集的数据转成profinetIO协议转发给其他系统。2VFBOX网关工作原理VFBOX网关是协议转换网关,是把一......