资讯详情

arduino小车制作心得

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 = "";  //置空数组,进入下一次循环 
	}
 } 

标签: arduino电位器串口监视器电位器turn

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台