Jump to content

IMU & ARDUINO UNO


MMK

Recommended Posts

I have an Arduino UNO R3...... I actually wants to interface it with a 6DOF IMU so that I can get visual data on my computer from it........ I am a novice on programming the Microcontroller so plzz provide me source codes and useful links for the same! Also recommend me a good IMU too!


>>A code I found on the internet:-

 

#define Gyro_Sens 0.00333 // Gyro sensitivity = 3.33mV/deg/s
#define VPQ 0.00322581 // Volts Per Quid --- value of 3.3V/1023
#define ADC_Avg_Num 100.// Number of averaging readings for calibration
#define Rad2Deg 57.2957795 // 1 radian = 57.2957795 degrees
#define Deg2Rad 0.0174532925 // 0.0174532925 rads = 1 deg

//The minimum and maximum values that came from
//the accelerometer...
//You very well may need to change these
int minValx = 403;
int maxValx = 610;

int minValy = 401;
int maxValy = 614;

int minValz = 413;
int maxValz = 619;

//Calibration variables
float Gx_Cal, Gy_Cal, Gz_Cal;

float GyroRateX=0, GyroRateY=0, GyroAngleZ=0, GyroAngleZ_dt=0;
float AccAngleX=0, AccAngleY=0, AccAngleZ=0;

float Pitch, Yaw, Roll;

int AN[6]; // Hold analogRead data

unsigned long pre_time, print_clock=0;
float dtime;


void setup()
{
analogReference(EXTERNAL); // sets reference voltage to use voltage applied to VREF pin
Serial.begin(115200);
delay(300); // Give things time to "warm-up"

Calibrate(); // Calibrate sensors
pre_time = millis(); //store current time to be used as "previous" time
}



void loop()
{

if(millis()-pre_time>=20) // Read ADC and does Calculations every 20ms
{
dtime=millis()-pre_time; //current time - previous time
pre_time = millis(); //store current time to be used as "previous" time
dtime=dtime/1000.;

Read_ADC();
Calculate();
}


if(millis()-print_clock>=50) //print every 50ms
{
Serial.print(Pitch);
Serial.print(",");
Serial.print(Roll);
Serial.print(",");
Serial.println(Yaw);

print_clock=millis(); // store current time

} //end if


}





///////////////////////////////////////////////////////////////////////
//////////////////////// Functions ///////////////////////////////
///////////////////////////////////////////////////////////////////////



void Read_ADC(void)
{

AN[0] = analogRead(1); // Gyro_X
AN[1] = analogRead(0); // Gyro_Y
AN[2] = analogRead(2); // Gyro_Z
AN[3] = analogRead(5); // Acc_X
AN[4] = analogRead(4); // Acc_Y
AN[5] = analogRead(3); // Acc_Z
}



void Calculate(void)
{

// Gyro portion
//----------------------------------------------------------------
GyroRateX = -1.0*dtime * (((AN[0]*3.3)/1023.-Gx_Cal)/Gyro_Sens);
GyroRateY = dtime * (((AN[1]*3.3)/1023.-Gy_Cal)/Gyro_Sens);

GyroAngleZ_dt = dtime * (((AN[2]*3.3)/1023.-Gz_Cal)/Gyro_Sens);
GyroAngleZ += -1.0 * GyroAngleZ_dt * (1/(cos(Deg2Rad*Roll))); // convert Roll angle to Rads, find sin to use as scaler for Yaw

if(GyroAngleZ<0) GyroAngleZ+=360; // Keep within range of 0-360 deg
if(GyroAngleZ>=360) GyroAngleZ-=360;
//----------------------------------------------------------------

//convert read values to degrees -90 to 90 - Needed for atan2
int xAng = map(AN[3], minValx, maxValx, -90, 90);
int yAng = map(AN[4], minValy, maxValy, -90, 90);
int zAng = map(AN[5], minValz, maxValz, -90, 90);

//Caculate 360deg values like so: atan2(-yAng, -zAng)
//atan2 outputs the value of -π to π (radians)
//We are then converting the radians to degrees
AccAngleX = Rad2Deg * (atan2(-xAng, -zAng) + PI);
AccAngleY = Rad2Deg * (atan2(-yAng, -zAng) + PI);

// Keep angles between +-180deg
if(AccAngleX>180) AccAngleX=AccAngleX-360;

if(AccAngleY<=180) AccAngleY=-1.0*AccAngleY;
if(AccAngleY>180) AccAngleY=360-AccAngleY;

// Final values...
Roll = (0.98)*(Roll + GyroRateX) + (0.02)*(AccAngleX);
Pitch = (0.98)*(Pitch + GyroRateY) + (0.02)*(AccAngleY);
Yaw = GyroAngleZ;
}


// Reads and averages ADC values for calibration
float Avg_ADC(int ADC_In)
{
long ADC_Temp=0;
for(int i=0; i<ADC_Avg_Num; i++)
{
ADC_Temp = ADC_Temp+analogRead(ADC_In);
delay(10); // Delay 10ms due to gyro bandwidth limit of 140Hz (~7.1ms)
}
return VPQ*(ADC_Temp/ADC_Avg_Num); //Average ADC, convert to volts
}

void Calibrate(void)
{
Gx_Cal = Avg_ADC(1); // Gyro_x on pin 1
Gy_Cal = Avg_ADC(0); // Gyro_y on pin 0
Gz_Cal = Avg_ADC(2); // Gyro_z on pin 2
}

////////////////////////
//////// END CODE //////
////////////////////////

I found this code from a website....... Will it work if I use it in the below configuration?????
6DOF_arduino_hookup.png
And for visualization I use this Altitude Indicator below:-
Plz tell me if all of this stuff will work out......... and if not plz help me in making changes here....... PLZ HELP!!!
Edited by MMK
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.