基于Arduino UNO可蓝牙操控、避障、循迹、鸣笛的四驱智能小车

        采用 Arduino Uno单片机作为主控单元,采用四轮式移动平台,四轮均可驱动,可以通过蓝牙控制小车前进、后退、原地转向等操作,可调节车速,可鸣笛警报,可自动识别并躲避障碍物,可遵循特定轨道自动行驶,且以上功能均可通过蓝牙进行控制的智能小车。

先前准备:

总体方案(硬件框图):

PCB板制作:

                设计软件:Altium Designer 8.3

                制作 :嘉立创公司(非广告,仅代表本人选择)

Arduino开发环境:Arduino 1.8.9

所需硬件:(本人于淘宝信泰微电子购买)

                Arduino UNO(主控单片机):

                4轮小车底座带马达(需要自行焊线):

                L239D(电机驱动芯片):

                两节18650电池:

                K78L05(稳压器):

【注:若使用LM7805需要配合三节18650电池,本人并未做尝试, 可以参考文章:https://www.arduino.cn/forum.php?mod=viewthread&tid=93639&highlight=%E5%B0%8F%E8%BD%A6

                HC-05(蓝牙模组):

                HC-SR04(超声波模组):

                9g舵机(舵机,用以配合超声波模块在前方转动,做范围测量):

                无源蜂鸣器:

                TCRT5000(红外光电传感器):

 

PCB制作:

PCB规格:10cm*10cm

元器件名称

库文件夹

所属的元器件库

L7805CV

Library

ST Power Mgt Voltage Regulator.IntLib

SW-SPST

Library

Miscellaneous Devices.IntLib

Res3

Library

Miscellaneous Devices.IntLib

Cap

Library

Miscellaneous Devices.IntLib

Cap Pol1

Library

Miscellaneous Devices.IntLib

Header 2

Library

Miscellaneous Connectors.IntLib

Header 3

Library

Miscellaneous Connectors.IntLib

Header 4

Library

Miscellaneous Connectors.IntLib

L293D

Library

ST Interface DC & Stepper Motor Controller.IntLib

PCB原理图:

PCB电路图:

 PCB实物图:

软件部分:

软件框图:

主体代码:

#include "MOTOR.h"                     //自定义电机驱动库
#include "pitch.h"
#include <SoftwareSerial.h>            //蓝牙库

MotorControl motorR(1);   //右侧电机
MotorControl motorL(2);   //左侧电机
led LED(12);
buzzeron BUZZER(9);


int motorspeed; //小车速度变量
int trac1 = 14; //从车头方向的最左边开始排序接红外寻迹模块
int trac2 = 15;
int trac3 = 16;
int trac4 = 17;
int trac5 = 18;
int val1;         //寻迹模块储存值
int val2;
int val3;
int val4;
int val5;
int servopin = 10;    //定义舵机接口数字接口10

int bl;             //定义运行指针
int bll;
unsigned int L; //左距离存储
unsigned int R; //右距离存储
unsigned int S; //中距离存储

int trig=2; //发射信号
int echo=13; //接收信号



void setup() {  
  Serial.begin(9600);
  LED.ledset();  
  pinMode(trac1, INPUT);  //寻迹模块引脚初始化
  pinMode(trac2, INPUT);
  pinMode(trac3, INPUT);
  pinMode(trac4, INPUT);
  pinMode(trac5, INPUT);
  pinMode(trig,OUTPUT); //超声波设置引脚模式
  pinMode(echo,INPUT);
  motorspeed=200; 
  pinMode(servopin,OUTPUT);//设定舵机v接口为输出接口
  zw();//定义舵机中位
  delay(500); //开机延时
  bl=1;//定义运行指针值
  bll=1;//定义运行指针记忆值
}

void loop() {  

if(Serial.available()>0){   // 蓝牙串口有数据              
              chuspeed();  // 给小车速度赋值
              lytest();    // 运行蓝牙解码判断         
              }   

if(bl==2){      
                 
                chuspeed(); // 给小车速度赋值
                xunji();// 运行寻迹
                BUZZER.tone1();

                }   

if(bl==3){                  
                  chuspeed();// 给小车速度赋值
                  motorun();  // 小车前进不停
                  delay(1000);

                  }
if(bl==4){       
                          
                 chuspeed();// 给小车速度赋值
                  bz();  // 小车避障
                  }

if(bl==5){                    
                  motostop();
                  BUZZER.tone3();
                  if(bll==2){bl=2;}// 喇叭响完以后继续之前程序指针
                  else if(bll==3){bl=3;}
                  else if(bll==4){bl=4;}
                  else {
                        bll=1;
                        bl=1;}
                  }  



else{ motostop();}  
}


/******************************************
                    电机  
******************************************/
void chuspeed(void){                  // 定义小车初始速度
motorR.motorsetSpeed(motorspeed);   
motorL.motorsetSpeed(motorspeed);
}
void motostop(void){                  // 定义小车停止 
              chuspeed();  
              motorR.motorrun(GORELEASE);
              motorL.motorrun(GORELEASE);
}
void motorun(void){                  // 定义小车前进
              chuspeed();  
              motorR.motorrun(GOFORWARD);
              motorL.motorrun(GOFORWARD);
}
void motodown(void){                  // 定义小车后退
              BUZZER.tone2();
              chuspeed();   
              motorR.motorrun(GOBACKWARD);
              motorL.motorrun(GOBACKWARD);
}
void motoleft(void){                  // 定义小车原地左拐
              chuspeed();   
              motorR.motorrun(GOFORWARD);
              motorL.motorrun(GOBACKWARD);
}

void motoright(void){                 // 定义小车原地右拐
               chuspeed();   
              motorR.motorrun(GOBACKWARD);
              motorL.motorrun(GOFORWARD);
}
void motorle(void){                  // 定义小车左拐
              chuspeed(); 
              motorR.motorrun(GOFORWARD);
              motorL.motorrun(GORELEASE);
}
void motorri(void){                  // 定义小车右拐
             chuspeed(); 
              motorR.motorrun(GORELEASE);
              motorL.motorrun(GOFORWARD);
}

/******************************************
                 蓝牙
******************************************/
void lytest(){// 定义蓝牙串口解码判断
         int cmd = Serial.read();//读取蓝牙模块发送到串口的数据
         LED.ledon();
         BUZZER.tone1();         
          if(cmd==49){   // 手机蓝牙输出1,对应ascii数是49
           Serial.println("Go forward"); //输出状态
              motostop();  
              delay(100);
              motorun();
              delay(200);
                     }

          if(cmd==50){  // 手机蓝牙输出2,对应ascii数是50,后面以此类推即加48
          Serial.println("Go back"); //输出状态
              motostop();              
              delay(100);
              motodown();
              delay(200);
                       }

               if(cmd==51){   
                 Serial.println("I say Ting Ting--"); //输出状态
              motostop();
              bl=1;
              bll=1;            
              delay(100);              
                         }

                if(cmd==52){   
              Serial.println("Turn left"); //输出状态
              motostop();               
              delay(100);
              motoleft();
              delay(200);            
                       }
                  if(cmd==53){   
              Serial.println("Turn Right"); //输出状态
              motostop();            
              delay(100);
              motoright();
              delay(200);            
                  }
                 if(cmd==54){
                 Serial.println("Speed up");
                 motorspeed+=5;
                 if(motorspeed>255){motorspeed=255; } //不超过255最高值
                 Serial.print("speed=");
                 Serial.println(motorspeed);
                         }
                   if(cmd==55){
                 Serial.println("Speed down");
              motorspeed-=5;
               if(motorspeed<80){motorspeed=80;}//不低于0
              Serial.print("speed=");
              Serial.println(motorspeed);
                               }

                   if(cmd==56){ //指针寻迹
                   bl=2;
                   bll=2;
                   Serial.println("Follow your heart---"); 
                   delay(50);}                       


                  if(cmd==57){  //指针一直进      
                  bl=3;
                  bll=3;
                  Serial.println("Go Forward---");
                  delay(50);
                  }

                  if(cmd==99){  //速度最小      
                  Serial.println("Lowest Speed");
              motorspeed =100;
              
              Serial.print("speed=");
              Serial.println(motorspeed);
                  }

                   if(cmd==100){  //速度最大      
                  Serial.println("Highest Speed");
              motorspeed =255;
              
              Serial.print("speed=");
              Serial.println(motorspeed);
                  }                    


                 if(cmd==97){//按健a,对应ASCII码是97 指针避障
                 bl=4;
                 bll=4;
                 Serial.println("Avoid---");
                 delay(50);}            


                 if(cmd==98){ //按健b,对应ASCII码是98  指针喇叭
                      bl=5;

                    Serial.println("DiDiDi---"); }
}

/******************************************
                 红外线循迹
******************************************/
void xunji(){         //寻迹主函数
motostop();
delay(300);
       
val1 = digitalRead(trac1);
val2 = digitalRead(trac2); //寻迹模块返回值
val3 = digitalRead(trac3);
val4 = digitalRead(trac4);
val5 = digitalRead(trac5);

val1=!val1;
val2=!val2;
val3=!val3;
val4=!val4;
val5=!val5;

Serial.print(val1);
Serial.print(val2);
Serial.print(val3);
Serial.print(val4);
Serial.println(val5);

if(val1==1 && val2==1 && val3==0  && val4==1 && val5==1  )  //11011中间黑线,即0为黑线
{
motostop();
Serial.println("Go forward");
motorun();
delay(100);
}

else if(val1==1 && val2==0 && val3==0  && val4==0 && val5==1  )  //10001中间三黑线,十字路
{
  motostop();
Serial.println("Go forward");
motorun();
delay(100);
}

else if(val1==0 && val2==0 && val3==0  && val4==0 && val5==0  )  //00000都检测到黑线
{
Serial.println("I say Ting Ting--");
motostop();
delay(500);
}

else if(val1==1 && val2==1 && val3==1  && val4==1 && val5==1  )  //11111都无检测到黑线
{
Serial.println("go...?");
motostop();
motorun();
delay(100);
}



else if(val1==1 && val2==0 && val3==0  && val4==1 && val5==1  )  //10011
{  
motostop();
delay(200);
Serial.println("Turn left");
motoleft();
delay(100);
}

else if(val1==0 && val2==1 && val3==0  && val4==1 && val5==1  )  //01011
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}

else if(val1==1 && val2==0 && val3==1  && val4==1 && val5==1  )  //10111
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}


else if(val1==0 && val2==0 && val3==1  && val4==1 && val5==1  )  //00111
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}


else if(val1==0 && val2==0 && val3==0  && val4==1 && val5==1  )  //00011
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}


else if(val1==0 && val2==1 && val3==1  && val4==1 && val5==1  )  //01111
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}

else if(val1==1 && val2==1 && val3==0  && val4==0 && val5==1  )  //11001
{
motostop();
delay(20);
Serial.println("Turn right");
motoright();
delay(100);
}

else if(val1==1 && val2==1 && val3==0  && val4==1 && val5==0  )  //11010
{
motostop();
delay(20);
Serial.println("Turn right");
motoright();
delay(100);
}

else if(val1==1 && val2==1 && val3==1  && val4==0 && val5==1  )  //11101
{
motostop();
delay(20);
Serial.println("Turn rightt");
motoright();
delay(100);
}

else if(val1==1 && val2==1 && val3==1  && val4==0 && val5==0  )  //11100
{
motostop();
delay(20);
Serial.println("Turn right");
//motorri();
motoright();
delay(100);
}

else if(val1==1 && val2==1 && val3==0  && val4==0 && val5==0  )  //11000
{
motostop();
delay(20);
Serial.println("Turn right");
motoright();
delay(400);
}

else if(val1==1 && val2==1 && val3==1  && val4==1 && val5==0  )  //11110
{
motostop();
delay(20);
Serial.println("Turn right");
//motorri();
motoright();
delay(100);
}


else if(val1==1 && val2==0 && val3==1  && val4==0 && val5==1  )  //10101
{
motostop();
delay(20);
Serial.println("Turn right");
motoright();
delay(100);
}

else{
   motostop();
  
 delay(20);
  }

  }
/******************************************
                    避障
******************************************/
  void bz(){//避障主程序
     motostop();              
     delay(50);
   range();     //先对中间测距值为S
  if (S>60){   // 如果S大于60cm
     motostop();              
     delay(20);
     Serial.print("Distance:");
     Serial.println(S);
     Serial.println("Go forward"); //输出状态
     motorun();//前进
     delay(80);   
    }

  else if(S<30){  // 如果S小于30cm
              Serial.print("Distance:");
              Serial.println(S);
              Serial.println("Go backward"); //输出状态
              motostop();              
              delay(200);
              motodown();//后退
              delay(400);
    }


  else{   // 即S小于60cm,大于30cm 
    Serial.print("Distance:");
     Serial.println(S);    
     Serial.println("Stay...Detecting..."); //输出状态
    turn();                      //调出左右探测距离函数,判断左右距离值
    Serial.print("Distance Left:"); //输出状态
   Serial.println(L); //输出状态
    Serial.print("Distance:"); //输出状态
   Serial.println(S); //输出状态
    Serial.print("Distance Right:"); //输出状态
   Serial.println(R); //输出状态


             if((L>R) && (L>S)){//左边比前方和右方距离大
              Serial.println("Turn left"); //输出状态
              motostop();               
              delay(100);
              motoleft();//左转
              delay(500);      
                    }
             else if ((R>L) && (R>S)){//右边比前方和左方距离大
              Serial.println("Turn Right"); //输出状态
              motostop();               
              delay(100);
              motoright();//右转
              delay(500);
               }

              else if ((L>R) && (L<S)){   //左边比右方距离大,但是小于前方
              Serial.println("Turn Right"); //输出状态
              motostop();               
              delay(100);
              motoleft();   //从左边大转弯,相当于从左边调头
              delay(700);
               }

              else if ((R>L) && (R<S)){   //右边比左方距离大,但是小于前方
              Serial.println("Turn Right"); //输出状态
              motostop();               
              delay(100);
              motoright();//从右边大转弯,相当于从右边调头
              delay(700);
               }


             else{ motodown();
              delay(100);    }      
    }
   }
/******************************************
                    超声波
******************************************/
void range(){ //定义中间测距函数
digitalWrite(trig,LOW); //测距
delayMicroseconds(2); //延时2微秒
digitalWrite(trig,HIGH);
delayMicroseconds(20);
digitalWrite(trig,LOW);
int distance = pulseIn(echo,HIGH); //读取高电平时间
distance = distance/58; //按照公式计算
S = distance; //把值赋给S
//Serial.println(S);

}

void rangel(){ //定义左边测距函数
digitalWrite(trig,LOW); //测距
delayMicroseconds(2); //延时2微秒
digitalWrite(trig,HIGH);
delayMicroseconds(20);
digitalWrite(trig,LOW);
int distance = pulseIn(echo,HIGH); //读取高电平时间
distance = distance/58; //按照公式计算
L = distance; //把值赋给L
//Serial.println(L); //向串口发送L的值,可以在显示器上显示距离
}


void ranger(){ //定义右边测距函数
digitalWrite(trig,LOW); //测距
delayMicroseconds(2); //延时2微秒
digitalWrite(trig,HIGH);
delayMicroseconds(20);
digitalWrite(trig,LOW);
int distance = pulseIn(echo,HIGH); //读取高电平时间
distance = distance/58; //按照公式计算
R = distance; //把值赋给R
//Serial.println(R); //向串口发送R的值,可以在显示器上显示距离
}

void turn(){      //左右探测距离函数
  motostop();
  delay(500);
    lw();     //舵机转到150度既左边(角度与安装方式有关)
   delay(800);     //留时间给舵机转向
   rangel();//左边测距值为L

   zw();    //测距完成,舵机回到中位
   delay(800);   //留时间给舵机转向
   range();//中间测距值为S

     rw(); //舵机转动到30度,测右边距离
    delay(800);//留时间给舵机转向
    ranger();   //右边测距值为R

    zw(); //回中位
     delay(800);//留时间给舵机转向
     }  
/******************************************
                    舵机
******************************************/
void zw(){   //定义舵机中位
   for(int i=0;i<50;i++)  //发送50个脉冲
        {
          servopulse(115);   //引用脉冲函数  舵机位置中
         }   
   }

void lw(){  //舵机150度角
   for(int i=0;i<50;i++)  //发送50个脉冲
        {
          servopulse(175);   //引用脉冲函数 舵机150度角
         }   
}
void rw(){   //舵机30度角
   for(int i=0;i<50;i++)  //发送50个脉冲
        {
          servopulse(55);   //引用脉冲函数 舵机30度角
         }   
  }
  
void servopulse(int angle)//定义一个脉冲函数   舵机函数
{
  int pulsewidth=(angle*11)+500;  //将角度转化为500-2480的脉宽值
  digitalWrite(servopin,HIGH);    //将舵机接口电平至高
  delayMicroseconds(pulsewidth);  //延时脉宽值的微秒数
  digitalWrite(servopin,LOW);     //将舵机接口电平至低
  delayMicroseconds(20000-pulsewidth);
}

            

电机源文件:

//MOTOR.cpp

#include"MOTOR.h"
#include"Arduino.h"

/******************************************
                    电机
******************************************/
MotorControl::MotorControl(uint8_t num){//电机控制初始化
  motornum=num;
  switch (num) {
  case 1:
    pinMode(IN1,OUTPUT);
    pinMode(IN2,OUTPUT);
    pinMode(ENA,OUTPUT);
    break;
  case 2:
    pinMode(IN3,OUTPUT);
    pinMode(IN4,OUTPUT);
    pinMode(ENB,OUTPUT);
    break;
}
}

void MotorControl::motorrun(uint8_t cmd) {//车轮方向控制
  uint8_t a, b;
  switch(motornum){
    case 1:
    a=IN1;b=IN2;break;
    case 2:
    a=IN3;b=IN4;break; 
  }
  switch(cmd){
    case GOFORWARD:
    digitalWrite(a,LOW);
    digitalWrite(b,HIGH);
    break;
    case GOBACKWARD:
    digitalWrite(a,HIGH);
    digitalWrite(b,LOW);
    break;
    case GORELEASE:
    digitalWrite(a,LOW);
    digitalWrite(b,LOW);
    break;
  }
}

void MotorControl::motorsetSpeed(uint16_t motorspeed){//小车速度控制
    switch(motornum){
    case 1:
    analogWrite(ENA, motorspeed);break;
    case 2:
    analogWrite(ENB, motorspeed);break;
    //delay(20);
  }
}

/******************************************
                    LED
******************************************/
led::led(uint8_t pin){
  ledpin=pin;
  pinMode(ledpin,OUTPUT);
}

void led::ledset(void){
  digitalWrite(ledpin,LOW);
  delay(200);
}
void led::ledon(void){
  digitalWrite(ledpin,HIGH);
  delay(200);
  digitalWrite(ledpin,LOW);
  digitalWrite(ledpin,HIGH);
  delay(200);
  digitalWrite(ledpin,LOW);
}

电机头文件:

//MOTOR.h

#ifndef _MOTOR_h_
#define _MOTOR_h_

//导入Arduino核心头文件
#include"Arduino.h"

//电机驱动使用的引脚
#define ENA 11
#define ENB 3
#define IN1 4
#define IN2 5
#define IN3 6
#define IN4 7


#define GOFORWARD 1
#define GOBACKWARD 2
#define GORELEASE 3

//电机
class MotorControl
{
  public:
    MotorControl(uint8_t motornum);
    void motorrun(uint8_t);
    void motorsetSpeed(uint16_t);
  private:
    uint8_t motornum; //motornum1为小车右侧轮子,2为左侧轮子
 
};

class led{
  public:
  led(uint8_t ledpin);
  void ledset(void);
  void ledon(void);
  private:
  uint8_t ledpin;
};





#endif

蜂鸣器源文件:

#include"pitch.h"
#include"Arduino.h"


/******************************************
                 蜂鸣器
******************************************/

buzzeron::buzzeron(uint8_t pin){
  buzzerpin=pin;
  pinMode(buzzerpin,OUTPUT);
}

void buzzeron::tone1(void){ //提示音
  int melodydoudizhu[] = {
    
  NOTE_G4, NOTE_C5
};
  int noteDurations[] = {

  8, 8
};
for (int thisNote = 0; thisNote < 2; thisNote++) {

    int noteDuration = 1000 / noteDurations[thisNote];

    tone(buzzerpin, melodydoudizhu[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1.30;

    delay(pauseBetweenNotes);

    noTone(buzzerpin);

}
}

void buzzeron::tone2(void){ //倒车音
int melodydoudizhu[] = {

  NOTE_G4, NOTE_C5
};

int noteDurations[] = {

  8, 8
};
for (int thisNote = 0; thisNote < 2; thisNote++) {

    int noteDuration = 1000 / noteDurations[thisNote];

    tone(buzzerpin, melodydoudizhu[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1.30;

    delay(pauseBetweenNotes);

    noTone(buzzerpin);

  }


}

void buzzeron::tone3(void){//斗地主
  int melodydoudizhu[] = {

  NOTE_G3, NOTE_G3, NOTE_A3, NOTE_C4, NOTE_G3, NOTE_A3, NOTE_C4,
  NOTE_G4, NOTE_G4, NOTE_G4, NOTE_E4, NOTE_G4,
  NOTE_G3, NOTE_G3, NOTE_A3, NOTE_C4, NOTE_G3, NOTE_A3, NOTE_E4, 
  NOTE_D4, NOTE_D4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_D4,
  
};

int noteDurations[] = {

  2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
  2, 4, 4, 4, 4, 4, 4, 4, 8, 8, 4, 4, 1
};

for (int thisNote = 0; thisNote < 25; thisNote++) {

    int noteDuration = 1000 / noteDurations[thisNote];

    tone(buzzerpin, melodydoudizhu[thisNote], noteDuration);


    int pauseBetweenNotes = noteDuration * 1.30;

    delay(pauseBetweenNotes);

    noTone(buzzerpin);

  }

}


void buzzeron::tone4(void){//爱情买卖
  int melodydoudizhu[] = {

  NOTE_E4, NOTE_A4, NOTE_C5, NOTE_C5, NOTE_E4, NOTE_A4, NOTE_C5,
  NOTE_B4, NOTE_A4, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_D4, NOTE_E4,
  NOTE_D4, NOTE_D4, NOTE_D4, NOTE_A3, NOTE_D4, NOTE_E4, NOTE_G4, 
  NOTE_E4, NOTE_B4, NOTE_B4, NOTE_G4, NOTE_D4, NOTE_E4,
  NOTE_E4, NOTE_A4, NOTE_C5, NOTE_C5, NOTE_E4, NOTE_A4, NOTE_C5,
  NOTE_E5, NOTE_D5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, 
  NOTE_E5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, NOTE_D5, NOTE_C5, NOTE_B4,
  NOTE_G4, NOTE_G4, NOTE_E4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4,
};

int noteDurations[] = {

  4, 4, 4, 4, 4, 4, 2, 
  4, 8, 8, 4, 4, 4, 1.5,
  4, 4, 4, 4, 4, 4, 2, 
  4, 4, 4, 4, 8, 1.5,
  4, 4, 4, 4, 4, 4, 2,
  4, 8, 8, 4, 4, 1,
  3,8,4,4,3,8,4,4,
  4,8,8,4,8,8,1
};
for (int thisNote = 0; thisNote < 55; thisNote++) {

    int noteDuration = 1000 / noteDurations[thisNote];

    tone(buzzerpin, melodydoudizhu[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1.30;

    delay(pauseBetweenNotes);

    noTone(buzzerpin);

  }



}

void buzzeron::tonestop(void){
  noTone(buzzerpin);
  pinMode(buzzerpin,INPUT);
  pinMode(buzzerpin,OUTPUT);
  }

蜂鸣器头文件:

/*************************************************

 * Public Constants

 *************************************************/
#ifndef _PITCH_h_
#define _PITCH_h_


#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978

#include"Arduino.h"

class buzzeron
{
  public:
    buzzeron(uint8_t pin);
    void tone1(void);//提示音
    void tone2(void);//倒车音
    void tone3(void);//斗地主
    void tone4(void);//爱情买卖
    void tonestop(void);
  private:
    uint8_t buzzerpin; 
 
};


#endif

蓝牙:

需要使用一个蓝牙助手适配蓝牙模块:

 完成后界面:

 

 

 

 

 

 

 

 

 

 

 

最终成品:

 

版权声明:本文为CSDN博主「万千Inf」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40072174/article/details/118946684

        采用 Arduino Uno单片机作为主控单元,采用四轮式移动平台,四轮均可驱动,可以通过蓝牙控制小车前进、后退、原地转向等操作,可调节车速,可鸣笛警报,可自动识别并躲避障碍物,可遵循特定轨道自动行驶,且以上功能均可通过蓝牙进行控制的智能小车。

先前准备:

总体方案(硬件框图):

PCB板制作:

                设计软件:Altium Designer 8.3

                制作 :嘉立创公司(非广告,仅代表本人选择)

Arduino开发环境:Arduino 1.8.9

所需硬件:(本人于淘宝信泰微电子购买)

                Arduino UNO(主控单片机):

                4轮小车底座带马达(需要自行焊线):

                L239D(电机驱动芯片):

                两节18650电池:

                K78L05(稳压器):

【注:若使用LM7805需要配合三节18650电池,本人并未做尝试, 可以参考文章:https://www.arduino.cn/forum.php?mod=viewthread&tid=93639&highlight=%E5%B0%8F%E8%BD%A6

                HC-05(蓝牙模组):

                HC-SR04(超声波模组):

                9g舵机(舵机,用以配合超声波模块在前方转动,做范围测量):

                无源蜂鸣器:

                TCRT5000(红外光电传感器):

 

PCB制作:

PCB规格:10cm*10cm

元器件名称

库文件夹

所属的元器件库

L7805CV

Library

ST Power Mgt Voltage Regulator.IntLib

SW-SPST

Library

Miscellaneous Devices.IntLib

Res3

Library

Miscellaneous Devices.IntLib

Cap

Library

Miscellaneous Devices.IntLib

Cap Pol1

Library

Miscellaneous Devices.IntLib

Header 2

Library

Miscellaneous Connectors.IntLib

Header 3

Library

Miscellaneous Connectors.IntLib

Header 4

Library

Miscellaneous Connectors.IntLib

L293D

Library

ST Interface DC & Stepper Motor Controller.IntLib

PCB原理图:

PCB电路图:

 PCB实物图:

软件部分:

软件框图:

主体代码:

#include "MOTOR.h"                     //自定义电机驱动库
#include "pitch.h"
#include <SoftwareSerial.h>            //蓝牙库

MotorControl motorR(1);   //右侧电机
MotorControl motorL(2);   //左侧电机
led LED(12);
buzzeron BUZZER(9);


int motorspeed; //小车速度变量
int trac1 = 14; //从车头方向的最左边开始排序接红外寻迹模块
int trac2 = 15;
int trac3 = 16;
int trac4 = 17;
int trac5 = 18;
int val1;         //寻迹模块储存值
int val2;
int val3;
int val4;
int val5;
int servopin = 10;    //定义舵机接口数字接口10

int bl;             //定义运行指针
int bll;
unsigned int L; //左距离存储
unsigned int R; //右距离存储
unsigned int S; //中距离存储

int trig=2; //发射信号
int echo=13; //接收信号



void setup() {  
  Serial.begin(9600);
  LED.ledset();  
  pinMode(trac1, INPUT);  //寻迹模块引脚初始化
  pinMode(trac2, INPUT);
  pinMode(trac3, INPUT);
  pinMode(trac4, INPUT);
  pinMode(trac5, INPUT);
  pinMode(trig,OUTPUT); //超声波设置引脚模式
  pinMode(echo,INPUT);
  motorspeed=200; 
  pinMode(servopin,OUTPUT);//设定舵机v接口为输出接口
  zw();//定义舵机中位
  delay(500); //开机延时
  bl=1;//定义运行指针值
  bll=1;//定义运行指针记忆值
}

void loop() {  

if(Serial.available()>0){   // 蓝牙串口有数据              
              chuspeed();  // 给小车速度赋值
              lytest();    // 运行蓝牙解码判断         
              }   

if(bl==2){      
                 
                chuspeed(); // 给小车速度赋值
                xunji();// 运行寻迹
                BUZZER.tone1();

                }   

if(bl==3){                  
                  chuspeed();// 给小车速度赋值
                  motorun();  // 小车前进不停
                  delay(1000);

                  }
if(bl==4){       
                          
                 chuspeed();// 给小车速度赋值
                  bz();  // 小车避障
                  }

if(bl==5){                    
                  motostop();
                  BUZZER.tone3();
                  if(bll==2){bl=2;}// 喇叭响完以后继续之前程序指针
                  else if(bll==3){bl=3;}
                  else if(bll==4){bl=4;}
                  else {
                        bll=1;
                        bl=1;}
                  }  



else{ motostop();}  
}


/******************************************
                    电机  
******************************************/
void chuspeed(void){                  // 定义小车初始速度
motorR.motorsetSpeed(motorspeed);   
motorL.motorsetSpeed(motorspeed);
}
void motostop(void){                  // 定义小车停止 
              chuspeed();  
              motorR.motorrun(GORELEASE);
              motorL.motorrun(GORELEASE);
}
void motorun(void){                  // 定义小车前进
              chuspeed();  
              motorR.motorrun(GOFORWARD);
              motorL.motorrun(GOFORWARD);
}
void motodown(void){                  // 定义小车后退
              BUZZER.tone2();
              chuspeed();   
              motorR.motorrun(GOBACKWARD);
              motorL.motorrun(GOBACKWARD);
}
void motoleft(void){                  // 定义小车原地左拐
              chuspeed();   
              motorR.motorrun(GOFORWARD);
              motorL.motorrun(GOBACKWARD);
}

void motoright(void){                 // 定义小车原地右拐
               chuspeed();   
              motorR.motorrun(GOBACKWARD);
              motorL.motorrun(GOFORWARD);
}
void motorle(void){                  // 定义小车左拐
              chuspeed(); 
              motorR.motorrun(GOFORWARD);
              motorL.motorrun(GORELEASE);
}
void motorri(void){                  // 定义小车右拐
             chuspeed(); 
              motorR.motorrun(GORELEASE);
              motorL.motorrun(GOFORWARD);
}

/******************************************
                 蓝牙
******************************************/
void lytest(){// 定义蓝牙串口解码判断
         int cmd = Serial.read();//读取蓝牙模块发送到串口的数据
         LED.ledon();
         BUZZER.tone1();         
          if(cmd==49){   // 手机蓝牙输出1,对应ascii数是49
           Serial.println("Go forward"); //输出状态
              motostop();  
              delay(100);
              motorun();
              delay(200);
                     }

          if(cmd==50){  // 手机蓝牙输出2,对应ascii数是50,后面以此类推即加48
          Serial.println("Go back"); //输出状态
              motostop();              
              delay(100);
              motodown();
              delay(200);
                       }

               if(cmd==51){   
                 Serial.println("I say Ting Ting--"); //输出状态
              motostop();
              bl=1;
              bll=1;            
              delay(100);              
                         }

                if(cmd==52){   
              Serial.println("Turn left"); //输出状态
              motostop();               
              delay(100);
              motoleft();
              delay(200);            
                       }
                  if(cmd==53){   
              Serial.println("Turn Right"); //输出状态
              motostop();            
              delay(100);
              motoright();
              delay(200);            
                  }
                 if(cmd==54){
                 Serial.println("Speed up");
                 motorspeed+=5;
                 if(motorspeed>255){motorspeed=255; } //不超过255最高值
                 Serial.print("speed=");
                 Serial.println(motorspeed);
                         }
                   if(cmd==55){
                 Serial.println("Speed down");
              motorspeed-=5;
               if(motorspeed<80){motorspeed=80;}//不低于0
              Serial.print("speed=");
              Serial.println(motorspeed);
                               }

                   if(cmd==56){ //指针寻迹
                   bl=2;
                   bll=2;
                   Serial.println("Follow your heart---"); 
                   delay(50);}                       


                  if(cmd==57){  //指针一直进      
                  bl=3;
                  bll=3;
                  Serial.println("Go Forward---");
                  delay(50);
                  }

                  if(cmd==99){  //速度最小      
                  Serial.println("Lowest Speed");
              motorspeed =100;
              
              Serial.print("speed=");
              Serial.println(motorspeed);
                  }

                   if(cmd==100){  //速度最大      
                  Serial.println("Highest Speed");
              motorspeed =255;
              
              Serial.print("speed=");
              Serial.println(motorspeed);
                  }                    


                 if(cmd==97){//按健a,对应ASCII码是97 指针避障
                 bl=4;
                 bll=4;
                 Serial.println("Avoid---");
                 delay(50);}            


                 if(cmd==98){ //按健b,对应ASCII码是98  指针喇叭
                      bl=5;

                    Serial.println("DiDiDi---"); }
}

/******************************************
                 红外线循迹
******************************************/
void xunji(){         //寻迹主函数
motostop();
delay(300);
       
val1 = digitalRead(trac1);
val2 = digitalRead(trac2); //寻迹模块返回值
val3 = digitalRead(trac3);
val4 = digitalRead(trac4);
val5 = digitalRead(trac5);

val1=!val1;
val2=!val2;
val3=!val3;
val4=!val4;
val5=!val5;

Serial.print(val1);
Serial.print(val2);
Serial.print(val3);
Serial.print(val4);
Serial.println(val5);

if(val1==1 && val2==1 && val3==0  && val4==1 && val5==1  )  //11011中间黑线,即0为黑线
{
motostop();
Serial.println("Go forward");
motorun();
delay(100);
}

else if(val1==1 && val2==0 && val3==0  && val4==0 && val5==1  )  //10001中间三黑线,十字路
{
  motostop();
Serial.println("Go forward");
motorun();
delay(100);
}

else if(val1==0 && val2==0 && val3==0  && val4==0 && val5==0  )  //00000都检测到黑线
{
Serial.println("I say Ting Ting--");
motostop();
delay(500);
}

else if(val1==1 && val2==1 && val3==1  && val4==1 && val5==1  )  //11111都无检测到黑线
{
Serial.println("go...?");
motostop();
motorun();
delay(100);
}



else if(val1==1 && val2==0 && val3==0  && val4==1 && val5==1  )  //10011
{  
motostop();
delay(200);
Serial.println("Turn left");
motoleft();
delay(100);
}

else if(val1==0 && val2==1 && val3==0  && val4==1 && val5==1  )  //01011
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}

else if(val1==1 && val2==0 && val3==1  && val4==1 && val5==1  )  //10111
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}


else if(val1==0 && val2==0 && val3==1  && val4==1 && val5==1  )  //00111
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}


else if(val1==0 && val2==0 && val3==0  && val4==1 && val5==1  )  //00011
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}


else if(val1==0 && val2==1 && val3==1  && val4==1 && val5==1  )  //01111
{
motostop();
delay(20);
Serial.println("Turn left");
motoleft();
delay(100);
}

else if(val1==1 && val2==1 && val3==0  && val4==0 && val5==1  )  //11001
{
motostop();
delay(20);
Serial.println("Turn right");
motoright();
delay(100);
}

else if(val1==1 && val2==1 && val3==0  && val4==1 && val5==0  )  //11010
{
motostop();
delay(20);
Serial.println("Turn right");
motoright();
delay(100);
}

else if(val1==1 && val2==1 && val3==1  && val4==0 && val5==1  )  //11101
{
motostop();
delay(20);
Serial.println("Turn rightt");
motoright();
delay(100);
}

else if(val1==1 && val2==1 && val3==1  && val4==0 && val5==0  )  //11100
{
motostop();
delay(20);
Serial.println("Turn right");
//motorri();
motoright();
delay(100);
}

else if(val1==1 && val2==1 && val3==0  && val4==0 && val5==0  )  //11000
{
motostop();
delay(20);
Serial.println("Turn right");
motoright();
delay(400);
}

else if(val1==1 && val2==1 && val3==1  && val4==1 && val5==0  )  //11110
{
motostop();
delay(20);
Serial.println("Turn right");
//motorri();
motoright();
delay(100);
}


else if(val1==1 && val2==0 && val3==1  && val4==0 && val5==1  )  //10101
{
motostop();
delay(20);
Serial.println("Turn right");
motoright();
delay(100);
}

else{
   motostop();
  
 delay(20);
  }

  }
/******************************************
                    避障
******************************************/
  void bz(){//避障主程序
     motostop();              
     delay(50);
   range();     //先对中间测距值为S
  if (S>60){   // 如果S大于60cm
     motostop();              
     delay(20);
     Serial.print("Distance:");
     Serial.println(S);
     Serial.println("Go forward"); //输出状态
     motorun();//前进
     delay(80);   
    }

  else if(S<30){  // 如果S小于30cm
              Serial.print("Distance:");
              Serial.println(S);
              Serial.println("Go backward"); //输出状态
              motostop();              
              delay(200);
              motodown();//后退
              delay(400);
    }


  else{   // 即S小于60cm,大于30cm 
    Serial.print("Distance:");
     Serial.println(S);    
     Serial.println("Stay...Detecting..."); //输出状态
    turn();                      //调出左右探测距离函数,判断左右距离值
    Serial.print("Distance Left:"); //输出状态
   Serial.println(L); //输出状态
    Serial.print("Distance:"); //输出状态
   Serial.println(S); //输出状态
    Serial.print("Distance Right:"); //输出状态
   Serial.println(R); //输出状态


             if((L>R) && (L>S)){//左边比前方和右方距离大
              Serial.println("Turn left"); //输出状态
              motostop();               
              delay(100);
              motoleft();//左转
              delay(500);      
                    }
             else if ((R>L) && (R>S)){//右边比前方和左方距离大
              Serial.println("Turn Right"); //输出状态
              motostop();               
              delay(100);
              motoright();//右转
              delay(500);
               }

              else if ((L>R) && (L<S)){   //左边比右方距离大,但是小于前方
              Serial.println("Turn Right"); //输出状态
              motostop();               
              delay(100);
              motoleft();   //从左边大转弯,相当于从左边调头
              delay(700);
               }

              else if ((R>L) && (R<S)){   //右边比左方距离大,但是小于前方
              Serial.println("Turn Right"); //输出状态
              motostop();               
              delay(100);
              motoright();//从右边大转弯,相当于从右边调头
              delay(700);
               }


             else{ motodown();
              delay(100);    }      
    }
   }
/******************************************
                    超声波
******************************************/
void range(){ //定义中间测距函数
digitalWrite(trig,LOW); //测距
delayMicroseconds(2); //延时2微秒
digitalWrite(trig,HIGH);
delayMicroseconds(20);
digitalWrite(trig,LOW);
int distance = pulseIn(echo,HIGH); //读取高电平时间
distance = distance/58; //按照公式计算
S = distance; //把值赋给S
//Serial.println(S);

}

void rangel(){ //定义左边测距函数
digitalWrite(trig,LOW); //测距
delayMicroseconds(2); //延时2微秒
digitalWrite(trig,HIGH);
delayMicroseconds(20);
digitalWrite(trig,LOW);
int distance = pulseIn(echo,HIGH); //读取高电平时间
distance = distance/58; //按照公式计算
L = distance; //把值赋给L
//Serial.println(L); //向串口发送L的值,可以在显示器上显示距离
}


void ranger(){ //定义右边测距函数
digitalWrite(trig,LOW); //测距
delayMicroseconds(2); //延时2微秒
digitalWrite(trig,HIGH);
delayMicroseconds(20);
digitalWrite(trig,LOW);
int distance = pulseIn(echo,HIGH); //读取高电平时间
distance = distance/58; //按照公式计算
R = distance; //把值赋给R
//Serial.println(R); //向串口发送R的值,可以在显示器上显示距离
}

void turn(){      //左右探测距离函数
  motostop();
  delay(500);
    lw();     //舵机转到150度既左边(角度与安装方式有关)
   delay(800);     //留时间给舵机转向
   rangel();//左边测距值为L

   zw();    //测距完成,舵机回到中位
   delay(800);   //留时间给舵机转向
   range();//中间测距值为S

     rw(); //舵机转动到30度,测右边距离
    delay(800);//留时间给舵机转向
    ranger();   //右边测距值为R

    zw(); //回中位
     delay(800);//留时间给舵机转向
     }  
/******************************************
                    舵机
******************************************/
void zw(){   //定义舵机中位
   for(int i=0;i<50;i++)  //发送50个脉冲
        {
          servopulse(115);   //引用脉冲函数  舵机位置中
         }   
   }

void lw(){  //舵机150度角
   for(int i=0;i<50;i++)  //发送50个脉冲
        {
          servopulse(175);   //引用脉冲函数 舵机150度角
         }   
}
void rw(){   //舵机30度角
   for(int i=0;i<50;i++)  //发送50个脉冲
        {
          servopulse(55);   //引用脉冲函数 舵机30度角
         }   
  }
  
void servopulse(int angle)//定义一个脉冲函数   舵机函数
{
  int pulsewidth=(angle*11)+500;  //将角度转化为500-2480的脉宽值
  digitalWrite(servopin,HIGH);    //将舵机接口电平至高
  delayMicroseconds(pulsewidth);  //延时脉宽值的微秒数
  digitalWrite(servopin,LOW);     //将舵机接口电平至低
  delayMicroseconds(20000-pulsewidth);
}

            

电机源文件:

//MOTOR.cpp

#include"MOTOR.h"
#include"Arduino.h"

/******************************************
                    电机
******************************************/
MotorControl::MotorControl(uint8_t num){//电机控制初始化
  motornum=num;
  switch (num) {
  case 1:
    pinMode(IN1,OUTPUT);
    pinMode(IN2,OUTPUT);
    pinMode(ENA,OUTPUT);
    break;
  case 2:
    pinMode(IN3,OUTPUT);
    pinMode(IN4,OUTPUT);
    pinMode(ENB,OUTPUT);
    break;
}
}

void MotorControl::motorrun(uint8_t cmd) {//车轮方向控制
  uint8_t a, b;
  switch(motornum){
    case 1:
    a=IN1;b=IN2;break;
    case 2:
    a=IN3;b=IN4;break; 
  }
  switch(cmd){
    case GOFORWARD:
    digitalWrite(a,LOW);
    digitalWrite(b,HIGH);
    break;
    case GOBACKWARD:
    digitalWrite(a,HIGH);
    digitalWrite(b,LOW);
    break;
    case GORELEASE:
    digitalWrite(a,LOW);
    digitalWrite(b,LOW);
    break;
  }
}

void MotorControl::motorsetSpeed(uint16_t motorspeed){//小车速度控制
    switch(motornum){
    case 1:
    analogWrite(ENA, motorspeed);break;
    case 2:
    analogWrite(ENB, motorspeed);break;
    //delay(20);
  }
}

/******************************************
                    LED
******************************************/
led::led(uint8_t pin){
  ledpin=pin;
  pinMode(ledpin,OUTPUT);
}

void led::ledset(void){
  digitalWrite(ledpin,LOW);
  delay(200);
}
void led::ledon(void){
  digitalWrite(ledpin,HIGH);
  delay(200);
  digitalWrite(ledpin,LOW);
  digitalWrite(ledpin,HIGH);
  delay(200);
  digitalWrite(ledpin,LOW);
}

电机头文件:

//MOTOR.h

#ifndef _MOTOR_h_
#define _MOTOR_h_

//导入Arduino核心头文件
#include"Arduino.h"

//电机驱动使用的引脚
#define ENA 11
#define ENB 3
#define IN1 4
#define IN2 5
#define IN3 6
#define IN4 7


#define GOFORWARD 1
#define GOBACKWARD 2
#define GORELEASE 3

//电机
class MotorControl
{
  public:
    MotorControl(uint8_t motornum);
    void motorrun(uint8_t);
    void motorsetSpeed(uint16_t);
  private:
    uint8_t motornum; //motornum1为小车右侧轮子,2为左侧轮子
 
};

class led{
  public:
  led(uint8_t ledpin);
  void ledset(void);
  void ledon(void);
  private:
  uint8_t ledpin;
};





#endif

蜂鸣器源文件:

#include"pitch.h"
#include"Arduino.h"


/******************************************
                 蜂鸣器
******************************************/

buzzeron::buzzeron(uint8_t pin){
  buzzerpin=pin;
  pinMode(buzzerpin,OUTPUT);
}

void buzzeron::tone1(void){ //提示音
  int melodydoudizhu[] = {
    
  NOTE_G4, NOTE_C5
};
  int noteDurations[] = {

  8, 8
};
for (int thisNote = 0; thisNote < 2; thisNote++) {

    int noteDuration = 1000 / noteDurations[thisNote];

    tone(buzzerpin, melodydoudizhu[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1.30;

    delay(pauseBetweenNotes);

    noTone(buzzerpin);

}
}

void buzzeron::tone2(void){ //倒车音
int melodydoudizhu[] = {

  NOTE_G4, NOTE_C5
};

int noteDurations[] = {

  8, 8
};
for (int thisNote = 0; thisNote < 2; thisNote++) {

    int noteDuration = 1000 / noteDurations[thisNote];

    tone(buzzerpin, melodydoudizhu[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1.30;

    delay(pauseBetweenNotes);

    noTone(buzzerpin);

  }


}

void buzzeron::tone3(void){//斗地主
  int melodydoudizhu[] = {

  NOTE_G3, NOTE_G3, NOTE_A3, NOTE_C4, NOTE_G3, NOTE_A3, NOTE_C4,
  NOTE_G4, NOTE_G4, NOTE_G4, NOTE_E4, NOTE_G4,
  NOTE_G3, NOTE_G3, NOTE_A3, NOTE_C4, NOTE_G3, NOTE_A3, NOTE_E4, 
  NOTE_D4, NOTE_D4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_D4,
  
};

int noteDurations[] = {

  2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
  2, 4, 4, 4, 4, 4, 4, 4, 8, 8, 4, 4, 1
};

for (int thisNote = 0; thisNote < 25; thisNote++) {

    int noteDuration = 1000 / noteDurations[thisNote];

    tone(buzzerpin, melodydoudizhu[thisNote], noteDuration);


    int pauseBetweenNotes = noteDuration * 1.30;

    delay(pauseBetweenNotes);

    noTone(buzzerpin);

  }

}


void buzzeron::tone4(void){//爱情买卖
  int melodydoudizhu[] = {

  NOTE_E4, NOTE_A4, NOTE_C5, NOTE_C5, NOTE_E4, NOTE_A4, NOTE_C5,
  NOTE_B4, NOTE_A4, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_D4, NOTE_E4,
  NOTE_D4, NOTE_D4, NOTE_D4, NOTE_A3, NOTE_D4, NOTE_E4, NOTE_G4, 
  NOTE_E4, NOTE_B4, NOTE_B4, NOTE_G4, NOTE_D4, NOTE_E4,
  NOTE_E4, NOTE_A4, NOTE_C5, NOTE_C5, NOTE_E4, NOTE_A4, NOTE_C5,
  NOTE_E5, NOTE_D5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, 
  NOTE_E5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, NOTE_D5, NOTE_C5, NOTE_B4,
  NOTE_G4, NOTE_G4, NOTE_E4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4,
};

int noteDurations[] = {

  4, 4, 4, 4, 4, 4, 2, 
  4, 8, 8, 4, 4, 4, 1.5,
  4, 4, 4, 4, 4, 4, 2, 
  4, 4, 4, 4, 8, 1.5,
  4, 4, 4, 4, 4, 4, 2,
  4, 8, 8, 4, 4, 1,
  3,8,4,4,3,8,4,4,
  4,8,8,4,8,8,1
};
for (int thisNote = 0; thisNote < 55; thisNote++) {

    int noteDuration = 1000 / noteDurations[thisNote];

    tone(buzzerpin, melodydoudizhu[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1.30;

    delay(pauseBetweenNotes);

    noTone(buzzerpin);

  }



}

void buzzeron::tonestop(void){
  noTone(buzzerpin);
  pinMode(buzzerpin,INPUT);
  pinMode(buzzerpin,OUTPUT);
  }

蜂鸣器头文件:

/*************************************************

 * Public Constants

 *************************************************/
#ifndef _PITCH_h_
#define _PITCH_h_


#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978

#include"Arduino.h"

class buzzeron
{
  public:
    buzzeron(uint8_t pin);
    void tone1(void);//提示音
    void tone2(void);//倒车音
    void tone3(void);//斗地主
    void tone4(void);//爱情买卖
    void tonestop(void);
  private:
    uint8_t buzzerpin; 
 
};


#endif

蓝牙:

需要使用一个蓝牙助手适配蓝牙模块:

 完成后界面:

 

 

 

 

 

 

 

 

 

 

 

最终成品:

 

版权声明:本文为CSDN博主「万千Inf」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40072174/article/details/118946684

生成海报
点赞 0

万千Inf

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

基于8051单片机实现电子时钟+数字秒表设计

概述 电子时钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。随着人们生活环境的不断改善和美化,在许

基于STM32的指纹密码锁

设计简介: 本设计是基于单片机的指纹密码锁,主要实现以下功能: 矩阵按键输入密码,并通过按键显示*号可通过按键或手机开门密码可通过按键进行开门可通过蓝牙模块连接手机进行开门可通过指纹进