简介:
小车使用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 wheel for(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 代码块(部分):
结束语:
灰度传感器买错了,所以巡线的部分还没有写。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/addevelopment/896138.html