自平衡車
待修改
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include <Kalman.h>
#include "Timer.h"
Kalman kalmanX , kalmanY, kalmanZ;
MPU6050 accelgyro;
int16_t ax, ay, az, gx, gy, gz;
double accX, accY, accZ, gyroX, gyroY, gyroZ;
uint32_t timer;
double pitch, roll, yaw, AngleX, AngleY, AngleZ, Xrate, Yrate, Zrate;
//pid参数
float SetpointX=180;
float InputX,OutputX,errSumX,lastErrX;
float kpX=20;
float kiX=0;
float kdX=10;
float SetpointY=180;
float InputY,OutputY,errSumY,lastErrY;
float kpY=20;
float kiY=0;
float kdY=10;
float timeChange=1;//pid采样时间间隔毫秒
int cons=100;
int pwm1,pwm2,pwm3,pwm4;
Timer t;//定时器时间
void front(){
analogWrite(5,255);
analogWrite(6,0);
analogWrite(9,0);
analogWrite(10,255);
}
void setup() {
Wire.begin();
Serial.begin(115200);
pinMode(5,OUTPUT);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
pinMode(6,OUTPUT);
accelgyro.initialize();
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
accX = ax; accY = ay; accZ = az; gyroX = gx; gyroY = gy; gyroZ = gz;
pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
roll = atan2(accY , accZ) * RAD_TO_DEG;
yaw = atan2(accX , accY) * RAD_TO_DEG;
kalmanY.setAngle(pitch);
kalmanX.setAngle(roll);
kalmanZ.setAngle(yaw);
t.every(timeChange, PIDCalc) ;//每10毫秒pid一次
}
void PIDCalc ()
{
float errorX = SetpointX - InputX;
errSumX += (errorX * timeChange);
float dErrX = (errorX - lastErrX) / timeChange;
OutputX = kpX * errorX +kiX * errSumX + kdX* dErrX ;
lastErrX = errorX;
float errorY = SetpointY - InputY;
errSumY += (errorY * timeChange);
float dErrY = (errorY - lastErrY) / timeChange;
OutputY = kpY * errorY +kiY * errSumY + kdY * dErrY ;
lastErrY = errorY;
}
void loop() {
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
accX = ax;
accY = ay;
accZ = az;
gyroX = gx;
gyroY = gy;
gyroZ = gz;
double dt = (double)(micros() - timer) / 1000000; // Calculate delta time
timer = micros();
pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
roll = atan2(accY,accZ) * RAD_TO_DEG;
yaw = atan2(accX , accY) * RAD_TO_DEG;
Yrate = gyroY / 131.0; // Convert to deg/s
Xrate = gyroX / 131.0;
Zrate = gyroZ / 131.0;
AngleY = kalmanY.getAngle(pitch, Yrate, dt)+2;
// AngleX = int(kalmanX.getAngle(roll, Xrate, dt));
//AngleZ = int(kalmanZ.getAngle(yaw, Zrate, dt));
// InputX=map(AngleX,-180,180,0,360);
InputY=map(AngleY,-180,180,0,360);
t.update();
if(AngleY<=-0.8){
pwm1=cons+OutputY;
pwm1=constrain(pwm1,0,255);
analogWrite(5,0);
analogWrite(10,0);
analogWrite(6, pwm1);
analogWrite(9,pwm1);
}
if(AngleY>=0.8){
pwm1=cons-OutputY;
pwm1=constrain(pwm1,0,255);
analogWrite(6,0);
analogWrite(9,0);
analogWrite(5, pwm1);
analogWrite(10,pwm1);
}
if(AngleY>-0.8&&AngleY<0.8){
pwm1=cons-OutputY;
pwm1=constrain(pwm1,0,255);
analogWrite(6,0);
analogWrite(9,0);
analogWrite(5, 0);
analogWrite(10,0);
}
// analogWrite(5,pwm1);
// analogWrite(6,pwm4);
// analogWrite(9,pwm2);
// analogWrite(10,pwm3);
Serial.print(AngleY);
Serial.print(',');
Serial.println(pwm1);
//Serial.print(',');
// Serial.println(AngleZ);
//Serial.print(',');
//Serial.println(pwm4);
}
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include <Kalman.h>
#include "Timer.h"
Kalman kalmanY;
MPU6050 accelgyro;
int16_t ax, ay, az, gx, gy, gz;
double accX, accY, accZ, gyroX, gyroY, gyroZ;
uint32_t timer;
double pitch, roll, yaw, AngleX, AngleY, AngleZ, Xrate, Yrate, Zrate;
//pid参数
float SetpointY=0;
float InputY,OutputY,errSumY,lastErrY;
float kpY=20;
float kiY=0;
float kdY=10;
float timeChange=1;//pid采样时间间隔毫秒
int cons=100;
int v,k;
Timer t;//定时器时间
void setup() {
Wire.begin();
Serial.begin(115200);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
accelgyro.initialize();
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
accX = ax; accY = ay; accZ = az; gyroX = gx; gyroY = gy; gyroZ = gz;
pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
roll = atan2(accY , accZ) * RAD_TO_DEG;
yaw = atan2(accX , accY) * RAD_TO_DEG;
kalmanY.setAngle(pitch);
t.every(timeChange, PIDCalc) ;//每1毫秒pid一次
}
void PIDCalc ()
{
float errorY = SetpointY - InputY;
errSumY += (errorY * timeChange);
float dErrY = (errorY - lastErrY) / timeChange;
OutputY = kpY * errorY +kiY * errSumY + kdY * dErrY ;
lastErrY = errorY;
}
void loop() {
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
accX = ax;
accY = ay;
accZ = az;
gyroX = gx;
gyroY = gy;
gyroZ = gz;
double dt = (double)(micros() - timer) / 1000000; // Calculate delta time
timer = micros();
pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
roll = atan2(accY,accZ) * RAD_TO_DEG;
yaw = atan2(accX , accY) * RAD_TO_DEG;
Yrate = gyroY / 131.0; // Convert to deg/s
Xrate = gyroX / 131.0;
Zrate = gyroZ / 131.0;
AngleY = kalmanY.getAngle(pitch, Yrate, dt)+5;
InputY=AngleY;
t.update();
if( AngleY>=0){
digitalWrite(7,1);
digitalWrite(5,0);
}else{
digitalWrite(7,0);
digitalWrite(5,1);
}
k=500/t
for(int i=0 , i<k,i++)
digitalWrite(6,1);
digitalWrite(8,1);
delayMicroseconds(t)
digitalWrite(6,0);
digitalWrite(8,0);
delayMicroseconds(t)
Serial.print(AngleY);
Serial.print(',');
Serial.println(pwm1);
}