Arduino小程序——超声波避障遥控小车

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010815486/article/details/83477031

之前偶然间了解到Arduino,脑子一热果断入手一套简单的小车开发套件,后来由于忙些其他的东西,就把它丢在角落里吃灰了……上个月正好表妹过生日,决定弄一弄也算准备一个诚意满满的小礼物了;这也是第一次接触硬件编程,也算是个小挑战。

由于只是入门级别的套件,像超声波,舵机,直流电机等配件的代码都是现成的,只需要配置开发环境,写自己的小车运行逻辑就行了,忍不住吐槽一下黑心商家的配件,各种问题搞得开发过程中莫名其妙的被坑……

安装好开发软件,把开发板接入电脑就可以写代码了,开发板接入电脑后先看看端口号:

然后开发软件中记得选择对应的端口,不然无法烧录程序。

新建一个项目,发现自动生成2个函数:

void setup()函数是初始化函数,里面的语句只会执行一次,一般用来设置硬件的引脚;void loop()函数是程序运行函数,里面的语句会重复执行(有点类似createjs的Ticker类),下面贴一个简单LED灯闪烁代码。

void setup(){
  pinMode(11, OUTPUT); //将11号引脚上拉输出
}

void loop(){
  digitalWrite(11,HIGH); //设置11号引脚位高电平
  delay(1000);
  digitalWrite(11,LOW); //设置11号引脚为低电平
  delay(1000); // 闪烁时间间隔为1S
}

写完代码需要先编译再烧录到开发板里才能看到效果,有些复杂的配件需要监控返回值,比如超声波要看返回检测到障碍物的距离,红外遥控要看返回按键的键值,这就要用到串口监视器了;写好代码,每次按下红外遥控器,串口监视器会返回键值:

Serial.print(results.value);//返回当前按键值

注意串口监视器下面的波特率要和我们设置的一致。

Serial.begin(9600);

使用自带的开发界面写代码很不习惯,可以在首选项里设置使用外部编辑器,这样软件会把开发页面锁死,只能通过其他编辑器写代码了,这里我用sublime text(语言选择C++代码才会高亮显示)。

下面贴个全部源码,留个备份:

#include <Servo.h>
#include <IRremote.h>

long control;
boolean car_automatic_move = false;
boolean car_trajectory = false;

//红外避障模块
// long SL;
//红外接收模块
int RECV_PIN = 11;//管脚
//舵机
int servopin = 10;

IRrecv irrecv(RECV_PIN);
decode_results results;

long unsigned  int return_decode() {
  if (irrecv.decode(&results)) {
    irrecv.resume();
    Serial.print(results.value);//返回当前按键值
    return results.value;
  }
  else
  {
    return 0;
    irrecv.resume();
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(4, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  pinMode(A0, INPUT);
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  irrecv.enableIRIn();//初始化红外遥控
}

void loop() {
  // SL = digitalRead(A0);//左避障管脚

  // if (car_automatic_move && SL == 0) {//左避障触发
  //   car_forward();
  // }

  control = return_decode();
  if (control == 16712445) {//前进
    car_forward();
    delay(500);
    car_stop();

  } else if (control == 16720605) {//后退
    car_back();
    delay(500);
    car_stop();
  } else if (control == 16769055) {// -
    car_left();
    delay(150);
    car_stop();
  } else if (control == 16754775) {// +
    car_right();
    delay(150);
    car_stop();
  } else if (control == 16761405) {//暂停
    car_stop();
    car_automatic_move = false;
  } else if (control == 16748655) {//EQ
    car_automatic_move = true;
  } else if (control == 16750695) {//100+
  } else if (control == 16756815) {//200+
  } else if (control == 16738455) {//0 原地打转
    car_left();
  } else if (control == 16753245) {//CH-
    servopulse(servopin, 180);
  } else if (control == 16769565) {//CH+
    servopulse(servopin, 0);
  } else if (control == 16736925) {//CH
    servopulse(servopin, 65);
  }
  // car_line();
  car_automatic();
}


void car_forward() {//前进
  analogWrite(3, 0);
  analogWrite(5, 255);
  analogWrite(6, 255);
  analogWrite(9, 0);
}
void car_back() {//后退
  analogWrite(3, 255);
  analogWrite(5, 0);
  analogWrite(6, 0);
  analogWrite(9, 255);
}
void car_stop() {//停车
  analogWrite(3, 0);
  analogWrite(5, 0);
  analogWrite(6, 0);
  analogWrite(9, 0);
}
void car_left() {//左转
  analogWrite(3, 255);
  analogWrite(5, 0);
  analogWrite(6, 255);
  analogWrite(9, 0);
}
void car_right() {//右转
  analogWrite(3, 0);
  analogWrite(5, 255);
  analogWrite(6, 0);
  analogWrite(9, 255);
}
void car_line() {//红外循迹
  if (car_trajectory) {
    if (digitalRead(4)) {//左探头
      Serial.print("left");
    }
    if (digitalRead(2)) {//右探头
      Serial.print("right");
    }
  }
}


long speedF;
long speedL;
long speedR;
// 超声波检测距离
int ardublockUltrasonicSensorCodeAutoGeneratedReturnCM(int trigPin, int echoPin) {
  long duration;
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(20);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  duration = duration / 59;
  return duration;
}
//定义一个脉冲函数
void servopulse(int servopin, int myangle) {
  int  pulsewidth, count;
  for (count = 0; count < 25; count++)
  {
    pulsewidth = (myangle * 11) + 500; //将角度转化为500-2480的脉宽值
    digitalWrite(servopin, HIGH); //将舵机接口电平至高
    delayMicroseconds(pulsewidth);//延时脉宽值的微秒数
    digitalWrite(servopin, LOW); //将舵机接口电平至低
    delay(20 - pulsewidth / 1000);
  }
}
// 测量前方距离
int range_F() {
  speedF = ardublockUltrasonicSensorCodeAutoGeneratedReturnCM(7, 8) ;
  Serial.print("speedF:");
  Serial.println(speedF);
  return speedF;
}

// 自动行驶
void car_automatic() {
  if (car_automatic_move) {
    car_forward();
    if (range_F() <= 18) {
      car_stop();
      car_automatic_move = false;
      delay(300);
      servopulse(servopin, 20);
      if (range_F() > 18) { //检测右方距离
        servopulse(servopin, 65);
        car_right();
        delay(120);
        car_automatic_move = true;
      } else if (range_F() <= 18) { //检测右方距离
        delay(300);
        servopulse(servopin, 110);
        if (range_F() > 18) { //检测左方距离
          servopulse(servopin, 65);
          car_left();
          delay(120);
          car_automatic_move = true;
        } else if (range_F() <= 18) { //检测左方距离
          car_back();
          servopulse(servopin, 65);
          delay(120);
          car_right();
          delay(120);
          car_automatic_move = true;
        }
      }
    }
  }
}

本来要写红外避障模块的,可惜有一个红外避障配件是坏的,而且红外感应器“怕太阳光”,即使没有直接被阳光直射到,白天在室内也可能被太阳热辐射影响到红外信号,避障变成“智障”……一个直流电机也有问题,只有设置电流参数255才会工作,所以无法调整小车的行驶速度,再次吐槽一下黑心商家……

猜你喜欢

转载自blog.csdn.net/u010815486/article/details/83477031