1.pinMode(端口,模式)
:INPUT(输入模式),OUTPUT(输出模式),INPUT_PULLUP(输入上拉模式)
void setup() { // put your setup code here, to run once: pinMode(2,INPUT_PULLUP); pinMode(13,OUTPUT); } void loop() { // put your main code here, to run repeatedly: int val = digitalRead(2); ///读取引脚2的状态,在mega将5拉到板上V(高电平) if(val == HIGH) { digitalWrite(13,LOW); } else //按下开关,和GND相连,变为低电平 { digitalWrite(13,HIGH); } }
2.digital系列
(高电平是1[HIGH],低电平是0[lLOW])
3.analog系列(digitalWrite()和digitalRead()函数已经初始化,不需要set up 初始化)
4.Serial系列
我选择了四轮驱动汽车,因为它是四轮驱动的,所以我使用了两L298N但是只有一个电源,所以我选择并联两个电机,电源电压最低9V(不要问为什么,因为我有血的教训),其他的就是接线。
最终效果图如下:
第一部分:汽车前进、后退、左右转弯
驱动汽车四轮直流电机L298N电机连接,知道哪个接口对应哪个轮子,借助PWM进行调速。
#define FORWARD 0 #define BACKWARD 1 #define LEFT 2 #define RIGHT 3 #define STOP 4 前两个轮子 int rightMotor1 = 36; int rightMotor2 = 34; int leftMotor1 = 30; int leftMotor2 = 32; //后两个轮子 int rightMotor3 = 22; int rightMotor4 = 24; int leftMotor3 = 28; int leftMotor4 = 26; //前两个PWM int leftPWM1 = 10; int rightPWM2 =11 ; //后两个轮子的PWM int leftPWM3 = 8; int rightPWM4 = 9;
注:拔掉时PWM跳帽时,如果不使用,汽车将无法移动(解决方案:1。插入跳帽2。PWM进行调速)
void Control_direction(int dir,int val1,int val2,int val3,int val4) //val4右后轮 val3左后轮 val2右前轮 val1 左前轮 { analogWrite(leftPWM1,val1); //设置PWM,设置速度 analogWrite(rightPWM2,val2); analogWrite(leftPWM3,val3); //设置PWM,设置速度 analogWrite(rightPWM4,val4); switch(dir) { case FORWARD: Serial.println("FORWARD"); digitalWrite(leftMotor1,HIGH); digitalWrite(leftMotor2,LOW); digitalWrite(rightMotor1,HIGH); digitalWrite(rightMotor2,LOW); digitalWrite(leftMotor3,LOW); digitalWrite(leftMotor4,HIGH); digitalWrite(rightMotor3,LOW); digitalWrite(rightMotor4,HIGH); break; case BACKWARD: Serial.println("BACKWARD"); digitalWrite(leftMotor1,LOW); digitalWrite(leftMotor2,HIGH); digitalWrite(rightMotor1,LOW); digitalWrite(rightMotor2,HIGH); digitalWrite(leftMotor3,HIGH); digitalWrite(leftMotor4,LOW); digitalWrite(rightMotor3,HIGH); digitalWrite(rightMotor4,LOW); break; case LEFT: Serial.println("LEFT"); digitalWrite(leftMotor1,HIGH); digitalWrite(leftMotor2,LOW); digitalWrite(rightMotor1,HIGH); digitalWrite(rightMotor2,LOW); digitalWrite(leftMotor3,LOW); digitalWrite(leftMotor4,HIGH); digitalWrite(rightMotor3,LOW); digitalWrite(rightMotor4,HIGH); break; case RIGHT: Serial.println("RIGHT"); digitalWrite(leftMotor1,HIGH); digitalWrite(leftMotor2,LOW); digitalWrite(rightMotor1,HIGH); digitalWrite(rightMotor2,LOW); dgitalWrite(leftMotor3,LOW);
digitalWrite(leftMotor4,HIGH);
digitalWrite(rightMotor3,LOW);
digitalWrite(rightMotor4,HIGH);
break;
}
}
(超声波避障)
原理(使用 Arduino 采用数字引脚给 SR04 的 Trig 引脚至少 10 μ s 的高电平信号,触发 SR04 模块测距功能,触发后,模块会自动发送 8 个 40KHz 的超声波脉冲,并自动检测是否有信号返回。这步会由模块内部自动完成,如有信号返回, Echo 引脚会输出高电平,高电平持续的时间就是超声波从发射到返回的时间。此时,我们能使用 pulseIn() 函数获取到测距的结果,并计算出距被测物的实际距离。因为声速在空气中的速度大约为340m/s,用时间/2再乘以速度,大约就是距离,然后将距离实时的返回给板子。
pulseln()检测高低电平的脉冲宽度。
int getDistance()
{
digitalWrite(outputPin, LOW); // 使发出发出超声波信号接口低电平2μs
delayMicroseconds(2);
digitalWrite(outputPin, HIGH); // 使发出发出超声波信号接口高电平10μs,这里是至少10μs
delayMicroseconds(10);
digitalWrite(outputPin, LOW); // 保持发出超声波信号接口低电平
int distance = pulseIn(inputPin, HIGH); // 读出脉冲时间
distance= distance/58; // 将脉冲时间转化为距离(单位:厘米)
Serial.println(distance); //输出距离值
if (distance >=50)
{
//如果距离小于50厘米返回数据
return 50;
}//如果距离小于50厘米小灯熄灭
else
return distance;
}
除此之外还需要舵机,通过舵机可以将SR04进行一个全方位的转动,从而可以测得各个方向的距离,从而让小车完成最优选择路径。
舵机的使用需要调用库函数#include <Servo.h>,而且需要初始化引脚myServo.attach(引脚)。还需要定义舵机变量
void avoidance()
{
int pos;
int dis[3];//距离
myServo.write(95); //将舵机正对前面
motorRun(FORWARD,60,60,60,60);
dis[1]=getDistance(); //中间
if(dis[1]<30)
{
motorRun(STOP,0,0,0,0);
for (pos = 95; pos <= 150; pos += 1)
{
myServo.write(pos);
delay(20);
}
dis[2]=getDistance(); //左边
for (pos = 150; pos >= 30; pos -= 1)
{
myServo.write(pos);
delay(20);
if(pos==95)
dis[1]=getDistance(); //中间
}
dis[0]=getDistance(); //右边
for (pos = 30; pos <= 95; pos += 1)
{
myServo.write(pos);
delay(20);
}
if(dis[0]<dis[2]) //右边距离障碍的距离比左边近
{
//左转
motorRun(TURNLEFT,0,60,0,60);
delay(1000);
}
else if(dis[0]>dis[2]) //右边距离障碍的距离比左边远
{
//右转
motorRun(TURNRIGHT,60,0,60,0);
delay(1000);
}
}
}
3.循迹部分(借助红外模块检测黑线,若检测到黑线返回1----低电平,否则返回0---高电平)
将每一个信号都存在数组里面
我做的小车只是用了三个红外模块
int date[3];
date[0]=digitalRead(left);
date[1]=digitalRead(mid);
date[2]=digitalRead(right);
if(date[0]==0&&date[1]==1&&date[2]==0)
go(60,60,60,60);
if(date[0]==1&&date[1]==1)
{
left_(0,60,0,60);
delay(50);
}
if(date[1]==0&&date[2]==1)
{
right_(60,0,60,0);
delay(50);
}
if(date[0]==1&&date[1]==1&&date[2]==1)
{
stop_(0,0,0,0);
delay(2000);
}
4.蓝牙部分,我使用的是HC-05蓝牙模块,首先需要明白蓝牙和小车之间借助串口通信的方式进行信息交互,手机和蓝牙模块相连接,就可以控制小车了。
Arduino 5V - VCC Arduino GND - GND Arduino Pin10 - TXD Arduino Pin11 - RXD
第一步:蓝牙模块的AT模式:长按蓝牙模块上的小黑按钮,然后将usb接口插入电脑,此时蓝牙模块会两秒亮灭的形式(进入了AT模式)
#include <SoftwareSerial.h>
// Pin11为RX,接HC05的TXD
// Pin12为TX,接HC05的RXD
SoftwareSerial BT(11,12);
char val;
void setup() {
Serial.begin(38400);
Serial.println("BT is ready!");
// HC-05默认,38400
BT.begin(38400);
}
void loop() {
if (Serial.available()) {
val = Serial.read();
BT.print(val);
}
if (BT.available()) {
val = BT.read();
Serial.print(val);
}
}
借助这个代码则可以在arduino串口监视器进行AT指令的操作,当然你也可以借助Xcom或者sscom进行串口调试。记得将蓝牙模块设为从机
将蓝牙和小车连接好之后,代码的书写很简单(读取串口监视器的数字或者字母,然后将字母的对应功能设计出来就行)
if(Serial.available()>0)
{
char cmd = Serial.read();//读取蓝牙模块发送到串口的数据
switch(cmd)
{
/*相应的功能设计*/
}
}
大概思路模板就是这样(具体控制代码想要的可以私聊哦!!!)
在这里拓展一下,当你需要读入一个字符串的时候,可以定义一个字符串变量,然后将串口Serial.read()存到字符串中,然后每次读取后,将字符串数组置空就行了
string pp = "";
void loop()
{
while(Serial.available()>0)
{
pp += char(Serial.read());
delay(2);
}
target = pp.toInt(); //将(char)数字转化为(int/float/double)数字
if(pp.length>0)
{
pp = ""; //置空数组,进入下一次循环
}
}