1.首先介绍两个基本函数
void setup() { // put your setup code here, to run once: 把你的设置代码放在这里,运行一次 } void loop() { // put your main code here, to run repeatedly: 把你的主代码放在这里,重复运行 }
2.L298N控制逻辑
根据我们的接线:
左电机由引脚2,3控制,右电机由4,5控制。正反转导致前进后退需要根据输出端子那边的电机接线实际验证 测试。
接线说明:
左电机安装朝向是接杜邦线的那侧朝外(朝轮子) 左轮上,接左端子的OUT2口, 左轮下,接左端子的OUT1口, IN1由2控制,IN2为3控制 右电机安装朝向是接杜邦线的那侧朝内(背对轮子) 右轮上,接右端子的OUT3口, 右轮下,接右端子的OUT4口, IN3由4控制,IN4为5控制
3.让小车实现前后左右轮子动代码示例:
void setup() { // put your setup code here, to run once: //左轮信号方向初始化 pinMode(2,OUTPUT);// 配置2口为输出引脚 pinMode(3,OUTPUT);// 配置3口为输出引脚 //右轮信号方向初始化 pinMode(4,OUTPUT);// 配置4口为输出引脚 pinMode(5,OUTPUT);// 配置5口为输出引脚 } void loop() { // put your main code here, to run repeatedly: //小车前进 digitalWrite(2,LOW); digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(5,LOW); delay(1000); //小车后退 digitalWrite(2,HIGH); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,HIGH); delay(1000); //小车左转,右轮前,左轮后 digitalWrite(2,HIGH); digitalWrite(3,LOW); digitalWrite(4,HIGH); digitalWrite(5,LOW); delay(1000); //小车右转,左轮前,右轮后 digitalWrite(2,LOW); digitalWrite(3,HIGH); digitalWrite(4,LOW); digitalWrite(5,HIGH); delay(1000); }
可以用函数封装,代码示例:
void qianJin() { // 小车前进的功能 digitalWrite(2,LOW); digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(5,LOW); } void houTui() {//函数的封装 // 小车后退的功能 digitalWrite(2,HIGH); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,HIGH); } void zuoZhuan(){ digitalWrite(2,HIGH); digitalWrite(3,LOW); digitalWrite(4,HIGH); digitalWrite(5,LOW); } void youZhuan(){ digitalWrite(2,LOW); digitalWrite(3,HIGH); digitalWrite(4,LOW); digitalWrite(5,HIGH); } void carInit() { // put your setup code here, to run once: pinMode(2,OUTPUT);// 配置2口为输出引脚 pinMode(3,OUTPUT);// 配置3口为输出引脚 //右轮信号方向初始化 pinMode(4,OUTPUT);// 配置4口为输出引脚 pinMode(5,OUTPUT);// 配置5口为输出引脚 } void setup() { carInit(); } void loop() { qianJin();//函数的调用 delay(1000); houTui(); delay(1000); zuoZhuan(); delay(1000); youZhuan(); delay(1000); }
4.串口介绍
我们把程序通过电脑下载到WemosD1上的时候,就是通过串口通信
在程序中,我们也可以通过函数调用实现串口通信
串口的初始化函数:
描述:开启串口,通常置于setup()函数中。 Serial.begin(speed)
参数: speed:波特率,一般取值9600,115200等。
ArduinoUno通过串口发送一个消息给电脑
Serial.print(“test message,这里是消息,喜欢发什么消息,就写什么消息”)
Serial.println(“test message,这里是消息,喜欢发什么消息,就写什么消息”), 比上面多了ln,代表换行
代码示例:
void setup() { // put your setup code here, to run once: Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly: Serial.print("zglnb"); Serial.println("zglnb"); }
打开测试
5.跟随小车开发
主要用到超声波模块,型号:HC-SR04
原理图:
超声波代码通过串口测验:
void setup() { // put your setup code here, to run once: // Trig 接 9,通过9发送一个触发信号给超声波 pinMode(9,OUTPUT); // Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间 pinMode(8,INPUT); Serial.begin(9600); } void loop() { long shijian; long juli; // put your main code here, to run repeatedly: // 发送一个10us的信号给超声波,9Trig digitalWrite(9, LOW); delayMicroseconds(2); digitalWrite(9, HIGH); delayMicroseconds(10); digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波 // 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒 shijian = pulseIn(8,HIGH); // 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm juli = shijian * 0.017; Serial.print(juli); Serial.println("cm"); } //封装测距代码 //函数:名 参数 返回值 long getDis() { // 测距函数 long shijian; long juli; // put your main code here, to run repeatedly: // 发送一个10us的信号给超声波,9Trig digitalWrite(9, LOW); delayMicroseconds(2); digitalWrite(9, HIGH); delayMicroseconds(10); digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波 // 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒 shijian = pulseIn(8,HIGH); // 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm juli = shijian * 0.017; return juli; } void setup() { // put your setup code here, to run once: // put your setup code here, to run once: // Trig 接 9,通过9发送一个触发信号给超声波 pinMode(9,OUTPUT); // Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间 pinMode(8,INPUT); Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: long juli; juli = getDis(); Serial.print(juli); Serial.println("cm"); }
跟随小车代码:
//前进 void qianJin() { // 小车前进的功能 digitalWrite(2,LOW); digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(5,LOW); } //后退 void houTui() {//函数的封装 // 小车后退的功能 digitalWrite(2,HIGH); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,HIGH); } //ting void ting() {//函数的封装 // 小车后退的功能 digitalWrite(2,LOW); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,LOW); } //测距 //函数:名 参数 返回值 long getDis() { // 测距函数 long shijian; long juli; // put your main code here, to run repeatedly: // 发送一个10us的信号给超声波,9Trig digitalWrite(9, LOW); delayMicroseconds(2); digitalWrite(9, HIGH); delayMicroseconds(10); digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波 // 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒 shijian = pulseIn(8,HIGH); // 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm juli = shijian * 0.017; return juli; } void carInit() { // put your setup code here, to run once: pinMode(2,OUTPUT);// 配置2口为输出引脚 pinMode(3,OUTPUT);// 配置3口为输出引脚 //右轮信号方向初始化 pinMode(4,OUTPUT);// 配置4口为输出引脚 pinMode(5,OUTPUT);// 配置5口为输出引脚 } void setup() { // put your setup code here, to run once: carInit(); // Trig 接 9,通过9发送一个触发信号给超声波 pinMode(9,OUTPUT); // Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间 pinMode(8,INPUT); } void loop() { // put your main code here, to run repeatedly: delay(50);//为了放缓超声波交互的速度,交互过快,得出距离后会卡顿,影响效果体验 long juli; juli = getDis(); //如果距离大于3且小于13,后退 if( 3 < juli && juli < 15){ houTui(); } //如果距离大于14且小于40,前进 if( 14 < juli && juli < 40){ qianJin(); } if(juli > 50){ ting(); } }
6.摇头避障小车开发
需要舵机模块
如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制用处:垃圾桶项目开盖 用、智能小车的全比例转向、摄像头云台、机械臂等 常见的有0-90°、0-180°、0-360°
Arduino官方提供Servo类来支持舵机操作
//舵机的初始化 Servo myServo; //定义一个Servo变量 myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10 myServo.write(0);//转到某角度,根据实际执行观看 myServo.write(90);//转到某角度,根据实际执行观看
摇头避障小车代码:
#include <Servo.h> Servo myServo;//因为很多子函数要用这个变量,所以把servo定义成全局变量,作用域是整个代码文件 void ting() { // 小车前进的功能 digitalWrite(2, LOW); digitalWrite(3, LOW); digitalWrite(4, LOW); digitalWrite(5, LOW); } void qianJin() { // 小车前进的功能 digitalWrite(2, LOW); digitalWrite(3, HIGH); digitalWrite(4, HIGH); digitalWrite(5, LOW); } void houTui() {//函数的封装 // 小车后退的功能 digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, LOW); digitalWrite(5, HIGH); } void zuoZhuan() { digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, HIGH); digitalWrite(5, LOW); } void youZhuan() { digitalWrite(2, LOW); digitalWrite(3, HIGH); digitalWrite(4, LOW); digitalWrite(5, HIGH); } void carInit() { // put your setup code here, to run once: pinMode(2, OUTPUT); // 配置2口为输出引脚 pinMode(3, OUTPUT); // 配置3口为输出引脚 //右轮信号方向初始化 pinMode(4, OUTPUT); // 配置4口为输出引脚 pinMode(5, OUTPUT); // 配置5口为输出引脚 } long getDis() { // 测距函数 long shijian; long juli; // put your main code here, to run repeatedly: // 发送一个10us的信号给超声波,9Trig digitalWrite(9, LOW); delayMicroseconds(2); digitalWrite(9, HIGH); delayMicroseconds(10); digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波 // 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒 shijian = pulseIn(8, HIGH); // 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm juli = shijian * 0.017; return juli; } void setup() { // put your setup code here, to run once: //定义一个Servo变量 carInit(); myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10 // Trig 接 9,通过9发送一个触发信号给超声波 pinMode(9, OUTPUT); // Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间 pinMode(8, INPUT); Serial.begin(9600); } void loop() { long youjuli; long zhongjuli; long zuojuli; //如果前面没有障碍物,我让小车往前走 myServo.write(100);//中间方向 delay(500); zhongjuli = getDis(); Serial.print("中间距离是:"); Serial.println(zhongjuli); if (zhongjuli < 35) { ting();//检测到前方右障碍物 //往右边摇头,并测距 myServo.write(30);//右方向 delay(500); youjuli = getDis(); Serial.print("右边距离是:"); Serial.println(youjuli); myServo.write(100);//测完右边距离,再回到中间,此时可以不测距 delay(500); //往左边摇头,测左边距离 myServo.write(170);//左边方向 delay(500); zuojuli = getDis(); Serial.print("左边距离是:"); Serial.println(zuojuli); myServo.write(100);//测完右边距离,再回到中间,此时可以不测距 delay(500); if(zuojuli > youjuli){ Serial.println("左转"); zuoZhuan(); delay(100); ting(); } if(zuojuli < youjuli){ Serial.println("右转"); youZhuan(); delay(100); ting(); } } else { //前方无障碍物,小车前进 qianJin(); } }
7.实物展示