STM32循迹小车系列教程(三)—— 使用灰度传感器循迹

news2024/11/26 17:52:33

本章节主要讲解如何获取灰度传感器值以及如何使用灰度传感器循迹

灰度传感器简介

灰度传感器如图 1 所示

灰度传感器 使用一对抗干扰较强的光电传感器,其中发射管的光源采用高亮白色聚光 LED,发射管端发出的光线通过不同环境背景的反射之后,最终由光敏接收管来接收,光敏接收管的阻抗随反射光线的强弱变化而变化(反射光线越强,阻值越小),最后通过分压和运放比较电路实现数字/模拟信号的双输出。

灰度传感器模块对白光反射强弱不同背景环境有非常好的识别效果,背景差异越大,分辨效果越好。灰度传感器相比普通红外传感器有着更高的抗干扰能力。

灰度传感器检测原理

灰度传感器是一组模拟传感器,由一只发光二极管和一只光敏接收管组成,二者安装在同一面上。 灰度传感器利用不同颜色的检测背景对光的反射程度不同,同时光敏接收管接收到不同检测面返回的光线,其阻值也不同的原理进行颜色深浅检测。

当光敏接收管接收到的光线越强, 它的阻值就越小, 即地面背景灰度越深或者离地距离越远, 光敏二极管的阻值越大。

在有效的检测距离内,发光二极管发出白光,照射在检测面上,检测面反射部分光线, 光敏接收管检测此光线的强度并通过分压电路和运放比较电路将其转换模拟/数字信号,最后通过机器人主板上的模拟/数字口输入到微控制器进行处理。

电路分析

在上图所示灰度传感器检测电路中,LED1~3为发射补光管, LEDP1为光敏接收管,U1为比较运放芯片LM393A。用户可根据是否使用比较运放芯片决定使用模拟量或数字量。

使用模拟量时,ADC端的电压通过光电二极管分压得到,由光电二极管的特性曲线可得,当光电二极管接收光线弱时,光电二极管阻值趋向于无穷,此时ADC端电压接近于0。反之,当光电二极管接收光线强时,光电二极管阻值趋向于0,此时ADC端电压接近5V,由于不用颜色对于光的吸收程度不同,ADC端反映的值也不同,由此可根据光电二极管的值判断小车处于线的位置。

使用数字量时,当地面背景为深色或者高灰度值时, 经地面反射后进入光敏接收管端的光线较少, 2端输出的电压较高,经比较器比较后1端输出低电平控制三极管导通,GPIO输出高电平。同理当地面背景为浅色或者低灰度值时, 经地面反射后进入光敏接收管端的光线较多, 2端输出的电压较低,经比较器比较后1端输出低电平控制三极管截止,GPIO输出低电平。

数字量可满足大部分MCU,用户通过调节电位器RPOT1即可设定循迹阈值,而模拟量需要MCU具备ADC转化功能,将转化的数字量比较赛道路线的阈值即可获得和数字量一样的效果。相比之下,使用模拟量相对简单,但是需要消耗的MCU资源较多,而数字量不方便调节,但目前大多数MCU的IO口均有检测电平输入功能,用户无需二次配置。

循迹原理

巡线原理

1.先在平整的路面上调小车走直线。通过调整小车左右电机的速度,尽可能的让小车走直线,这样可以减少在巡线过程中调整的次数,可以让小车跑的更快。

2.巡线过程中,小车偏离线,如图1左,小车向左偏,应该增加左侧电机的速度,减小右侧的速度,减小或增加的量,根据小车实际情况修改测试。如图1右,小车向右偏,则相反。

3.靠近中心的探头照到线,调整的量要小些,越是离中心探头远的管子照到线,调整的量要越大。

4.调整的时候,切记不要将其中一个轮子停下来或者倒转。要用差速来调整方向这样车行走比较稳,而且速度要快。

路口判断

路口判断,如图2所示,以7路巡线传感器为例,1号探头用来判断左侧T型路口。7号探头用来判断右侧T型路口。1和7同时照到线,用来判断十字路口。

转弯判断

1.巡线走到需要转弯的路口,如图3。

2.车继续向前走一小段,让小车的旋转中心点靠近线的交叉点。小车有编码器可以用编码器精确控制,或没有编码器可以用延时,让车继续向前走一段时间,这些都需要实际写代码测试。

3.小车原地转弯,直到中间的探头(4号),照到线。这是转到第一个路口,若这条线是设定的路线,则巡线向前走,若不是这条线,继续旋转,等待中间的探头照到线,则转到了下一个路口。

循迹小车功能实现

灰度部分

uint8_t stop_way = 0;//停止线检测
uint8_t sensor_val[5];//灰度返回值
uint16_t gray_state = 0x0;//当前灰度状态
uint16_t gray_status[2]={0},gray_status_backup[2][20]={0};//灰度传感器状态与历史值
uint32_t gray_status_worse=0;	//灰度管异常状态计数器

/****************************
函数名称:
函数作用:5路循迹获取状态
函数参数:无
函数返回值:当前巡线状态 16进制
****************************/
uint16_t Sensor_GetState(void)
{
	uint16_t State = 0X0000;
	
//	sensor_val[0] = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
//	sensor_val[1] = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1);
//	sensor_val[2] = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2);
//	sensor_val[3] = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3);
//	sensor_val[4] = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4);
//	
//	State |= (sensor_val[4] << 4);
//	State |= (sensor_val[3] << 3);
//	State |= (sensor_val[2] << 2);
//	State |= (sensor_val[1] << 1);
//	State |= (sensor_val[0] << 0);
	
	for(int8_t i=4;i>=0;i--)
	{
		sensor_val[i] = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0<<i);
		State |= (sensor_val[i]<<i);
	}
	
	return State;
}

void gray_check(void)
{
	gray_state = Sensor_GetState();
	
	//记录上一次传感器量
	for(uint16_t i=19;i>0;i--)
	{
	    gray_status_backup[0][i]=gray_status_backup[0][i-1];
	}
	
	gray_status_backup[0][0]=gray_status[0];
	
	//灰度检测
	switch(gray_state)
	{
		case 0x01:gray_status[0] = 4; gray_status_worse/=2;break;	  //00001b
		case 0x03:gray_status[0] = 3; gray_status_worse/=2;break;	  //00011b
	    case 0x02:gray_status[0] = 2;	gray_status_worse/=2;break;   //00010b
		case 0x06:gray_status[0] = 1;	gray_status_worse/=2;break;	  //00110b
		case 0x04:gray_status[0] = 0;	gray_status_worse/=2;break;   //00100b
		case 0x0C:gray_status[0] = -1;gray_status_worse/=2;break;		//01100b
		case 0x08:gray_status[0] = -2;gray_status_worse/=2;break;		//01000b
		case 0x18:gray_status[0] = -3;gray_status_worse/=2;break;		//11000b
		case 0x10:gray_status[0] = -4;gray_status_worse/=2;break;		//10000b
		case 0x00:gray_status[0] = gray_status_backup[0][0];gray_status_worse++;break; //00000b
		
		default://其它特殊情况单独判断
		{
			gray_status[0]=gray_status_backup[0][0];
			gray_status_worse++;
		}
	}	
	
		switch(gray_state)//停止线检测
		{
			case 0x0F://01111b
			case 0x1E://11110b
			case 0x1F://11111b
			{
				stop_way++;
			}
			break;
		}		
}

主函数部分

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM3_Init();
  MX_TIM2_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
		
		HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
		HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		motor_ctrl(500+gray_status[0]*100,-(500-gray_status[0]*100));
		Get_Encoder();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

可以观察到小车延黑线行驶 

循迹效果

需要代码的朋友可以点击以下链接下载,有问题请私信我。 

x(85条消息) 【免费】STM32循迹小车(灰度+OpenMV权重判断)资源-CSDN文库 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/940874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言练习6(巩固提升)

C语言练习6 编程题 前言 “宝剑锋从磨砺出&#xff0c;梅花香自苦寒来。”人类的美好理想&#xff0c;都不可能唾手可得&#xff0c;都离不开筚路蓝缕、手胼足胝的艰苦奋斗。我们的国家&#xff0c;我们的民族&#xff0c;从积贫积弱一步一步走到今天的发展繁荣&#xff0c;靠的…

国产当自强!深圳触觉智能「全国产化主板」大盘点(二)

上期我们给大家盘点了RK3568国产主板&#xff0c;本期为大家盘点的是深圳触觉智能RK3566系列产品&#xff0c;话不多说&#xff0c;上干货&#xff01; RK3566系列 深圳触觉智能 IDO-SOM3566 核心板 IDO-SOM3566-V1采用 Rockchip 新一代 64 位处理器 RK3566&#xff08;Q…

pyqt5-快捷键QShortcut

import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *""" 下面示例揭示了&#xff0c;当关键字绑定的控件出现的时候&#xff0c;快捷键才管用&#xff0c; 绑定的控件没有出现的时候快捷键无效 """…

正中优配:多只内房股沦为仙股 投资者信心何时恢复?

8月25日&#xff0c;受房地产利好方针推进&#xff0c;房地产板块直线大幅拉升&#xff0c;其中在港交所上市的富力地产大涨超过5%&#xff0c;股价重回1港元/股上方&#xff0c;然后暂时摆脱了“仙股”的称号。 实践上&#xff0c;近期&#xff0c;碧桂园、融创我国、SOHO我国…

智慧矿山IT智能运维自动化解决方案

矿山企业是国民经济中的重要组成部分&#xff0c;其资源开发和产业链条中涉及的环节与过程非常繁琐和复杂。随着我国矿山企业规模逐年扩大&#xff0c;为了提高其生产效率和降低其生产成本&#xff0c;信息化、数字化建设成为当下矿山企业发展的重要趋势。 第1章 智慧矿山的建…

Mac性能优化:深入了解WindowServer及其影响

文章目录 Mac性能优化:深入了解WindowServer及其影响WindowServer是什么?WindowServer为什么会占用那么多CPU?如何检查WindowServer是否使用了过多的CPU使用率?如何减少WindowServer的CPU使用率?Mac性能优化:深入了解WindowServer及其影响 大家好!今天我们来聊聊Mac上的…

14-redis

一 Redis概述 1 为什么要用NoSQL 单机Mysql的美好年代 在90年代&#xff0c;一个网站的访问量一般都不大&#xff0c;用单个数据库完全可以 轻松应付。在那个时候&#xff0c;更多的都是静态网页&#xff0c;动态交互类型的网站不多。 遇到问题&#xff1a; 随着用户数的增长…

第六章:数据结构与算法-part3:数据结构算法提升

文章目录 一、排序算法1.1 插入排序1、直接插入排序2、折半插入排序3、希尔排序 1.2、交换排序法1、起泡排序2、快速排序 1.3 选择类排序1、简单选择排序 二、业务逻辑算法设计2.1 基本概念和术语2.2 静态查找表2.3、有序表的查找 一、排序算法 排序是数据处理过程中经常使用的…

1990-2020年中国投入产出表

1990-2020年中国投入产出表 1、时间&#xff1a;1990-2020年 2、用途&#xff1a; 投入产出表提供了中国各个经济部门的投入和产出的详细信息。这些数据通常以货物和服务的形式表示&#xff0c;可以显示每个部门如何接收和分配资源&#xff0c;以及他们的经济互动情况。 可…

万级数据优化EasyExcel+mybatis流式查询导出封装

文章目录 前言.千万级数据优化一. 直接上流式查询封装工具代码二. 传统分页导出查询三. 流式查询概念游标查询 前言.千万级数据优化 我们不妨先给大家讲一个概念&#xff0c;利用此概念我们正好给大家介绍一个数据库优化的小技巧&#xff1a; 需求如下&#xff1a;将一个地市表…

Docker Compose 安装使用 教程

Docker Compose 1.1 简介 Compose 项目是 Docker 官方的开源项目&#xff0c;负责实现对 Docker 容器集群的 快速编排 。从功能上看&#xff0c;跟 OpenStack 中的 Heat 十分类似。 其代码目前在 https://github.com/docker/compose 上开源。 Compose 定位是 「定义和运行多个…

list【1】介绍与使用(超详解哦)

list的介绍与使用 引言list介绍接口使用默认成员函数迭代器容量元素访问数据修改 list的算法接口总结 引言 继vector之后&#xff0c;我们继续来介绍STL容器&#xff1a;list 对于容器的使用其实有着类似的模式&#xff0c;参考之前vector的使用可以让我们更快的上手&#xff…

Focal Loss-解决样本标签分布不平衡问题

文章目录 背景交叉熵损失函数平衡交叉熵函数 Focal Loss损失函数Focal Loss vs Balanced Cross EntropyWhy does Focal Loss work? 针对VidHOI数据集Reference 背景 Focal Loss由何凯明提出&#xff0c;最初用于图像领域解决数据不平衡造成的模型性能问题。 交叉熵损失函数 …

嵌入式底层驱动需要知道的基本知识

先说结论&#xff0c;能&#xff0c;肯定能&#xff0c;必须能&#xff01; 但是&#xff0c;问题重点在于坚持&#xff0c;程序员这一行 &#xff0c;下班回家一般都要10点了&#xff0c;再刷两个小时枯燥的学习视频&#xff0c;我想大多数人是坚持不下来的。 但是&#xff…

ABB D674A906U01流量计变送器模块

流量测量&#xff1a; 该模块用于准确测量液体或气体的流量&#xff0c;通常以标准单位&#xff08;如立方米每小时或加仑每分钟&#xff09;表示。 传感器技术&#xff1a; 它通常使用各种传感器技术&#xff08;例如涡轮、电磁、超声波等&#xff09;来检测流体的流动并进行…

冠达管理:股票停牌后会大涨吗?

股票停牌是指证券买卖所为了保护市场秩序、保护出资者利益等原因暂时中止某些股票的买卖。但是&#xff0c;股票停牌前的股价与停牌后的股价会有什么不同呢&#xff1f;股票停牌后是否会大涨呢&#xff1f;在本文中&#xff0c;咱们将从多个视点进行剖析&#xff0c;以帮助人们…

合宙Air724UG LuatOS-Air LVGL API控件--按钮 (Button)

按钮 (Button) 按钮控件&#xff0c;这个就不用多说了&#xff0c;界面的基础控件之一。 示例代码 – 按键回调函数 event_handler function(obj, event) if event lvgl.EVENT_CLICKED then print(“Clicked\n”) elseif event lvgl.EVENT_VALUE_CHANGED then print(“To…

java.lang.IllegalStateException: Unable to find

java.lang.IllegalStateException: Unable to find a SpringBootConfiguration, you need to use ContextConfiguration or SpringBootTest(classes…) with your test 错误场景&#xff1a;在使用mybatisplus做测试时&#xff0c;出现此错误 解决方案&#xff1a;SpringBoot…

【MCU】SD NAND芯片之国产新选择

文章目录 前言传统SD卡和可贴片SD卡传统SD卡可贴片SD卡 实际使用总结 前言 随着目前时代的快速发展&#xff0c;即使是使用MCU的项目上也经常有大数据存储的需求。可以看到经常有小伙伴这样提问&#xff1a; 大家好&#xff0c;请问有没有SD卡芯片&#xff0c;可以直接焊接到P…

python可视化matplotlib——绘制正弦和余弦

这是一个使用matplotlib库绘制正弦和余弦函数曲线的代码示例。代码中导入了需要的库&#xff0c;并设置了x轴和y轴的标签字体为华文楷体。然后&#xff0c;使用numpy生成一组x轴上的值t&#xff0c;并使用正弦函数生成对应的y轴值s&#xff0c;再使用余弦函数生成对应的y轴值z。…