hi guys,
i trying make pid control robot, accelometer angles reading @ fixed angle. accelometer readings spike -150 down -0.6, isnt if i'm trying read angle. when call readings sensor same angle on , on again, doesn't make sense...
i trying make pid control robot, accelometer angles reading @ fixed angle. accelometer readings spike -150 down -0.6, isnt if i'm trying read angle. when call readings sensor same angle on , on again, doesn't make sense...
code: [select]
#include <wire.h> //define wire library
#include <adafruit_motorshield.h> //define adafruit motorshield library
//////////define accelometer variables//////////////////
const int xpin = a0;
const int ypin = a1;
float accel_x;
float accel_y;
float angle;
/////////define sampling variables voltage bias @ ground level/////////
int samplenum = 500;
float vb = 0;
int sampletime = 10;
unsigned long time;
//////pid contorl variables////////////////
int setpoint = 0; //set point / desired angle robot
double kp = 0.3; //set gain portional --> kickstart correction system
double ki = 2; //set gain integral --> add little more correction if set point isn't met
double kd = 5; //set gain derivative --> control correction rate
float guard_gain = 30; //sets limit integral --> limit error correction?...
int last_error = 0; //sets last error of loop 0 @ start
int integrated_error = 0; //sets total error of system during loop 0 @ start
float pidval = 0; //sets pid value 0 @ start | returns pwm value correction of angle
////////define variables dc motors////////////////////////////
adafruit_motorshield afms = adafruit_motorshield(); //define motorshield object
adafruit_dcmotor *mymotor = afms.getmotor (1); //define motor 1
adafruit_dcmotor *mymotor2 = afms.getmotor (2); //define motor 2
/////////setup serial & begin 1 time setup processes///////////////////////
void setup() {
serial.begin(115200);
serial.println("*setup begin*");
//accelometer setup
serial.println();
serial.println ("accelometer setup start");
//determine voltage bias @ current ground level
serial.println();//space between text
serial.println ("sample voltage bias");
for(int n=0;n<samplenum;n++){ //take total of 500 samples increasing 1 increment
accel_x = analogread(xpin); //read values x-axis port i.e. a5 --> redfine accel_x value obtained
vb += accel_x; //add readings variable accel_x vb (voltage bias) each sample conducted
}
serial.println();//space between text
serial.println ("vb sampling completed"); //indicate end of vb sampling
vb = vb/samplenum; //redefine voltage bias (bits) according sampling. (total voltage bias / sample number) = redefined voltage bias
vb = vb*0.00488758553; //convert voltage bias bits voltage using factor (5/1023)
serial.println();//space between text
serial.print("[voltage bias]:"); //print "voltage bias:" on serial montior
serial.print(vb); // print vb value next "vb:"
serial.println();//space between text
serial.println();//space between text
serial.println ("*end of accelometer setup process*"); //print after setup has completed
serial.println();//space between text
//motor setup
serial.println();//space between text
serial.println ("*start of motor setup*");
afms.begin(); //turn on motorshield
serial.println();//space between text
serial.println ("*end of motor setup*");
serial.println();//space between text
serial.println("*accelometer readings*"); //print out accelometer readings in text
delay(500); //delay system 500 milli-seconds -> allows time user read vb
}
///////////////begin looping process controller///////////////////////////
void loop() { //start loop sequence
////////////read raw data accelomoter & convert angle////////////////////
accel_x = xpin; //read values a0, convert bits->volts using conversion factor (5/1024), define them accel_x
accel_x = accel_x*0.00488758553; //convert readings accelometer bits voltage
accel_x = accel_x - vb; //subtract voltage bias voltage reading of sensor
angle = (accel_x/0.0159); //use degree equation determine degree given corrected voltage output & sensitivity
serial.println(); //space between text
serial.print("initial angle:"); //print "old angle:" in serial monitor
serial.print(angle); //print angle variable value next "angle:" in serial monitor
////////////status check of robot angle////////////////////
while (angle != setpoint) //check if angle equal setpoint i.e. 0 degrees --> if angle doesn't equal setpoint this...
{
serial.println(); // space
serial.print("robot state: unbalanced"); //print out
/////////////////read sensor again incase while-statement not met////////////////////////
accel_x = xpin; //read values a0, convert bits->volts using conversion factor (5/1024), define them accel_x
accel_x = accel_x*0.00488758553; //convert readings accelometer bits voltage
accel_x = accel_x - vb; //subtract voltage bias voltage reading of sensor
angle = (accel_x/0.0159); //use degree equation determine degree given corrected voltage output & sensitivity
//////////////use pid control attempt correct error & reach setpoint/////////////
serial.println(); //space between text
serial.println("pid controller: start"); //print text
float error = setpoint - angle; //determine error set point
float pterm = kp * error; //find p term of pid
integrated_error += error; //add sum of errors in order integrate
float iterm = ki * constrain(integrated_error, -guard_gain, guard_gain); //find term of pid | limit value -30 30 degrees?
float dterm = kd * (error - last_error); //find d term of pid
last_error = error; //redefine last_error value current error next loop iteration
pidval = constrain ((pterm + iterm + dterm), -255, 255); //redefine pidval variable pid value of controller | limited -255 255 --> pwm output
serial.println(); //space between text
serial.println("pid controller: end"); //print text
//////////////////////send pid controller output motors correct angle error////////////////
serial.println(); //space between text
serial.println("motors: correcting"); //print this
if (pidval > 0) //check whether pid value correction positive if this
{
mymotor->setspeed(pidval); //set motor 1 speed pid value correction
mymotor2->setspeed(pidval); //set motor 2 speed pid value correction
mymotor->run(forward); //tell motor 1 go forward
mymotor2->run(forward); //tell more 2 go forward
}
else //if pid value correction negative this
{
mymotor->setspeed(abs(pidval)); //set motor 1 speed pid value correction | take absolute value of pid value
mymotor2->setspeed(abs(pidval)); //set motor 2 speed pid value correction | take absolute value of pid value
mymotor->run(backward); //tell motor 1 go backward
mymotor2->run(backward); //tell motor 2 go backward
}
///////////////////////////read corrected angle value after pid-motor corrections//////////
accel_x = xpin;
accel_x = accel_x*0.00488758553;
accel_x = accel_x - vb;
angle = (accel_x/0.0159);
serial.println(); //space between text
serial.print("corrected angle:"); //print "old angle:" in serial monitor
serial.print(angle); //print angle variable value next "angle:" in serial monitor
}
serial.println(); //space between text
serial.println("robot state: balanced"); //print this
delay (100); //delay system 100 ms before next sample reading
}
in book of experiences accelerometer returns accelerations, measure of change in movement speed vertical accelerometer plane.
if accelerometer has build in calculator, returns angle found biggest x,y accelerations, understand disappointed.
i bit lost here, may missing point.
what type of acc unit using ?
if accelerometer has build in calculator, returns angle found biggest x,y accelerations, understand disappointed.
i bit lost here, may missing point.
what type of acc unit using ?
Arduino Forum > Using Arduino > Programming Questions > Problems Coding Accelometer
arduino
Comments
Post a Comment