从零开始,学做智能小车【4-程序初级篇】
如何着手制作一个机器人小车--给初学者【下】

如何着手制作一个机器人小车--给初学者【下】[三]控制器部分适合机器人的控制芯片有很多:单片机、DSP、甚至我们计算机上所用的CPU,都可以。
不过我们这里主要介绍的针对机器人小车的技术,所以把其他的先放一放,让我们把注意力放到物美价廉的单片机上来。
首先还是理论课,不要抱怨,我的信条是:不懂理论的开发者永远只能是一个拼装师。
单片机:单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。
概括的讲:一块芯片就成了一台计算机。
它的体积小、质量轻、价格便宜、为学习、应用和开发提供了便利条件。
小芯片有大智慧单片机是自动控制系统中应用非常广泛的控制芯片,现在就在我们身边的许多的电器中都有单片机的身影。
想自己动手制作机器人的话,相应的单片机知识是必不可少的。
系统的单片机知识我这里不想多说,想要对单片机系统有一个深入的理解,还是要找一本比较好的单片机教材一页一页的看下去,网上的任何“技巧”“快速入门”(包括本文)都只能算是水果、零食之类,闲暇无事时可以拿来开开胃,真正想要吃饱吃好,还是要用大饼卷馒头就着米饭吃才行。
我这里只提一些基础的入门概念,给真正的入门者起一点抛砖引玉的作用。
一块我们刚刚从商家手里拿到的单片机芯片,还是一块空白,什么也做不了。
如同一个刚出世的孩子,我们开发人员要做的,就是教会单片机处理各种各样的问题,给单片机配备上各种各样的扩展工具,使单片机可以将复杂的问题简单化,数字化。
单片机开发涉及两方面:硬件、软件。
单片机不同于其他电器,拿过插销直接插在电源上就可以使用,一块空白的单片机想要使用,还需要一些其他的电路来支持。
一般来说,最基本的电路就是单片机最小系统:所谓的单片机最小系统就是指可以让单片机工作起来的最基本的电路,在所有的单片机系统中,你都可以找到类似的电路。
至于它的原理,我这里就不累述了,找本书看去吧。
我再介绍一些做机器人需要的扩展电路:程序下载电路:单片机最终需要程序来控制,一般都是在PC上编写好程序,通过下载线来下载到单片机中执行。
机器人智能小车制作与编程

机器人智能小车制作与编程
一、智能小车的制作
1、准备材料:电机、智能小车及其相关的板、轮子、电池、杜邦线、螺丝刀、钳子、电钻、活动榫头、把手以及其他相关材料。
2、连接电机与电池:将电机与电池连接起来,用杜邦线将正极引脚
连接到电机的正极,负极引脚连接到电机的负极,确保电池与电机之间的
稳定连接和电路的正确性。
3、安装电机:将电机安装在智能小车的底盘上,使用螺丝刀将电机
固定在底盘上,确保电机的稳定性和牢固性。
4、连接轮子:将轮子连接到电机上,将活动榫头连接到轮子上,再
将把手连接到活动榫头上,以保证轮子与电机之间的稳定连接。
5、安装智能小车板:将智能小车板安装在轮子上,使用螺丝刀将其
固定在轮子上,以保证智能小车板的稳定性和牢固性。
二、智能小车的编程
2、配置参数:将智能小车的电机、电池、摄像头等硬件连接到计算
机上,打开Arduino IDE软件,根据硬件的设置进行参数配置,确保硬件
参数的正确性。
3、编写代码:根据智能小车的功能,利用Arduino IDE进行软件编写,编写完成后,将代码上传到智能小车板上。
零基础三天三十元做出智能车(第六讲)

占空比
例如:脉冲宽度1μs,信号周期4μs的脉冲序列占 空比为0.25。 在一段连续工作时间内脉冲占用的时间与总时间的 比值。
占空比
• • • • • 生动比喻:占空比又比如 0% 占空比 :人每天三顿饭一顿也不吃 33%占空比 :人每天三顿饭只吃一顿 67%占空比 :人每天三顿饭只吃两顿 100%占空比 :人每天三顿饭吃三顿
占空比
• 使用PWM控制一个电机快慢前进与后退 • 使用PWM控制两个个电机快慢前进与后退
驱动电路图
二:各模块连接
循迹电路图
系统板电路图
实物图
三:算法
• 学习如何控制单片机 输出 • 实现 信号 • 单片机 驱动模块
反馈 信号 控制
电机
• 循迹模块
路线分析
左电机 P0.2 P0.3 LA 0 0 LB 0 不转 1 前转 右电机 P0.0 P0.1 RA 0 0 RB 0 不转 1 前转
三天三十元让你做出智能车
第一章:三天学会制作循迹小车!
第六节课
零基础
主讲:张欢
一:认识和使用占空比控制电机转速பைடு நூலகம்
• (1):占空比又称为PWM • (2):什么是占空比?
认识占空比(PWM)
占空比的图例占空比又名占空度、占空因数。 • 占空比有如下含义: 在一串理想的脉冲周期序列中(如方波), 正脉冲的持续时间与脉冲总周期的比值。
谢谢观看 ! 零基础三天三十元做出智能车 系类视频教程
感谢大家对穿山乙工作室的支持!
1
1
0 后转
1 不转
1
1
0 后转
1 不转
单片机------电机驱动模块------小车
P0.2 P0.3 P0.0 P0.1
智能小车制作详细教程

智能小车制作详细教程智能小车是一种具有自主导航和智能决策能力的机器人车辆。
它可以通过传感器感知周围环境,并根据程序进行自主控制,实现不同场景下的导航、避障和定位等功能。
下面将为你介绍如何制作一辆智能小车的详细教程。
首先,我们需要准备以下材料和设备:1. 一个底盘,它可以是一个具有轮子的坚固平台,也可以是一个注重设计的小车模型。
2. 两个直流电机,用于驱动车辆的轮子。
3. 一个电源,例如锂电池,用于给电机和电子设备供电。
4. 一个主控制器,如Arduino板或Raspberry Pi,用于处理传感器数据和执行控制程序。
5. 一套传感器,例如超声波传感器、红外线传感器和摄像头,用于感知周围环境。
6. 一些导线、电路板和螺丝等连接和固定材料。
7. 一个电脑,用于程序开发和调试。
接下来,我们可以开始制作智能小车:1. 首先,将直流电机连接到主控制器上,确保它们可以通过电源进行驱动。
2. 通过编程,编写一个基本的控制程序,使电机可以运行并控制车辆的前进、后退、左转和右转等行为。
3. 安装传感器模块,例如超声波传感器或红外线传感器,用于检测障碍物和测量距离。
4. 根据传感器的数据,更新控制程序,使车辆能够在遇到障碍物时自动停下或转向避开障碍物。
5. 如果需要进行定位和导航,可以添加一个GPS模块或采用视觉识别技术,例如使用摄像头检测道路标志或地标。
6. 调试程序并优化车辆的导航和控制性能。
7. 最后,将所有组件和电子设备固定在底盘上,确保它们牢固可靠。
通过以上步骤,我们可以制作出一辆基本的智能小车。
当然,实际制作中可能会遇到一些困难和挑战,需要更深入的知识和技能来解决。
不过,这个简单的教程可以为初学者提供一个入门指南,让他们了解智能小车制作的基本流程和方法。
希望这个教程对你有所帮助!。
手把手教做智能小车

手把手教做智能小车我们学习完51单片机入门之后,一定要多做一些有意思的小制作,才能将单片机知识理解的更加深刻,而智能小车不失为一个不错的选择,今天将全程介绍智能小车的制作过程。
一般而言,常见的智能小车分为:蓝牙遥控、超声波避障、光电寻迹等。
这次主要介绍蓝牙遥控和超声波避障。
1.蓝牙遥控小车1.1功能要求使用手机串口软件和小车上的蓝牙芯片进行通信,控制小车转向、前进、后退、停止、启动等。
1.2元器件准备STC89C52单片机一片(其他型号的51同样可以,注意要有配套的下载器或者开发板,下载程序比较方便);L298N驱动模块两个;亚克力板车架一个(淘宝有卖,配有电机、轮胎);蓝牙模块一个(型号HC06);电池盒、电池(建议两节18650电池);杜邦线若干;上述所有的原材料淘宝均有卖,请自行选购。
1.3小车拼装购买齐备上述原材料之后,可以查看卖家提供的说明或者相应芯片的Datasheet,并使用杜邦线将各部分电路连接起来。
既然选择学习单片机和电子制作,就要有一定的探索精神和钻研精神,小车拼装过程比较简单,就不再一一赘述,拼装完如下:这是我几年之前做的,比较简陋,刚开始使用的是四节小电池,动力不够强劲,后来改成两节18650就跑的飞起。
1.4程序设计部分小车的基本功能要求有了,主体也实现了,接下来当然是程序设计了。
下面以STC89C52单片机为例,以KEIL2为开发软件,程序如下,比较简单,自行理解:#includesbit IN1=P1^0;sbitIN2=P1^1;sbit IN3=P1^2;sbit IN4=P1^3;sbit IN5=P1^4;sbit IN6=P1^5;sbit IN7=P1^6;sbit IN8=P1^7;#define left_go {IN1=1,IN2=0,IN3=1,IN4=0;}//P1:0-3控制左边#defineleft_back {IN1=0,IN2=1,IN3=0,IN4=1;}#define left_stop {IN1=0,IN2=0,IN3=0,IN4=0;}#define right_go{IN5=1,IN6=0,IN7=1,IN8=0;}//P1:4-7控制右边#define right_back {IN5=0,IN6=1,IN7=0,IN8=1;}#define right_stop {IN5=0,IN6=0,IN7=0,IN8=0;}#define uchar unsignedchar#define uint unsigned intvoid run();void backrun();void leftrun();void rightrun();void stoprun();void delay(uchar time);void init();uchar flag,com;void main(){ init(); while(1) { if(flag==1) { switch(com) { case 1: run(); break; case 2: backrun(); break; case 3: leftrun(); break; case 4: rightrun(); break; case 5: stoprun(); break; default: break; } }RI=1; }}void init(){ TMOD=0x20; TH1=0xfd; TL1=0xfd;TR1=1; REN=1; SM0=0; SM1=1; EA=1; ES=1;flag=0;}void run(){ left_go; right_go;}voidbackrun(){ left_back; right_back;}void leftrun(){ left_back; right_go;}void rightrun(){ left_go; right_back;}voidstoprun(){ left_stop; right_stop;}void ser() interrupt 4{ RI=0; com=SBUF; flag=1;} 几年前初学单片机写的C51程序,献丑了!1.5 完成至此,蓝牙小车就初步完成,在网上找一个串口软件,连上小车上的蓝牙芯片,就可以实现相应的功能。
第4课 搭建智能小车

搭建智能小车1. 研究汽车上的轮轴作用,并尝试使用轮轴解决问题2. 了解车体中摩擦力与速度的关系3. 学习了解车体结构并使用各类传感器制作不同功能的小车4. 学习了解车的形态、思考车体的搭建方法车辆包括人力车和畜力车,是最古老的交通、运输和作战机械之一。
利用畜力推车拉磨,甚至耕田种地,都需要依据牲畜的身躯特点而创制有效的挽具。
挽具的发明,是人类智慧的表现之一。
古代车马图我想让我的爱车“善解人意”,有什么办法能做到吗?受到滚动圆木,或纺轮、陶轮和玉质圆形物滚动的启发,在公元前2000年,中国就出现了原始的车。
早期车轮称为「辁quán」,即无辐条的圆木板。
此后直到战国时期,马车的形制基本相同。
秦始皇陵出土的铜车马不仅对不同构件采用不同铜、锡比例的青铜合金,而且构件的焊接形式多样化,并在车轱辘其间涂抹油脂,既保证坚固耐用,又能减少摩擦阻力和加快车速。
润滑油脂的应用,应是由古代中国人最早发现的。
造车是先秦一个大型的工程技术部门。
《考工记》中「轮人」、「舆yú人」和「辀zhōu人」,是迄今尚存较完整叙述制车技艺的三篇文字,它们记载了从西周到春秋战国之际一系列造车的技术规范与检测标准,充满工程工艺学、材料力学和应用物理学的内容。
智能小车作为现代的新发明,是以后的发展方向,它可以按照预先设定的模式在一个环境里自动的运作、不需要人为的管理,可应用于科学勘探等等的用途。
智能小车能够实时显示时间、速度、里程,具有自动寻迹、寻光、避障等等功能,可程控行驶速度、准确定位停车,远程传输图像等功能。
本课题就专为智能小车设计,来一起看看车世界的智能是什么样吧!设计并搭建:I.这辆车有四只轮胎,一个发动机II.赛车要求具备流线型车体和较低的底盘III.安装电机、主控及所需传感器注意:孩子们对小车有很多自己的想法并充满了想象,但是一定注意器材使用的合理性,用有限的物料解决问题。
建构(construct)将两个电机按图所示与一根9孔直条洞梁相连并用4根蓝色三节销将之固定在一边加一根11孔直条洞梁,并用两根黑两节销固定连接制作车体的车轮,将3M带帽十字轴插入轮毂gū内,然后套上轮胎,加入厚轴套将之固定制作车的车体:将两根圈梁用7孔直条洞梁相连接,插入两根蓝三节销固定在车体两圈梁连接处加入两根黑两节销连接一根7孔直条洞梁,并用两根黑两节销连接随后加入I形洞梁架将之固定加入万向轮作为车子的转向轮最后一步:加入主控加入传感器,使作品可通过Arduino编程独立运行试试让下车从斜面上开下来后,走一段很小距离后,再冲上另一个斜面,看看它能不能再冲到原来的那个斜面的高度了呢?不能了,因为能量已经逐步消耗掉了。
智能小车程序(完整)

智能小车程序(完整)智能小车程序---------超长完整版---------#include "reg52.h"#define det_Dist 2.55 //单个脉冲对应的小车行走距离,其值为车轮周长/4#define RD 9 //小车对角轴长度#define PI 3.1415926#define ANG_90 90#define ANG_90_T 102#define ANG_180 189/*============================全局变量定义区============================*/sbit P10=P1^0; //控制继电器的开闭sbit P11=P1^1; //控制金属接近开关sbit P12=P1^2; //控制颜色传感器的开闭sbit P07=P0^7; //控制声光信号的开启sbit P26=P2^6; //接收颜色传感器的信号,白为0,黑为1sbit P24=P2^4; //左sbit P25=P2^5; //右接收左右光传感器的信号,有光为0unsigned char mType=0; //设置运动的方式,0 向前1 向左2 向后3 向右unsigned char Direction=0; //小车的即时朝向0 朝上1 朝左2 朝下3 朝右unsigned sX=50; unsigned char sY=0; //小车的相对右下角的坐标CM(sX,sY)unsigned char StartTask=0; //获得铁片后开始执行返回卸货任务,StartTask置一unsigned char Inter_EX0=0; // 完成一个完整的任务期间只能有一次外部中断// Inter_EX0记录外部中断0的中断状态// 0 动作最近的前一次未中断过,// 1 动作最近的前一次中断过unsigned char cntIorn=0; //铁片数unsigned char bkAim=2; //回程目的地,0为A仓库,1为B仓库,2为停车场,//(在MAIN中接受铁片颜色判断传感器的信号来赋值)unsigned char Light_Flag=0;//进入光引导区的标志(1)unsigned int cntTime_5Min=0;//时间周期数,用于T0 精确定时unsigned int cntTime_Plues=0; //霍尔开关产生的脉冲数/*============================全局变量定义区============================*//*------------------------------------------------*//*-----------------通用延迟程序-------------------*//*------------------------------------------------*/void delay(unsigned int time) // time*0.5ms延时{unsigned int i,j;for(j=0;j<time;j++)< p="">{for(i=0;i<60;i++){;}}}/*-----------------------------------------------*//*-------------------显示控制模块----------------*//*-----------------------------------------------*//*数码管显示,显示铁片的数目(设接在P0,共阴)*/void Display(unsigned char n){charNumb[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x37,0x77}; P0=Numb[n];}/*-----------------------------------------------*//*-------------------传感器模块------------------*//*-----------------------------------------------*//*光源检测程序: *//*用于纠正小车运行路线的正确性*/unsigned char LightSeek(){ void Display(unsigned char);bit l,r;l=P24;r=P25;if(l==0&&r==1){//Display(1);return (3); //偏左,向右开}if(r==0&&l==1){//Display(3);return(1); //偏右,向左开}if((l==1&&r==1)||(l==0&&r==0)){//Display(9);return(0); //没有偏离,前进}}/*铁片检测程序: *//*判断铁片的颜色,设定bkAim,0为A仓库,1为B仓库,2为停车场*/ void IornColor(){delay(4000);bkAim=(int)(P26);Display((int)(P26)+2);}/*-----------------------------------------------*//*------------------运动控制模块-----------------*//*-----------------------------------------------*//*====基本动作层:完成基本运动动作的程序集====*/ /*运动调整程序: *//*对小车的运动进行微调*/void ctrMotor_Adjust(unsigned char t){if(t==0){P2=P2&240|11; //用来解决两电机不对称的问题delay(6);}if(t==3){delay(1);}if(t==1){P2=(P2&245);delay(1); //向右走}P2=((P2&240)|15);delay(10);}/*直走程序: *//*控制小车运动距离,dist为运动距离(cm),type为运动方式(0 2)*/ /*只改变小车sX 和sY的值而不改变Direction的值. */ void ctrMotor_Dist(float dist,unsigned char type) {unsigned char t=0;mType=type;P2=((P2&240)|15);cntTime_Plues=(int)(dist/det_Dist);while(cntTime_Plues){if(Inter_EX0==1&&StartTask==0){cntTime_Plues=0;break;}if(Light_Flag==1) t=LightSeek();if(type==0) //向前走{P2=P2&249;delay(40);ctrMotor_Adjust(t);}if(type==2) //向后退{P2=P2&246;delay(50);ctrMotor_Adjust(t);}if(mType==2) delay(60);//刹车制动0.5mselse delay(75);}}/*拐弯程序: *//*控制小车运动角度,type为运动方式(1 3)*//*只改变小车Direction的值而不改变sX 和sY的值*/void ctrMotor_Ang(unsigned char ang,unsigned char type,unsigned char dir) {unsigned char i=0;mType=type;P2=((P2&240)|15);cntTime_Plues=(int)((PI*RD*90/(180*det_Dist)*1.2)*ang/90);while(cntTime_Plues){if(Inter_EX0==1&&StartTask==0){cntTime_Plues=0;break;}if(type==1) //向左走{P2=P2&250;delay(100);ctrMotor_Adjust(0);}if(type==3) //向右走{P2=P2&245;delay(100);ctrMotor_Adjust(0);}P2=((P2&240)|15);delay(50);//刹车制动0.5ms}if(!(Inter_EX0==1&&StartTask==0)){Direction=dir;}}/*====基本路线层:描述小车基本运动路线的程序集====*//*当小车到达仓库或停车场时,放下铁片或停车(0,1为仓库,2为停车场)*/void rchPlace(){unsigned int time,b,s,g;time=(int)(cntTime_5Min*0.065535);//只有一个数码管时,轮流显示全过程秒数个十百b=time%100;s=(time-b*100)%100;g=(time-b*100-s*10)%10;if(bkAim==2){//到达停车场了,停车EA=0;P2=((P2&240)|15);while(1){Display(10); //Ndelay(2000);Display(cntIorn);delay(2000);Display(11);//Adelay(2000);Display(b);delay(2000);Display(s);delay(2000);Display(g);delay(2000);}}else{if(Inter_EX0==1&&StartTask==1)P10=0; //到达仓库,卸下铁片}}/*无任务模式: *//*设置小车的固定运动路线,未发现铁片时的运动路线*/void BasicRoute(){ //Light_Flag=1;ctrMotor_Dist(153,0);//Light_Flag=0;ctrMotor_Ang(ANG_90,1,1);ctrMotor_Dist(100-sX,0);ctrMotor_Dist(125,2);ctrMotor_Dist(73,0);ctrMotor_Ang(ANG_90,1,2);//Light_Flag=1;ctrMotor_Dist(153,0);//Light_Flag=0;ctrMotor_Ang(ANG_180,1,0);rchPlace();}/*任务模式: *//*设置小车的发现铁片后的运动路线*/void TaskRoute(){//基本运行路线表,记载拐弯0 向前1 左拐2 向后3 右拐,正读去A区;反读去B区StartTask=1;ctrMotor_Ang(ANG_90_T,1,2);if(bkAim==1) //仓库A{ctrMotor_Dist(10,0);P2=((P2&240)|15);delay(60);ctrMotor_Ang(ANG_90_T,1,3);ctrMotor_Dist(100-sX,2);ctrMotor_Ang(ANG_90_T,1,2);Light_Flag=1;ctrMotor_Dist(153,2);Light_Flag=0;// ctrMotor_Ang(208,1,0);}else if(bkAim==0) //仓库B{ctrMotor_Dist(10,0);P2=((P2&240)|15);delay(60);ctrMotor_Ang(ANG_90_T,1,3);ctrMotor_Dist(100-sX,0);ctrMotor_Ang(ANG_90_T,1,0);Light_Flag=1;ctrMotor_Dist(153,2);Light_Flag=0;//ctrMotor_Ang(208,1,0);}delay(5000);rchPlace();}/*---------------------------------------------*//*-------------------主程序段------------------*/ /*---------------------------------------------*/void main(){delay(4000);P2=0xff; //初始化端口P07=0;P1=0;TMOD=0x01; //初始化定时器0/1 及其中断TL0=0;TH0=0;TR0=1;ET0=1;ET1=1;IT0=1; //初始化外部中断EX0=1;IT1=1;EX1=1;EA=1;P11=1;while(1){Display(cntIorn);bkAim=2;BasicRoute();if(Inter_EX0==1){TaskRoute();//按获得铁片后的路线运动IE0=0;EX0=1;}Inter_EX0=0;}}/*----------------------------------------------------*//*----------------------中断程序段--------------------*//*----------------------------------------------------*//*定时器0中断程序: *//*当时间过了5分钟,则就地停车并进入休眠状态*/ void tmOver(void) interrupt 1{cntTime_5Min++;TL0=0;TH0=0;if(cntTime_5Min>=4520){Display(5);P2=((P2&240)|15);EA=0; //停车程序P07=1;delay(4000);PCON=0X00;while(1);}/*外部中断0中断程序: *//*发现铁片,发出声光信号并将铁片吸起,发光二极管和蜂鸣器*//*并联在一起(设接在P07). 0为A仓库,1为B仓库,2为停车场*/ void fndIorn(void) interrupt 0{unsigned char i;P10=1;P2=((P2&240)|15); //停车P07=1;delay(1000);//刹车制动0.5msP07=0;Inter_EX0=1;cntIorn++;Display(cntIorn);for(i=0;i<40;i++){P2=P2&249;delay(2);P2=((P2&240)|15);delay(2);}P2=P2&249;delay(100);P2=((P2&240)|15); //停车IornColor(); //判断铁片黑白,设置bkAimfor(i=0;i<95;i++){P2=P2&249;delay(3);P2=((P2&240)|15);delay(2);}P2=((P2&240)|15); //停车delay(4000); //把铁片吸起来EX0=0;}/*外部中断1中断程序: *//*对霍尔开关的脉冲记数,对小车的位置进行记录,以便对小车进行定位*/ void stpMove(void) interrupt 2{cntTime_Plues--;if(Direction==0) //向上{if(mType==0) sY+=det_Dist;else if(mType==2)sY-=det_Dist;}else if(Direction==1) //向左{if(mType==0) sX+=det_Dist;else if(mType==2)sX-=det_Dist;}else if(Direction==2) //向下{if(mType==0) sY-=det_Dist;else if(mType==2)sY+=det_Dist;}else if(Direction==3) //向右{if(mType==0) sX-=det_Dist; else if(mType==2)sX+=det_Dist;}</time;j++)<>。
智能_循迹小车详细制作过程

2.2.1道路识别模块..................................................................3
三、光电管与摄像头结合寻线:兼顾了光电寻线的抗干扰能力强和摄像头寻线前瞻性远、信息量大的特点。
难点:光电管与摄像头之间的配合,两者切换的条件。
2.2具体方案
2.2.1道路识别模块
使用了CMOS摄像头和单排七对红外发射接受二极管。根据比赛环境的不同
可灵活选择各个方案。
在光电管与摄像头结合寻线模式里,使用光电管检测的信息作为整幅图像处理的第一行,在采集的图像干扰过多或信息量过少时切换到光电管循线的模式。
6.2调试过程.................................................................................24
6.3主要技术参数说明.................................................................25第七章结论..........................................................................................27附录A参考书目.......................................................................................I
4.1整体介绍....................................................................................9
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
电子科技大学
CXY-STUDIO
Write By cpholr
电机,用手轻轻一捏住,就停下来了,不管转的多块多牛逼。但是带了减速箱的直流电机,在负重情况下 还是可以轻松的爬坡,吊起重物等等。 所以相比于普通不带减速的直流电机, 减速直流电机的线性度非常好, 相同周期下不同占空比的 PWM, 可以得到不同的转速,受负载的影响相比普通电机而言小了很多。
--黑线在 2-3 正上方,与中心偏差 -8.5*8 mm --黑线在 3-4 正上方,与中心偏差 -8.5*6 mm --黑线在 4-5 正上方,与中心偏差 -8.5*4 mm --黑线在 5-6 正上方,与中心偏差 -8.5*2 mm
0 --黑线在 6-7 正上方,与中心偏差 0 1 --黑线在 3 --黑线在
电子科技大学
CXY-STUDIO
Write By cpholr
最简单的做法就是,偏差越大,就大的越多,偏差越小,就超过的小。偏差为零,左右轮子就给出一 样的占空比,让他们转速一样。 如果读者已经理解到了这个地方, 那么, 只要你硬件弄正确了, 小车是不是已经可以沿着黑线跑了呢? 答案是当然可以,但是,这样子小车的速度只能像蜗牛一样的爬,并不能飙车。这是为什么呢? 欲知原因,请听下回讲解。
2 --黑线在 7-8 正上方,与中心偏差 8.5*2 mm 4 --黑线在 8-9 正上方,与中心偏差 8.5*4 mm 5 --黑线在 7 --黑线在 9 --黑线在 11 --黑线在 6 --黑线在 9-10 正上方,与中心偏差 8.5*6 mm 8 --黑线在 10-11 正上方,与中心偏差 8.5*8 mm 10 --黑线在 11-12 正上方,与中心偏差 8.5*10 mm 这样的话,巡线的精度就锁定在 8.5 毫米了,这样的精度对于巡线小车是足够的。 我们再继续验算一下上面的偏差编码:
比如图中的方波,占空比为 20%。当然,图中只能看出来占空比的大小,其他信息不能看到。 对于直流电机,比较形象的解释: 假如说,以 10 秒钟 1 个周期,这 10 秒钟里面,电机有 X 秒钟,也就是(X/10)*100 %的时间是通电 的,剩下的(1-X/10)*100%的时间断电。当 X 越大(当然不能超过周期的值了) ,明显的,电机的总体转 速就越快了,因为停歇的时间少了。但是这个时候,周期很长,10 秒钟啊,很明显的可以看出电机停停走 走。假如把周期变到了 1 秒钟,0.1 秒钟,0.01 秒钟,0.001 秒钟,0.0001 秒钟,再去改变通电的时间, 这样子,就明显感觉不出来电机停停走走了。而总体的效果,则是 X 越大,电机的转速越快,X 越小,电机 的转速越慢。当 X 为零的时候,电机完全不转,当 X 大于一定的值的时候,电机开始慢慢转动起来,当 X 值到达最大的时候,就是占空比接近 100%的时候,电机的速度达到最快。 不过,对于巡线小车用的电机,推荐使用带了减速箱的直流电机,而非普通直流电机。杠杆原理告 诉我们,省力了就不省距离,省距离了就不省力。对于电机也是一样的,减速直流电机经过减速箱的一大 堆齿轮,把飞快转动的电机的速度降低了几百倍,由此减速直流电机的力气就很大了。不带减速箱的直流
如图所示。 现在假设前面的红外传感器有 12 个,黑线宽度为 2.5cm,红外传感器等间距分布,相邻的两个红外传感 器间距为 1.7cm 小于黑线的宽度。 所以当巡线小车跑在直线上的时候的状态应该是这样子的
电子科技大学
CXY-STUDIO
Write By cpholr
图中,两个红点之间距离是 17 毫米,黑线的宽度是 25 毫米。图片中展示了小车刚好毫无偏差的压在黑线 正上面,中间两个红外传感器刚好全部被黑线覆盖。 我们需要先给红外传感器编号,从左边开始到右边,编码为 1-2-3-4-5-6-7-8-9-10-11-12 注意了,开始讲控制算法了。 首先引入偏差的概念,当黑线在上图中的那种状态,称为偏差为零。 考虑到物理学中的相对运动理论的正确性,原本黑线是不动,小车的红外巡线传感器在动,现在我以 黑线在动,而小车不动来讨论偏差的数字化。 当黑线往左边移动 8.5 毫米, 就是红外巡线传感器的第 6 个传感器刚好完全压在黑线上面的那种情况。 这时候,跟之前相比,出现了不为零的偏差了。我们约定:黑线偏向左边时候,偏差为负,偏向右边时候, 偏差为正。上一次恰好压在正中间(6 号和 7 号正上方)时候偏差为 0,现在的这种情况,我们约定偏差 为“-1” 。 同理,当黑线往左边移动 8.5x2 毫米,就是刚好移动 17 毫米的时候,就是刚好压在 5 号和 6 号的正 上方的时候,偏差就为“-2“。 同样,黑线从正中间往右边移动 17 毫米的时候,偏差就是“+2“。 这样的话,偏差就可以编码: -11 --黑线在 -9 -8 -7 -6 -5 -4 -3 -2 -1 --黑线在 --黑线在 --黑线在 --黑线在 --黑线在 1 2 3 4 5 6 7 8 9 10 11 12 正上方,与中心偏差 -8.5*11 mm mm -10 --黑线在 1-2 正上方,与中心偏差 -8.5*10
电子科技大学
CXY-STUDIO
Write By cpholr
PORTA&0x0f 将读回来的 PA7,PA6,PA5,PA4 这四位屏蔽掉,不管它们是什么值,读回来后相 应的位都是 0,而保留了 PA3,PA2,PA1,PA0 原来的值。 (PORTA&0x0f) <<8 是讲上面得到的值右移 8 位,使之成为 PORT 的高 8 位。 最后与 PORTB 按位或运算,就把 PORT 的低 8 位补上了。最后呢: PORT 红 外 编 号 接着呢,就可以把全部的偏差都在 C 语言中体现出来了: 需要在定义一个变量,叫做当次得到的偏差: int x1; //当次偏差,用 x1 表示 完整代码如下: 15 X 14 X 13 X 12 X 11 1 10 2 9 3 8 4 7 5 6 6 5 7 4 8 3 *9 mm 正上方,与中心偏差 -8.5*7 mm 正上方,与中心偏差 -8.5*5 mm 正上方,与中心偏差 -8.5*3 mm 正上方,与中心偏差 -8.5*1 mm mm 正上方,与中心偏差 8.5*1 mm 正上方,与中心偏差 8.5*3 mm 正上方,与中心偏差 8.5*5 mm 正上方,与中心偏差 8.5*7 mm 正上方,与中心偏差 8.5*9 mm 正上方,与中心偏差 8.5*11 mm
在程序中呢,假如要读回 I/O 的电平状态: 需要先定义一个 16 位的变量: unsigned int PORT; 然后读取端口的数据: PORT=PORTB | ( (PORTA&0x0f) <<8 ); (以 AVR 单片机为例,其他单片机也类似) 上面这句话呢,对 C 语言位运算比较熟悉的同学一眼就能看懂了。如果不懂 C 语言的位运算,请翻阅 谭浩强的《C 程序设计》 ,再回来看这篇文章。
电子科技大学 上面的代码与前面的列表一一对应。
CXY-STUDIO
Write By cpholr
到现在为止, 完成了红外巡线探头数据的采集。 上面的内容, 暂时先藏着, 最重要的就是那个函数了, 而那个函数还是需要根据实际硬件来改动, 有些人喜欢红外传感器中间密两边疏, 有些人喜欢等间距分布, 有些人喜欢用 8 个红外巡线传感器,有些人则用 7 个,还有些人用 4 个。 我之前参加巡线机器人大赛的时候,用了 14 个红外传感器,非等间距分布,那是因为当时手头上有 现成的 PCB 模块,用两片中间密两边疏的拼起来,就变成完全没有规律的非等间距分布。虽然最后我的小 车拿了第六届巡线机器人的冠军。但是我还是提倡大家使用 12 个红外传感器以及等间距分布,因为非等 间距的时候每个红外传感器的偏差值很难确定,需要用尺子去测量每个红外传感器与中间的偏差值,然后 再一个个算出权重,处理起来相当麻烦。 原本看上去 8 个红外传感器,刚好对应一组 I/O 口,刚好 8 位,处理起来更加方便,但是算一下,当 黑线在中心的时候,200/7mm=28.57mm>25mm=黑线宽度,显然并不是非常合适了。因为当一个传感 器都没有检测到的时候,无法确定是在哪两个红外传感器之间,只能通过程序的记忆的方法来确定,精度 不高,又复杂。 能用硬件轻松解决的事情,就用硬件解决,不要去为难写程序的同学。他毕竟是你的队友啊。 。 。 通常我们会使用 LM339 集成四通道比较器来组装红外巡线模块电路, 为了让全部的 12 个通道都用上, 使用 12 个红外传感器就非常合适了。 假如再增加一个红外, 变成 13 个红外传感器, 就多浪费了一个芯片, 浪费了三个比较器的通道,又多增加了许多电路,麻烦的很。 接着继续讲解,PWM。 PWM 的全称是:pulse width modulation 。简称是脉宽调制。简单的来说,就是频率恒定,占空 比可以改变的方波了。
电子科技大学
CXY-STUDIO
Write By cpholr
假如出现这样的情况,从上面列表中可以获得压线在 4 号传感器的正上方,偏差就是“-5”了。 而通常情况没有那么刚好,也可能出现下图的那样子的情况:
7 号传感器到底检测到了黑线了吗,这就不一定了,具体情况要看从传感器读回的数据。 从前面电路篇可以知道,当压到黑线的时候,相应的压到黑线的 LED 是要发光的,说明,当压到黑 线的时候,红外传感器输出低电平,为 0,当在正常的白线上的时候,红外传感器是输出高电平的,为 1。 而对于单片机,假如我们用了 12 个 I/O 口去读回传感器的数值。假如是用 AVR 单片机,我们用了 PA 口的 8 个和 PB 口的 4 个,凑成了 12 个 I/O 口来读取 12 路传感器的数据。 比如像下面这样子对应 红外 编号 I/O 口 1 PA3 2 PA2 3 PA1 4 PA0 5 PB7 6 PB6 7 PB5 8 PB4 9 PB3 10 PB2 11 PB1 12 PB0
电子科技大学
CXY-STUDIO
Write By cpholr
从零开始,学做智能小车【4-程序初级篇】