毕业设计 单片机与OpenMV机器视觉目标跟踪系统

这篇具有很好参考价值的文章主要介绍了毕业设计 单片机与OpenMV机器视觉目标跟踪系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


0 前言

🔥
这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 基于单片机 openmv的机器视觉目标跟踪系统

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:5分

基于单片机与openmv机器视觉目标跟踪系统目标,单片机,目标跟踪,毕业设计,openmv,stm32

课题简介

随着智能化技术的迅猛发展,网络智能视频监控系统也得到了广泛的应用。视频监控系统经历了从模拟化向数字化、网络化、智能化的发展过程,目标检测和跟踪技术是计算机视觉的重要组成部分,也是实现监控系统智能化的基础,因其广泛的应用前景而成为近年来的研究热点。本文通过OpenMV作为是识别模块去识别被测物体(以红色小球为例),当其识别到红色小球后,判断小球中心点所在的区域信息,并将其区域标志位通过串口发送给STM32,当STM32接收到位置信息后对x轴、y轴的两个舵机参数进行操作,最后通过定时器输出合适的PWM波,控制舵机旋转相应的角度,使OpenMV摄像头对准被测物体,以实现物体追踪功能。

设计框架

主要分为两个方面:一个是OpenMV识别部分,另一个是STM32控制部分。通过OpenMV对被测物体进行捕捉,所用的被测物体为红色小球,OpenMV编程时,先对红色的色域进行调整,在识别到红色后,对红色进行判断,判断出识别区域中红色区域最大的部分,此举在过滤掉背景中存在小部分红色区域,造成对识别的干扰,识别到红色小球后,用矩形框将其框住,并显示矩形框的中心位置,判断中心位置所在区域,并将区域的标志信息会通过串口传递给STM32,STM32接收到数据后进行相应动作,使定时器输出PWM波,控制舵机旋转相应的角度,使OpenMV摄像头对准被测物体,以实现物体追踪功能。主要研究内容如下:

  • 1.通过OpenMV识别出被测物体(以红色小球为例)。
  • 2.在OpenMV识别出目标物体后,判断物体所在区域,将区域信息通过串口传输给STM32。
  • 3.利用STM32的串口部分的应用及原理知识,对接收到的数据进行处理。
  • 4.利用STM32的应用及原理知识,对处理好的数据进行判断后,对舵机进行控制。
  • 5.利用STM32的定时器部分和PWM控制的应用及原理知识,控制舵机,使其转动适当角度,使OpenMV对准目标物体。主控制图如图所示。

基于单片机与openmv机器视觉目标跟踪系统目标,单片机,目标跟踪,毕业设计,openmv,stm32
舵机控制逻辑

基于单片机与openmv机器视觉目标跟踪系统目标,单片机,目标跟踪,毕业设计,openmv,stm32

3 openMV实现舵机定位色块STM32

使用openMV检测前方色块,并传回色块的坐标位置给STM32,控制舵机转动来跟踪色块。

openMV部分


    import sensor, image, time
    from pyb import UART
    import json
    
    red_threshold  = (87, 21, 27, 93, -5, 92)
    sensor.reset() # Initialize the camera sensor.
    sensor.set_pixformat(sensor.RGB565) # use RGB565.
    sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.
    sensor.skip_frames(10) # Let new settings take affeOpenMV_Xct.
    sensor.set_auto_whitebal(False) # turn this off.
    clock = time.clock() # Tracks FPS.
    
    uart = UART(3, 115200)
    uart.init(115200, bits=8, parity=None, stop=1)  #8位数据位,无校验位,1位停止位
    
    def find_max(blobs):
        max_size=0
        for blob in blobs:
            if blob[2]*blob[3] > max_size:
                max_blob=blob
                max_size = blob[2]*blob[3]
        return max_blob
    
        def sending_data(cx_max,cy_max):
            global uart;
            data = ustruct.pack(",              #格式为俩个字符俩个短整型(2字节)
                       0xff,
                       0xfe,
                       int(cx_max),
                       int(cy_max));
                                                       #数据1
                                        # up sample by 4#数据2LCD_ShowStringLCD_ShowString
            uart.write(data);   #必须要传入一个字节数组


​    

    while(True):
        clock.tick() # Track elapsed milliseconds between snapshots().
        img = sensor.snapshot() # Take a picture and return the image.
    
        blobs = img.find_blobs([red_threshold])
        if blobs:
    
            max_blob = find_max(blobs)
            img.draw_cross(max_blob.cx(),max_blob.cy())
            img.draw_circle(max_blob.cx(),max_blob.cy(),max_blob.cx()-max_blob.x(), color = (255, 255, 255))
            X =int(max_blob.cx()-img.width()/2)
            Y =int(max_blob.cy()-img.height()/2)
            
          #  FH = bytearray([0xb3,0xb3])
          #  uart.write(FH)     #打印帧头
    
            data = bytearray([0xb3,0xb3,X,Y,0x5b])
            uart.write(data)    #打印XY轴的偏移坐标


​     
​        

            print("X轴偏移坐标 : ",X)
            print("Y轴偏移坐标 : ",Y)print("帧率 : ",clock.fps())
    sending_data(blob.X,blob.Y)

代码介绍:此部分为openMV追踪色块(黄色)并且传回色块的横坐标位置给STM32C8T6t,同时也可以用串口打印出来色块距离中心坐标位置偏移值
如图所示
基于单片机与openmv机器视觉目标跟踪系统目标,单片机,目标跟踪,毕业设计,openmv,stm32
如果要利用串口显示的话可以用一根杜杜邦线接openMV的P4和USB转TTL的RXD接收端即可。

STM32部分

串口接收终端代码

void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	u8 com_data;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
			USART_ClearFlag(USART1,USART_FLAG_RXNE);
      com_data = USART1->DR;
			Openmv_Receive_Data(com_data);     //openmv数据处理函数
			Openmv_Data();		                 //openmv数据处理函数		
 		
     } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 

处理openMV数据代码


    #include "openmv.h"
    int openmv[5];//stm32接收数据数组
    int8_t OpenMV_X;          /*OPENMV X 轴反馈坐标*/
    int8_t OpenMV_Y;          /*OPENMV X 轴反馈坐标*/

    int i=0;
    
    void Openmv_Receive_Data(int16_t data)//接收Openmv传过来的数据
    {
    	static u8 state = 0;
    	if(state==0&&data==0xb3)
    	{
    		state=1;
    		openmv[0]=data;
    	}
    	else if(state==1&&data==0xb3)
    	{
    		state=2;
    		openmv[1]=data;
    	}
    	else if(state==2)
    	{
    		state=3;
    		openmv[2]=data;
    	}
    	else if(state==3)
    	{
    		state = 4;
    		openmv[3]=data;
    	}
    
    	else if(state==4)		//检测是否接受到结束标志
    	{
            if(data == 0x5B)
            {
                state = 0;
                openmv[4]=data;
                Openmv_Data();
            }
            else if(data != 0x5B)
            {
                state = 0;
                for(i=0;i<5;i++)
                {
                    openmv[i]=0x00;
                }           
            }
    	}    
    	else
    		{
    			state = 0;
                for(i=0;i<5;i++)
                {
                    openmv[i]=0x00;
                }
    		}
    }
    
    void Openmv_Data(void)
    {
        OpenMV_X=openmv[2];
        OpenMV_Y=openmv[3];
    
    }



其他部分的代码就很简单,在这里只列出关键部分代码

下面就是关键的控制舵机转动的代码


    while (1)
    	{
    		
    	    OpenMV_X= openmv[2];
    		printf ("\r\n%d\r\n",OpenMV_X);
    		if(OpenMV_X>=0&&OpenMV_X<80)
    		{
    			s=185-OpenMV_X/16;
    			TIM_SetCompare1(TIM1, s);	
    
    		}
    		
    		if(OpenMV_X>=180)
    		{
    			s=190-(OpenMV_X-180)/16;
    			TIM_SetCompare1(TIM1, s);	
			

    		}	
	

    	}



舵机的初始化代码在这里我就不列了,我用的是TIM1。

它是根据STM32接收到的数据的坐标位置来进行一个条件判断,这里32端接受到的数据为横坐标值,当色块在右侧,数据为0—80,当色块在左侧时,数据为260—180.由此来计算舵机的占空比具体是多大。

3 硬件设计

硬件连接部分使用杜邦线连接,连接如下:3S锂电池接稳压板输入端以及直接给LED补光板供电,稳压板输出端接OpenMV的VIN和GND引脚、STM32的5V和GND引脚以及两个舵机的正(红色)负(棕色)极。OpenMV的P4引脚(串口3的TX)接STM32的PA10引脚(串口1的RX),OpenMV的P5引脚(串口3的RX)接STM32的PA9引脚(串口1的TX),STM32的PC7引脚(定时器3通道2)接x轴的舵机的信号线(橙黄色),STM32的PC7引脚(定时器3通道1)接y轴的舵机的信号线(橙黄色)。

基于单片机与openmv机器视觉目标跟踪系统目标,单片机,目标跟踪,毕业设计,openmv,stm32

4 软件设计

4.1 硬件连接

我所用到的材料如下: 四针IIC
OLED,OpenMV(OV7725),STM32F103C8T6最小系统板,数据线N条(OpenMV的数据线只能用官方自带的,其他的基本都用不了),杜邦线若干。

1.OpenMV端:由图知UART_RX—P5 ------ UART_TX—P4
基于单片机与openmv机器视觉目标跟踪系统目标,单片机,目标跟踪,毕业设计,openmv,stm32
2.STM32端:USART_TX—PA9 -----USART_RX—PA10
基于单片机与openmv机器视觉目标跟踪系统目标,单片机,目标跟踪,毕业设计,openmv,stm323.四针OLED IIC连接:SDA—PA2-----SCL—PA1 由于使用的是模拟IIC而不是硬件IIC,可以根据个人需要修改IO口来控制SDA线和SCL线,只需要简单修改一下代码即可。

4.STM32的TX(RX)接OpenMV的RX(TX),OLED连接到STM32即可。


4.2 软件代码 OpenMV端


   import sensor, image, time,math,pyb
​    from pyb import UART,LED
​    import json
​    import ustruct
​    

    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    sensor.skip_frames(time = 2000)
    sensor.set_auto_gain(False) # must be turned off for color tracking
    sensor.set_auto_whitebal(False) # must be turned off for color tracking
    red_threshold_01=(10, 100, 127, 32, -43, 67)
    clock = time.clock()
    
    uart = UART(3,115200)   #定义串口3变量
    uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters
    
    def find_max(blobs):    #定义寻找色块面积最大的函数
        max_size=0
        for blob in blobs:
            if blob.pixels() > max_size:
                max_blob=blob
                max_size = blob.pixels()
        return max_blob


​    
​    def sending_data(cx,cy,cw,ch):global uart;#frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];#data = bytearray(frame)
​        data = ustruct.pack(",      #格式为俩个字符俩个短整型(2字节)0x2C,                      #帧头10x12,                      #帧头2int(cx), # up sample by 4   #数据1int(cy), # up sample by 4    #数据2int(cw), # up sample by 4    #数据1int(ch), # up sample by 4    #数据20x5B)
​        uart.write(data);   #必须要传入一个字节数组


​    
​    while(True):
​        clock.tick()
​        img = sensor.snapshot()
​        blobs = img.find_blobs([red_threshold_01])
​        cx=0;cy=0;if blobs:
​            	max_b = find_max(blobs)#如果找到了目标颜色
​                cx=max_b[5]
​                cy=max_b[6]
​                cw=max_b[2]
​                ch=max_b[3]
​                img.draw_rectangle(max_b[0:4]) # rect
​                img.draw_cross(max_b[5], max_b[6]) # cx, cy
​                FH = bytearray([0x2C,0x12,cx,cy,cw,ch,0x5B])#sending_data(cx,cy,cw,ch)
​                uart.write(FH)print(cx,cy,cw,ch)

bytearray([, , ,])组合uart.write()的作用与直接调用sending_data(cx,cy,cw,ch)作用是一样的

4.3 软件代码 STM32端

工程总共包含如下文件:main.c、iic.c、iic.h、oled.c、oled.h、uart.c、uart.h。由于OLED的代码存在版权问题,需要的可以邮箱私发。

> /***** oled.h *****/


    #ifndef __USART_H
    #define __USART_H
    #include "sys.h"
    void USART1_Init(void);//串口1初始化并启动
    #endif


> /***** oled.c *****/


    #include "uart.h"
    #include "oled.h"
    #include "stdio.h"
    
    static u8 Cx=0,Cy=0,Cw=0,Ch=0;
    
    void USART1_Init(void)
    {
    	 	//USART1_TX:PA 9   
    		//USART1_RX:PA10
    		GPIO_InitTypeDef GPIO_InitStructure;     //串口端口配置结构体变量
    		USART_InitTypeDef USART_InitStructure;   //串口参数配置结构体变量
    		NVIC_InitTypeDef NVIC_InitStructure;     //串口中断配置结构体变量
    
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   //打开PA端口时钟
    
        	//USART1_TX   PA9
        	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;          		 //PA9
       		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  		 //设定IO口的输出速度为50MHz
        	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	   		 //复用推挽输出
        	GPIO_Init(GPIOA, &GPIO_InitStructure);             	 	 //初始化PA9
        	//USART1_RX	  PA10
        	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;             //PA10
        	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //浮空输入
        	GPIO_Init(GPIOA, &GPIO_InitStructure);                 //初始化PA10 
    
        	//USART1 NVIC 配置
        	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;  //抢占优先级0
    		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		    //子优先级2
    		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			      					                 //IRQ通道使能
    		NVIC_Init(&NVIC_InitStructure);	                          //根据指定的参数初始化VIC寄存器
    
        	//USART 初始化设置
    		USART_InitStructure.USART_BaudRate = 115200;                  //串口波特率为115200
    		USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //字长为8位数据格式
    		USART_InitStructure.USART_StopBits = USART_StopBits_1;        //一个停止位
    		USART_InitStructure.USART_Parity = USART_Parity_No;           //无奇偶校验位
    		USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   //无硬件数据流控制
    		USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	                  //收发模式
        	USART_Init(USART1, &USART_InitStructure);                     //初始化串口1
    
        	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能中断
       		USART_Cmd(USART1, ENABLE);                     //使能串口1
    	  	USART_ClearFlag(USART1, USART_FLAG_TC);        //清串口1发送标志
    		
    }
    
    //USART1 全局中断服务函数
    void USART1_IRQHandler(void)			 
    {
    		u8 com_data; 
    		u8 i;
    		static u8 RxCounter1=0;
    		static u16 RxBuffer1[10]={0};
    		static u8 RxState = 0;	
    		static u8 RxFlag1 = 0;
    
    		if( USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)  	   //接收中断  
    		{
    				USART_ClearITPendingBit(USART1,USART_IT_RXNE);   //清除中断标志
    				com_data = USART_ReceiveData(USART1);
    			
    				if(RxState==0&&com_data==0x2C)  //0x2c帧头
    				{
    					RxState=1;
    					RxBuffer1[RxCounter1++]=com_data;OLED_Refresh();
    				}
    		
    				else if(RxState==1&&com_data==0x12)  //0x12帧头
    				{
    					RxState=2;
    					RxBuffer1[RxCounter1++]=com_data;
    				}
    		
    				else if(RxState==2)
    				{
    					RxBuffer1[RxCounter1++]=com_data;
    
    					if(RxCounter1>=10||com_data == 0x5B)       //RxBuffer1接受满了,接收数据结束
    					{
    						RxState=3;
    						RxFlag1=1;
    						Cx=RxBuffer1[RxCounter1-5];
    						Cy=RxBuffer1[RxCounter1-4];
    						Cw=RxBuffer1[RxCounter1-3];
    						Ch=RxBuffer1[RxCounter1-2];
    
    					}
    				}
    		
    				else if(RxState==3)		//检测是否接受到结束标志
    				{
    						if(RxBuffer1[RxCounter1-1] == 0x5B)
    						{
    									USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭DTSABLE中断
    									if(RxFlag1)
    									{
    									OLED_Refresh();
    									OLED_ShowNum(0, 0,Cx,3,16,1);
    									OLED_ShowNum(0,17,Cy,3,16,1);
    									OLED_ShowNum(0,33,Cw,3,16,1);
    									OLED_ShowNum(0,49,Ch,3,16,1);
    									}
    									RxFlag1 = 0;
    									RxCounter1 = 0;
    									RxState = 0;
    									USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
    						}
    						else   //接收错误
    						{
    									RxState = 0;
    									RxCounter1=0;
    									for(i=0;i<10;i++)
    									{
    											RxBuffer1[i]=0x00;      //将存放数据数组清零
    									}
    						}
    				} 
    	
    				else   //接收异常
    				{
    						RxState = 0;
    						RxCounter1=0;
    						for(i=0;i<10;i++)
    						{
    								RxBuffer1[i]=0x00;      //将存放数据数组清零
    						}
    				}
    
    		}
    		
    }

解释:OpenMV发送数据包给STM32,STM32利用中断接收数据并把数据存放在RxBuffer1这个数组里,并且在中断中利用OLED显示cx,cy,cw,ch四个坐标。在中断中,有如下函数:

else if(RxState==2){
​    					RxBuffer1[RxCounter1++]=com_data;if(RxCounter1>=10||com_data == 0x5B)       //RxBuffer1接受满了,接收数据结束
    					{
    						RxState=3;
    						RxFlag1=1;
    						Cx=RxBuffer1[RxCounter-5];
    						Cy=RxBuffer1[RxCounter-4];
    						Cw=RxBuffer1[RxCounter-3];
    						Ch=RxBuffer1[RxCounter1-2];
    
    					}
    				}

RxBuffer1是一个装有接收OpenMV数据的数组,RxCounter1起着一个计数器的作用,当RxBuffer[RxCounter1-1]存放的数据为数据包的帧位时,说明已经接收成功整个数据包,此时RxBuffer[RxCounter1-2]存放ch坐标值,RxBuffer[RxCounter1-3]存放cw坐标值,RxBuffer[RxCounter1-4]存放cy坐标值,RxBuffer[RxCounter1-5]存放cx坐标值,此后在RxState=3过程中将这四个坐标显示出来即可。
特别注意的是:STM32中断每发生一次,只会接收到一字节的数据,因此,进行七次才会接收完一整帧的数据包,这一点需要读者仔细揣摩,结合上文中说的静态变量关键字static,定义了:

​    
​    u8 com_data; 
​    u8 i;static u8 RxCounter1=0;static u8 RxBuffer1[10]={0};static u8 RxState = 0;static u8 RxFlag1 = 0;

请读者仔细揣摩为什么com_data(端口接收到的数据)、i定义的是动态的(auto),而RxBuffer1(装接收到数据的静态全局数组)、RxState(状态标志变量)、RxFlag1(接受结束标志变量)定义的确实静态的,这一点并不难理解。


4.4 利用PC端测试数据数据是否发送接收正常

在进行OpenMV与STM32的通信测试过程中,我使用了USB转TTL模块,将OpenMV(或STM32单片机)与PC端进行通信确保数据发出或者接收正常。
OpenMV &&PC;
OpenMV_RX接模块TX
OpenMV_TX接模块RX
OpenMV_GND接模块GND
然后打开OpenMV,在大循环while(True)中使用语句:

​    DATA=bytearray[(1,2,3,4,5)]
​    uart.write(DATA)

打开PC端串口助手,注意设置一样的波特率、停止位、发送字节数等,查看串口助手是否接受到了数据。
STM32 &&PC;
STM32_RX接模块TX
STM32_TX接模块RX
STM32_GND接模块GND
注意:不管是STM32与PC还是OpenMV与PC还是STM32与OpenMV通信,都要将二者的GND连接在一起。
在main.c中先调用stdio头文件,大循环中使用如下语句:

​    
​    while(1){printf("HelloWorld!");}

打开串口助手查看是否接收到了数据。


4.5 效果展示

基于单片机与openmv机器视觉目标跟踪系统目标,单片机,目标跟踪,毕业设计,openmv,stm32
从上到下依次为CX,CY,CW,CH文章来源地址https://www.toymoban.com/news/detail-770148.html

最后

到了这里,关于毕业设计 单片机与OpenMV机器视觉目标跟踪系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 基于单片机的毕业设计推荐

    ** ** 1、基于51单片机的多功能门禁系统(低端、功能限制较大)。 2、基于单片机的多功能实时时钟。 3、基于单片机的音乐播放器。 4、基于STM32单片机的多功能门禁系统(高端、没有限制)。 5、基于单片机的智能窗帘系统。 6、基于单片机的智能灯光系统。 7、基于单片机

    2024年02月06日
    浏览(75)
  • 【单片机毕业设计】【mcuclub-jj-011】基于单片机的加湿器的设计

    项目名:加湿器 项目编号:mcuclub-jj-011 单片机类型:STC89C52 具体功能: 1、通过DHT11获取湿度值,当湿度值低于设置最小值,则启动加湿器加湿,大于设置最大值,则停止加湿 2、通过液位检测模块检测加湿器中是否还有水,如果没有,则自动停止加湿、声光提醒 3、通过按键

    2023年04月17日
    浏览(99)
  • 毕业设计 单片机选题100例(一)

    【单片机毕业设计项目分享系列】 🔥 单片机毕业设计及享100例系列的第一篇,目的是分享高质量的毕设作品给大家,包含全面内容:源码+原理图+PCB+实物演示+论文。 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的单片机项目缺少创新和亮点,往往达不到

    2024年02月07日
    浏览(59)
  • 【单片机毕业设计】【mcuclub-dz-196】基于单片机下的新型智能花盆设计

    项目名:基于单片机下的新型智能花盆设计 项目名:花盆(实物) 项目编号:mcuclub-dz-196 单片机类型:STM32F103C8T6 具体功能: 1、通过防水式DS18B20测量土壤温度,当温度高于设置最大值时,进行风扇降温,低于设置最大值,进行防水加热 2、通过土壤湿度传感器检测湿度值,

    2024年02月19日
    浏览(93)
  • 【单片机毕业设计】【mcuclub-dz-032】基于单片机的智能门禁控制系统设计

    项目名:基于单片机的门禁的设计 单片机:STM32F103C8T6 mcuclub-dz-032 功能简介: 1、通过扫码枪进行扫描二维码,当二维码识别成功,10s内需触发红外避障管,并通过红外测温模块进行测温,如果温度正常,则自动开锁,如果温度异常,则声光报警3次,锁不打开 2、通过RFID进行

    2024年01月18日
    浏览(69)
  • 毕业设计 - 基于单片机的智能饮水机系统设计与实现 (物联网 嵌入式 单片机)

    Hi,大家好,学长今天向大家介绍一个 单片机项目 基于单片机的智能饮水机系统设计与实现 大家可用于 课程设计 或 毕业设计 这次设计的智能饮水机就是单片机结合传感器的一个应用。 该系统设计综合单片机以及电子技术理论,从生活实际出发,完善了饮水机的功能。整个

    2024年02月03日
    浏览(105)
  • 【单片机毕业设计】【mcuclub-dz-198】基于单片机的车辆安全驾驶预警系统设计

    项目名:基于单片机的车辆安全驾驶预警系统设计 项目名:驾驶检测(实物)(mcuclub-105) 项目编号:mcuclub-dz-198 单片机类型:STM32F103C8T6 具体功能: 1、通过红测速模块管检测当前老年车的速度; 2、通过超声波测距测量车前障碍物的距离,若距离大于设定最大值,绿灯亮;

    2024年02月20日
    浏览(53)
  • 毕业设计单片机可以用万能板吗?

    可以是可以,就是焊接起来比较麻烦,特别是有好几个重复连线点的时候,检测起来就不那么容易了,而且布线看起来乱糟糟的,如果后期一不小心把线弄断了,查起来就更麻烦了,倒不如pcb打板来的方便。最近很多小伙伴找我,说想要一些单片机的资料,然后我根据自己从

    2024年02月04日
    浏览(54)
  • 【毕业设计】基于单片机控制的交通灯毕业设计(附源代码)

    目 录 摘   要 Abstract 前   言 一、工程简介 ( 一)、概述 ( 二 ) 、 工艺 流程图 二、工程设计 (一)、控制方案的确定 (二)、硬件部分 ( 1 )、交通灯控制系统的硬件设计 ( 2 )、硬件系统的设计具备以下原则 ( 3 ) 、硬件结构框图 (如图 3 所示) ( 4 ) 、交通灯控

    2024年04月23日
    浏览(74)
  • 【单片机毕业设计】【mcuclub-dz-177】基于32单片机的自动扶梯控制系统设计

    项目名:基于32单片机的自动扶梯控制系统设计 项目名:扶梯(实物) 项目编号:mcuclub-dz-177 单片机类型:STM32F103C8T6 具体功能: 1、通过MX1508驱动两个直流电机模拟上下扶梯(一个正转代表上行,一个反转代表下行) 2、每个扶梯都有两个红外对射管,进行人数计数,如果扶

    2024年02月21日
    浏览(68)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包