基于单片机的家用智能浇灌系统

这篇具有很好参考价值的文章主要介绍了基于单片机的家用智能浇灌系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、开发环境

keil5,STM32CubeMX、Altium Designer

2、硬件清单

单片机:STM32F051K8Ux

土壤湿度传感器:TL - 69

温度传感器:DS18B20(数字传感器直接输出数字信号)

OLED屏幕:OLED12864、

水泵:L9110等;

3、功能设计

传感器采集空气和土壤的温度以及湿度,将数据传输给单片机,经单片机处理后输出在OLED显示屏上。

4、硬件连接

  • 将温度传感器DS18B20、土壤湿度传感器YL - 69、水泵L9110、连接到STM32的GPIO引脚上。
  • 将OLED屏幕OLED12862连接到STM32的I2C引脚上。

5、功能分析

5.1总体功能

  • 使用STM32的GPIO库和I2C库来配置和读取传感器数据。
  • 编写代码来读取温度传感器DS18B20、湿度传感器YL - 69的数据。
  • 根据传感器数据,编写代码判断植物是否需要灌溉,如果需要浇灌,使用GPIO库来控制水泵L9110的开关。
  • 使用STM32的I2C库来驱动oled显示屏。
  • 编写代码来实现空气温度和土壤湿度数据到OLED屏幕上。

5.2传感器采集数据

1. DS18B20温度传感器数据采集:

   - DS18B20是一种数字温度传感器,采用单总线接口进行通信。单片机通过GPIO口与DS18B20进行通信。

   - 通信过程中,单片机发送指令给DS18B20,例如读取温度的指令。

   - DS18B20将温度数据以序列的形式通过单总线返回给单片机。单片机通过接收和解析这个序列,得到DS18B20传感器的原始温度数据。

   - 单片机可以通过读取DS18B20的原始温度数据,并进行相应的计算,得到实际的温度值。

2. YL69湿度传感器数据采集:

   - YL69湿度传感器是一种模拟湿度传感器,输出模拟电压信号。它通常需要一个模数转换器(ADC)将模拟信号转换为数字信号,以便单片机进行处理。

   - 单片机通过GPIO口与YL69湿度传感器进行通信,读取YL69湿度传感器的模拟电压信号。

   - 单片机将YL69湿度传感器的模拟电压信号输入到内部的ADC模块中进行转换。

   - ADC模块将模拟电压信号转换为数字信号,并将转换后的数字数据传递给单片机。

   - 单片机可以通过读取ADC转换后的数字数据,并进行相应的处理,得到YL69湿度传感器的湿度值。

需要注意的是,具体的数据采集方式和通信协议可能因单片机、传感器和硬件平台的不同而有所差异。因此,在实际应用中,需要根据所使用的硬件和软件平台的要求,以及传感器的规格和接口,进行相应的配置和编程。以上是一种可能的实现方式,具体的实现细节可能会有所不同。

6、代码编写

1、GPIO管脚配置

可以在STM32CubeMX中选择相应的引脚,并将其配置为推挽输出模式,然后生成相应的代码。

void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能GPIOA和GPIOB的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);

    // 配置PA0引脚为推挽输出
    GPIO_InitStructure.GPIO_Pin = PUMP_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

2、配置 I2C

在STM32CubeMX中,可以通过图形化界面选择I2C外设并进行相应的配置,然后生成对应的代码。

步骤如下:

1. 打开STM32CubeMX软件,并创建一个新的工程。

2. 选择目标STM32F051K8Ux微控制器型号。

3. 在"Pinout & Configuration"选项卡中,找到I2C1外设,并配置相关的引脚。

4. 在"Configuration"选项卡中,找到I2C1外设,并设置相关的参数,如时钟速度、地址等。

5. 确认配置无误后,点击"Project"菜单,选择"Generate Code"生成代码。

6. 在生成的代码中,可以找到类似于你提供的`I2C_Configuration`函数的代码。

void I2C_Configuration(void)
{
    I2C_InitTypeDef I2C_InitStructure;

    // 使能I2C1的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    // 配置I2C1的引脚
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 配置I2C1的参数
    I2C_DeInit(I2C1);
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 100000;
    I2C_Init(I2C1, &I2C_InitStructure);

    // 使能I2C1
    I2C_Cmd(I2C1, ENABLE);
}

3、温度采集函数

void DS18B20_ReadTemperature(float *temperature)
{
    uint8_t buffer[2];

    // 发送读取温度命令
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
        ;
    I2C_Send7bitAddress(I2C1, DS18B20_ADDRESS, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
        ;
    I2C_SendData(I2C1, 0x00);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;
    I2C_GenerateSTOP(I2C1, ENABLE);

    // 读取温度数据
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
        ;
    I2C_Send7bitAddress(I2C1, DS18B20_ADDRESS, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
        ;
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    buffer[0] = I2C_ReceiveData(I2C1);
    I2C_AcknowledgeConfig(I2C1, DISABLE);
    I2C_GenerateSTOP(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    buffer[1] = I2C_ReceiveData(I2C1);

    // 计算温度值
    *temperature = (float)((buffer[1] << 8) | buffer[0]) / 16.0;
}

DS18B20_ReadTemperature函数从连接到I2C总线的DS18B20温度传感器中读取温度数据。以下是它的工作原理的逐步解释:

1. 声明一个数组 buffer 来存储2个字节的温度数据。

2. 通过在I2C总线上生成起始条件并将传感器选择为发送器,发送读取温度的命令。

3. 等待主发送器模式被选中,然后将温度寄存器的地址(0x00)发送给传感器。

4. 等待字节传输完成,然后生成停止条件来结束传输。

5. 通过在I2C总线上生成起始条件并将传感器选择为接收器,发送读取温度数据的命令。

6. 等待主接收器模式被选中,然后等待字节接收完成。

7. 将接收到的字节存储在 buffer[0] 中。

8. 禁用应答位,表示不再接收更多的字节。

9. 生成停止条件来结束传输。

10. 等待字节接收完成,并将其存储在 buffer[1] 中。

11. 通过将 buffer 中的两个字节组合起来并除以16.0来计算温度值。

12. 将温度值存储在由 temperature 指针指向的内存位置中。

总体而言,该函数从DS18B20传感器中读取温度数据,并计算出摄氏度的温度值。温度值然后存储在由 temperature 指针指向的内存位置中,以供进一步使用。

4、湿度采集函数

void YL69_ReadHumidity(float *humidity)
{
    uint8_t buffer[2];

    // 发送读取湿度命令
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
        ;
    I2C_Send7bitAddress(I2C1, YL69_ADDRESS, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
        ;
    I2C_SendData(I2C1, 0x00);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;
    I2C_GenerateSTOP(I2C1, ENABLE);

    // 读取湿度数据
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
        ;
    I2C_Send7bitAddress(I2C1, YL69_ADDRESS, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
        ;
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    buffer[0] = I2C_ReceiveData(I2C1);
    I2C_AcknowledgeConfig(I2C1, DISABLE);
    I2C_GenerateSTOP(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    buffer[1] = I2C_ReceiveData(I2C1);

    // 计算湿度值
    *humidity = (float)((buffer[1] << 8) | buffer[0]) / 1024.0 * 100.0;
}

读取YL69湿度传感器的湿度值,并将结果存储在 humidity 指针指向的内存位置中。

1. 定义一个 buffer 数组,用于存储从传感器读取的数据。

2. 发送读取湿度命令:

   - 生成起始条件,启动I2C总线。

   - 等待主模式选择事件。

   - 发送传感器的I2C地址和传输方向(发送器)。

   - 等待主传输器模式选择事件。

   - 发送读取湿度数据的命令(0x00)。

   - 等待主字节传输完成事件。

   - 生成停止条件,结束传输。

3. 读取湿度数据:

   - 生成起始条件,启动I2C总线。

   - 等待主模式选择事件。

   - 发送传感器的I2C地址和传输方向(接收器)。

   - 等待主接收器模式选择事件。

   - 等待主字节接收完成事件。

   - 将接收到的字节存储在 buffer[0] 中。

   - 禁用应答位,表示不再接收更多的字节。

   - 生成停止条件,结束传输。

   - 等待主字节接收完成事件。

   - 将接收到的字节存储在 buffer[1] 中。

4. 计算湿度值:

   - 将 buffer[1] 左移8位后与 buffer[0] 进行按位或操作,得到16位的湿度数据。

   - 将湿度数据转换为浮点型,除以1024.0后乘以100.0,得到湿度百分比值。

   - 将湿度百分比值存储在由 humidity 指针指向的内存位置中。

总体而言,这段代码通过I2C总线与YL69湿度传感器进行通信,发送读取湿度命令并读取湿度数据。然后,它将读取到的湿度数据转换为百分比值,并将结果存储在由`humidity`指针指向的内存位置中。文章来源地址https://www.toymoban.com/news/detail-643978.html

7、完整代码

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_i2c.h"
#include "stdio.h"

#define DS18B20_ADDRESS 0x48
#define YL69_ADDRESS 0x5C
#define PUMP_PIN GPIO_Pin_0

void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能GPIOA和GPIOB的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);

    // 配置PA0引脚为推挽输出
    GPIO_InitStructure.GPIO_Pin = PUMP_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void I2C_Configuration(void)
{
    I2C_InitTypeDef I2C_InitStructure;

    // 使能I2C1的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    // 配置I2C1的引脚
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 配置I2C1的参数
    I2C_DeInit(I2C1);
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 100000;
    I2C_Init(I2C1, &I2C_InitStructure);

    // 使能I2C1
    I2C_Cmd(I2C1, ENABLE);
}

void DS18B20_ReadTemperature(float *temperature)
{
    uint8_t buffer[2];

    // 发送读取温度命令
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
        ;
    I2C_Send7bitAddress(I2C1, DS18B20_ADDRESS, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
        ;
    I2C_SendData(I2C1, 0x00);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;
    I2C_GenerateSTOP(I2C1, ENABLE);

    // 读取温度数据
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
        ;
    I2C_Send7bitAddress(I2C1, DS18B20_ADDRESS, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
        ;
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    buffer[0] = I2C_ReceiveData(I2C1);
    I2C_AcknowledgeConfig(I2C1, DISABLE);
    I2C_GenerateSTOP(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    buffer[1] = I2C_ReceiveData(I2C1);

    // 计算温度值
    *temperature = (float)((buffer[1] << 8) | buffer[0]) / 16.0;
}

void YL69_ReadHumidity(float *humidity)
{
    uint8_t buffer[2];

    // 发送读取湿度命令
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
        ;
    I2C_Send7bitAddress(I2C1, YL69_ADDRESS, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
        ;
    I2C_SendData(I2C1, 0x00);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
        ;
    I2C_GenerateSTOP(I2C1, ENABLE);

    // 读取湿度数据
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
        ;
    I2C_Send7bitAddress(I2C1, YL69_ADDRESS, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
        ;
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    buffer[0] = I2C_ReceiveData(I2C1);
    I2C_AcknowledgeConfig(I2C1, DISABLE);
    I2C_GenerateSTOP(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        ;
    buffer[1] = I2C_ReceiveData(I2C1);

    // 计算湿度值
    *humidity = (float)((buffer[1] << 8) | buffer[0]) / 1024.0 * 100.0;
}

void ControlPump(float temperature, float humidity)
{
    if (temperature > 25.0 && humidity < 50.0) {
        // 打开水泵
        GPIO_SetBits(GPIOA, PUMP_PIN);
    } else {
        // 关闭水泵
        GPIO_ResetBits(GPIOA, PUMP_PIN);
    }
}

void OLED_WriteString(uint8_t row, uint8_t col, char *str)
{
    // 在OLED屏幕上写入字符串
    // ...
}

void OLED_Clear(void)
{
    // 清空OLED屏幕
    // ...
}

void DisplayData(float temperature, float humidity)
{
    char str[16];

    // 清空OLED屏幕
    OLED_Clear();

    // 显示温度数据
    sprintf(str, "Temp: %.2f C", temperature);
    OLED_WriteString(0, 0, str);

    // 显示湿度数据
    sprintf(str, "Humidity: %.2f%%", humidity);
    OLED_WriteString(1, 0, str);
}

int main(void)
{
    float temperature, humidity;

    // 初始化GPIO和I2C
    GPIO_Configuration();
    I2C_Configuration();

    while (1) {
        // 读取温度数据
        DS18B20_ReadTemperature(&temperature);

        // 读取湿度数据
        YL69_ReadHumidity(&humidity);

        // 控制水泵
        ControlPump(temperature, humidity);

        // 在OLED屏幕上显示数据
        DisplayData(temperature, humidity);

        // 延时一段时间
        // ...
    }
}

到了这里,关于基于单片机的家用智能浇灌系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【毕业设计】基于Arduino的智能灌溉系统 - 嵌入式 单片机 物联网

    Hi,大家好,这里是丹成学长,今天向大家介绍一个 单片机项目,大家可用于 课程设计 或 毕业设计 基于Arduino的智能灌溉系统 单片机-嵌入式毕设选题大全及项目分享: https://blog.csdn.net/m0_71572576/article/details/125409052 rduino NANO开发板 1块 IO扩展板 1块 IO扩展模块包 1套 开发工具

    2024年02月05日
    浏览(140)
  • 单片机项目分享 单片机家用燃气的可视化实时监控报警仪 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月22日
    浏览(75)
  • 【单片机毕设选题】 stm32智能运动计步系统 - 物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(67)
  • 嵌入式项目分享 单片机家用燃气的可视化实时监控报警仪 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月22日
    浏览(60)
  • 物联网项目分享 单片机家用燃气的可视化实时监控报警仪 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(47)
  • 毕设开源 基于stm32的智能平衡小车 - 单片机 物联网嵌入式

    文章目录 0 前言 1 项目背景 2 设计思路 3 硬件设计 4 软件设计 4.2 直立控制程序设计 4.3 速度控制程序设计 4.4 方向控制程序设计 4.5 关键代码 5 最后 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这

    2024年02月22日
    浏览(64)
  • 单片机项目分享 Stm32 WIFI智能家居温湿度和烟雾检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月19日
    浏览(68)
  • 单片机项目分享 基于stm32的便携用电功率统计系统 -物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月19日
    浏览(113)
  • 【毕业设计】基于STM32的智能路灯设计与实现 - 物联网 嵌入式 单片机

    Hi,大家好,这里是丹成学长,今天向大家介绍一个 单片机项目 基于STM32的智能路灯设计与实现 大家可用于 课程设计 或 毕业设计 单片机-嵌入式毕设选题大全及项目分享: https://blog.csdn.net/m0_71572576/article/details/125409052 每当夜幕降临,城市中各种各样、色彩缤纷的路灯亮起,

    2024年01月16日
    浏览(68)
  • 毕业设计 - 基于STM32的智能路灯设计与实现 - 物联网 嵌入式 单片机

    Hi,大家好,今天向大家介绍一个 单片机项目 基于STM32的智能路灯设计与实现 大家可用于 课程设计 或 毕业设计 🔥 项目分享与指导: https://gitee.com/sinonfin/sharing 每当夜幕降临,城市中各种各样、色彩缤纷的路灯亮起,为城市披上了一层绚丽的外衣。但在这绚丽的外表下则隐

    2024年02月05日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包