本文主要是介绍Arduino蓝牙小车制作(Arduino+APP Inventor),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
简介:
小车使用Arduino MEGA2560作为主控,4个TT电机带动4WD底盘,4节18650锂电池供电,2个L298N驱动板驱动电机,采用Android APP作为上位机发布指令,操纵小车运动、播放音乐等,两者通过BT蓝牙通信,同时使用2自由度云台辅助超声波传感器探测距离,躲避障碍,灰度传感器进行PID巡线(待完善)、音频解码器和3W喇叭播放音乐、ws2812LED发彩虹光。
使用材料:
MEGA2560开发板、4WD底盘、TT电机X4、L298N驱动板X2、18650锂电池X4、18650电池盒X2、2自由度云台、SG90舵机X2、HC-02蓝牙模块、DFrobot MiNi音频解码器、3W喇叭、ws812全彩LED模块、HCSR04超声波传感器、灰度传感器X2、手机
实物图:
Arduino代码(不含PID巡线):
#include<DFRobotDFPlayerMini.h>//DFrobot音频解码器库
#include<Adafruit_NeoPixel.h>//ws2812全彩LED库
#include<Servo.h>//舵机库
//引脚定义
#define led_pin 22
#define LFwheel_1 50
#define LFwheel_2 52
#define LFpwm 11
#define RFwheel_1 46
#define RFwheel_2 48
#define RFpwm 10
#define LBwheel_1 47
#define LBwheel_2 49
#define LBpwm 13
#define RBwheel_1 51
#define RBwheel_2 53
#define RBpwm 12
#define servopin_1 8
#define servopin_2 9
#define Trig_pin 31
#define Echo_pin 33
//计时变量
unsigned long cur_time=0;
//对象实例化
DFRobotDFPlayerMini myDFPlayer;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(7, led_pin, NEO_GRB + NEO_KHZ800);
Servo myservo1;
Servo myservo2;
void setup() {//串口波特率设置Serial2.begin(9600);Serial3.begin(9600);Serial.begin(115200);//调用初始化函数Init();
}void loop() {//读取字符串String str="";while(Serial3.available()){char ch=(char)Serial3.read();str+=ch;delay(2);}if(str.length()>0){Serial.println(str);if(getKey(str)=="up"){Forward(map(getValue(str),0,70,0,255));//调用前进函数Serial.print("Forward:");Serial.println(str);} if(getKey(str)=="down"){Back_off(map(getValue(str),0,70,0,255));//调用后退函数Serial.print("Back_off:");Serial.println(str);} if(getKey(str)=="left"){Turn_left(map(getValue(str),0,70,0,150));//调用左转函数Serial.print("Turn_left:");Serial.println(str);} if(getKey(str)=="right"){Turn_right(map(getValue(str),0,70,0,150));//调用右转函数Serial.print("Turn_right:");Serial.println(str);} if(getKey(str)=="stop"){Stop();//调用停止函数Serial.print("Stop:");Serial.println(str);}if(getKey(str)=="music"){myDFPlayer.play(random(1,10));//调用音乐播放函数,在音乐编号1~10中随机播放Serial.println("Music play"); }if(getKey(str)=="mustop"){myDFPlayer.pause();//调用音乐暂停函数Serial.println("Music sleep");}if(getKey(str)=="next"){myDFPlayer.next();//调用下一曲函数Serial.println("Next song");}if(getKey(str)=="previous"){myDFPlayer.previous();//调用上一曲函数Serial.println("Previous song");}if(getKey(str)=="light"){rainbowCycle(10);//调用彩虹闪烁函数Serial.println("LED rainbow");}if(getKey(str)=="dark"){colorWipe(strip.Color(0, 0, 0), 50);//关灯Serial.println("LED dark");}if(getKey(str)=="vangle"){myservo2.write(getValue(str));//舵机2垂直转动//delay(10);Serial.print("Vertical Angle:");Serial.println(getValue(str));}if(getKey(str)=="hangle"){myservo1.write(getValue(str));//舵机1水平转动//delay(10);Serial.print("Horizon Angle:");Serial.println(getValue(str));} } if(millis()-cur_time>3000){cur_time=millis();if(getDistance()<30){//超声波测距离,如果距离小于30厘米则亮红灯警示colorWipe(strip.Color(255, 0, 0), 50);Serial.println("RED LIGHT WARING");}else{colorWipe(strip.Color(0, 0, 0), 50);//否则关灯Serial.println("BE SAFE");}}
}//定义初始化函数
void Init(){for(int i=46;i<=53;i++){pinMode(i,OUTPUT);digitalWrite(i,LOW);}if (!myDFPlayer.begin(Serial2)) { Serial.println(F("Unable to begin:"));Serial.println(F("1.Please recheck the connection!"));Serial.println(F("2.Please insert the SD card!"));//while(1); }myDFPlayer.volume(20);strip.begin();strip.show(); myservo1.attach(servopin_1);myservo2.attach(servopin_2);pinMode(Trig_pin, OUTPUT); pinMode(Echo_pin, INPUT);
}
//定义前进函数
void Forward(int v){//左前轮analogWrite(LFpwm,v);digitalWrite(LFwheel_1,HIGH);digitalWrite(LFwheel_2,LOW);//右前轮analogWrite(RFpwm,v);digitalWrite(RFwheel_1,HIGH);digitalWrite(RFwheel_2,LOW);//左后轮analogWrite(LBpwm,v);digitalWrite(LBwheel_1,LOW);digitalWrite(LBwheel_2,HIGH);//右后轮analogWrite(RBpwm,v);digitalWrite(RBwheel_1,LOW);digitalWrite(RBwheel_2,HIGH);}
//定义后退函数
void Back_off(int v){//左前轮analogWrite(LFpwm,v);digitalWrite(LFwheel_1,LOW);digitalWrite(LFwheel_2,HIGH);//右前轮analogWrite(RFpwm,v);digitalWrite(RFwheel_1,LOW);digitalWrite(RFwheel_2,HIGH);//左后轮analogWrite(LBpwm,v);digitalWrite(LBwheel_1,HIGH);digitalWrite(LBwheel_2,LOW);//右后轮analogWrite(RBpwm,v);digitalWrite(RBwheel_1,HIGH);digitalWrite(RBwheel_2,LOW);}
//定义左转函数
void Turn_left(int v){//左前轮analogWrite(LFpwm,v);digitalWrite(LFwheel_1,LOW);digitalWrite(LFwheel_2,HIGH);//右前轮analogWrite(RFpwm,v);digitalWrite(RFwheel_1,HIGH);digitalWrite(RFwheel_2,LOW);//左后轮analogWrite(LBpwm,v);digitalWrite(LBwheel_1,HIGH);digitalWrite(LBwheel_2,LOW);//右后轮analogWrite(RBpwm,v);digitalWrite(RBwheel_1,LOW);digitalWrite(RBwheel_2,HIGH);
}
//定义右转函数
void Turn_right(int v){//左前轮analogWrite(LFpwm,v);digitalWrite(LFwheel_1,HIGH);digitalWrite(LFwheel_2,LOW);//右前轮analogWrite(RFpwm,v);digitalWrite(RFwheel_1,LOW);digitalWrite(RFwheel_2,HIGH);//左后轮analogWrite(LBpwm,v);digitalWrite(LBwheel_1,LOW);digitalWrite(LBwheel_2,HIGH);//右后轮analogWrite(RBpwm,v);digitalWrite(RBwheel_1,HIGH);digitalWrite(RBwheel_2,LOW);
}
//定义停止函数
void Stop(){for(int i=46;i<=53;i++){digitalWrite(i,LOW);}
}
//定义获取标识符函数
String getKey(String str){int pos0,pos1;String key;for(int i=0;i<str.length();i++){if(str[i]=='!')pos0=i;if(str[i]=='@'){pos1=i;break;}}key=str.substring(pos0+1,pos1);return key;
}
//定义获取数值函数
int getValue(String str){int pos0,pos1;int value;for(int i=0;i<str.length();i++){if(str[i]=='@')pos0=i;if(str[i]=='*'){pos1=i;break;} }value=getInt(str.substring(pos0+1,pos1));return value;
}
int getInt(String str){int num=0;for(int i=0;i<str.length();i++){num*=10;num+=str[i]-'0'; } return num;
}
//定义LED彩虹闪烁函数
void rainbowCycle(int wait) {int i, j;for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheelfor(i=0; i< strip.numPixels(); i++) {strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));}strip.show();delay(wait);}
}int Wheel(byte WheelPos) {if(WheelPos < 85) {return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);} else if(WheelPos < 170) {WheelPos -= 85;return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);} else {WheelPos -= 170;return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);}
}
//定义LED发光函数
void colorWipe(int c, int wait) {for(int i=0; i<strip.numPixels(); i++) {strip.setPixelColor(i, c);strip.show();delay(wait);}
}
//定义超声波获取距离函数
double getDistance(){double cm;digitalWrite(Trig_pin, LOW); delayMicroseconds(2); digitalWrite(Trig_pin, HIGH); delayMicroseconds(10); digitalWrite(Trig_pin, LOW); cm = pulseIn(Echo_pin, HIGH)/58.0; cm = (int(cm * 100.0))/100.0; return cm;
}
APP Inventor GUI 设计:
APP Inventor 代码块(部分):
结束语:
灰度传感器买错了,所以巡线的部分还没有写。
这篇关于Arduino蓝牙小车制作(Arduino+APP Inventor)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!