零知四轮小车入门版(零知mini主控)教程-程序控制电机开跑

本系列教程讲解零知小车套件以零知迷你板为主控,使用零知开源平台进行智能小车开发。

使用的硬件:零知智能小车套件

实现的功能:红外循迹、超声避障、直线运行等基本功能。

扩展:可以在小车上加入其它传感器模块进行扩展,比如加入摄像头模块进行监控、加入火焰传感器做灭火小车、加入更多超声波模块实现自动跟随...


本系列教程目录

零知四轮小车入门版(零知mini主控)系列教程-小车组装


零知四轮小车入门版(零知mini主控)系列教程-程序控制电机开跑


零知四轮小车入门版(零知mini主控)系列教程-红外循迹走S弯


零知四轮小车入门版(零知mini主控)系列教程-超声波自动避障


一、工具材料

(1)组装好的智能小车


二、电机驱动说明

这里使用电机驱动为DRV8833型号,我们需要根据它的逻辑表来驱动电机:

其完整的datasheet文件


三、程序代码

我们根据电机的驱动,使用PWM进行控制,程序如下:

							
							

	   
	
	/**********************************************************
	*    文件: lzsmartcar_v1.ino      by 零知实验室([url=http://www.lingzhilab.com]www.lingzhilab.com[/url])
	*    -^^- 零知开源,让电子制作变得更简单! -^^-
	*    时间: 2019/11/20 15:50
	*    说明: 零知智能小车-迷你板
	************************************************************/
	   
	//调试信息
	#define DEBUG_PRINT

	   
	/***************************************************************/
	//引脚说明
	//电机模块
	#define MotorIN1                        2
	#define MotorIN2                        3
	#define MotorIN3                        4
	#define MotorIN4                        5
	   
	#define MotorIN5                        8
	#define MotorIN6                        9
	#define MotorIN7                        10
	#define MotorIN8                        11
	/***************************************************************/
	   
	//小车运行方向
	enum carDirec{
	        carForward = 1,
	        carBack,
	        carLeft,
	        carRight,
	        carStop
	};

	#define MotorSpeedRoSlow                140
	#define MotorSpeedRoFast                100
	   
	#define MotorSpeedSlow                  140
	   
	//避障,转弯速度调节
	#define MotorSpeedNormal                140        //正常前进速度
	#define MotorSpeedRotate                240
	#define MotorSpeedFast                  80 
	   
	   
	void motorRun(byte motorNum, bool forward, int speed){		
	        //控制左前轮
	        if(motorNum == 1){
	                if(forward){
	                        analogWrite(MotorIN1,255);
	                        analogWrite(MotorIN2,speed);
	                }else{
	                        analogWrite(MotorIN1,speed);
	                        analogWrite(MotorIN2,255);
	                }
	        }
			//控制右前轮
	        if(motorNum == 2){
	                if(forward){
	                        analogWrite(MotorIN3,speed);
	                        analogWrite(MotorIN4,255);
	                }else{
	                        analogWrite(MotorIN3,255);
	                        analogWrite(MotorIN4,speed);
	                }
	        }
			//控制左后轮
	        if(motorNum == 3){
	                if(forward){
	                        analogWrite(MotorIN5,255);
	                        analogWrite(MotorIN6,speed);
	                }else{
	                        analogWrite(MotorIN5,speed);
	                        analogWrite(MotorIN6,255);
	                }
	        }
			//控制右后轮
	        if(motorNum == 4){
	                if(forward){
	                        analogWrite(MotorIN7,speed);
	                        analogWrite(MotorIN8,255);
	                }else{
	                        analogWrite(MotorIN7,255);
	                        analogWrite(MotorIN8,speed);
	                }
	        }
	}
	   
	void motorStop()
	{
	        analogWrite(MotorIN1,255);
	        analogWrite(MotorIN2,255);
	        analogWrite(MotorIN3,255);
	        analogWrite(MotorIN4,255);
	        analogWrite(MotorIN5,255);
	        analogWrite(MotorIN6,255);
	        analogWrite(MotorIN7,255);
	        analogWrite(MotorIN8,255);
	}
	   
	//小车根据命令运行
	void carGo(byte cmd){
	        switch(cmd){
	                case carForward:
	                motorRun(1,true,MotorSpeedNormal);
	                motorRun(2,true,MotorSpeedNormal);
	                motorRun(3,true,MotorSpeedNormal);
	                motorRun(4,true,MotorSpeedNormal);
	                break;
	                case carBack:
	                motorRun(1,false,MotorSpeedNormal);
	                motorRun(2,false,MotorSpeedNormal);
	                motorRun(3,false,MotorSpeedNormal);
	                motorRun(4,false,MotorSpeedNormal);
	                break;
	                case carLeft:
	                motorRun(1,true,MotorSpeedRotate);
	                motorRun(2,true,MotorSpeedFast);
	                motorRun(3,true,MotorSpeedRotate);
	                motorRun(4,true,MotorSpeedFast);
	                break;
	                case carRight:
	                motorRun(1,true,MotorSpeedFast);
	                motorRun(2,true,MotorSpeedRotate);
	                motorRun(3,true,MotorSpeedFast);
	                motorRun(4,true,MotorSpeedRotate);
	                break;
	                case carStop:
	                motorStop();
	                break;
	                default:
	                motorStop();
	                break;
	        }
	}
	   
	   
	// 复位或上电后运行一次:
	void setup() {
	        //在这里加入初始化相关代码,只运行一次:
	           
	        //串口调试
	        Serial.begin(9600);
	           
	        //设置引脚
	        pinMode(MotorIN1,OUTPUT);
	        pinMode(MotorIN2,OUTPUT);
	        pinMode(MotorIN3,OUTPUT);
	        pinMode(MotorIN4,OUTPUT);
	           
	        pinMode(MotorIN5,OUTPUT);
	        pinMode(MotorIN6,OUTPUT);
	        pinMode(MotorIN7,OUTPUT);
	        pinMode(MotorIN8,OUTPUT);
	        carGo(carStop);
	           
	}
	   
	//一直循环执行:
	void loop() {
	 if(Serial.available()){
	                char cmd = Serial.read();
					 //前进
	                if(cmd == '1'){
	                        carGo(carForward);
	                }//左转
	                else if(cmd == '2'){
	                        carGo(carLeft);
	                }//右转
	                else if(cmd == '3'){
	                        carGo(carRight);
	                }//后退
	                else if(cmd == '4'){
	                        carGo(carBack);
	                }//停车
	                else{
	                        carGo(carStop);
	                }
	        }
	}
													
	

							

将以上代码验证上传至小车,然后我们在串口调试窗口发送不同的命令,看小车是否按照我们预期的动作运转,如果有冲突是很正常的,因为有时候安装电机的方向不一样,这时候我们就可以根据实际情况修改上述代码,使之和我们安装好的小车运行情况一致。

小车车轮电机与扩展板接口的连接如下图所示:

图中的序号是程序中定义的车轮编号

若电机转是反方向转的,可以调换程序中对应车轮的以下部分代码:

哪个车轮方向反了,在程序中调换哪个车轮的。