作为一名学生,这里我就简单谈谈我们小组做这个循迹小车的一个过程。主要是实现小车寻黑线行驶的这样一个功能,速度可以调节(定时器中断模拟PWM波实现)
小车的主体框架是一个三轮的外在形态
电源:采用2S可充电锂电池作为主电源供给(主要是给驱动供电)
传感器:采用灰度传感器(2个)
灰度传感器工作原理很简单,下面有介绍。它和单片机之间的联系体现在:两个灰度传感器的信号输出端DO 分别接单片机的两个引脚,根据它们检测到的值的不同情况(即0,1两种取值,两两组合共4种情况)进而确定小车前进的方向。
驱动:采用的是L298N芯片,一片L298N可以控制两个直流电机,进而驱动两个后轮。关于这个芯片,网上有很多的用户手册,可以去搜索查看,这里我就简单说说他的用法:前面蓝色的3插口是外接电源供电用的,左右两个蓝色的2插口是输出,连接电机,逻辑输入引脚IN1-IN4 接单片机引脚(单片机与驱动的联系也就在这,单片机控制IN1~IN4进而控制小车两个轮子的正转和反转),IN1-IN4旁边的两路输入ENA和ENB分别对应控制左右两路输出(接单片机引脚,通过定时器调节来输出PWM波,实现小车转弯)
控制系统:小车采用了51单片机最小系统,主控芯片选择的是STC89C52RC
另外:亚克力板(车子底板),防滑车轮x2,万向轮x1,杜邦线若干
传感器:灰度传感器有两个检测灯,一个灯用于发射光,根据不同颜色的地面对光的吸收程度不同进而反射光强度肯定也不同,另一个灯则用于检测反射光的强度来判断是否检测到黑线。
若检测到黑线则输出低电平(0);信号灯熄灭;没检测到黑线则为高电平,信号灯点亮。(电源指示灯是一直亮着的)
左右两个灰度传感器对地面进行检测,单片机(STC89C52)根据测量值的不同情况组合判断小车的前进方向,同时通过驱动(L298N)来控制小车的运动情况。
几点注意:
1.传感器需要外接电源供电,这里我们直接使用的51单片机的5V输出电压供电
2.驱动芯片L298N也需要外接电源,这里我们使用的2s可充电锂电池连接的芯片的12V电源输入端
3.单片机也需要外接电源供电,这里我们直接连接的L298N的5V电源供电端,因为L298N已经外接了一个12V电源,所以我们直接使用它的5V电源供电端
4.小车各个模块的连线可以参考这个视频:(引用)寻迹小车连线,所谓"拼车"
5.最终小车的图片( ‘线’ 场一片混乱 )
#include<reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar Duty_left,Duty_right; //左右占空比标志,取1-100
uchar i=0,j=0;
uchar flag; //用于循迹方向的判断
//驱动L298N---->
//ENA,ENB为使能端; ENA,1,2和ENB,3,4分别控制一个电机;
sbit IN1 = P1^0;
sbit IN2 = P1^1;
sbit IN3 = P1^2;
sbit IN4 = P1^3;
sbit ENA = P1^6;
sbit ENB = P1^7;
sbit left=P3^2; //左右两个灰度传感器
sbit right=P3^3;
//小车直行速度赋值
void forward_move()
{
Duty_left=20;
Duty_right=12;
IN1=1; //两个电机均正转
IN2=0;
IN3=1;
IN4=0;
}
//小车停止
void stop()
{
Duty_left=0;
Duty_right=0;
IN1=0;
IN2=0;
IN3=0;
IN4=0;
}
//小车左转速度赋值(用于左边传感器检测到黑线)
void Left_turning()
{
Duty_left=18;
Duty_right=20;
IN1=1; //两个电机一个正转一个反转(或者一个正转一个不转)
IN2=0;
IN3=0;
IN4=1;
}
//小车右转速度赋值(用于右边传感器检测到黑线)
void Right_turning()
{
Duty_left=18;
Duty_right=20;
IN1=0;
IN2=1;
IN3=1;
IN4=0 ;
}
//定时器0中断初始化
void timer0init()
{
TMOD|=0x01;//定时器T0, 工作方式1, 16位
TH0=0xff;//定时 ff9c 0.1ms
TL0=0x9c;
EA=1; //开启总中断
ET0=1;//开启中断允许
TR0=1;//开启定时器中断
}
//定时器中断服务函数
void timer0() interrupt 1
{
TH0=0xff;
TL0=0x9c;
i++;
j++;
if(i<=Duty_left)//设置左轮占空比,即左轮速度
ENA=1;
else
ENA=0;
if(j<=Duty_right)
ENB=1;
else
ENB=0;
if(i==100) //设置pwm周期=0.1ms*100=10ms,这样开头定义的变量正好表示占空比数值
{
i=0;//加到100后变为0,重新计数
}
if(j==100)
{
j=0;
}
}
//循迹模块
void xunji()
{
if((left==0)&&(right==1))
{
flag = 0;//左边检测到黑线
}
else if((left==1)&&(right==0))
{
flag = 1;//右边检测到黑线
}
else if((left==1)&&(right==1))
{
flag = 3; //两边都没检测到黑线
}
else
{
flag = 4;
}
switch(flag)
{
case 0: Right_turning();break;
case 1: Left_turning();break;
case 3: forward_move();break;
case 4: forward_move();break;
default: forward_move();break;
}
}
void main()
{
timer0init();
//forward_move();
while(1)
{
xunji();
}
}
最后关于那个定时器中断模拟PWM波调速,我谈谈我的理解:
这里,小车的速度调节通过调节程序里定义的占空比变量的值(Duty_left,Duty_right)。例如,值为x就表示占空比为x%,占空比就是指一个周期内高电平持续时间占整个周期的比值,这里是调节占空比变量的值来控制EN的持续时间进而改变其速度。
文章浏览阅读1.1k次,点赞2次,收藏3次。一般情况下,我们使用的是官方推荐的操作系统 —— Raspbian OS。这是一款免费的基于Debian Linux的操作系统,可以安装到所有版本的树莓派上。这就意味着我们需要了解一些常用的linux命令,这样才能得心应手。_树莓派linux执行命令
文章浏览阅读702次。Matlab系列之符号运算(下)续符号矩阵符号矩阵的生成符号矩阵的运算符号微积分极限微分积分符号积分变换Fourier变换及其逆变换Laplace变换及其逆变换z变换及其逆变换符号方程求解代数方程求解微分方程求解无穷级数的求和运算更多精彩,等你发现~续上一篇主要对符号对象进行了一些生成和使用的基本操作,然后本篇将介绍符号矩阵、微积分、积分变换以及符号方程的求解,具体内容就往下慢慢看了。符号矩阵符号矩阵的生成符号矩阵的生成和数值矩阵的相关操作类似,创建方法有以下的几种:1、直接创建符号矩阵2、用_syms eqn可以是矩阵吗
文章浏览阅读352次。一 日志1 什么是日志通过日志查看程序的运行过程,运行信息,异常信息等。2 配置日志级别日志记录器(Logger)的行为是分等级的。一般分为:FATAL(致命)、ERROR(错误)、WARN(警告)、INFO(信息)、DEBUG(调试)默认情况下,spring boot从控制台打印出来的日志级别只有INFO及以上级别,可以配置日志级别# 设置日志级别为ERRORlogging: level: root: ERROR这种方式能将ERROR级别以及以上级别的日志打_spring boot
文章浏览阅读4.3k次。问题:在为windows7 sp1安装framework 4.6.2的时候,有两次证书方面的报错// 错误1:无法建立到信任根颁发机构的证书链// 错误2:已处理证书链,但是在不受信任的根证书中终止查找资料:经过查找,发现在4.6的前期版本,就已经有过次问题的解决方案,比如类似的文章:.NET Framework 4.6.1/4.6 的安全性更新 31360..._netframework4.6.2安装未成功
文章浏览阅读440次。为何光用姿态角表示姿态行不通?_欧拉角不同旋转顺序的区别
文章浏览阅读616次。ssdnerf_ssdnerf
文章浏览阅读113次。文章目录HashSetTreeSetHashSet源码:添加元素的过程:先调用该元素所属类的hashCode()方法计算哈希值,再处理得到底层数组的索引位置。如果得到的索引位置上已经有元素,二者的哈希值不一定是一样。这时,比较哈希值,如果相同,再用equals()方法比较,如果返回为true,添加失败。如果哈希值相同而且用equals()方法比较返回为false,用链表的方式添加到这个元素的后面,即原来的元素指向新添加的元素。*哈希值计算方法:哈希值相当于是一个随机数。乘数一般选31,_java treeset排序比较的是hash值吗
文章浏览阅读117次。在oracle中,常见的数据库对象有:表,视图,索引,序列,同义词存储过程,存储函数,触发器,包,包体,数据库链路(datalink),快照表是数据库的基本存储单元,以行列组成,命名规则:1,必须以字母开头2,长度在1~30之间3,oracle默认存储都存为大写创建表必须具备:权限 和 表空间常见的数据类型如下://创建表语法:crea..._oracle给3个表建立关系及约束同义词
文章浏览阅读1.3w次,点赞8次,收藏31次。Virtual texture 技术用于解决3D场景中大量贴图而内存有限的情况,它的思想可以参考虚拟内存。 虚拟内存技术中,物理内存是有限的,但是虚拟内存可以远远大于物理内存,虚拟内存被抽象成一个个page即分页文件,page可以真实的载入到物理内存中,也可以存在与磁盘文件上,寻址时采用的内存地址采用一个表来映射到具体的的内存位置,如果映射到物理内存里,即hit,如果在磁盘的page上,将其载入物_sparse virtual texture
文章浏览阅读205次。温故而知新。环境介绍windows 10jdk1.8tomcat 8.0.26dwr 3.0.2commons-logging-1.2.jareclipst 4.6.1在 ECLIPSE 中新建一个 Dynamic Web Project ,把以下文件装进去。1. 依赖包,路径 WEB-INF/lib dwr.jar commons
文章浏览阅读296次。#include #include #include #include using namespace std;const int maxn = 1e6 + 5;const int mod = 1e9;int a[32], dp[maxn];int main() { a[0] = 1; for (int i = 1; i <= 20; i++) a[i] = a[_poj2229完全背包
文章浏览阅读5.1w次,点赞2次,收藏13次。内容来自 DataSciComp,人工智能/数据科学比赛整理平台。Github:iphysresearch/DataSciComp本项目由 ApacheCN 强力支持。微博 | 知乎 | CSDN | 简书 | OSChina | 博客园2019世界机器人大赛—BCI脑控机器人大赛 暨 第三届中国脑机接口比赛http://www.worldrobotconference.com/ht..._l2rpn ijcnn 2019