项目开源,链接在文章最后。

一.项目背景

随着物联网和智能技术的不断发展,智慧仓储系统在仓储管理中扮演着越来越重要的角色。然而,传统的仓储管理存在着诸如火灾、烟雾和有毒气体等安全隐患,缺乏实时监测和预防机制,因此容易导致财产损失和人员伤亡。此外,传统的仓储管理也未能充分监测温湿度、气体等环境因素,这容易导致货物受损、腐败、发霉等问题,从而影响货物质量和库存周期。此外,传统的仓储管理需要人工实地检测仓库状况,而未能实现对仓库状况的远程监测。因此,迫切需要一种更智能、更高效的监测系统来提升仓储管理水平。为此,本项目基于OpenHarmony与OneNet平台,利用多种传感器和技术,设计并实现了一种智慧仓储监测系统,旨在实现对仓储环境、安全等方面的实时监测和管理.

.项目内容及研究意义

1.项目内容:

本项目主要涉及火焰检测模块、人体红外检测模块、WiFi模块、语音模块、有害气体检测模块、喷雾模块以及温湿度传感器等关键技术和模块。具体内容包括:

火焰检测模块: 用于监测仓储环境中的火焰情况,一旦检测到火焰,系统将立即发出警报并采取相应措施。

1、可以检测火焰或者波长在760纳米~1100纳米范围内的光源,打火机测试火焰距离为80cm,对火焰越大,测试距离越远
2、探测角度60度左右,对火焰光谱特别灵敏
3、灵敏度可调(图中蓝色数字电位器调节)
4、比较器输出,信号干净,波形好,驱动能力强,超过15mA5、配可调精密电位器调节灵敏度
6、:工作电压3.3-5V
7、输出形式:Do数字开关量输出(0和1)和Ao模拟电压输出8、设有固定螺栓孔,方便安装
9、小板PCB尺寸:32mm* 14mm10、使用宽电压LM393比较器
有害气体检测模块: 用于检测仓储环境中的气体浓度,特别是可燃气体,以确保仓储环境的安全。

MQ135气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(Sno2)。当传感器所处环境中存在污染气体时,传感器的电导率随空气中污染气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。
MQ135传感器对氨气、硫化物、苯系蒸汽的灵敏度高,对烟雾和其它有害的监测也很理想。这种传咸器可检测多种有害气体,是一款适合多种应用的低成本传感器。
 

小熊派使用说明:可以使用其DO口直接读取其TTL电平,也可读取AO口,进行adc采集读取电压值。我采用的是采集ADC值进行安全判断:

依据BearPi_HM Nano的芯片手册,小熊派有7个ADC采集接口通道,其中GPIO4对应ADC1,GPIO7对应ADC3。

////**********ADC********/////
////**********ADC********/////
////**********ADC********/////
/***** 获取电压值函数 *****/
static float GetVoltage(int i)
{
    unsigned int ret;
    unsigned short data;
    if(i==0)
        ret = AdcRead(WIFI_IOT_ADC_CHANNEL_1, &data, WIFI_IOT_ADC_EQU_MODEL_8, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
    else
        ret = AdcRead(WIFI_IOT_ADC_CHANNEL_3, &data, WIFI_IOT_ADC_EQU_MODEL_8, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
    if (ret != WIFI_IOT_SUCCESS)
    {
        printf("ADC Read Fail\n");
    }
    return (float)data*100/2300 ;
}
float voltage_MQ,voltage_FIRE;
static void ADCTask(void)
{
    //AO接口
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_4, WIFI_IOT_IO_PULL_NONE);//MQ
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_7, WIFI_IOT_IO_PULL_NONE);//FIRE
    //DO接口
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_PULL_NONE);//MQ
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_12, WIFI_IOT_IO_PULL_NONE);//FIRE
    while (1)
    {
        //获取电压值
        voltage_MQ = GetVoltage(1);
        printf("MQ:%.3f\n", voltage_MQ);
        if(voltage_MQ>=50){
            UartWrite(WIFI_IOT_UART_IDX_1, &dataToSend_mq, 1);        
            shan_on;    
        }
        usleep(500000);

        voltage_FIRE = 100-GetVoltage(0);
        printf("fire:%.3f\n", voltage_FIRE);
        if(voltage_FIRE>=50){
            UartWrite(WIFI_IOT_UART_IDX_1, &dataToSend_fire, 1);          
            peng_on;          
        }

        usleep(500000);
    }
}

温湿度传感器: 用于监测仓储环境的温湿度情况,以确保货物的质量和储存条件。

1、可以检测周围环境的湿度和温度2、传感器采用DHT11
3、湿度测量范围:20%-95%(0度-50度范围)湿度测量误差:+-5%4、温度测量范围:0度-50度温度测量误差:+-2度
4、工作电压3.3v-5V
5、输出形式数字输出
6、设有固定螺栓孔,方便安装7、小板PCB尺寸: 3.2cm * 1.4cm8、电源指示灯(红色)
9、每套重量约为8g
依据DHT11的手册根据其内的时序图我们可以写出小熊派读取DHT11的代码:

////**********DHT11********/////
////**********DHT11********/////
////**********DHT11********/////
#define  DHT11_OUT  PC_OUT(13)
#define  DHT11_IN   PC_IN(13)
/*DHT11复位和检测响应函数,返回值:1-检测到响应信号;0-未检测到响应信号*/
WifiIotGpioValue inputdata={0};
WifiIotGpioValue outputdata={0};
// //应该延时了1us吧
void delay_us(int num)
{
    while(num--)
    {
        for(int i=0;i<25;i++){}
    }
}
int DHT11RstAndCheck(void)
{
     int timer = 0;
    GpioInit();
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13,WIFI_IOT_IO_FUNC_GPIO_13_GPIO);
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_PULL_UP);
    GpioSetDir(WIFI_IOT_GPIO_IDX_13,WIFI_IOT_GPIO_DIR_OUT);
    GpioSetOutputVal(WIFI_IOT_GPIO_IDX_13,0);
    osDelay(2U);
    GpioSetOutputVal(WIFI_IOT_GPIO_IDX_13,1);
     delay_us(30);     	       //拉高20~40us  
    GpioSetDir(WIFI_IOT_GPIO_IDX_13,WIFI_IOT_GPIO_DIR_IN);
    GpioGetInputVal(WIFI_IOT_GPIO_IDX_13,&inputdata);
    int num=0;
    while(inputdata&&num<=100)
    {
        num++;
        GpioGetInputVal(WIFI_IOT_GPIO_IDX_13,&inputdata);
    }
    if(num>100)return 0;
    while(!inputdata&&timer<=100)
    {
        timer++;
        delay_us(1);
        GpioGetInputVal(WIFI_IOT_GPIO_IDX_13,&inputdata);
    }
 
    if (timer>100 || timer<20) //判断响应时间
    {
        return 0;
    }
    timer = 0;
    while(inputdata&&timer<=100)
    {
        timer++;
        GpioGetInputVal(WIFI_IOT_GPIO_IDX_13,&inputdata);
        delay_us(1);
    }
    if (timer>100 || timer<20) //检测响应信号之后的高电平
    {
        return 0;
    }
    return 1;
}
 
 
// /*读取一字节数据,返回值-读到的数据*/
int DHT11ReadByte(void)
{
    uint8_t i;
    int byt = 0;
    for (i=0; i<8; i++)
    {
        GpioGetInputVal(WIFI_IOT_GPIO_IDX_13,&inputdata);
        int num=0;
        while (inputdata&&num<=100)  //等待低电平,数据位前都有50us低电平时隙
        {
            GpioGetInputVal(WIFI_IOT_GPIO_IDX_13,&inputdata);
            num++;
        }
        num=0;
        while (!inputdata&&num<=100) //等待高电平,开始传输数据位
        {
            GpioGetInputVal(WIFI_IOT_GPIO_IDX_13,&inputdata);
            num++;
        }
        num=0;
        while(inputdata&&num<=80)
        {
            GpioGetInputVal(WIFI_IOT_GPIO_IDX_13,&inputdata);
            num++;
        }
        byt <<= 1;         //因高位在前,所以左移byt,最低位补0
        if (num>30)      //将总线电平值读取到byt最低位中
        {
            byt |= 0x01;
        }
    }
 
    return byt;
}
 
// /*读取一次数据,返回值:Humi-湿度整数部分数据,Temp-温度整数部分数据;返回值: -1-失败,1-成功*/
int DHT11ReadData(int *Humi, int *Temp)
{
    //printf("access\n");
    int sta = 0;
    uint8_t i;
    int buf[5];
 
    if (DHT11RstAndCheck())         //检测响应信号
    {
        for(i=0;i<5;i++)            //读取40位数据
        {
            buf[i]=DHT11ReadByte(); //读取1字节数据
        }
        if(buf[0]+buf[1]+buf[2]+buf[3] == buf[4]) //校验成功
        {
            *Humi = buf[0];         //保存湿度整数部分数据
            *Temp = buf[2];         //保存温度整数部分数据
        }
        sta = 1;
    }
    else //响应失败返回-1
    {
        *Humi = 0xFF; //响应失败返回255
        *Temp = 0xFF; //响应失败返回255
        sta = -1;
    }
    return sta;    
}
int Tempr,Humid,i;
unsigned char dataToSend_tempr = 0x01;
unsigned char dataToSend_mq = 0x02;
unsigned char dataToSend_fire = 0x03;
static void DHTsk(void)
{
   
    while (1)
    {
        DHT11ReadData(&Humid,&Tempr);
        printf("h=%d,t=%d\n",Humid,Tempr);
        if(Tempr>=34)
            UartWrite(WIFI_IOT_UART_IDX_1, &dataToSend_tempr, 1);
        usleep(1000000);
    }
}

人体红外检测模块: 用于监测仓储区域内是否有人员活动,以及人员的活动情况,从而实现对仓储安全的监测和管理。

1.全自动感应(当有人进入其感应范围则输入高电平,人离开感应范围则自动延时关闭高电平输出低电平);
2.预留有光敏控制位置,可添加光敏电阻,白天或光线强时不感应(5539光敏电阻配合使用);3.两种触发方式(L不可重复、H可重复,可跳线选择,默认为H) ;
4.具有感应封锁时间(默认3-4秒) ;
感应模块在每一次感应输出后(高电平变为低电平),可以紧跟着设置一个封锁时间,在此时间段内感应器不接收任何感应信号。此功能可以实现(感应输出时间和封锁时间)两者的间隔工作,可应用于间隔探测产品同时此功能可有效抑制负载切换过程中产生的各种干扰。5.工作电压范围宽(默认DC5v) ;
6.微功耗,静态电流65微安,特别适合干电池供电的电器产品。
人体红外模块只能输出TTL电压,故我们可以将它当作一个轻触按键进行代码编写:

////**********PEO********/////
////**********PEO********/////
////**********PEO********/////
// // 中断处理函数,当检测到下降沿(无人时)触发
static void F1_Pressed(char *arg)
{
    (void)arg;
    
    // 读取GPIO的电平状态
    unsigned int gpioStatus = 0;
    GpioGetInputVal(WIFI_IOT_IO_NAME_GPIO_11, &gpioStatus);

    // 根据电平状态更新变量peo
    if (gpioStatus == 1) {
        peo = 1;  // 有人
        printf("Detected: Someone is here\n");
    } else {
        peo = 0;  // 无人
        printf("Detected: No one is here\n");
    }
}
static void ButtonExampleEntry(void)
{
    GpioInit();
    
    // 初始化F1按键,设置为下降沿触发中断
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_IO_FUNC_GPIO_11_GPIO);

    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_GPIO_DIR_IN);  // 设置为输入模式
    IoSetPull(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_IO_PULL_UP);    // 上拉设置
    
    // 注册中断函数,检测下降沿(无人时触发)
    GpioRegisterIsrFunc(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, F1_Pressed, NULL);

    printf("Button Example Initialized\n");
}

而类似的MQ与火焰模块的DO接口代码与其类似,想使用DO口的可以依据下面代码使能对应接口即可。

喷雾模块:可以根据预设的条件,自动进行喷雾消毒或湿度调节,提高仓库内部环境的舒适度和卫生条件。

网上有喷雾模块的售卖,但价格一般,我们可以在商店中搜索小加湿器按照价格排序,便宜的只需要1~2.5元,将其拆开,可以看出其与喷雾模块更便宜且功能一样。

对于喷雾模块,我们可以借用继电器控制其工作与否,有些喷雾模块是无开关的,我们可以直接将其电源一段接入继电器,而用的喷雾模块有按键控制工作,我们可以将继电器接在其按键上直接其一个按键作用。

小熊派控制喷雾模块(继电器)代码有小熊派控制一个led代码类似:

#define shan_on GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 1)
#define shan_off GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 0)
#define peng_on GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1)
#define peng_off GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0)

    GpioInit();

    // 初始化shan (GPIO_2)
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_DIR_OUT);

    // 初始化peng (GPIO_8)
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_GPIO_DIR_OUT);

语音模块: 通过语音输入实现对系统的控制和操作,提高了系统的易用性和用户体验,并进行警告语音报警。

语音模块我使用的是ASR-PRO,其可以通过串口直接与小熊派通信。且其开发的独特性,使其上手简单。

ASR-PRO代码:

而小熊派依据手册拥有3个串口,我使用的是串口1,其GPIO0为TX1,GPIO1为RX1。

小熊派代码:

////**********UART********/////
////**********UART********/////
////**********UART********/////
static const char *data = "Hello, BearPi!\r\n";

#define shan_on GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 1)
#define shan_off GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 0)
#define peng_on GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1)
#define peng_off GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0)

static void UART_Task(void)
{
    uint8_t uart_buff[UART_BUFF_SIZE] = {0};
    uint8_t *uart_buff_ptr = uart_buff;
    uint32_t ret;

    GpioInit();

    // 初始化shan (GPIO_2)
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_DIR_OUT);

    // 初始化peng (GPIO_8)
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_GPIO_DIR_OUT);

    WifiIotUartAttribute uart_attr = {

        //baud_rate: 9600
        .baudRate = 9600,

        //data_bits: 8bits
        .dataBits = 8,
        .stopBits = 1,
        .parity = 0,
    };

    //Initialize uart driver
    ret = UartInit(WIFI_IOT_UART_IDX_1, &uart_attr, NULL);
    if (ret != WIFI_IOT_SUCCESS)
    {
        printf("Failed to init uart! Err code = %d\n", ret);
        return;
    }
    printf("UART Test Start\n");

    while (1)
    {
      //通过串口1接收数据
      ret = UartRead(WIFI_IOT_UART_IDX_1, uart_buff, UART_BUFF_SIZE);
        if (ret > 0) // 确保成功读取数据
        {
            // 处理接收的数据
            switch (uart_buff[0])
            {
                case 0x0f:
                    shan_off;
                    printf("Shan OFF\n");
                    break;
                case 0x1f:
                    shan_on;
                    printf("Shan ON\n");
                    break;
                case 0x09:
                    peng_off;
                    printf("Peng OFF\n");
                    break;
                case 0x19:
                    peng_on;
                    printf("Peng ON\n");
                    break;
                default:
                    printf("Unknown command: 0x%x\n", uart_buff[0]);
                    break;
            }
        }
        usleep(300000);//1000000=1s
    }
}

WiFi模块: 用于系统与网络的连接,实现数据的传输和远程监控功能,提高了系统的灵活性和便捷性。

由于小熊派自带WIFI功能故我们不需要格外添加wifi模块,只需对其进行wifi配置。

在通过MQTT协议与ONENET进行通信,将数据上传,

由于我使用的ONNET为老版本的(以停止维护),所以我的代码只供参考:

#define ONENET_INFO_PROID "60****"
#define ONENET_MASTER_APIKEY "HfOl**************="

#define ONENET_INFO_DEVID "107****4"
#define ONENET_INFO_AUTH "123**"
#define ONENET_INFO_APIKEY "p3y******************="

#define Wifi_SSID "EDUI"
#define Wifi_PASSWORD "12345678"
void onenet_cmd_rsp_cb(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size)
{

    printf("recv data is %.*s\n", recv_size, recv_data);

    *resp_data = NULL;
    *resp_size = 0;
}

void MQTT_Report_Task(void)
{
    int who=0;
    WifiConnect(Wifi_SSID, Wifi_PASSWORD);
    device_info_init(ONENET_INFO_DEVID, ONENET_INFO_PROID, ONENET_INFO_AUTH, ONENET_INFO_APIKEY, ONENET_MASTER_APIKEY);
    onenet_mqtt_init();
    onenet_set_cmd_rsp_cb(onenet_cmd_rsp_cb);
    while (1)
    {

        if(who==0){
            onenet_mqtt_upload_digit("Tempreture", Tempr);
            onenet_mqtt_upload_digit("Humidity",Humid);   
            onenet_mqtt_upload_digit("MQ135", (int)voltage_MQ);
            who++;         
        }
        else{
            onenet_mqtt_upload_digit("intensity", peo);
            onenet_mqtt_upload_digit("LED1", (int)voltage_FIRE); 
            who=0;           
        }
        sleep(1);
    }
}

最后,再写一个简单的微信小程序来对数据进行远程查看

2.研究意义:

提升仓储管理效率: 通过实时监测仓储环境,及时发现并处理各种安全隐患,提升了仓储管理的效率和水平。

应对火灾和安全隐患: 仓储环境中火灾是一种严重的安全隐患,可能导致重大财产损失甚至人员伤亡。通过项目中的火焰检测模块和喷雾模块,能够及时发现火灾并采取相应措施,提高了对火灾的应对能力,保障了仓储安全。

监测有害气体保障人员安全: 仓储环境中可能存在有害气体,如一氧化碳等,对人员健康和货物安全造成威胁。通过MQ2气体模块的应用,可以实时监测有害气体的浓度,及时预警和处理,保障了仓储环境和货物的安全。

提高操作效率和用户体验: 传统的仓储管理往往需要人工巡检和操作,效率低下且容易出现疏漏。通过语音识别等技术的应用,简化了用户的操作流程,提高了操作效率和用户体验,使仓储管理更加智能化和便捷化。

推动智能仓储发展: 随着物联网和智能技术的不断发展,智能仓储已成为未来发展的趋势。

本项目采用了一系列先进的物联网和智能技术,为智能仓储的发展提供了实践基础和技术支持,推动了智能仓储技术的应用和推广。推动智能仓储发展: 本项目采用了一系列先进的物联网和智能技术,为智能仓储的发展提供了一种可行的解决方案和技术支持。

在这个项目中,对小熊派进行了简单的开发,对其的GPIO,UART,ADC等进行了简单开发。个人小项目,结束。

完整项目下载。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐