Poll
Question: I will need help with my project ?
With the programing part - 47 (58%)
With the DC motors - 34 (42%)
Total Voters: 26

Pages: 1 ... 13 14 [15] 16   Go Down
Author Topic: Balancing robot for dummies  (Read 136233 times)
0 Members and 2 Guests are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm trying to use the Kalman code described in this thread. When the angle of my bot changes rapidly, the filter can take 10 cycles to settle. In other words, the computed angle lags the accelerometer angle by as much as 10 cycles. This is making my bot slow to respond. Is this lag normal? Is there anything I can do to speed up the response?

Thanks!
Osman
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@osmaneralp

I had something simulare but i found that I had the wrong value when setting the scaling of the gyro rate. Check in the data sheet for you sensor what the sensitivity is for mV/(deg/sec)

Code:
int getGyroRate() {                                             // ARef=3.3V, Gyro sensitivity=2mV/(deg/sec)
  return int(sensorValue[GYR_Y] * 4.583333333);                 // in quid/sec:(1024/360)/1024 * 3.3/0.002)
}

Also it's important that you have a good value on the ACC_Z and it should be equal when having it standing as up side down...
Quote
For ACC_Z, gravity correction = (0° value - 180° value)/2
Quote
2 – Zeroing sensor
Before aquiring data in the loop, sensors should be zeroed
This means that when the bot is stricly still and vertical, sensors should read “0[ch8243]
except for the vertical axis (Acc_Z), which is sensing gravity (1g)
Zero mesurement is performed in setup:
Code:
void calibrateSensors() {                                 // Set zero sensor values
  long v;
  for(int n=0; n<3; n++) {
    v = 0;
    for(int i=0; i<50; i++)       v += readSensor(n);
    sensorZero[n] = v/50;
  }
  sensorZero[ACC_Z] -= 102;
}
calibrateSensors() is a one off action, so we have time to average 3 X 50 measurements
Finally, gravity value is deducted to Acc_Z
For ADXL330/335: 1g = 330 mV (+- 10%)
ACC_Z correction for 10 bit ADC and 3.3V AREF: 330/3300*1024 = 102 (to be fine tuned later on)

Hope you find the problem.. What sensor are you using?
« Last Edit: January 13, 2011, 09:42:11 am by X-firm » Logged

The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have now gotten my BlueSmirf and the other parts I was missing to be able to complete my bot.

I tried the wireless communication at 115200 bps and it worked right out of the box. Very happy with it and maybe now I can finalize the bot and the Balancing Bot GUI 2.0..

I have gotten the speed of the communication between the bot and GUI to a acceptable level. I have split ed the data in five groups and each group is sent each fifth loop..

I will post some images and a video on the interface and robot in the end of the week hopefully..  :-/
Logged

The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Patrik

Thanks for the suggestion. I'll look more closely at the gyro. I'm using an LPY510AL connected to a MCP3302 13-bit a2d converter. I went with an external a2d to try to get more accuracy. Whether or not I need the extra resolution is not yet clear. I can explain how to connect the a2d to get all 13 bits of resolution if anyone's interested.

I'm using the 4X out instead of the 1X out from the gyro. Anyone know if this is a good idea? The 4X out gives 10mv/deg/sec. The a2d has 8096 units in a 2.48v range. That's about 0.3mv/unit. So each a2d unit represents 0.03 deg/s or 0.085 quid/s. This is quite different from the 4.58 quid/s used in this thread. Does this mean I will have to change the kalman matrix parameters?  :-/

The accelerometer is built into the Chumby that also contains the ARM processor which is the brains of my bot. I'm getting good symetrical readings from the acc, so I don't think that's my problem.

Here's a picture of my bot:


--Osman
« Last Edit: January 14, 2011, 12:11:51 pm by osmaneralp » Logged

Toronto, Canada
Offline Offline
Full Member
***
Karma: 0
Posts: 144
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So cute! And it's blue! I love it!
Logged


Toronto, Canada
Offline Offline
Full Member
***
Karma: 0
Posts: 144
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Guys, I have a question, since I won $40 loyalty from SF, I want to get a new IMU board. Question is: should I get the recommended 5DOF IMU ($44.95) OR should I get the new 6DOF IMU that uses I2C ($64.95)?
The advantage of the last one being freeing the analog pins so I can use pots to fine tune the PID and perhaps a better accuracy. But is I2C fast enough in this case? Also the acc-meter has 2 interrupt output pins that you can program to trigger when falling too fast or when new measurement is ready, etc.
Logged


0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@osmaneralp

I'm using a similar sensor I think and it's running in 4X mode. I got the following gyro rate as below but then I use a Arduino analog port directly.

Quote
I'm using a nother GYR called LPR510AL and that one has a sensitivity of 10 mV/(°/s) at ±100°/s. ( and it's running in 4X mode)

It looks like I have made a miss calculation where it should have been:  

// ARef=3.3V, Gyro sensitivity=10mV/(deg/sec)
// in quid/sec:(1024/360)/1024 * 3.3/0.010)
return int((sensorValue[GYR_Y] * 0,9166679)*-1);

Measurement range:       ±100°/s and ±400°/s
Sensitivity:       10 mV/(°/s) and 2.5 mV/(°/s)


@Ro-Bot-X

I know to little about the SPI buss but I love the idea to getting the analog ports free. If you buy it and it works good I will defiantly go for one later on to..


« Last Edit: January 14, 2011, 02:46:45 am by X-firm » Logged

The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@kas
@osmaneralp
@Ro-Bot-X
@GuzZzt

I would like to have a page on the projects homepage with some example robots that has used this project to be able to build a balancing robot or something else...

If you feel that this project had helped you with your bot could you send me a link to a homepage or a build blog there you describe your bots and what components you have used. With some images and videos etc.

Otherwise send some text and the images and links to videos and I can make a page on my web server for the bot..
Logged

The balancing robot for dummies guide
http://www.x-firm.com/?page_id=145

0
Offline Offline
Sr. Member
****
Karma: 17
Posts: 395
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I got my hands on a free L298N H-Bridge: http://www.st.com/stonline/books/pdf/docs/1773.pdf
Unfortunately it only can handle spikes of 3 A (repetitive 2.5 A). Did you ever get an idea of what currents are used? I plan on making the bot relatively small...
I would take the motor stall current as the H-bridge amp requirement

Quote
Also, have you ever run into speed problems from the microcontroller? Is 16 MHz fast enough?
16 MHz is fast enough

Quote
My understanding was that the sensors act as the feedback to tell the motors direction and speed, so a motor encoder is not necessary. I see you made the same statement in your initial post.
You will get "basic" balance w/o encoders, but the bot will drift forward/backward




Quote
I have now gotten my BlueSmirf and the other parts I was missing to be able to complete my bot.
...
I will post some images and a video on the interface and robot in the end of the week hopefully..
Congratulation Patrik
I will also post my XBee version this week end smiley-wink smiley-wink



Logged

Toronto, Canada
Offline Offline
Full Member
***
Karma: 0
Posts: 144
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, I ordered the 6DOF IMU. It has I2C interface, not SPI. Standard speed is 100k/s, faster speed is 400k/s. To poll the sensor we need the Wire library, I have experience working with I2C sensors and I have 4 Arduinos on a robot linked through I2C interface. So, I hope it will work fine. The only thing I have a problem with is the 3.3V interface. I'll see what I can do. I think I need to use 4.7k pull up resistors tied to 3.3V instead of 5V. Also, the sensor needs 3.3V that I will get from the Arduino board directly (I still need to check the current requirements).

I will create a blog page with my attempt, although it did not work because of the design I tried just to see if it works. New version coming as soon as I will get the new IMU.
Logged


0
Offline Offline
Sr. Member
****
Karma: 17
Posts: 395
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

08:16 14/01/2011
@Osmaneram
Nice bot  smiley
I played with a MPC3208 ADC which is the 8 input version
As far as I remember, those are 12 bit ADC's with 4096 units (not 8096)  :o
Please clarify

Your IMU board may have a different noise pattern that may require specific Kalman filter tuning.
The ADC should not inpact Kalman tuning (it didn't on my setup)



@Ro-Bot-X
I am also tempted to go digital for several reasons
 - analogic is noisy by nature
 - additional features
 - this is the future...

I2C frequency is in the 100KHz range, don't be affraid
Please try it and let us know the outcome, we all need guinea pigs  smiley-wink smiley-wink
 

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I played with a MPC3208 ADC which is the 8 input version
As far as I remember, those are 12 bit ADC's with 4096 units (not 8096)  
Please clarify

@kas Good catch. I'm actually using a 3302, which is a four channel 13-bit differential input a2d. The extra bit compared to the 32xx parts is a sign bit. To take advantage of the sign bit, the a2d input voltage must swing above and below the a2d vref. If the vref of your arduino is tied to 3.3v, you the input voltage from the gyro will never go above vref, and so you only get 12 bits.

To get the full 13 bits, take the vref from the gyro, which on my gyro is 1.241v, and connect it to the vref on the a2d and channel 1 on the a2d. Take the vout from the gyro and connect it to channel 0 on the a2d. Configure the a2d to run in differential mode. This means that the a2d will compare channel 0 to channel 1. If the voltage on channel 0 is greater than the voltage on channel 1, the output of the a2d is positive and the sign bit is 0, otherwise the sign bit is 1 which indicates a negative value. In addition to the sign bit, there are 12 more bits of resolution. This means that you get 12 bits from 0 to vref, and another 12 bits from vref to 2 x vref. That's 13 bits effective resolution.

Whether or not all 13 bits will be useful is not yet clear!  :-/

--Osman
« Last Edit: January 14, 2011, 12:13:07 pm by osmaneralp » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 18
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Kas,

compliments for your great job and info.

I have terminated a self balancing robot very similar to your (same IMU), except for motors.

I used 6V HITEC HS-325HB hacked to run continuosly, but this motors are not enough for he job they have to do.

I tried to make the robot less high but it became too instable..

anyway I order the same Your Pololu equipment...waiting for shipment.

Two questions:

(1) in the setup, with the function calibrateSensors(); you have to put the robot (each time you switch it on) exactly in the static equilibrium position in order to evaluate zero values (exept for z).

is this a little bit boring and could produce errors (if it is not perfectly perpendicular)?

If during the calibrateSensors() i'll give a tilt, the Robot will work to keep the tilt!

maybe there is something that I cannot understand?

(2) what do You use to recharge the 12V batteries?


thanks,

bye,

Prof
« Last Edit: January 14, 2011, 01:35:07 pm by prof_jazz » Logged

0
Offline Offline
Sr. Member
****
Karma: 17
Posts: 395
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi prof_jazz, welcome  smiley
please let us have a photo of your new pet

Quote
I used 6V HITEC HS-325HB hacked to run continuosly, but this motors are not enough for he job they have to do
I also waste one year following this track  smiley-wink

Quote
(1) in the setup, with the function calibrateSensors(); you have to put the robot (each time you switch it on) exactly in the static equilibrium position in order to evaluate zero values (exept for z).
is this a little bit boring and could produce errors (if it is not perfectly perpendicular)?
If during the calibrateSensors() i'll give a tilt, the Robot will work to keep the tilt!
No No...
If you tilt the bot forward before calibrateSensors(), it will move forward and find a vertical equilibrium
This will happen only with encoder(s) implementation, look here

Quote
(2) what do You use to recharge the 12V batteries?
I ordered the battery charger shown here



Logged

0
Offline Offline
Sr. Member
****
Karma: 17
Posts: 395
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

       [size=14] ** Balancing robot for dummies **[/size]


[size=14]Part seven: Xbee wireless control, KasBot V 3.0[/size]

The objective is to obtain basic motion control (Forward/Backward, Stop Right/Left)
Xbee modules act as a serial line replacement, a USB cable without the cable smiley
See post #82 for more info


[size=14]1) controller side:[/size]

Shopping list at post #77
Transmitter with Nunchuck joystick controller is shown on post #107
The additional micro joystick and the 3 LED's will be used for advanced features wich are beyong the scope of this basic KasControl V1.0

Nunchuk_kas.h does take care of the I2C communication with the joystick
Code:
// Nunchuck_kas.h        joystick functions ----------------------------------------------------------------

#include "Wprogram.h"
#include <Wire.h>

static uint8_t nunchuck_buf[6];                             // array to store nunchuck data,

void nunchuck_init()  {
  Wire.begin();                                                  // join i2c bus as master
  Wire.beginTransmission(0x52);                                  // transmit to device 0x52
  Wire.send(0x40);                                        // sends memory address
  Wire.send(0x00);                                        // sends a zero.  
  Wire.endTransmission();                                  // stop transmitting
}

void nunchuck_send_request()  {                             // Send a request for data to nunchuck
  Wire.beginTransmission(0x52);                                  // transmit to device 0x52
  Wire.send(0x00);                                        // sends one byte
  Wire.endTransmission();                                  // stop transmitting
}
 
char nunchuk_decode_byte (char x)  {                         // Encode data to format that most wiimote drivers
  x = (x ^ 0x17) + 0x17;                                     // except only needed if you use one of the regular
  return x;                                                  // wiimote drivers
}

int nunchuck_get_data()  {                                   // Receive data back from the nunchuck
  int cnt=0;
  Wire.requestFrom (0x52, 6);                                  // request data from nunchuck
  while (Wire.available ()) {                               // receive byte as an integer
    nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
    cnt++;
  }
  nunchuck_send_request();                                  // send request for next data payload
  if (cnt >= 5)     return 1;                               // If we recieved the 6 bytes, then go print them
  return 0;                                                 // failure
}                                                           // returns 1 on success read, returns 0 on failure

int nunchuck_joyx()  {                                     // returns value of x-axis joystick
  return nunchuck_buf[0];
}

int nunchuck_joyy()  {                                     // returns value of y-axis joystick
  return nunchuck_buf[1];
}
This is a strip down version of the code that can be found in the Arduino Playground section.
We only use the joystick data, (we have enough accelerometers in this project  smiley-wink)
More info on wiring and code here

The main code uses a communication protocol based on 3 Bytes:
   controlByte = 'd'      (just says "hey, I am coming with new joystick data !!")
   dataByte_1 = value of y-axis joystick
   dataByte_2 = value of x-axis joystick

To reduce traffic, data is only sent when joystick is moved
Code:
// ** Kas Control V10     Balancing bot RC with nunchuk **  

// Yellow: Clock SCL (AI5)  Red: 3.3V  Green: Data SDA(AI4)  Write: Ground
// serial data format:   <controlByte> <dataByte_1> <dataByte_2> <CR>
// V1.0 basic control

#include <Wire.h>
#include "Nunchuck_kas.h"

int refreshTime = 100;                                    // time in millisecs between Nunchuck poolings
long lastPulse = 0;
char controlByte = 0;
char dataByte_1 = 0;                                      // joystick data
char dataByte_2 = 0;

void setup()  {
  Serial.begin(19200);
  nunchuck_init();                                         // send the initilization handshake
  delay(100);
  nunchuck_joyx();
  nunchuck_joyy();
}

void loop()  {
  if (millis() - lastPulse >= refreshTime) {                // x ms have passed
    checkNunchuck();
    lastPulse = millis();                                   // save the time of last pulse
  }
}

void checkNunchuck()  {
  static int Byte1_ant, Byte2_ant;
  nunchuck_get_data();
  controlByte = 'd';
  dataByte_1 = map(nunchuck_joyy(), 27, 218, 0, 40);        // nunchuck joystick North/South                    
  dataByte_2 = map(nunchuck_joyx(), 27, 218, 0, 40);        // nunchuck joystick East/West
  dataByte_1 = constrain(dataByte_1, 0, 40);                                
  dataByte_2 = constrain(dataByte_2, 0, 40);
  if((dataByte_1!=Byte1_ant)||(dataByte_2!=Byte2_ant))  {
    updateBot();
    Byte1_ant = dataByte_1;
    Byte2_ant = dataByte_2;
  }
}

void updateBot()    {                                       // send data stream
    Serial.print(controlByte);        
    Serial.print(dataByte_1);    
    Serial.print(dataByte_2);
    Serial.print("\n");
}

...........

« Last Edit: January 16, 2011, 01:29:52 am by kas » Logged

Pages: 1 ... 13 14 [15] 16   Go Up
Jump to: