1 前言

本人也是零基础进行Arduino学习的初学者,做小车期间遇到过很多困难,在此写下整个小车的制作流程以及遇到的问题与解决方案,希望对后来者有所帮助。在制作期间参考了许多文章得到了大佬的指点,以及下面展示成果如建模等是由朋友做的,在此一并表示感谢。

总结来说,小车基于Arduino UNO单片机,通过并联L298N电机驱动板实现八输出(因为同时控制四个轮的正反转需要八个变量)来控制小车除前后直线移动,左拐右拐之外,还可以顺时针逆时针原地自旋以及向左向右横向平移。并加载Arduino扩展板实现循迹、寻光、避障、蓝牙遥控和无源蜂鸣器报警功能。

2 总体结构概括

2.1 机械结构

首先整体结构为双层亚克力板,如图其下层承载四个TT电机、三个循迹模块传感器以及两个红外避障传感器和18650电池组,上层承载Arduino开发板与拓展板、两个L298N电机驱动板、蜂鸣器、蓝牙模块和两个循光传感器。两层亚克力板间采用铜柱与螺栓联接。

车体亚克力板部分以及循迹、寻光、红外避障传感器、蓝牙模块、tt电机都是由淘宝买的套件小车的产品,不需要自己配置散件。可以购买时仔细阅读套件清单或者直接向商家问个清楚,商家都很有耐心的。(依次为红外避障、寻光、循迹传感器)

麦克纳姆轮是需要单独购买的,小车套件里面的是四个普通的轮子。电池也是单独购买的两节18650可充电锂电池,电机驱动板是两个L298N,此外还单独购买了一个无源蜂鸣器。这些单独购买的也可以很容易在淘宝上找到,但是有一些购买细节,这些在下文会单独说明。

2.2 电路连接

需要说明的是,虽然Arduino需要5V的供电电压,但是并不需要再额外配置一个5V电压源,因为两节18650接入电机驱动板供电后,电机驱动板可以有一路降压输出5V给Arduino板子。

对于蓝牙模块接线,除了蓝牙模块的+-与Arduino板子的+-对应以外。蓝牙模块上标注RX的接口需要连接板子TX的接口,同样蓝牙TX要对应板子RX(rx是接收receive,tx是发送transport)。同样容易出错的是上传程序时需要把蓝牙模块卸下,因为其占用着Arduino板子的RX与TX,程序报错无法上传。

对于不同的套件、接入不同的传感器有不同的接线图,认清是A口还是D口,哪里是VCC哪里是GND,灵活变通即可。接线图如图所示。

3 具体细节说明

3.1 电机驱动板

电机驱动板是在Arduino主板和tt电机之间的角色,以实现对TT电机的控制。虽然只需要一个L293D就可以实现八输出,但是需要插到Arduino主板上进行供电,就因此无法再安装扩展板,也就没法安装众多的传感器(其实是可以的,但我不会,对不起)。

每个L298N有四个输入接口:IN1、IN2、IN3、IN4,用四根线和Arduino的四个Digital接口连接,以实现主板对电机驱动板的控制。每个L298N同时有四个输出接口OUT1、OUT2、OUT3、OUT4(与四个输入接口是一一对应的),因此用四根线可以分别连接两个电机的正负极,这样两个电机驱动板可以实现四个电机的正反转控制。由于电机安装方向和接线方向的影响,直接判断哪个接口可以使轮子正转也可以,单建议安装完电机后通过程序试一试来确定IN1、IN2、IN3、IN4四个接口中哪个接口输入高电平可以使轮子正转。

然后是电机驱动板之间的并联,就是电源的正极和两个电机驱动板的正极连接,从电机驱动板的5V引出一路给Arduino主板供电,电源负极和两个电机驱动板还有主板的负极连接在一起,如上图左侧电路示意图。并联的原因就是为了可以少用一个电源,减少麻烦,所以若是不想并联各自给电机驱动板配置一个电源也无所谓,记得两个电机驱动板和Arduino主板的GNG要接在一起就可以了。

3.2 麦克纳姆轮

对于四轮小车来说,一套麦克纳姆轮至少应含有两种不同的轮子。我们选择两种就好—两个左轮两个右轮(注意这个左右不是位于左边的轮子和位于右边的轮子的意思,是轮子的构造方向不一样)。左轮右边轮构型如图所示,所以购买的时候一定要和商家说清楚。

具体麦克纳姆轮如何实现平移以及自旋,还有轮子的安装顺序都可以看这篇文章,在此对作者表达感谢(不知道这样引用对不对)。然后控制程序可以见下文,我的控制程序更零基础(小白)一些。

https://blog.csdn.net/handsome_Ares/article/details/120140997?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167679074216782429723326%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167679074216782429723326&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-120140997-null-null.142^v73^insert_down2,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=%E9%BA%A6%E5%85%8B%E7%BA%B3%E5%A7%86%E8%BD%AE&spm=1018.2226.3001.4187https://blog.csdn.net/handsome_Ares/article/details/120140997?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167679074216782429723326%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167679074216782429723326&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-120140997-null-null.142^v73^insert_down2,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=%E9%BA%A6%E5%85%8B%E7%BA%B3%E5%A7%86%E8%BD%AE&spm=1018.2226.3001.4187

3.3 无源蜂鸣器

有源无源可能不是没有了解过的人想像的那个意思, “源” 不是指电源,而是指振荡源。简而言之无源蜂鸣器可以自己编写一些勉强分得清在唱什么的曲调,有源的就不可以。

需要注意的是想要实现蜂鸣器唱歌需要在程序中加入头文件 pitches.h,该文件包含典型音符的所有音高值。加入头文件的方法十分容易,若是不会可以百度一下。记得把头文件和Arduino程序文件放在同一个文件夹里就好。

如果有兴趣可以看下面这篇文章。(谢谢作者!)

https://luhuadong.blog.csdn.net/article/details/103395351?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-103395351-blog-128067566.pc_relevant_recovery_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-103395351-blog-128067566.pc_relevant_recovery_v2&utm_relevant_index=5https://luhuadong.blog.csdn.net/article/details/103395351?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-103395351-blog-128067566.pc_relevant_recovery_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-103395351-blog-128067566.pc_relevant_recovery_v2&utm_relevant_index=5

3.4 电源

电源是受挫最多的地方,起初图方便用六节南孚电池作为电源,结果程序在电脑上调试时好好的,一断开USB线用电源供电就执行的晕头转向,十分玄学。后来由大佬的指点发现是因为南孚电池电流太大导致Arduino主板一直不定时重启。

所以后来更换了更为稳定的两节18650可充电锂电池,一共7.4V,问题得以解决(要是实在解决不了可以先把所有程序都调好了后上传试试,说不定就可以了呢)。

3.5 其他

还有就是不可忽略的小车的传感器的调试环节,上传代码成功后小车依旧无法巡线无法避障,这时候可能不是代码的问题,可能是传感器输入调试没做好。网上或者淘宝商家也有一些传感器的调试方法可以借鉴,最重要的就是亲自一点点扭转传感器上的电位器一遍遍试,找到最合适的电位器位置以及最合适的传感器安装位置。(比如三个巡线传感器就可以适当离的宽一些)

最后小车还有一个非常玄学的地方,就是右侧后轮经常莫名其妙地没有指令就转起来了。即使重新接线也不行,令人困惑。没有找到根源,但是基于经验是只要按压小车前端就可以让他停止这种现象,所以用轧带将前端进行固定。

4 结果展示

4.1 建模

有点地方不太对,不过无伤大雅,加了一个车壳和保险杠,不过没加工出来。

4.2 巡线

GIF太大无法上传,想看看巡线、蓝牙遥控的视频可以去主页,写的时候还在审核不知道能不能过。至于避障、寻光也没必要上传了。

4.5 蓝牙遥控

蓝牙遥控的app是一个朋友做的,不方便共享,不过这玩意可以在应用市场下载,就是有些广告。下面是操作命令表,也可以到程序里自己差(避障模式2的指令是p,忘记写上了):

5 代码说明

俯看小车,车头在上将四个轮子分别编号为左1左2右1右2(程序中轮子的对应名称,这个需要根据前文所说的哪个接口接入高电平是正转自己更改程序,很简单小学二年级就学过)。

这是无源蜂鸣器播放《致爱丽丝》的功能,需要的pitches.h头文件。头文件下面是各个功能合并后的代码,可以用蓝牙来进行功能模式的切换。由于用的都是些学c语言第一课就能学完的基础语句,具体原理看代码就能很容易看懂,就无需多言了。

//pitches.h 音高定义//pitches.h 定义了不同音符对应的不同频率#define NOTE_B0 31 //B0 ····7#define NOTE_C1 33 //C1 ···1#define NOTE_CS1 35 //C1##define NOTE_D1 37 //D1 ···2#define NOTE_DS1 39 //D1##define NOTE_E1 41 //E1 ···3#define NOTE_F1 44 //F1 ···4#define NOTE_FS1 46 //F1##define NOTE_G1 49 //G1 ···5#define NOTE_GS1 52 //G1##define NOTE_A1 55 //A1 ···6#define NOTE_AS1 58 //A1##define NOTE_B1 62 //B1 ···7#define NOTE_C2 65 //C2 ··1#define NOTE_CS2 69 //C2##define NOTE_D2 73 //D2 ··2#define NOTE_DS2 78 //D2##define NOTE_E2 82 //E2 ··3#define NOTE_F2 87 //F2 ··4#define NOTE_FS2 93 //F2##define NOTE_G2 98 //G2 ··5#define NOTE_GS2 104 //G2##define NOTE_A2 110 //A2 ··6#define NOTE_AS2 117 //A2##define NOTE_B2 123 //B2 ··7#define NOTE_C3 131 //C3 ·1#define NOTE_CS3 139 //C3##define NOTE_D3 147 //D3 ·2#define NOTE_DS3 156 //D3##define NOTE_E3 165 //E3 ·3#define NOTE_F3 175 //F3 ·4#define NOTE_FS3 185 //F3##define NOTE_G3 196 //G3 ·5#define NOTE_GS3 208 //G3##define NOTE_A3 220 //A3 ·6#define NOTE_AS3 233 //A3##define NOTE_B3 247 //B3 ·7#define NOTE_C4 262 //C4 1(中央C大调)#define NOTE_CS4 277 //C4##define NOTE_D4 294 //D4 2#define NOTE_DS4 311 //D4##define NOTE_E4 330 //E4 3#define NOTE_F4 349 //F4 4#define NOTE_FS4 370 //F4##define NOTE_G4 392 //G4 5#define NOTE_GS4 415 //G4##define NOTE_A4 440 //A4 6#define NOTE_AS4 466 //A4##define NOTE_B4 494 //B4 7#define NOTE_C5 523 //C5 1·#define NOTE_CS5 554 //C5##define NOTE_D5 587 //D5 2·#define NOTE_DS5 622 //D5##define NOTE_E5 659 //E5 3·#define NOTE_F5 698 //F5 4·#define NOTE_FS5 740 //F5##define NOTE_G5 784 //G5 5·#define NOTE_GS5 831 //G5##define NOTE_A5 880 //A5 6·#define NOTE_AS5 932 //A5##define NOTE_B5 988 //B5 7·#define NOTE_C6 1047 //C6 1··#define NOTE_CS6 1109 //C6##define NOTE_D6 1175 //D6 2··#define NOTE_DS6 1245 //D6##define NOTE_E6 1319 //E6 3··#define NOTE_F6 1397 //F6 4··#define NOTE_FS6 1480 //F6##define NOTE_G6 1568 //G6 5··#define NOTE_GS6 1661 //G6##define NOTE_A6 1760 //A6 6··#define NOTE_AS6 1865 //A6##define NOTE_B6 1976 //B6 7··#define NOTE_C7 2093 //C7 1···#define NOTE_CS7 2217 //C7##define NOTE_D7 2349 //D7 2···#define NOTE_DS7 2489 //D7##define NOTE_E7 2637 //E7 3···#define NOTE_F7 2794 //F7 4···#define NOTE_FS7 2960 //F7##define NOTE_G7 3136 //G7 5···#define NOTE_GS7 3322 //G7##define NOTE_A7 3520 //A7 6···#define NOTE_AS7 3729 //A7##define NOTE_B7 3951 //B7 7···#define NOTE_C8 4186 //C8 1····#define NOTE_CS8 4435 //C8##define NOTE_D8 4699 //D8 2····#define NOTE_DS8 4978 //D8#
//(寻线 红外避障 蓝牙遥控 寻光)多功能程序
//***********************定义电机腳位*************************
#include "pitches.h"
int MotorLeft1R = 2;
int MotorLeft1B = 3;
int MotorLeft2R = 5;
int MotorLeft2B = 4;
int MotorRight1R = 10;
int MotorRight1B = 9;
int MotorRight2R = 6;
int MotorRight2B = 7;// 记录曲子的音符
int melody[] = { 0, 0, NOTE_E5, NOTE_D5, NOTE_E5, NOTE_D5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_A4, 0, NOTE_C4, NOTE_E4, NOTE_A4, NOTE_B4, 0, NOTE_E4, NOTE_G4, NOTE_B4, NOTE_C5, 0, NOTE_E4, NOTE_E5, NOTE_D5, NOTE_E5, NOTE_D5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5,NOTE_A4, 0, NOTE_C4, NOTE_E4, NOTE_A4, NOTE_B4, 0, NOTE_E4, NOTE_C5, NOTE_B4,NOTE_A4};
// 音符持续时间:4为四分音符,8为八分音符
int noteDurations[] = { 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8,4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4};int counter = 0;
char val;
//*************************定义寻线模块脚位************************************
const int SensorLeft = 8;      //左传感器
const int SensorMiddle = 11;   //中传感器
const int SensorRight = 12;     //右传感器
int SL;    //左传感器状态
int SM;    //中传感器状态
int SR;    //右传感器状态const int barrier_left = A5; //左红外避障
const int barrier_right = A4; //右红外避障const int followLight_left = A3; //左寻光
const int followLight_right = A2; //右寻光//********************************************************************(SETUP)
void setup()
{Serial.begin(9600);pinMode(MotorLeft1R,OUTPUT);pinMode(MotorLeft1B,OUTPUT);pinMode(MotorLeft2R,OUTPUT);pinMode(MotorLeft2B,OUTPUT);pinMode(MotorRight1R,OUTPUT);pinMode(MotorRight1B,OUTPUT);pinMode(MotorRight2R,OUTPUT);pinMode(MotorRight2B,OUTPUT);pinMode(SensorLeft, INPUT); //pinMode(SensorMiddle, INPUT);//pinMode(SensorRight, INPUT); //pinMode(barrier_left, INPUT);pinMode(barrier_right, INPUT);pinMode(followLight_left, INPUT);pinMode(followLight_right, INPUT);Serial.println("-----------------");
}
//******************************************************************(Void)
void advance(int a) // 前进
{Serial.println("advance");//直走 1的R为前,2的B为前digitalWrite(MotorLeft1R, HIGH);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, HIGH);digitalWrite(MotorRight1R, HIGH);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, HIGH);delay(a * 100);
}
void right(int b) //右转
{Serial.println("right");//右转(普通)digitalWrite(MotorLeft1R, HIGH);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, HIGH);digitalWrite(MotorRight1R, LOW);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, LOW);delay(b * 100);
}
void left(int c) //左转
{Serial.println("left");//左转(普通)digitalWrite(MotorLeft1R, LOW);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, LOW);digitalWrite(MotorRight1R, HIGH);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, HIGH);delay(c * 100);
}
void turnR(int d) //右转 双轮
{Serial.println("turnR");//右转自旋(快速)digitalWrite(MotorLeft1R, HIGH);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, HIGH);digitalWrite(MotorRight1R, LOW);digitalWrite(MotorRight1B, HIGH);digitalWrite(MotorRight2R, HIGH);digitalWrite(MotorRight2B, LOW);delay(d * 100);
}
void turnL(int e) //左转 双轮
{Serial.println("turnL");//左转(快速)digitalWrite(MotorLeft1R, LOW);digitalWrite(MotorLeft1B, HIGH);digitalWrite(MotorLeft2R, HIGH);digitalWrite(MotorLeft2B, LOW);digitalWrite(MotorRight1R, HIGH);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, HIGH);delay(e * 100);
}
void stopp(int f) //停止
{Serial.println("stopp");//停止digitalWrite(MotorLeft1R, LOW);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, LOW);digitalWrite(MotorRight1R, LOW);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, LOW);delay(f * 100);
}
void back(int g) //后退
{Serial.println("back");digitalWrite(MotorLeft1R, LOW);digitalWrite(MotorLeft1B, HIGH);digitalWrite(MotorLeft2R, HIGH);digitalWrite(MotorLeft2B, LOW);digitalWrite(MotorRight1R, LOW);digitalWrite(MotorRight1B, HIGH);digitalWrite(MotorRight2R, HIGH);digitalWrite(MotorRight2B, LOW);delay(g * 100);
}
void toR(int v) //右平移
{Serial.println("toR");digitalWrite(MotorLeft1R, HIGH);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, HIGH);digitalWrite(MotorLeft2B, LOW);digitalWrite(MotorRight1R, LOW);digitalWrite(MotorRight1B, HIGH);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, HIGH);delay(v * 100);
}
void toL(int x) //左平移
{Serial.println("toL");digitalWrite(MotorLeft1R, LOW);digitalWrite(MotorLeft1B, HIGH);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, HIGH);digitalWrite(MotorRight1R, HIGH);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, HIGH);digitalWrite(MotorRight2B, LOW);delay(x * 100);
}
//******************************************************************************(LOOP)
void loop()
{SL = digitalRead(SensorLeft);SM = digitalRead(SensorMiddle);SR = digitalRead(SensorRight);performCommand();
}void performCommand()
{if (Serial.available()) {val = Serial.read();}
//**********************红外避障模式if (val == 'q') //红外壁障{while (1){val = Serial.read();if ((digitalRead(barrier_left)==LOW) && (digitalRead(barrier_right)==LOW)){back(3);//后退}else if (digitalRead(barrier_left)==LOW){turnR(3); // 右转;}else if (digitalRead(barrier_right)==LOW){turnL(3); // 左转;}else{advance(3);//前进}if (val == 'a'){digitalWrite(MotorLeft1R, LOW);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, LOW);digitalWrite(MotorRight1R, LOW);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, LOW);break;} }}
//**********************红外避障模式2if (val == 'p') //红外壁障{while (1){val = Serial.read();if ((digitalRead(barrier_left)==LOW) && (digitalRead(barrier_right)==LOW)){stopp(3);//停止for(int thisNote = 0; thisNote < sizeof(melody)/sizeof(melody[0]); thisNote++) {// 需要根据音符类型换算音符的持续时间int noteDuration = 1000/noteDurations[thisNote];tone(A1, melody[thisNote], noteDuration);// 为了能辨别出不同的音调,需要在两个音调间设置一定的延时,增加30%比较合适int pauseBetweenNotes = noteDuration * 1.30;delay(pauseBetweenNotes);noTone(A1);}}else if (digitalRead(barrier_left)==LOW){turnR(3); // 右转;}else if (digitalRead(barrier_right)==LOW){turnL(3); // 左转;}else{advance(3);//前进}if (val == 'a'){digitalWrite(MotorLeft1R, LOW);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, LOW);digitalWrite(MotorRight1R, LOW);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, LOW);break;} }}
//**********************寻光模式if (val == 't') {while (1){val = Serial.read();if ((digitalRead(followLight_left)==LOW) && (digitalRead(followLight_right)==LOW)){advance(3);//前进}else if (digitalRead(followLight_left)==LOW){turnL(3); // 左转;}else if (digitalRead(followLight_right)==LOW){turnR(3); // 右转;}else{stopp(3);}if (val == 'a'){digitalWrite(MotorLeft1R, LOW);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, LOW);digitalWrite(MotorRight1R, LOW);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, LOW);break;} }}//**********************寻线模式if (val == 'd') {while (1){val = Serial.read();{SL = digitalRead(SensorLeft);SM = digitalRead(SensorMiddle);SR = digitalRead(SensorRight);Serial.print(SL);Serial.print("-");Serial.print(SM);Serial.print("-");Serial.println(SR);if (SM == HIGH)//中间传感器检测到黑线  黑线为1 白为0{if (SL == LOW & SR ==  HIGH) //左白右黑, 向右转弯{Serial.println("BL");right(1); // 右转;}else if ( SL ==  HIGH & SR == LOW) // 左黑右白, 向左转弯{Serial.println("BR");left(1); // 左转;}else  // 两侧为白色,前进{Serial.println("Bw");advance(1); //前进;}}else // 中间传感器在白色区域{if (SL == LOW & SR == HIGH ) // 左白右黑, 快速右转{Serial.println("WL");turnR(1);}else if ( SL == HIGH & SR == LOW ) // 左黑右白, 快速左转{Serial.println("WR");turnL(1);}else // 都是白色, 保护不变{Serial.println("ww");}}  }if (val == 'a'){digitalWrite(MotorLeft1R, LOW);digitalWrite(MotorLeft1B, LOW);digitalWrite(MotorLeft2R, LOW);digitalWrite(MotorLeft2B, LOW);digitalWrite(MotorRight1R, LOW);digitalWrite(MotorRight1B, LOW);digitalWrite(MotorRight2R, LOW);digitalWrite(MotorRight2B, LOW);break;} }}
//**********************无源蜂鸣器if (val == 'i') //致爱丽丝{while (1){val = Serial.read();// 遍历整个曲子的音符for(int thisNote = 0; thisNote < sizeof(melody)/sizeof(melody[0]); thisNote++) {// 需要根据音符类型换算音符的持续时间int noteDuration = 1000/noteDurations[thisNote];tone(A1, melody[thisNote], noteDuration);// 为了能辨别出不同的音调,需要在两个音调间设置一定的延时,增加30%比较合适int pauseBetweenNotes = noteDuration * 1.30;delay(pauseBetweenNotes);noTone(A1);}if (val == 'a'){break;} }}//蓝牙控制**********************正常遥控模式if (val == 'f') { // Forwardadvance(10);} else if (val == 'b') { // Backwardback(10);} else if (val == 'r') { // Rightright(10);} else if (val == 'l') { // Leftleft(10);} else if (val == 's') { // Stopstopp(10) ;}else if (val == 'y') { // RightturnR(10);} else if (val == 'z') { // LeftturnL(10);} else if (val == 'v') { // toR(10) ;}else if (val == 'x') { // toL(10) ;}
}

基于Arduino通过并联L298N实现四驱麦克纳姆轮巡迹小车相关推荐

  1. 四驱麦克纳姆轮运行原理

    在知乎上有一个短片显示了安装有四驱麦克纳姆(Mecanum)轮的小型车模在桌面 运行情况.清晰揭示了车模四个独立驱动的Mecanum轮的安装结构与各种模式的运行原理.帮助快速建立起Mecanum轮车模 ...

  2. 麦克纳姆轮小车matlab仿真,学习使用Python控制麦克纳姆轮底盘

    学习使用Python控制麦克纳姆轮底盘 这里小龟给大家分享如何使用Python控制麦克纳姆轮底盘的小龟小车. 首先小伙伴得参考小龟提供的改造手册进行先把小龟小车改造成麦克纳姆轮底盘,假如小伙伴在改造过 ...

  3. 关于麦克纳姆轮的速度分解,以及多方向控制

    参考文章: [1]李彦文,楼佩煌,楼航飞,翟晶晶.协同搬运系统中的麦克纳姆轮AGV运动控制研究[J].机械制造与自动化,2021,50(06):224-227.DOI:10.19344/j.cnki. ...

  4. 基于arduino及PS2的麦克纳姆轮遥控小车

    实物展示 1.选材用料 2.设计原理 2.代码展示 #include <PS2X_lib.h> #include<AFMotor.h> #define PS2_DAT 13 / ...

  5. arduino 4WD 麦克纳姆轮小车支持Mixly/Scratch

    加粗样式 完整资料教程下载链接: 前往界面 1.简介: 提及编程,很多人都会觉得是一件令人非常头疼的事情. 然而,基于arduino的麦克纳姆轮小车套件可以让您发现编程不再那么难.这款可编程套件,提高 ...

  6. python firmata协议利用arduino操控麦克纳姆轮小车(附完整代码)

    python firmata协议利用arduino操控麦克纳姆轮小车 前言 一.python中pyfirmata的环境 材料 二.使用步骤 1.小车的安装方式 我在这采用的是X型安装方式 总结 前言 ...

  7. 【Arduino】麦克纳姆轮原理及驱动程序

    文章目录 Arduino 麦克纳姆轮 麦克纳姆轮全向移动原理[已整理] 麦轮测试程序 Arduino UNO+L298N 带红外控制程序 Arduino UNO+L298N+红外 其他链接: [UGV ...

  8. 基于 RT-Thread的麦克纳姆轮小车循迹运动控制算法开发和研究

    学校:浙江工业大学 队伍名称:浙工大鸿泉全向 SOLO 队参赛队员:杨一帆.袁启恒.何志涛 带队教师:陈国定.褚衍清 简 介: 本文详细介绍了全向行进组智能车的制作方案.该方案以南京沁恒公司的 CH3 ...

  9. 使用STM32F103C8T6控制L298N电机驱动麦克纳姆轮小车(HAL库)

    文章目录 一.L298N驱动介绍 二.麦克纳姆轮特点及其运动 三.CubeMx配置 1.RCC 2.SYS 3.GPIO 四.代码 一.L298N驱动介绍 驱动部分介绍选https://blog.cs ...

最新文章

  1. 跌宕中,特斯拉拿下上海工厂,给蔚来们留下不到两年窗口期
  2. 辽宁大连花灯闹新春 逾万民众赏灯迎新年
  3. Linux中的各种软件安装
  4. (转)谷歌公开dopamine
  5. Truffle 4.0、Geth 1.7.2、TestRPC在私有链上搭建智能合约
  6. 【C++】C++自学旅程(5):指针和引用
  7. kindEditor富文本编辑器的工具栏设置
  8. linux代码实现进程监控,linux进程监控shell脚本代码
  9. javascript基础知识-数组
  10. Caffe学习:使用pycaffe读取mean.binaryproto文件参数
  11. 结对编程项目总结(王开207, 唐彬170)
  12. 计算机libeay32.dll丢失怎么办,电脑libeay32.dll丢失的解决方法
  13. 使用 Python 开发 QGIS 插件
  14. 触摸屏查询软件1.8.4下载
  15. 风控模型——评分卡模型
  16. 基于selenium的大麦网自动抢票脚本实测(新年第一篇)
  17. 十大关系数据库SQL注入工具一览
  18. 缓存 redis 缓存失效 分布式锁 Redisson SpringCache
  19. 2个步骤,让人才成为组织进化的发动机
  20. 清华大学计算机系2016名单,清华大学2016年自主招生北京考生入选名单汇总

热门文章

  1. 西门子系列全套学习视频,免费领取!
  2. SpringBoot开发实用
  3. unity | 竖排显示文字text
  4. HashMap的工作原理(一):Hash算法
  5. 电商-商品搜索列表设计思路
  6. 向控件拖放数据,不积硅步无以至千里
  7. 汐月教育之理解TensorFlow(四)词向量
  8. 一文了解常用思维导图与画图软件
  9. python爬虫--小猪短租的租房信息
  10. ?php get_sidebar(); ?,wordpress函数get_sidebar()用法示例