# DC motor control with PID

**URL:** <https://forum.arduino.cc/t/dc-motor-control-with-pid/8716>\
**Category:** Exhibition\
**Created:** [August 21, 2010, 10:00am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716 "2010-08-21T10:00:53Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![kas](https://avatars.discourse-cdn.com/v4/letter/k/a88e57/32.png) [@kas](https://forum.arduino.cc/u/kas)\
**Post date:** [August 21, 2010, 10:00am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/1 "2010-08-21T10:00:53Z")

</div>

Hi,

For my final projects (balancing robot), I acquired 2X 350 RPM Pololu motors with integrated encoders  
and a 14A dual motor driver

> **[Pololu - 30:1 Metal Gearmotor 37Dx52L mm 12V with 64 CPR Encoder (No End Cap)](https://www.pololu.com/product/1443)**
>
> Note: This gearmotor has been replaced by a functionally identical version with a protective end cap over the encoder.This gearmotor is a powerful 12V brushed DC motor with a 30:1 metal gearbox and an integrated quadrature encoder that provides a...

> **[Pololu - Dual VNH2SP30 Motor Driver Carrier MD03A](https://www.pololu.com/product/708)**
>
> If you are looking to drive two high-power motors through one compact unit, these dual VNH2SP30 motor driver carriers are perfect for you. With these boards, it’s easy to get a medium-sized, differential drive robot running in no time.
> Note: The...

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/5/8/f/58f0c9d8508089d5544b18e5729be355c5a98396.jpeg)

In an attempt to understand DC motor control, I developped two source codes

The first one is real basic, giving motion control:

- forward(power)
- backward(power)
- stop()

power parameter beeing the PWM value (0-255) sent to the motor

```arduino
// MD03A_Motor_basic
// Test MD03a / Pololu motor

#define InA1 10 // INA motor pin
#define InB1 11 // INB motor pin 
#define PWM1 6 // PWM motor pin

void setup() {
  pinMode(InA1, OUTPUT);
  pinMode(InB1, OUTPUT);
  pinMode(PWM1, OUTPUT);
}

void loop() {
  motorForward(200); //(25%=64; 50%=127; 100%=255)
  delay(5000);

  motorStop();
  delay(2000);

  motorBackward(200);
  delay(5000);
}

void motorForward(int PWM_val) {
  analogWrite(PWM1, PWM_val);
  digitalWrite(InA1, LOW);
  digitalWrite(InB1, HIGH);
}

void motorBackward(int PWM_val) {
  analogWrite(PWM1, PWM_val);
  digitalWrite(InA1, HIGH);
  digitalWrite(InB1, LOW);
}

void motorStop() {
  analogWrite(PWM1, 0);
  digitalWrite(InA1, LOW);
  digitalWrite(InB1, LOW);
}

```

The "full blown" gives PID control over speed parameter, pretty much as the "Cruse Control" feature found on modern cars.  
When mechanicaly loaded, the system will increase PWM in an attempt to maintain "actual speed" at "target speed" level.  
This is the only way to run at low speed (20 RPM) while maintaining a high torque  
"Actual speed" is computed based upon the encoder informations, acquired in an interrupt routine.  
Voltage ("low bat" warning) and current (overheating) are also continuously monitored  
Speed and direction of rotation are adjustable through computer keyboard

```arduino
// Test MD03a / Pololu motor with encoder
// speed control (PI), V & I display
// Credits:
// Dallaby http://letsmakerobots.com/node/19558#comment-49685
// Bill Porter http://www.billporter.info/?p=286
// bobbyorr (nice connection diagram) http://forum.pololu.com/viewtopic.php?f=15&t=1923

#define InA1 10 // INA motor pin
#define InB1 11 // INB motor pin 
#define PWM1 6 // PWM motor pin
#define encodPinA1 3 // encoder A pin
#define encodPinB1 8 // encoder B pin
#define Vpin 0 // battery monitoring analog pin
#define Apin 1 // motor current monitoring analog pin

#define CURRENT_LIMIT 1000 // high current warning
#define LOW_BAT 10000 // low bat warning
#define LOOPTIME 100 // PID loop time
#define NUMREADINGS 10 // samples for Amp average

int readings[NUMREADINGS];
unsigned long lastMilli = 0; // loop timing 
unsigned long lastMilliPrint = 0; // loop timing
int speed_req = 300; // speed (Set Point)
int speed_act = 0; // speed (actual value)
int PWM_val = 0; // (25% = 64; 50% = 127; 75% = 191; 100% = 255)
int voltage = 0; // in mV
int current = 0; // in mA
volatile long count = 0; // rev counter
float Kp = .4; // PID proportional control Gain
float Kd = 1; // PID Derivitave control gain

void setup() {
  analogReference(EXTERNAL); // Current external ref is 3.3V
  Serial.begin(115600);
  pinMode(InA1, OUTPUT);
  pinMode(InB1, OUTPUT);
  pinMode(PWM1, OUTPUT);
  pinMode(encodPinA1, INPUT); 
  pinMode(encodPinB1, INPUT); 
  digitalWrite(encodPinA1, HIGH); // turn on pullup resistor
  digitalWrite(encodPinB1, HIGH);
  attachInterrupt(1, rencoder, FALLING);
  for(int i=0; i<NUMREADINGS; i++) readings[i] = 0; // initialize readings to 0

  analogWrite(PWM1, PWM_val);
  digitalWrite(InA1, LOW);
  digitalWrite(InB1, HIGH);
}

void loop() {
  getParam(); // check keyboard
  if((millis()-lastMilli) >= LOOPTIME) { // enter tmed loop
    lastMilli = millis();
    getMotorData(); // calculate speed, volts and Amps
    PWM_val= updatePid(PWM_val, speed_req, speed_act); // compute PWM value
    analogWrite(PWM1, PWM_val); // send PWM to motor
  }
  printMotorInfo(); // display data
}

void getMotorData() { // calculate speed, volts and Amps
static long countAnt = 0; // last count
  speed_act = ((count - countAnt)*(60*(1000/LOOPTIME)))/(16*29); // 16 pulses X 29 gear ratio = 464 counts per output shaft rev
  countAnt = count;                  
  voltage = int(analogRead(Vpin) * 3.22 * 12.2/2.2); // battery voltage: mV=ADC*3300/1024, voltage divider 10K+2K
  current = int(analogRead(Apin) * 3.22 * .77 *(1000.0/132.0)); // motor current - output: 130mV per Amp
  current = digital_smooth(current, readings); // remove signal noise
}

int updatePid(int command, int targetValue, int currentValue) { // compute PWM value
float pidTerm = 0; // PID correction
int error=0;                                  
static int last_error=0;                             
  error = abs(targetValue) - abs(currentValue); 
  pidTerm = (Kp * error) + (Kd * (error - last_error));                            
  last_error = error;
  return constrain(command + int(pidTerm), 0, 255);
}

void printMotorInfo() { // display data
  if((millis()-lastMilliPrint) >= 500) {                     
    lastMilliPrint = millis();
    Serial.print("SP:"); Serial.print(speed_req);  
    Serial.print(" RPM:"); Serial.print(speed_act);
    Serial.print(" PWM:"); Serial.print(PWM_val);  
    Serial.print(" V:"); Serial.print(float(voltage)/1000,1);
    Serial.print(" mA:"); Serial.println(current);

    if (current > CURRENT_LIMIT) Serial.println(" ***CURRENT_LIMIT***");                
    if (voltage > 1000 && voltage < LOW_BAT) Serial.println(" ***LOW_BAT***");                
  }
}

void rencoder() { // pulse and direction, direct port reading to save cycles
  if (PINB & 0b00000001) count++; // if(digitalRead(encodPinB1)==HIGH) count ++;
  else count--; // if (digitalRead(encodPinB1)==LOW) count --;
}

int getParam() {
char param, cmd;
  if(!Serial.available()) return 0;
  delay(10);                  
  param = Serial.read(); // get parameter byte
  if(!Serial.available()) return 0;
  cmd = Serial.read(); // get command byte
  Serial.flush();
  switch (param) {
    case 'v': // adjust speed
      if(cmd=='+') {
        speed_req += 20;
        if(speed_req>400) speed_req=400;
      }
      if(cmd=='-') {
        speed_req -= 20;
        if(speed_req<0) speed_req=0;
      }
      break;
    case 's': // adjust direction
      if(cmd=='+'){
        digitalWrite(InA1, LOW);
        digitalWrite(InB1, HIGH);
      }
      if(cmd=='-') {
        digitalWrite(InA1, HIGH);
        digitalWrite(InB1, LOW);
      }
      break;
    case 'o': // user should type "oo"
      digitalWrite(InA1, LOW);
      digitalWrite(InB1, LOW);
      speed_req = 0;
      break;
    default: 
      Serial.println("???");
    }
}

int digital_smooth(int value, int *data_array) { // remove signal noise
static int ndx=0;                                                         
static int count=0;                          
static int total=0;                          
  total -= data_array[ndx];               
  data_array[ndx] = value;                
  total += data_array[ndx];               
  ndx = (ndx+1) % NUMREADINGS;                                
  if(count < NUMREADINGS) count++;
  return total/count;
}

```

Credits: (Inspiration rarely comes from the Vacuum) 😉  
Dallaby [http://letsmakerobots.com/node/19558#comment-49685](http://letsmakerobots.com/node/19558#comment-49685)  
Bill Porter [SAGAR Update, New Motor Controller and Motors « The Mind of Bill Porter](http://www.billporter.info/?p=286)

Anyone feeling like buildind a library ??  
Enjoy

---

<div class="post-metadata">

**Author:** ![kas](https://avatars.discourse-cdn.com/v4/letter/k/a88e57/32.png) [@kas](https://forum.arduino.cc/u/kas)\
**Post date:** [August 28, 2010, 2:32pm UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/2 "2010-08-28T14:32:26Z")

</div>

Finally, this source code moves the motor to a specific position, based on encoder counts number:  
moveMotor(FORWARD, speed, encoder\_ticks); // direction, PWM, ticks number  
The DC motor now beheaves as a stepper motor

```arduino
// MD03A_Motor_basic + encoder

#define InA1 10 // INA motor pin
#define InB1 11 // INB motor pin 
#define PWM1 6 // PWM motor pin
#define encodPinA1 3 // encoder A pin
#define encodPinB1 8 // encoder B pin

#define LOOPTIME 100 // PID loop time
#define FORWARD 1 // direction of rotation
#define BACKWARD 2 // direction of rotation

unsigned long lastMilli = 0; // loop timing 
unsigned long lastMilliPrint = 0; // loop timing
long count = 0; // rotation counter
long countInit;
long tickNumber = 0;
boolean run = false; // motor moves

void setup() {
  pinMode(InA1, OUTPUT);
  pinMode(InB1, OUTPUT);
  pinMode(PWM1, OUTPUT);
  pinMode(encodPinA1, INPUT); 
  pinMode(encodPinB1, INPUT); 
  digitalWrite(encodPinA1, HIGH); // turn on pullup resistor
  digitalWrite(encodPinB1, HIGH);
  attachInterrupt(1, rencoder, FALLING);
}

void loop() {
  moveMotor(FORWARD, 50, 464*2); // direction, PWM, ticks number
  delay(3000);
  moveMotor(BACKWARD, 50, 464*2); // 464=360°
  delay(3000);
}

void moveMotor(int direction, int PWM_val, long tick) {
  countInit = count; // abs(count)
  tickNumber = tick;
  if(direction==FORWARD) motorForward(PWM_val);
  else if(direction==BACKWARD) motorBackward(PWM_val);
}

void rencoder() { // pulse and direction, direct port reading to save cycles
  if (PINB & 0b00000001) count++; // if(digitalRead(encodPinB1)==HIGH) count_r ++;
  else count--; // if (digitalRead(encodPinB1)==LOW) count_r --;
  if(run)  
    if((abs(abs(count)-abs(countInit))) >= tickNumber) motorBrake();
}

void motorForward(int PWM_val) {
  analogWrite(PWM1, PWM_val);
  digitalWrite(InA1, LOW);
  digitalWrite(InB1, HIGH);
  run = true;
}

void motorBackward(int PWM_val) {
  analogWrite(PWM1, PWM_val);
  digitalWrite(InA1, HIGH);
  digitalWrite(InB1, LOW);
  run = true;
}

void motorBrake() {
  analogWrite(PWM1, 0);
  digitalWrite(InA1, HIGH);
  digitalWrite(InB1, HIGH);
  run = false;
}

```

For the Pololu VNH2SP30 motor driver users:  
What is your experience with the motor Amp monitoring (CS)?  
I find the signal _very_ noisy...

The balancing robot under construction  
[![](https://europe1.discourse-cdn.com/arduino/original/4X/a/b/5/ab5cc2412b0a2993b1ad7f1dde4af8cb3e6e3431.jpeg)](http://imgur.com/CQbTH.jpg)

I will report on progress

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 31, 2010, 6:35am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/3 "2010-08-31T06:35:41Z")

</div>

This is off to a great start! I'll be interested in how it goes. How long do you have to complete this project?

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 31, 2010, 7:30pm UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/4 "2010-08-31T19:30:28Z")

</div>

This is a very cool project, I was thinking about doing something like it myself.

EDIT: Nevermind, I'm completely retarded for not knowing what an encoder is.

Anyway, I can't wait for progress.

---

<div class="post-metadata">

**Author:** ![kas](https://avatars.discourse-cdn.com/v4/letter/k/a88e57/32.png) [@kas](https://forum.arduino.cc/u/kas)\
**Post date:** [September 4, 2010, 6:01pm UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/5 "2010-09-04T18:01:13Z")

</div>

Robot body is nearly finished, waiting for the 12V battery to be placed on the top

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/6/e/e/6eee5733aaccef5b192b0c2ebad20f019d3672ac.jpeg)

Angle measurement is performed with a 5 DOF IMU (2 axis Gyroscope + 3 axis accelerometer)

> **[IMU Analog Combo Board - 5 Degrees of Freedom IDG500/ADXL335 - SEN-09268 -...](https://www.sparkfun.com/products/retired/9268)**
>
> \*\*Replacement:\*\*\[SEN-11072\](http://www.sparkfun.com/products/11072). This brave warrior was laid to rest during the \[SparkFun Viking Funeral\](http://www.sp

The sensors board is located between the wheels, near the rotation axis

Actually motor encoding is not required for balancing.  
This feature can be added later on to prevent robot from drifting forward or backward

Here is the pseudo code for the balancing process:

loop (fixed time loop 10ms = 100Hz)

- sensors aquisition, smoothing and zeroing
- Acc angle (degrees) and Gyro rate (degrees per second) calculation and scaling
- Acc and Gyro data fusing though Kalman algorithm
- PWM calculation using a PID control algorithm
- PWM feeding to DC motors  
endLoop

Before tackling next step, make sure that previous data is OK  
we all know: Garbage in ... 😉

The actual loop will look like that:

```arduino
void loop() {
// *********************Sensor aquisition & filtering*******************
  updateSensors();
  ACC_angle = angleDeg(); // in degrees
  GYRO_rate = rateDegPerSec(); // in degrees/seconds
  actAngle = kalmanCalculate(ACC_angle, GYRO_rate, lastLoopTime); // calculate Absolute Angle

// ***********************Angle Control and motor drive*****************
  drive = updatePid(setPoint, actAngle); // PID algorithm

  if(actAngle>(setPoint-20) && actAngle<(setPoint+20)) Drive_Motor(drive); 
  else Drive_Motor(0); // stop motors if situation is hopeless
  
// *********************Debug info**********************************  
// SerialOut_timing();
// SerialOut_raw();
// SerialOut_sensor();
    SerialOut_labView();
  
// ***********************loop timing control**************************
  lastLoopUsefulTime = millis()-loopStartTime;
  if(lastLoopUsefulTime<STD_LOOP_TIME) delay(STD_LOOP_TIME-lastLoopUsefulTime);
  lastLoopTime = millis() - loopStartTime;
  loopStartTime = millis();
}

```

Further readings:

wheel encoder: [http://www.mindspring.com/~tom2000/Delphi/Codewheel.html](http://www.mindspring.com/~tom2000/Delphi/Codewheel.html)  
Kalman filter: [Kalman filter - Wikipedia](http://en.wikipedia.org/wiki/Kalman_filter)  
PID conrol: [PID controller - Wikipedia](http://en.wikipedia.org/wiki/PID_controller)  
those documents are "hard theory" and do not need to be fully understood for implementing the project

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [September 5, 2010, 4:15am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/6 "2010-09-05T04:15:57Z")

</div>

Hi kas,  
what does "Acc" mean?.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [September 5, 2010, 8:47am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/7 "2010-09-05T08:47:18Z")

</div>

> what does "Acc" mean?.

Maybe Accelermeter?

---

<div class="post-metadata">

**Author:** ![kas](https://avatars.discourse-cdn.com/v4/letter/k/a88e57/32.png) [@kas](https://forum.arduino.cc/u/kas)\
**Post date:** [September 5, 2010, 1:35pm UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/8 "2010-09-05T13:35:27Z")

</div>

Accelerometers are used to sense both static (gravity) and dynamic (sudden starts/stops) acceleration - in m/s² or g.  
Gyroscopes measure angular velocity, how fast something is spinning about an axis - in RPM, or degrees per second.  
Accelerometer data are noisy, Gyros tend to drift; the combination (data fusing) gives usable information

See: [http://www.sparkfun.com/commerce/tutorial\_info.php?tutorials\_id=167](http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=167)

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [September 6, 2010, 1:11pm UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/9 "2010-09-06T13:11:05Z")

</div>

how high does your little car? ;D

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [September 7, 2010, 10:14pm UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/10 "2010-09-07T22:14:03Z")

</div>

How are things going with your project Kas?

---

<div class="post-metadata">

**Author:** ![kas](https://avatars.discourse-cdn.com/v4/letter/k/a88e57/32.png) [@kas](https://forum.arduino.cc/u/kas)\
**Post date:** [September 9, 2010, 4:40pm UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/11 "2010-09-09T16:40:51Z")

</div>

haha97: 33cm (13")  
Gibby623: I received my 3800mAh 12V Battery, the robot will (should) balance this weekend

Here is a comparaison between the raw accelerator angle (red) and the Kalman filtered angle (blue)  
The smoothing effect is impressive :o  
[P1020588 - YouTube](http://www.youtube.com/v/H5Drlqv1t3s)?

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [September 10, 2010, 12:27am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/12 "2010-09-10T00:27:28Z")

</div>

Hi kas,  
where did the graph display s/w (in the youtube video) come from?

---

<div class="post-metadata">

**Author:** ![kas](https://avatars.discourse-cdn.com/v4/letter/k/a88e57/32.png) [@kas](https://forum.arduino.cc/u/kas)\
**Post date:** [September 11, 2010, 5:23am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/13 "2010-09-11T05:23:39Z")

</div>

This is a simple custom development in LabView.  
The Arduino sends 2 integers separated by a comma

```cpp
void serialOut_labView() {
  Serial.print(Angle + 512);           Serial.print(",");         // in Quids
  Serial.print(ACC_angle + 512);       Serial.print("\n");
}

```

Data can be sent alternatively to IDE serial monitor or to LabView

Angles are scaled in Quids (360° = 2 PI = 1024 Quids)  
This unit is convenient and can be manipulated as integer while retaining a good resolution

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [September 11, 2010, 5:40am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/14 "2010-09-11T05:40:03Z")

</div>

Can you explain combining the accelerometer values and gyro values with a little more detail?

---

<div class="post-metadata">

**Author:** ![kas](https://avatars.discourse-cdn.com/v4/letter/k/a88e57/32.png) [@kas](https://forum.arduino.cc/u/kas)\
**Post date:** [September 11, 2010, 6:47am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/15 "2010-09-11T06:47:42Z")

</div>

> I know you are going to get swarmed for your code for the Kalman, but I am really struggling getting this to work. Can you detail how you went about this? Was the programming intensive? ...

Hi Gibby623, sorry, I just got your PM's  
If your robot rolls about the x axis, you only need GYR\_X, ACC\_Y and ACC\_Z  
I notice that signal quality is much better when the sensor is upward, apparently, the IMU does not appreciate to be up side down  
I will publish the full code pretty soon

here is the Kalman module:

```arduino
// Kalman filter module

 float Q_angle  =  0.001;
 float Q_gyro   =  0.003;
 float R_angle  =  0.03; 

 float x_angle = 0;
 float x_bias = 0;
 float P_00 = 0, P_01 = 0, P_10 = 0, P_11 = 0;      
 float dt, y, S;
 float K_0, K_1;

  float kalmanCalculate(float newAngle, float newRate,int looptime) {
    dt = float(looptime)/1000;                                  
    x_angle += dt * (newRate - x_bias);
    P_00 +=  - dt * (P_10 + P_01) + Q_angle * dt;
    P_01 +=  - dt * P_11;
    P_10 +=  - dt * P_11;
    P_11 +=  + Q_gyro * dt;
    
    y = newAngle - x_angle;
    S = P_00 + R_angle;
    K_0 = P_00 / S;
    K_1 = P_10 / S;
    
    x_angle +=  K_0 * y;
    x_bias  +=  K_1 * y;
    P_00 -= K_0 * P_00;
    P_01 -= K_0 * P_01;
    P_10 -= K_1 * P_00;
    P_11 -= K_1 * P_01;
    
    return x_angle;
  }

```

The function parameters:

- newAngle = ACC\_angle (Accelerometers angle)
- newRate = GYRO\_rate (Gyro angle rate)
- looptime = lastLoopTime (time between sensors measurement)

More info this week end, lets keep it public

---

<div class="post-metadata">

**Author:** ![kas](https://avatars.discourse-cdn.com/v4/letter/k/a88e57/32.png) [@kas](https://forum.arduino.cc/u/kas)\
**Post date:** [September 14, 2010, 9:50am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/16 "2010-09-14T09:50:24Z")

</div>

It's balancing (at first try) 🙂 🙂 🙂

 ![](https://europe1.discourse-cdn.com/arduino/original/4X/7/6/1/761202893ba2bf5f4f4d430c454f6f426f9798e4.jpeg)

See it live: [Balancing robot - YouTube](http://www.youtube.com/v/pC6yeyDunJg)?

As soon as I install the battery on top (charger still not received), I will open a new thread with a more relevant title

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [September 14, 2010, 11:45am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/17 "2010-09-14T11:45:32Z")

</div>

This is freaking awesome!!! Congratulations!

I was so busy with my other projects that I neglected my balancing robot (I bought smaller motors and same Pololu wheels, they plug in directly on the motor shaft). I have a 2 axis accelerometer and a one axis gyro, do you think it will suffice or should I get a 5 axis IMU?

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [September 15, 2010, 1:59am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/18 "2010-09-15T01:59:46Z")

</div>

That is amazing, why is mine so bad... Sigh... What controller are you using for he wheels?

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [September 15, 2010, 5:12am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/19 "2010-09-15T05:12:37Z")

</div>

// Kalman filter module  
float Q\_angle = 0.001;  
float Q\_gyro = 0.003;  
float R\_angle = 0.03;

Hi Kas, awesome work on the project! My mate at uni was showing this to me today looks cool, great progress!

I am also working with an IMU a 6dof one and just wondering for your kalman filter above, how did you find the covariance matrices for measurement error and process error? lke what did you do and stuff?  
Because im upto that aswell, i have my state space of the kalman filter, just dont understand how to get the covariance matrix.  
Any help would be appreciated.

Thanks!!

---

<div class="post-metadata">

**Author:** ![kas](https://avatars.discourse-cdn.com/v4/letter/k/a88e57/32.png) [@kas](https://forum.arduino.cc/u/kas)\
**Post date:** [September 15, 2010, 7:17am UTC](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716/20 "2010-09-15T07:17:00Z")

</div>

Hi Ro-Bot-X, nice to see you around 😉

I hope your robot will balance soon  
Two axis accelerometer & one axis gyro are OK for the job  
If you use separate breakout boards, make sure that axis are orthogonal, you may end up having the gyro board being perpendicular to the main board.  
Also sensors units should match, don't fuse radian with deg/sec in your code  
Finally the backlash we talked about is noticiable, but manageable

Please keep me informed of your progress, here  
or there [http://letsmakerobots.com/node/19558](http://letsmakerobots.com/node/19558)

[Next page](https://forum.arduino.cc/t/dc-motor-control-with-pid/8716.md?page=2)
