教程一:简单介绍和电机驱动
//电机驱动01 /* 11 10 | | |M| |M| | | 6 5 */ void setup() { pinMode(11, OUTPUT); pinMode(6, OUTPUT); pinMode(10, OUTPUT); pinMode(5, OUTPUT); } void loop() { // 左前进 // 6↑ → 11↓ digitalWrite(6,HIGH); digitalWrite(11,LOW); //延时1秒 delay(1000); // 左后退 // 11↑ → 6↓ digitalWrite(6,LOW); digitalWrite(11,HIGH); //延时1秒 delay(1000); // 左停止 // 6↓ = 11↓ digitalWrite(6,LOW); digitalWrite(11,LOW); delay(1000); //右前进 // 5↑ → 10↓ digitalWrite(5,HIGH); digitalWrite(10,LOW); //延时1秒 delay(1000); //右后退 // 10↑ → 5↓ digitalWrite(5,LOW); digitalWrite(10,HIGH); //延时1秒 delay(1000); //右停止 // 5↓ = 10↓ digitalWrite(5,LOW); digitalWrite(10,LOW); //延时1秒 delay(1000); } |
//电机驱动02 /* 11 10 | | |M| |M| | | 6 5 */ void setup() { pinMode(11, OUTPUT); pinMode(6, OUTPUT); pinMode(10, OUTPUT); pinMode(5, OUTPUT); } void loop() { //左前进 6↑ → 11↓ digitalWrite(6,HIGH); digitalWrite(11,LOW); //右前进 5↑ → 10↓ digitalWrite(5,HIGH); digitalWrite(10,LOW); delay(1000); //左停止 digitalWrite(6,LOW); digitalWrite(11,LOW); //右停止 digitalWrite(5,LOW); digitalWrite(10,LOW); delay(1000); //左后退 11↑ → 6↓ digitalWrite(6,LOW); digitalWrite(11,HIGH); //右后退 10↑ → 5↓ digitalWrite(5,LOW); digitalWrite(10,HIGH); delay(1000); //左停止 digitalWrite(6,LOW); digitalWrite(11,LOW); //右停止 digitalWrite(5,LOW); digitalWrite(10,LOW); delay(1000); //左转(左后退,右前进) digitalWrite(6,LOW); digitalWrite(11,HIGH); digitalWrite(5,HIGH); digitalWrite(10,LOW); delay(1000); //左停止 digitalWrite(6,LOW); digitalWrite(11,LOW); //右停止 digitalWrite(5,LOW); digitalWrite(10,LOW); delay(1000); //右转(左前进,右后退) digitalWrite(6,HIGH); digitalWrite(11,LOW); digitalWrite(5,LOW); digitalWrite(10,HIGH); delay(1000); //左停止 digitalWrite(6,LOW); digitalWrite(11,LOW); //右停止 digitalWrite(5,LOW); digitalWrite(10,LOW); delay(1000); } |
//电机驱动03 int speed = 100; void setup() { pinMode(11, OUTPUT); pinMode(6, OUTPUT); pinMode(10, OUTPUT); pinMode(5, OUTPUT); Serial.begin(9600); } void loop() { Serial.println("Forward"); //左前进 6↑ → 11↓ analogWrite(6,speed); digitalWrite(11,LOW); //右前进 5↑ → 10↓ analogWrite(5,speed); digitalWrite(10,LOW); delay(1000); blinkgogoStop(); Serial.println("Backward"); //左后退 11↑ → 6↓ digitalWrite(6,LOW); analogWrite(11,speed); //右后退 10↑ → 5↓ digitalWrite(5,LOW); analogWrite(10,speed); delay(1000); blinkgogoStop(); //左转(左后退,右前进) digitalWrite(6,LOW); analogWrite(11,speed); analogWrite(5,speed); digitalWrite(10,LOW); delay(1000); blinkgogoStop(); //右转(左前进,右后退) analogWrite(6,speed); digitalWrite(11,LOW); digitalWrite(5,LOW); analogWrite(10,speed); delay(1000); blinkgogoStop(); delay(1000); } void blinkgogoStop() { //左停止 digitalWrite(6,LOW); digitalWrite(11,LOW); //右停止 digitalWrite(5,LOW); digitalWrite(10,LOW); } |
教程二:runBlinkgogo封装和走回形
//runBlinkgogo封装 测试 long speed; /* 11 10 | | |M| |M| | | 6 5 */ void runBlinkgogo(long leftSpeed, long rightSpeed) { if (leftSpeed >= 0) { //6→11 analogWrite(6,leftSpeed); digitalWrite(11,LOW); } else { //11→6 analogWrite(11,0-leftSpeed); digitalWrite(6,LOW); } if (rightSpeed >= 0) { //5→10 analogWrite(5,rightSpeed); digitalWrite(10,LOW); } else { //10→5 analogWrite(10,0-rightSpeed); digitalWrite(5,LOW); } } void setup() { speed = 200; pinMode(11, OUTPUT); pinMode(6, OUTPUT); pinMode(10, OUTPUT); pinMode(5, OUTPUT); } void loop() { //前进 runBlinkgogo(speed, speed); delay(1000); //后退 runBlinkgogo(0 - speed, 0 - speed); delay(1000); //左转 runBlinkgogo(0 - speed, speed); delay(1000); //右转 runBlinkgogo(speed, 0 - speed); delay(1000); //停止 runBlinkgogo(0, 0); delay(1000); } |
// long speed; /* 11 10 | | |M| |M| | | 6 5 */ void runBlinkgogo(long leftSpeed, long rightSpeed) { if (leftSpeed >= 0) { //6→11 analogWrite(6,leftSpeed); digitalWrite(11,LOW); } else { //11→6 analogWrite(11,0-leftSpeed); digitalWrite(6,LOW); } if (rightSpeed >= 0) { //5→10 analogWrite(5,rightSpeed); digitalWrite(10,LOW); } else { //10→5 analogWrite(10,0-rightSpeed); digitalWrite(5,LOW); } } void setup() { speed = 200; pinMode(11, OUTPUT); pinMode(6, OUTPUT); pinMode(10, OUTPUT); pinMode(5, OUTPUT); } void loop() { //前进 runBlinkgogo(speed, speed); delay(1000); //停止 runBlinkgogo(0, 0); delay(300); //右转 runBlinkgogo(40, 0 - 40); delay(500); //停止 runBlinkgogo(0, 0); delay(300); } |
// long leftSpeed; long rightSpeed; /* 11 10 | | |M| |M| | | 6 5 */ void runBlinkgogo(long leftSpeed, long rightSpeed) { if (leftSpeed >= 0) { //6→11 analogWrite(6, leftSpeed); digitalWrite(11, LOW); } else { //11→6 analogWrite(11, 0 - leftSpeed); digitalWrite(6, LOW); } if (rightSpeed >= 0) { //5→10 analogWrite(5, rightSpeed); digitalWrite(10, LOW); } else { //10→5 analogWrite(10, 0 - rightSpeed); digitalWrite(5, LOW); } } void setup() { pinMode(11, OUTPUT); pinMode(6, OUTPUT); pinMode(10, OUTPUT); pinMode(5, OUTPUT); Serial.begin(9600); } void loop() { // 顺时针转圈 runBlinkgogo(255, 80); delay(8000); // 逆时针转圈 runBlinkgogo(80, 255); delay(8000); // 操场式转圈 runBlinkgogo(255, 100); delay(3600); runBlinkgogo(255, 255); delay(1000); // 8字型回环 runBlinkgogo(255, 80); delay(4000); runBlinkgogo(255, 255); delay(1000); runBlinkgogo(80, 255); delay(4000); runBlinkgogo(255, 255); delay(1000); //蛇形前进(曲率变化) for (int speedOffset = -100; speedOffset < 100; speedOffset += 5) { leftSpeed = 125 + speedOffset; rightSpeed = 125 - speedOffset; Serial.print(leftSpeed); Serial.print("\t"); Serial.println(rightSpeed); runBlinkgogo(leftSpeed, rightSpeed); delay(25); } delay(500); for (int speedOffset = 100; speedOffset > -100; speedOffset -= 5) { leftSpeed = 125 + speedOffset; rightSpeed = 125 - speedOffset; Serial.print(leftSpeed); Serial.print("\t"); Serial.println(rightSpeed); runBlinkgogo(leftSpeed, rightSpeed); delay(25); } delay(500); } |
教程三:探测黑线传感器使用和blink测试
//chapter 03 line_follow01 long runSpeed; //电机基本速度 long sensorValueAll; //存储左右巡线传感器L2、L3的检测值 byte lastDirection; //存储上一次转向 void setup() { runSpeed = 80; //电机基本速度 sensorValueAll = 0; //存储左右巡线传感器L2、L3的检测值 lastDirection = 0; //存储上一次转向 pinMode(2, INPUT); //左巡线传感器L2 pinMode(3, INPUT); //右巡线传感器L3 pinMode(11, OUTPUT); //左马达 Motor B2 pinMode(6, OUTPUT); //左马达 Motor B1 pinMode(10, OUTPUT); //右马达 Motor A2 pinMode(5, OUTPUT); //右马达 Motor A1 } void loop() { //将L2与L3生成一个两位十进制数,存于sensorValueAll用于后续判断偏离方向分类 sensorValueAll = 10 * digitalRead(2) + digitalRead(3); //用switch语句来选择分支机构,共4种情况 switch (sensorValueAll) { case 0: //00,左右巡线传感器L2、L3都检测到黑线 runBlinkgogo(runSpeed, runSpeed); //继续左右同速直线前行 break; case 1: //01,左巡线传感器L2检测到黑线,右巡线传感器L3检测到离开黑线 runBlinkgogo(runSpeed, 100); //Motor B < Motor A,左转 lastDirection = 0; //存储本次转向,零为右转 break; case 10: //10,左巡线传感器L2检测到离开黑线,右巡线传感器L3检测到黑线 runBlinkgogo(100, runSpeed); //Motor B > Motor A,右转 lastDirection = 1; //存储本次转向,零为左转 break; case 11: //11,左右巡线传感器L2、L3都检测到离开黑线 if (lastDirection) //依照上次转向,单轮速度为零,加大转向速度 { runBlinkgogo(runSpeed, 0); //依照上次转向,右电机不动,左电机前进,右轮为中心右转 } else { runBlinkgogo(0, runSpeed); //依照上次转向,左电机不动,右电机前进,左轮为中心左转 } break; default: //其它情况 runBlinkgogo(0, 0); //停机 break; } } //传入左右电机运动参数,参数有效范围-256至于+255, //但近0附近数值因摩擦阻力等存在死区,约-40至+40,导致电机无法转动 void runBlinkgogo(long leftSpeed, long rightSpeed) { if (leftSpeed >= 0) { //6→11 analogWrite(6, leftSpeed); digitalWrite(11, LOW); } else { //11→6 analogWrite(11, 0 - leftSpeed); digitalWrite(6, LOW); } if (rightSpeed >= 0) { //5→10 analogWrite(5, rightSpeed); digitalWrite(10, LOW); } else { //10→5 analogWrite(10, 0 - rightSpeed); digitalWrite(5, LOW); } } |
//chapter 03 line_follow02 long speedBase = 100; //电机基本速度 long speedOffset = 40; //电机偏置速度 long speedLeft = 100; //左电机速度参数传入值 long speedRight = 100; //右电机速度参数传入值 boolean lastDirectionLeft = true; //上一次偏转方向是否为的右布尔值 void setup() { pinMode(13, OUTPUT); pinMode(2, INPUT); pinMode(3, INPUT); } void loop() { //根据左右巡线传感器L2、L3是否压线亮灯 detectBlink(); if(onLine(2)&&onLine(3)) //左右巡线传感器L2、L3都检测到黑线 { runBlinkgogo(speedBase,speedBase); //继续左右同速直线前行 } if(!onLine(2)&&!onLine(3)) //左右巡线传感器L2、L3都检测到离开黑线 { if (lastDirectionLeft) runBlinkgogo(0, speedRight+speedOffset); //Motor B < Motor A,左转 else runBlinkgogo(speedLeft+speedOffset, 0); //Motor B > Motor A,右转 } if(onLine(2)&&!onLine(3)) //左巡线传感器L2检测到黑线,右巡线传感器L3检测到离开黑线 { runBlinkgogo(speedLeft-speedOffset, speedRight+speedOffset); lastDirectionLeft = true; //存储本次转向,零为右转 } if(!onLine(2)&&onLine(3)) //左巡线传感器L2检测到离开黑线,右巡线传感器L3检测到黑线 { runBlinkgogo(speedLeft+speedOffset, speedRight-speedOffset); lastDirectionLeft = false; //存储本次转向,零为左转 } } //检测Ln是否压黑线 boolean onLine(int Ln) { return !digitalRead(Ln); } //检测到左右巡线传感器L2、L3都压黑线则关LED灯 //其中一个离开则亮全车LED灯提醒 void detectBlink() { if(onLine(2) && onLine(3)) digitalWrite(13,LOW); else digitalWrite(13,HIGH); } //传入左右电机运动参数,参数有效范围-256至于+255, //但近0附近数值因摩擦阻力等存在死区,约-40至+40,导致电机无法转动 void runBlinkgogo(long leftSpeed, long rightSpeed) { if (leftSpeed >= 0) { //6→11 analogWrite(6,leftSpeed); digitalWrite(11,LOW); } else { //11→6 analogWrite(11,0-leftSpeed); digitalWrite(6,LOW); } if (rightSpeed >= 0) { //5→10 analogWrite(5,rightSpeed); digitalWrite(10,LOW); } else { //10→5 analogWrite(10,0-rightSpeed); digitalWrite(5,LOW); } } |
//chapter 03 line_follow03 #define L1 4 //左上角巡线传感器L1 #define L2 2 //左巡线传感器L2 #define L3 3 //右巡线传感器L3 #define L4 7 //右上角巡线传感器L4 long noLineTimes = 0; //存储所有巡线传感器没检测到黑线的次数 long speedBase = 100; //电机基本速度 long speedLeft; //左电机速度参数传入值 long speedRight; //右电机速度参数传入值 long speedOffset = 40; //电机偏置速度 boolean lastDirectionLeft;//上一次偏转方向是否为右的布尔值 void setup() { Serial.begin(9600); pinMode(13, OUTPUT); //全车LED pinMode(L1, INPUT); //左上角巡线传感器L1 pinMode(L2, INPUT); //左巡线传感器L2 pinMode(L3, INPUT); //右巡线传感器L3 pinMode(L4, INPUT); //右上角巡线传感器L4 speedLeft = speedBase; //左电机速度参数传入值 speedRight = speedBase; //右电机速度参数传入值 } void loop() { detectBlink(); //根据左右巡线传感器L2、L3是否压线亮灯 //全部巡线传感器检测或检测不到黑线 if ((onLine(L1) && onLine(L2) && onLine(L3) && onLine(L4)) == true || (onLine(L1) || onLine(L2) || onLine(L3) || onLine(L4)) == false) { noLineTimes ++; //存储所有巡线传感器没检测到黑线的次数加一 Serial.print("noLineTimes++"); Serial.println(noLineTimes); } else { //L1压黑线 if (onLine(L1))//L1 is connect to PIN D4 { //只有L1压黑线 if (!onLine(L2) && !onLine(L3) && !onLine(L4)) { speedLeft = -speedOffset; speedRight = speedOffset; lastDirectionLeft = true; } } //L4黑线 else if (onLine(L4))//L4 is connect to PIN D7 { //只有L4压黑线 if (!onLine(L1) && !onLine(L2) && !onLine(L3)) { speedLeft = speedOffset; speedRight = -speedOffset; lastDirectionLeft = false; } } else { //左右巡线传感器L2、L3都检测到黑线 if (onLine(L2) && onLine(L3)) { speedLeft = speedBase; speedRight = speedBase; } //L2压黑线、L3不压黑线 if (onLine(L2) && !onLine(L3)) { speedLeft = speedBase; speedRight = speedBase + speedOffset; lastDirectionLeft = true; } //L2不压黑线、L3压黑线 if (!onLine(L2) && onLine(L3)) { speedLeft = speedBase + speedOffset; speedRight = speedBase; lastDirectionLeft = false; } //L2与L3都不压黑线 if (!onLine(L2) && !onLine(L3)) { //上一次转向为左 if (lastDirectionLeft) { speedLeft = 0; speedRight = speedBase + speedOffset; } //上一次转向为右 else { speedLeft = speedBase + speedOffset; speedRight = 0; } } } noLineTimes = 0; } //存储所有巡线传感器没检测到黑线的次数,是否传入电机参数运行 if (noLineTimes < 50) { runBlinkgogo(speedLeft, speedRight); } else { runBlinkgogo(0, 0); } } //检测Ln是否压黑线 boolean onLine(int Ln) { return !digitalRead(Ln); } void detectBlink() { if (onLine(2) && onLine(3)) digitalWrite(13, LOW); else digitalWrite(13, HIGH); } //传入左右电机运动参数,参数有效范围-256至于+255, //但近0附近数值因摩擦阻力等存在死区,约-40至+40,导致电机无法转动 void runBlinkgogo(long leftSpeed, long rightSpeed) { if (leftSpeed >= 0) { //6→11 analogWrite(6, leftSpeed); digitalWrite(11, LOW); } else { //11→6 analogWrite(11, 0 - leftSpeed); digitalWrite(6, LOW); } if (rightSpeed >= 0) { //5→10 analogWrite(5, rightSpeed); digitalWrite(10, LOW); } else { //10→5 analogWrite(10, 0 - rightSpeed); digitalWrite(5, LOW); } } |
教程四:简单巡线和速度尝试
教程五:playMusic和速度参数调试lineFollower
教程六:寻光测试 lightFollower
教程七:走迷宫 goMaze
教程八:红外遥控控制原理和尝试测试
教程九:较大规模的程序功能划分与红外控制
教程十:集成手机应用程序的控制小车appControlBlinkgogo