arduino nano基于超声波的平衡小车

在网上一直看到两轮平衡车,是通过陀螺仪的角度变化结合pid实现的
某宝上卖的平衡车也买过一个,的确是平衡能力很强,有个很大的原因是电机后装了编码器,可以比较精确的得到和控制轮子走的距离。
但价格贵呀。。。
所以我们就用arduino+普通的香蕉电机+驱动模块+超声波做一个两轮平衡车。
首先是硬件组装,这部分很简单,就是拿个电路板把电机和轮子装好,然后在上方布局nano板,电池,最好放置的时候就让重量均匀分在轮子两侧,别压在一侧,想平衡也平衡不了啊。
在板子上装三个滑动变阻器,用来调节小车的pid参数。
简单的硬件就是这样。
代码部分,本来想自己写pid的,结果写了自己的,然后和pid库的结果对比,发现还是用pid库比较稳一点。
用到的库可以在https://github.com/br3ttb/Arduino-PID-Library中下载

#include 
#include          //引入超声波头文件
#define PID_P  A4
#define PID_I  A5
#define PID_D  A6
int Motor_1A = 3;           //左电机
int Motor_1B = 4;
int Motor_2A = 6;           //右电机
int Motor_2B = 5;
double Len_filter = 0, Len_0 = 200; //测距滤波,机械平衡距离''
unsigned int TrigPin = 8; //HC-SR04触发信号
unsigned int EchoPin = 7; //HC-SR04回波检测
unsigned int Len_Echo = 0; //回波时间
double kp, ki, kd ;
unsigned long time = 0;
long count = 0; //计数值
int i;
double Input, Output, Setpoint;
PID myPID(&Input, &Output, &Setpoint, kp, ki, kd, REVERSE);
SR04 sr04 = SR04(TrigPin, EchoPin);
void setup() {// put your setup code here, to run once:HARDwareINT();SoftwareINT();
}
void HARDwareINT()
{pinMode(Motor_1A, OUTPUT);     //左电机pinMode(Motor_1B, OUTPUT);pinMode(Motor_2A, OUTPUT);     //右电机pinMode(Motor_2B, OUTPUT);pinMode(EchoPin, INPUT);       //超声波测距  pinMode(TrigPin, OUTPUT);
}
void SoftwareINT()
{Serial.begin(115200);for (int i = 0; i < 64; i++){kp += analogRead(PID_P); //读取平衡点电位器设定值ki += analogRead(PID_I); //读取PID-P电位器设定值kd += analogRead(PID_D); //读取PID-D电位器设定值}kp = kp / 2000; //Kp = 3.23;ki = ki / 1000; //Kd = 8.14;kd = kd / 1000; //Len_0 = 189;//  Serial.print(kp); Serial.print("\t"); Serial.print(ki); Serial.print("\t"); Serial.println(kd);//查看设置参数attachInterrupt(0, blinkA, FALLING   );  //注册中断0调用函数blinkAattachInterrupt(1, blinkB, FALLING   );  //注册中断1调用函数blinkBtime = micros(); //时间初值myPID.SetTunings(kp, ki, kd);myPID.SetOutputLimits(-255, 255);myPID.SetSampleTime(5);myPID.SetMode(1);
}
void loop() {// put your main code here, to run repeatedly:digitalWrite(TrigPin, HIGH); //发送超声波测量触发脉冲delayMicroseconds(10);digitalWrite(TrigPin, LOW);Len_Echo = pulseIn(EchoPin, HIGH); //回波时间测量if ((Len_Echo > 50) && (Len_Echo < 1000)){i++;Input = Len_Echo;myPID.Compute();int PWM_Out;Setpoint = 300;PWM_Out = Output;if((((Setpoint-Len_Echo)>10)||((Len_Echo-Setpoint)>40))&&(i>50)){
//      Serial.println(fabs(Setpoint-Len_Echo));
//      Serial.println(PWM_Out);i=100;SetMotorVoltage(PWM_Out);}else{SetMotorVoltage(0);if(fabs(Setpoint-Len_Echo)<20)i=0;//      Serial.print("PWM_Out:");//      Serial.println(PWM_Out);}}else{SetMotorVoltage(0);i=0;  }//      delay(5); //延时5毫秒,保证超声测距可靠工作
}
//中断0调用函数
void blinkA()
{if ((micros() - time) > 15) //防抖动处理count ++;time = micros();
}//中断1调用函数
void blinkB()
{if ((micros() - time) > 15)  //防抖动处理count --;time = micros();
}
void SetMotorVoltage(int MotorVol)
{// Serial.println(MotorVol);if (MotorVol >= 0){digitalWrite(Motor_1B, 0);digitalWrite(Motor_2B, 0);if (MotorVol > 255)MotorVol = 255; //防止PWM值超过255analogWrite(Motor_1A, MotorVol);analogWrite(Motor_2A, MotorVol);}else{digitalWrite(Motor_1B, 1);digitalWrite(Motor_2B, 1);MotorVol = -MotorVol;if (MotorVol > 255)MotorVol = 255; //防止PWM值超过255analogWrite(Motor_1A, MotorVol);analogWrite(Motor_2A, MotorVol);}}

如果有一些优化部分的建议,可以在评论区留言,一起进步。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部