Arduino uno循迹小车总结 |
您所在的位置:网站首页 › 循迹小车报告总结 › Arduino uno循迹小车总结 |
1.HW-096 4路循迹模块(红外发射器和红外接收器)
输出信号:TTL电平(可直接连接单片机I/0号,感应到传感器反射回来的红外光时,红指示灯亮,输出低电平;没有红外光时,指示灯不亮,输出高电平。) 2.L298N电机驱动模块双继电器驱动4线2相电机1:驱动步进电机 驱动普通4线2相电机 接法如图所示 使能ENA ENB 之后 从IN1--IN4输入如下驱动时序,即可控制步进电机的转速和方向
3.arduino uno开发板 成品 1.循迹的原理 我们做的四驱小车前轮是不能转向的,那么怎么样才可以左右转呢?其实就是通过左右轮的差速就可以转弯,想要小车左转的话,那么 右轮的速度就要大于左轮的速度,想要小车向左转90°的话,差速就行不通了,这时候怎么办呢?当然也是有解决办法的啦!可以让左轮反转,右轮正转,小车就可以原地大幅度转弯了,反转和正转的数值越大,小车转弯的幅度也就越大。 2.判断情况 循迹模块的主要情况,其中0表示检测到白线,1表示检测到黑线 其中中间两路巡线是一直在黑线上,小车会直行,当任意一个出来,则小车会自动纠正,如果最外面的检测到黑线,则小车以更大速度纠正到正确黑线上面 以上为处理直线、小弯、直角、锐角的传感器状态分析。 3.调速代码Left1_Speed、Left2_Speed控制左轮的速度,Right1_Speed、Right2_Speed控制右轮的速度, 4.循迹代码当里面的两个循迹模块,有一个检测到黑线(0-1-0-0或0-0-1-0),说明小车轻微偏离轨道,这时候我们可以用差速,让小车小转弯,这样小车就摆正回来了 /** * @par Copyright (C): 2010-2019, Shenzhen Yahboom Tech * @file tracking.c * @author Danny * @version V1.0 * @date 2017.07.26 * @brief 巡线实验 * @details * @par History 见如下说明 * */ int Left_motor_go = 8; //左电机前进 AIN1 int Left_motor_back = 7; //左电机后退 AIN2 int Right_motor_go = 2; //右电机前进 BIN1 int Right_motor_back = 4; //右电机后退 BIN2 int Left_motor_pwm = 6; //左电机控速 PWMA int Right_motor_pwm = 5; //右电机控速 PWMB int key = A0; //定义按键为arduino的模拟口A0 //循迹红外引脚定义 //TrackSensorLeftPin1 TrackSensorLeftPin2 TrackSensorRightPin1 TrackSensorRightPin2 // A2 A1 A3 A4 const int TrackSensorLeftPin1 = A2; //定义左边第一个循迹红外传感器引脚为A2 const int TrackSensorLeftPin2 = A1; //定义左边第二个循迹红外传感器引脚为A1 const int TrackSensorRightPin1 = A3; //定义右边第一个循迹红外传感器引脚为A3 const int TrackSensorRightPin2 = A4; //定义右边第二个循迹红外传感器引脚为A4 //定义各个循迹红外引脚采集的数据的变量 int TrackSensorLeftValue1; int TrackSensorLeftValue2; int TrackSensorRightValue1; int TrackSensorRightValue2; /** * Function setup * @author Danny * @date 2017.07.25 * @brief 初始化配置 * @param[in] void * @retval void * @par History 无 */ void setup() { //初始化电机驱动IO口为输出方式 pinMode(Left_motor_go, OUTPUT); pinMode(Left_motor_back, OUTPUT); pinMode(Right_motor_go, OUTPUT); pinMode(Right_motor_back, OUTPUT); //定义按键接口为输入接口 pinMode(key, INPUT); //定义四路循迹红外传感器为输入接口 pinMode(TrackSensorLeftPin1, INPUT); pinMode(TrackSensorLeftPin2, INPUT); pinMode(TrackSensorRightPin1, INPUT); pinMode(TrackSensorRightPin2, INPUT); //按键初始化为高电平 digitalWrite(key, HIGH); //四路循迹红外传感器初始化为高电平 digitalWrite(TrackSensorLeftPin1, HIGH); digitalWrite(TrackSensorLeftPin2, HIGH); digitalWrite(TrackSensorRightPin1, HIGH); digitalWrite(TrackSensorRightPin2, HIGH); //调用按键扫描函数 key_scan(); } /** * Function run * @author Danny * @date 2017.07.26 * @brief 小车前进 * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void run(int left_speed, int right_speed) { //左电机前进 digitalWrite(Left_motor_go, HIGH); //左电机前进使能 digitalWrite(Left_motor_back, LOW); //左电机后退禁止 analogWrite(Left_motor_pwm, left_speed ); //右电机前进 digitalWrite(Right_motor_go, HIGH); //右电机前进使能 digitalWrite(Right_motor_back, LOW); //右电机后退禁止 analogWrite(Right_motor_pwm, right_speed); } /** * Function brake * @author Danny * @date 2017.07.25 * @brief 小车刹车 * @param[in] time:延时时间 * @param[out] void * @retval void * @par History 无 */ void brake(int time) { digitalWrite(Left_motor_go, LOW); digitalWrite(Left_motor_back, LOW); digitalWrite(Right_motor_go, LOW); digitalWrite(Right_motor_back, LOW); delay(time * 100); } /** * Function left * @author Danny * @date 2017.07.25 * @brief 小车左转(左轮不动,右轮前进) * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void left(int left_speed, int right_speed) { //左电机停止 digitalWrite(Left_motor_go, LOW); //左电机前进禁止 digitalWrite(Left_motor_back, LOW); //左电机后退禁止 analogWrite(Left_motor_pwm, left_speed); //右电机前进 digitalWrite(Right_motor_go, HIGH); //右电机前进使能 digitalWrite(Right_motor_back, LOW); //右电机后退禁止 analogWrite(Right_motor_pwm, right_speed); } /** * Function right * @author Danny * @date 2017.07.25 * @brief 小车右转(右轮不动,左轮前进) * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void right(int left_speed, int right_speed) { //左电机前进 digitalWrite(Left_motor_go, HIGH); //左电机前进使能 digitalWrite(Left_motor_back, LOW); //左电机后退禁止 analogWrite(Left_motor_pwm, left_speed); //右电机停止 digitalWrite(Right_motor_go, LOW); //右电机前进禁止 digitalWrite(Right_motor_back, LOW); //右电机后退禁止 analogWrite(Right_motor_pwm, right_speed); } /** * Function spin_left * @author Danny * @date 2017.07.25 * @brief 小车原地左转(左轮后退,右轮前进) * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void spin_left(int left_speed, int right_speed) { //左电机后退 digitalWrite(Left_motor_go, LOW); //左电机前进禁止 digitalWrite(Left_motor_back, HIGH); //左电机后退使能 analogWrite(Left_motor_pwm, left_speed); //右电机前进 digitalWrite(Right_motor_go, HIGH); //右电机前进使能 digitalWrite(Right_motor_back, LOW); //右电机后退禁止 analogWrite(Right_motor_pwm, right_speed); } /** * Function spin_right * @author Danny * @date 2017.07.25 * @brief 小车原地右转(右轮后退,左轮前进) * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void spin_right(int left_speed, int right_speed) { //左电机前进 digitalWrite(Left_motor_go, HIGH); //左电机前进使能 digitalWrite(Left_motor_back, LOW); //左电机后退禁止 analogWrite(Left_motor_pwm, left_speed); //右电机后退 digitalWrite(Right_motor_go, LOW); //右电机前进禁止 digitalWrite(Right_motor_back, HIGH); //右电机后退使能 analogWrite(Right_motor_pwm, right_speed); } /** * Function back * @author Danny * @date 2017.07.25 * @brief 小车后退 * @param[in] time:延时时间 * @param[out] void * @retval void * @par History 无 */ void back(int time) { //左电机后退 digitalWrite(Left_motor_go, LOW); //左电机前进禁止 digitalWrite(Left_motor_back, HIGH); //左电机后退使能 analogWrite(Left_motor_pwm, 40); //右电机后退 digitalWrite(Right_motor_go, LOW); //右电机前进禁止 digitalWrite(Right_motor_back, HIGH); //右电机后退使能 analogWrite(Right_motor_pwm, 40); delay(time ); } /** * Function key_scan * @author Danny * @date 2017.07.25 * @brief 按键检测(包含软件按键去抖) * @param[in] void * @param[out] void * @retval void * @par History 无 */ void key_scan() { while (digitalRead(key)); //当按键没有被按下一直循环 while (!digitalRead(key)) //当按键被按下时 { delay(10); //延时10ms if (digitalRead(key) == LOW)//第二次判断按键是否被按下 { delay(100); while (!digitalRead(key)); //判断按键是否被松开 } } } /** * Function loop * @author Danny * @date 2017.07.25 * @brief 先调用setup初始化配置里面的按键扫描函数, * 循迹模式开启 * @param[in] void * @retval void * @par History 无 */ void loop() { //检测到黑线时循迹模块相应的指示灯亮,端口电平为LOW //未检测到黑线时循迹模块相应的指示灯灭,端口电平为HIGH TrackSensorLeftValue1 = digitalRead(TrackSensorLeftPin1); TrackSensorLeftValue2 = digitalRead(TrackSensorLeftPin2); TrackSensorRightValue1 = digitalRead(TrackSensorRightPin1); TrackSensorRightValue2 = digitalRead(TrackSensorRightPin2); //四路循迹引脚电平状态 // 0 0 X 0 // 1 0 X 0 // 0 1 X 0 //以上6种电平状态时小车原地右转,速度为250,延时80ms //处理右锐角和右直角的转动 if ( (TrackSensorLeftValue1 == LOW || TrackSensorLeftValue2 == LOW) && TrackSensorRightValue2 == LOW) { spin_right(250, 250); delay(80); } //四路循迹引脚电平状态 // 0 X 0 0 // 0 X 0 1 // 0 X 1 0 //处理左锐角和左直角的转动 else if ( TrackSensorLeftValue1 == LOW && (TrackSensorRightValue1 == LOW || TrackSensorRightValue2 == LOW)) { spin_left(250, 250); delay(80); } // 0 X X X //最左边检测到 else if ( TrackSensorLeftValue1 == LOW) { spin_left(150, 150); //delay(2); } // X X X 0 //最右边检测到 else if ( TrackSensorRightValue2 == LOW ) { spin_right(150, 150); //delay(2); } //四路循迹引脚电平状态 // X 0 1 X //处理左小弯 else if ( TrackSensorLeftValue2 == LOW && TrackSensorRightValue1 == HIGH) { left(0, 220); } //四路循迹引脚电平状态 // X 1 0 X //处理右小弯 else if (TrackSensorLeftValue2 == HIGH && TrackSensorRightValue1 == LOW) { right(220, 0); } //四路循迹引脚电平状态 // X 0 0 X //处理直线 else if (TrackSensorLeftValue2 == LOW && TrackSensorRightValue1 == LOW) { run(255, 255); } //当为1 1 1 1时小车保持上一个小车运行状态 } /** * @par Copyright (C): 2010-2019, Shenzhen Yahboom Tech * @file tracking.c * @author Danny * @version V1.0 * @date 2017.07.26 * @brief 巡线实验 * @details * @par History 见如下说明 * */ int Left_motor_go = 8; //左电机前进 AIN1 int Left_motor_back = 7; //左电机后退 AIN2 int Right_motor_go = 2; //右电机前进 BIN1 int Right_motor_back = 4; //右电机后退 BIN2 int Left_motor_pwm = 6; //左电机控速 PWMA int Right_motor_pwm = 5; //右电机控速 PWMB int key = A0; //定义按键为arduino的模拟口A0 //循迹红外引脚定义 //TrackSensorLeftPin1 TrackSensorLeftPin2 TrackSensorRightPin1 TrackSensorRightPin2 // A2 A1 A3 A4 const int TrackSensorLeftPin1 = A2; //定义左边第一个循迹红外传感器引脚为A2 const int TrackSensorLeftPin2 = A1; //定义左边第二个循迹红外传感器引脚为A1 const int TrackSensorRightPin1 = A3; //定义右边第一个循迹红外传感器引脚为A3 const int TrackSensorRightPin2 = A4; //定义右边第二个循迹红外传感器引脚为A4 //定义各个循迹红外引脚采集的数据的变量 int TrackSensorLeftValue1; int TrackSensorLeftValue2; int TrackSensorRightValue1; int TrackSensorRightValue2; /** * Function setup * @author Danny * @date 2017.07.25 * @brief 初始化配置 * @param[in] void * @retval void * @par History 无 */ void setup() { //初始化电机驱动IO口为输出方式 pinMode(Left_motor_go, OUTPUT); pinMode(Left_motor_back, OUTPUT); pinMode(Right_motor_go, OUTPUT); pinMode(Right_motor_back, OUTPUT); //定义按键接口为输入接口 pinMode(key, INPUT); //定义四路循迹红外传感器为输入接口 pinMode(TrackSensorLeftPin1, INPUT); pinMode(TrackSensorLeftPin2, INPUT); pinMode(TrackSensorRightPin1, INPUT); pinMode(TrackSensorRightPin2, INPUT); //按键初始化为高电平 digitalWrite(key, HIGH); //四路循迹红外传感器初始化为高电平 digitalWrite(TrackSensorLeftPin1, HIGH); digitalWrite(TrackSensorLeftPin2, HIGH); digitalWrite(TrackSensorRightPin1, HIGH); digitalWrite(TrackSensorRightPin2, HIGH); //调用按键扫描函数 key_scan(); } /** * Function run * @author Danny * @date 2017.07.26 * @brief 小车前进 * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void run(int left_speed, int right_speed) { //左电机前进 digitalWrite(Left_motor_go, HIGH); //左电机前进使能 digitalWrite(Left_motor_back, LOW); //左电机后退禁止 analogWrite(Left_motor_pwm, left_speed ); //右电机前进 digitalWrite(Right_motor_go, HIGH); //右电机前进使能 digitalWrite(Right_motor_back, LOW); //右电机后退禁止 analogWrite(Right_motor_pwm, right_speed); } /** * Function brake * @author Danny * @date 2017.07.25 * @brief 小车刹车 * @param[in] time:延时时间 * @param[out] void * @retval void * @par History 无 */ void brake(int time) { digitalWrite(Left_motor_go, LOW); digitalWrite(Left_motor_back, LOW); digitalWrite(Right_motor_go, LOW); digitalWrite(Right_motor_back, LOW); delay(time * 100); } /** * Function left * @author Danny * @date 2017.07.25 * @brief 小车左转(左轮不动,右轮前进) * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void left(int left_speed, int right_speed) { //左电机停止 digitalWrite(Left_motor_go, LOW); //左电机前进禁止 digitalWrite(Left_motor_back, LOW); //左电机后退禁止 analogWrite(Left_motor_pwm, left_speed); //右电机前进 digitalWrite(Right_motor_go, HIGH); //右电机前进使能 digitalWrite(Right_motor_back, LOW); //右电机后退禁止 analogWrite(Right_motor_pwm, right_speed); } /** * Function right * @author Danny * @date 2017.07.25 * @brief 小车右转(右轮不动,左轮前进) * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void right(int left_speed, int right_speed) { //左电机前进 digitalWrite(Left_motor_go, HIGH); //左电机前进使能 digitalWrite(Left_motor_back, LOW); //左电机后退禁止 analogWrite(Left_motor_pwm, left_speed); //右电机停止 digitalWrite(Right_motor_go, LOW); //右电机前进禁止 digitalWrite(Right_motor_back, LOW); //右电机后退禁止 analogWrite(Right_motor_pwm, right_speed); } /** * Function spin_left * @author Danny * @date 2017.07.25 * @brief 小车原地左转(左轮后退,右轮前进) * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void spin_left(int left_speed, int right_speed) { //左电机后退 digitalWrite(Left_motor_go, LOW); //左电机前进禁止 digitalWrite(Left_motor_back, HIGH); //左电机后退使能 analogWrite(Left_motor_pwm, left_speed); //右电机前进 digitalWrite(Right_motor_go, HIGH); //右电机前进使能 digitalWrite(Right_motor_back, LOW); //右电机后退禁止 analogWrite(Right_motor_pwm, right_speed); } /** * Function spin_right * @author Danny * @date 2017.07.25 * @brief 小车原地右转(右轮后退,左轮前进) * @param[in1] left_speed:左轮速度 * @param[in2] right_speed:右轮速度 * @param[out] void * @retval void * @par History 无 */ void spin_right(int left_speed, int right_speed) { //左电机前进 digitalWrite(Left_motor_go, HIGH); //左电机前进使能 digitalWrite(Left_motor_back, LOW); //左电机后退禁止 analogWrite(Left_motor_pwm, left_speed); //右电机后退 digitalWrite(Right_motor_go, LOW); //右电机前进禁止 digitalWrite(Right_motor_back, HIGH); //右电机后退使能 analogWrite(Right_motor_pwm, right_speed); } /** * Function back * @author Danny * @date 2017.07.25 * @brief 小车后退 * @param[in] time:延时时间 * @param[out] void * @retval void * @par History 无 */ void back(int time) { //左电机后退 digitalWrite(Left_motor_go, LOW); //左电机前进禁止 digitalWrite(Left_motor_back, HIGH); //左电机后退使能 analogWrite(Left_motor_pwm, 40); //右电机后退 digitalWrite(Right_motor_go, LOW); //右电机前进禁止 digitalWrite(Right_motor_back, HIGH); //右电机后退使能 analogWrite(Right_motor_pwm, 40); delay(time ); } /** * Function key_scan * @author Danny * @date 2017.07.25 * @brief 按键检测(包含软件按键去抖) * @param[in] void * @param[out] void * @retval void * @par History 无 */ void key_scan() { while (digitalRead(key)); //当按键没有被按下一直循环 while (!digitalRead(key)) //当按键被按下时 { delay(10); //延时10ms if (digitalRead(key) == LOW)//第二次判断按键是否被按下 { delay(100); while (!digitalRead(key)); //判断按键是否被松开 } } } /** * Function loop * @author Danny * @date 2017.07.25 * @brief 先调用setup初始化配置里面的按键扫描函数, * 循迹模式开启 * @param[in] void * @retval void * @par History 无 */ void loop() { //检测到黑线时循迹模块相应的指示灯亮,端口电平为LOW //未检测到黑线时循迹模块相应的指示灯灭,端口电平为HIGH TrackSensorLeftValue1 = digitalRead(TrackSensorLeftPin1); TrackSensorLeftValue2 = digitalRead(TrackSensorLeftPin2); TrackSensorRightValue1 = digitalRead(TrackSensorRightPin1); TrackSensorRightValue2 = digitalRead(TrackSensorRightPin2); //四路循迹引脚电平状态 // 0 0 X 0 // 1 0 X 0 // 0 1 X 0 //以上6种电平状态时小车原地右转,速度为250,延时80ms //处理右锐角和右直角的转动 if ( (TrackSensorLeftValue1 == LOW || TrackSensorLeftValue2 == LOW) && TrackSensorRightValue2 == LOW) { spin_right(250, 250); delay(80); } //四路循迹引脚电平状态 // 0 X 0 0 // 0 X 0 1 // 0 X 1 0 //处理左锐角和左直角的转动 else if ( TrackSensorLeftValue1 == LOW && (TrackSensorRightValue1 == LOW || TrackSensorRightValue2 == LOW)) { spin_left(250, 250); delay(80); } // 0 X X X //最左边检测到 else if ( TrackSensorLeftValue1 == LOW) { spin_left(150, 150); //delay(2); } // X X X 0 //最右边检测到 else if ( TrackSensorRightValue2 == LOW ) { spin_right(150, 150); //delay(2); } //四路循迹引脚电平状态 // X 0 1 X //处理左小弯 else if ( TrackSensorLeftValue2 == LOW && TrackSensorRightValue1 == HIGH) { left(0, 220); } //四路循迹引脚电平状态 // X 1 0 X //处理右小弯 else if (TrackSensorLeftValue2 == HIGH && TrackSensorRightValue1 == LOW) { right(220, 0); } //四路循迹引脚电平状态 // X 0 0 X //处理直线 else if (TrackSensorLeftValue2 == LOW && TrackSensorRightValue1 == LOW) { run(255, 255); } //当为1 1 1 1时小车保持上一个小车运行状态 } |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |