基于51单片机和Openmv也能做垃圾分类系统(课程抵修)

 文章会在我的个人网站优先更新:http://www.xiaokai1999.cn/archives/306

如果想要资源,可以在下面评论,我整理好了会发到我的个人网站上,供大家下载学习。

目录

介绍

1. 摘要

1.2 应用方向

1.3 设计创新点

2 系统的结构设计

3 OpenMV3

4 程序流程图

4.1 STC89C52RC串口接收

4.2 定时器中断函数控制PWM信号输出

4.3 舵机及LED开关控制

4.4 OpenMV3检测物体

5 系统调试


 

介绍

这个项目是我们学院单片机课程抵修(这门课的学分就拿到了,一学期不用上课),主要检测电池,金属,其他纸类

因为当时上海正在推行垃圾分类,那我就想简单的做一下吧,这样还能完成抵修。

当时的成绩

基于51单片机的垃圾分类系统(课程抵修)

想法:说实话,当时条件有限,检测的方法的确很捞:(现在主要都是靠深度学习了,这种不值一提具体可以看视频)

  1. 使用openmv模板匹配(NCC算法)图像,确定类型
  2. 再用金属传感器检测,是否为金属
  3. 最后确定检测的物体是金属还是电池
其中的一部分模板

 

说明:OpenMV不能实现深度学习!!!,本身只是基于STM32的,没有机会给我们跑深度学习的!!不过好像可以用模型,但是支持的较少。

在寒假里为了增强垃圾分类的功能,我做了深度学习实现垃圾分类(用自己的电脑跑了整整3个小时~~

1. 摘要

         随着人们生活水平的提高,越来越多的家庭进入智能化时代,人们对智能化家电的需求越来越高,但是现在垃圾分类还是我们最大的问题,现在的国民素质还有待培养,对扔垃圾懒惰随意的意识型态还没改变,而且居民对垃圾分类知识很是缺乏,为了让更多的人享受到科技带来的便利和培养居民垃圾分类的意识,所以开发了本系统。相对那些售价高昂的智能垃圾桶,本产品更加适合大多数的普通家庭,本产品基于 OpenMV3 对垃圾进行检测,有效的分离电池和其他垃圾。

1.2 应用方向

本产品可以应用在几乎所有场合,适用范围广泛环境搭建更加的简单,可以轻松实现垃圾检测的功能。本产品可以应用在所有想提高自己生活体验的家庭里,为他们带来更方便快捷的生活体验。

1.3 设计创新点

现在的这款垃圾桶相比于传统的产品更加的方便,对于家中原本的垃圾桶省去了手动去分类的烦恼,同时也比别家公司生产的产品更加的节能。比如温度检测可以随时提醒用户扔垃圾,不仅仅达到了让居民养成一个扔垃圾的好习惯,同时也让家里变得非常整洁,使人们获得更加舒适的体验的同时也保护了家里的环境。再比如说本产品可以对用户扔的垃圾进行分类,达到了分类的目的,还能让居民学习垃圾分类的小知识,在垃圾同外部还装有一个小灯,能在他颜色变化的时候观察垃圾桶的工作状态。

2 系统的结构设计

        本系统主要的目的是实现 OpenMV3 摄像头模块通过 NCC 算法检测垃 圾,并且和 STC89C52RC 单片机串口通信,单片机从而通过 OpenMV3 传 输下来的数据进行进一步的检测当前投递的垃圾属于哪类垃圾,从而实现 垃圾分类的效果。

openmv系统的工作流程图
标题

3 OpenMV3

OpenMV3摄像头是一款小巧,低功耗,低成本的电路板,它帮助你很轻松的完成机器视觉(machine vision)应用。你可以通过高级语言Python脚本(准确的说是 MicroPython ),而不是C/C++。Python的高级数据结构使你很容易在机器视觉算法中处理复杂的输出。但是,你仍然可以完全控制OpenMV3,包括IO引脚。你可以很容易的使用外部终端触发拍摄或者或者执行算法,也可以把算法的结果用来控制IO引脚。如果使用此摄像头模块可以大大降低开发成本,缩短研发周期。

OpenMV3实物图

 

4 程序流程图

当给单片机上电以后,系统会对各个模块进行初始化的设置,所有的模块初始化完成以后,程序会进入主函数中的while循环里,在循环里会进行按键的采集和串口数据的接收,然后根据接收的数据来控制各个设备工作。如果串口没有接收到数据,那么就会执行温度采集的函数,并把采集到的温度显示在LCD上。

 

系统流程图

4.1 STC89C52RC串口接收

51单片机串行口是一个可编程全双工的通信接口,具有Uart(异步收发器)的全部功能,能同时进行数据的发送与接收,也可作为同步一位寄存器使用,本处主要是用来接收数据。51有两个独立的串行数据缓冲寄存器SBUF (一个发送,一个接收)和发送控制器、接收控制器,输入移位寄存器及若干控制门电路。本次串口的使用方式为方式4。

STC89C52RC流程图

串口的发送和接收程序如下:

//初始化串口
void Usart_Init(void)
{
        TMOD = 0x20;
    SCON = 0x50;
    TH1 = 0xFD;
    TL1 = TH1;
    PCON = 0x00;
    EA = 1;
    ES = 1;
    TR1 = 0;
}
//发送单个字节
void SendOneByte(unsigned char c)
{
    SBUF = c;
    while(!TI);
    TI = 0;
} /**串口中断函数**/
void UARTInterrupt(void) interrupt 4
{
    c=’0’;
    if(RI)
{
    RI = 0;
    c=SBUF;
}
else
{
    TI = 0;
}
}



 

4.2 定时器中断函数控制PWM信号输出

本次系统一共用到了2个定时器,其中一个用于串口输入,最后一个定时器0用于产生不同频率的PWM,用以控制舵机。两个定时器的初始化以及中断服务函数如下:

/******初始化中断0函数******/
void Timer0_Init()
{
    TMOD=0x01;
    TH0 = 0xff;
  TL0 = 0xa4;      //0.1ms中断一次
    EA=1;
    ET0=1;
    TR0=0;
}
/******中断0函数******/
void Time0() interrupt 1
{
    Basis++;
    TH0=0xff; TL0=0xa4;
    if (Basis==200)
    Basis=0;
    PWM = (Basis<=PWM_NUM) ? 1: 0;
} 
//初始化串口
void Usart_Init(void)
{
        TMOD = 0x20;
    SCON = 0x50;
    TH1 = 0xFD;
    TL1 = TH1;
    PCON = 0x00;
    EA = 1;
    ES = 1;
    TR1 = 0;
}
/******串口中断函数******/
void UARTInterrupt(void) interrupt 4
{
        c='0';
    if(RI)
    {
        RI = 0;
        c=SBUF;
    }
    else
        {
            TI = 0; 
        }     
}

4.3 舵机及LED开关控制

当串口接收到OpenMV发送过来的数据之后,单片机要根据对应的数据控制相应的设备,并把设备的状态通过LED显示出口。舵机的作用是用来控制门窗的开关,对应的状态也会通过LED显示出来。舵机的控制以及LED显示的控制函数如下:

/******1602显示******/
void Display1602(int i)
{
    uchar num;
    switch(i)
    {
        case 0://开机初始化
        {
            LcdWriteCom(0x80);
            for(num=0;num<12;num++)
            {
                LcdWriteData(table[num]);//显示开机画面
            }
            LcdWriteCom(0x80+0x40);
            for(num=0;num<6;num++)
            {
                LcdWriteData('.');//显示开机画面
                delay(50);
            }
            bee=0;
            delay(100);
            bee=1;
            TR0=1;
            PWM_NUM =31;//初始化舵机
            delay(10);
            TR0=0;
            break;
        }

 

4.4 OpenMV3检测物体

当我们按下执行按钮,OpenMV通过NCC样本匹配算法来检测垃圾的形状和颜色是否与样本所匹配,检测完毕后将会通过串口发送给STC89C52RC单片机,OpenMV主要程序如下:

if(not pin3.value()):
            r = img.find_template(template, 0.9, step=4, search=SEARCH_EX)
            if r:
                img.draw_rectangle(r,color=(0,255,0))
            if r==None:
                r1 = img.find_template(template1, 0.8, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
                for tp in template2:
                    t = image.Image(tp)
                    r2 = img.find_template(t, 0.85, step=4, search=SEARCH_EX)
                    if r2:
                        break
                for tp in template3:
                    t = image.Image(tp)
                    r3 = img.find_template(t, 0.8, step=4, search=SEARCH_EX) 
                    if r3:
                        break
                if r1:
                    img.draw_rectangle(r1)
                    uart.write('1')#检测到电池
                    print(1)
                elif r2:
                    img.draw_rectangle(r2)
                    uart.write('1')#检测到电池
                    print(2)
                elif r3:
                    img.draw_rectangle(r3)
                    uart.write('1')#检测到电池
                    print(3)
                else:
                    uart.write('3')#检测到有物体
                    print(4)
            else:
                uart.write('0')#检测到无物体
                print(0)

5 系统调试

整体实物图如图5.1所示,上边的摄像头为OpenMV,下面的桶为垃圾回收处理中心

整体实物图

 

将单片机通上电,实时获取温度并且温度实时显示在LCD1602上。

LCD1602显示温度

 

首先是检测电池(5号电池如图5.3所示,18650充电电池如图5.4所示,7号电池如图5.5所示)的测试。

 

检测5号电池

 

 

图5.4  检测18650电池

 

 

图5.5  检测7号电池


放上电池,按下检测按钮。垃圾桶盖子通过舵机转动自动打开如图5.6所示,电池随即滚入盒内,并进行进一步检测。

 
图5.6  垃圾桶盖子自动打开

 

 

图5.7  内部滑坡图

 

 

电池最后停留在固定位置,内部的滑坡图如图5.7所示,经过金属传感器检测如图5.8所示:

物体最终停留图

 

 

检测完毕,显示电池为有害垃圾并且蜂鸣器连续鸣叫六下。

接下来我们检测金属,实际效果如图5.9所示:

检测结果为Harmful waste 有害垃圾

 

 

我们随机放上一个粗螺丝,实际效果如图5.10所示:

检测目标为一颗螺丝

 

 

结果为Metal waste金属垃圾,效果图如图5.11所示:

Metal waste为金属垃圾

 检测目标为一张卷过的纸,效果图如图5.12所示:

 
检测目标为一张卷过的纸

 

最后的检测结果为Other waste其他垃圾,效果图如图5.13所示:

 other waste其他垃圾

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章