基于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单片机实现电子时钟+数字秒表设计

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

汇编实现LED点亮

汇编点亮一个LED MCS-51单片机 也许C语言人人都会,但使用汇编语言就不一定了。 使用汇编语言点亮一个LED灯 程序: ORG 0000H MAIN:CLR P2.0 LJMP MAINEND 注释如下&#

pwm电机调速的原理介绍与代码实现

1、pwm实现调速的原理与介绍 PWM(Pulse Width Modulation)脉冲宽度调制。 1)占空比 pwm占空比就是一个脉冲周期内有效电平在整个周期所占的比例。 通过调节PWM的占空比就能调节IO口上电压的持续