Introduction: Another Easier Inverted Pendulum Robot
This is an improved version of my earlier instructable titled "A Simple and Very Easy Inverted Pendulum Balancing Robot". There are four advantages in this version.
- Easier to get a material
- Fewer materials needed
- Simpler program to balance itself
- Higher stability in balancing
I have published the original version in English and Japanese. I have gotten a considerable number of successful comments with videos (e.g. 1, 2, 3, 4, 5) to Japanese version but rare to English version. The first and the second points above are based on comments to the original version in English. These two improvements could eliminate a barrier from residents outside Japan. Under the introduction video below, some details for each these four points are described.
:
[Introduction Video]
:
(1) Digital Gyro Sensor
In the original version a gyro module with two analog output sensors (*1) is used. But outside Japan, it is not easy to get it or its equivalent product (*2). In this version a gyro module with a digital output sensor made by STMicroelectronics is used. It is easy to get it or its equivalent product either inside or outside Japan.
(*1) This analog output sensor has no constant value for the output at rest. Hence it is needed to measure the value of output in static state before balancing itself in the original version. But it is not needed in this version.
(*2) The gyro module used in the original version has angular acceleration contamination in angular velocity through its HPF. Therefore a fine soldering is required to cancel this contamination. However, it is not required in this improved version.
:
(2) Single Motor Driver IC
The inverted robot we would make here has two motors. In the original version two ICs drive them respectively. But in this version only an IC drives two motors.
:
(3) No Timer Library in Program
In the original version a timer library, Ms Timer2, is used in program for interrupt handling (*1). In this version no interrupt handling or no timer library is used in program (*2).
(*1) My original project was started with a numerical simulation on PC. The interrupt handling follows it.
(*2) See below.
:
(4) Noise Reduction Step in Program
In program, another revision is made also to reduce noise in output of gyro module (*2).
(*2) An alternative program with these revises was added to my original (earlier) instructable.
:
In following steps I will not avoid the same statements described in the original version to make this instractable a complete one.
* A Japanese version for this instructable is available.
Step 1: Gather Materials
Body (using TAMIYA's Educational Construction Series)
- A Universal Plate Set (2pcs.)
- A Universal Arm Set
- A Double Gearbox (Left/Right Independent 4-Speed, two DC motors included)
- A Slim Tire Set (36mm, 55mm Dia.)
Electrics
- An Arduino UNO
- A small solderless breadboard
- Some jumper wires
- A motor driver IC (STMicroelectoronics L298N)
- A gyro module (Akizuki-denshi AE-L3DG20: sensor L3GD20 on this module)
- Four AA batteries
- A 4AA battery holder
- A 9V battery (PP3)
- Two battery snaps
- Some rubber bands
:
[Tutorial for Step1]
:
[Commentary for Gyro Module]
Here a digital output gyro module is used instead of analog output one. This module is a L3GD20 carrier. The detail of L3GD20 is described subsequently. I have encountered with some troubles below while using it. So I recommend you to get 2 or 3 modules at once to isolate the problem.
:
(1) Inconsistent Sign of Gyro Output
I have tried two gyro modules with same model number alternatively to know individual difference of the module. Both of them are made by Akizuki-Denshi and they are L3GD20 carriers. I was surprised that signs of output of them are different around two axes. Therefore "R + ry" might have to be rewritten to "R - ry" in the line "DL29" in the program in Step 5.
:
(2) Abnormal Output of Gyro
A digital gyro module used here would begin to output strange data for some reason (*1). In that case, try to disconnect power supply to module or Arduino. If that fails, once upload a very simple program with the module to Arduino (*2), and upload the program for an inverted robot again.
(*1) I have seen non-zero value in a still state or constant value in motion, though I do not know the causes of them well.
(*2) The simple program is shown in the pdf file "dgtlGYRO_L3GD20_SPI_recover.pdf" attached to the end of Step 5.
:
(3) Equivalent or Alternative Gyro Module
In this instructable, a digital gyro module AE-L3GD20 made by Akizuki-Denshi is used as a carrier board for the L3GD20 three-axis gyroscope provided STMicroelectronics. It could be replaced by a near-equivalent module "item #: 2125" made by Pololu (*1), which is a carrier for the same gyroscope L3GD20. Outside Japan, it would be easier to get the latter. Pin mapping between each module and Arduino is shown below (*2).
- (Function: Pin of Akizuki's, [Pin of Pololu's], {Pin of Arduino})
- VIN: #1, [VIN], {3.3V}
- GND: #8, [GND], {GND}
- SPC: #2, [SCL], {D13}
- SDI: #3, [SDA], {D11}
- SDO: #4, [SDO], {D12}
- CS: #5, [CS], {D10}
(*1) I have not gotten or tried the Pololu's module. I do not know well the attaching direction of L3GD20 chip to the board of the Pololu's module. In this instructable with Akizuki's module, the angle around Y-axis is measured to balance. But when the Pololu's is used, other axis (X or Z) might be measured or sign of output might be inverted. If such the differences are recognized, the program in Step 5 should be corrected.
(*2) Pololu's module has not only VDD pin but also VIN pin. It is described in its website, "Never supply voltage to VDD when VIN is connected, and never supply more than 3.6 V to VDD".
Step 2: Solder Wires to Some Components
First you should solder wires and pins to some electrical components.
- Solder wire to each point of 2 motors (4 points in all)
- Cut 4 jumper wires in half (8 half jumpers gotten)
- Solder these half jumpers to 8 wires of 2 motors and 2 battery snaps
- Cover each point soldered with chip of tape for insulation
- Solder header pins to an Akizuki's gyro module
:
[Tutorial for Step2]
Step 3: Assemble the Body of Robot
To build the body of inverted robot, TAMIYA's Educational Construction Series are used.
- Make two V-shaped cuts to Universal Plate
- Attach 4 L-angles included in Universal Arm Set to this Plate
- Assemble Double Gearbox to make its gear ratio 114.7:1
- Set 2 motors with 4 wires in this Gearbox
- Attach this Gearbox to Universal Plate above
- Assemble Slim Tire Set (two 55mm Dia. wheels gotten)
- Install these wheels to shafts of Gearbox above
:
[Tutorial for Step3]
Step 4: Put Electrical Components Together
Put electrical components together and attach them to the body built in the former step. Then a robot without program is gotten.
- Referring to Note 1 below, adjust two lines of pins of motor driver IC (L298N) respectively
- Referring to the picture of breadboard above, plug a gyro module and motor driver IC into your breadboard
- Wind some rubber bands around the breadboard and attach it on the lower L-angles of body of robot
- According to a wiring diagram above, plug jumper wires into the breadboard
- Also plug both wires of the battery snap into breadboad, which will be connected to a 4AA battery holder
- Wind a small rubber band around Arduino and mount it on the upper L-angles of the body of robot
- According to a wiring diagram above, plug jumper wires into the pinholes of Arduino
- Insert four AA batteries to 4AA battery holder
- Wind a bigger rubber band around the body of robot and fix the battery holder to the back side of robot
:
[Tutorial for Step4]
:
[Note 1]
L298N should be plug into breadboard straddling over its center ditch. But two lines of pins of this IC are not fitted for this plugging. So we make two adjustments for these pins.
- Shorter pins: Shift the line of shorter pins to backside of IC by 2.5mm (making a wider distance to the line of longer pins)
- Longer pins: Shift the line of longer pins to right-hand side of IC by a little bit
:
[Note 2]
L298N has two pins (#1 and #15) to measure current flowing through each motor respectively. Here no current is measured. So both of them are connected to GND.
:
[Note 3]
The robot gotten here has no power switch. To turn on/off power, battery snap is connected/disconnected.
Step 5: Upload the Sample Sketch to Arduino
Using IDE, the sample Sketch for inverted robot is uploaded to Arduino.
- Connect Arduino to PC via a USB cable
- Disconnect the battery snap from 4AA battery holder
- Lay down robot on desktop or floor and leave it at rest
- Download (*) the pdf file attached to the next to the last line in this step (* You get a corrupted program if you open this file in web browser and copy its content)
- Open the file in proper reader and copy the whole of text in the file
- Paste the copy to IDE and correct misprints
- Upload corrected sketch to Arduino using IDE
:
[note 4]
To make an inverted pendulum balance itself, motor torque is controlled dynamically. This control method is expressed as a plane formula with 4 variables related to the state of pendulum.
"motor torque = k1 * angle of pendulum
+ k2 * angular velocity of pendulum
+ k3 * velocity of the lower end of pendulum
+ k4 * displacement of the lower end of pendulum from a reference point"
k1, k2, k3 and k4 are static coefficients with appropriate values. In a sample sketch in pdf file below, a long equation at line 72 expresses this formula. To make inverted robot balance itself, we have to select proper values for these 4 coefficients respectively and know right value of each of these 4 variables in real time.
The gyro sensor gives the second variable value, angular velocity of pendulum, dynamically by a 16-bit integer. And Arduino estimates the first variable value, angle of pendulum, contemporaneously by integrating the second variable.
On the other hand, the third or the fourth variable value cannot be measured by gyro sensor. So another kind of sensor or meter should be used to get them in real time. But our inverted robot has no more device than a gyro module. Thus it becomes a puzzle to estimate these 2 variables values dynamically. In a sample sketch in pdf file below, 2 masked equations at lines 76 and 77 should be used to estimate them. Here they are left masked not to spoil solving this puzzle.
:
[Note 5]
L3GD20 digital gyro sensor has three different measurement ranges; +/- 250dps, +/- 500dps and +/- 2000dps (dps: Degree per Second). This sensor outputs angular velocity as a 16bit integer. In this instructable the minimum range (+/- 250dps) is adopted, where a digit of output means 0.00875dps.
:
[Note 6]
The output of the gyro sensor is transmitted to Arduino by SPI interface. General technical discussion about SPI or wiring for it is not described here. If the gyro module made by Pololu were used instead of Akizuki’s one, see "(3) Equivalent or Alternative Gyro Module" [in Commentary for Gyro Module] in Step 1. I have not tried Pololu’s module. In the sample program attached to the end of this step, the angle around Y-axis is measured to balance. But when the Pololu's were used, other axis (X or Z) might be measured or sign of output might be inverted. For example, if the posture of robot were detected around X-axis of L3GD20 and sign of output is inverted, the right hand of line DL28 in the sample program should be rewritten “- ( (L3GD20_read(0x29) << 8) | L3GD20_read(0x28) )”.
:
[The Sample sketch (program) for inverted robot]
Copy whole text of "invertedRobot_v20d_noTimer.pdf" below, paste it to IDE and upload it to Arduino (**1-5).
(*1) Save the pdf file in your PC and open it in proper pdf-reader. Or you get a corrupted program by opening it in web-browser.
(*2) If "; //72" is not shown at the end of line 72, substitute whole a equation below for it. It is not the same as the original version.
powerScale = ( kAngle * thetaI / 100 ) + ( kOmega * omegaI / 100 ) + ( kSpeed * vE5 / 1000 ) + ( kDistance * xE5 / 1000 ); //72
(*3) Pasting the copy to IDE or editor, misprints such as "/ /" as "//" (an obstacle space inserted) might happen, then correct them.
(*4) The line number written in the sample sketch as comment (e.g. //DL2) is consistent with the earlier sketch ”invertedRobot.pdf” or ”invertedRobot_v20_noTimer.pdf” in the original version.
(*5) Copyright (C) 2015 ArduinoDeXXX All Rights Reserved.
:
[The sketch to restore L3GD20 carrier gyro module]
If the output of gyro module becomes strange, see "(2) Abnormal Output of Gyro" [in Commentary for Gyro Module] in Step 1. There two countermeasures are shown. The sketch used in the second measure, “dgtlGYRO_L3GD20_SPI_recover.pdf,” is attached to the last line of this step.
Step 6: Get an Inverted Following Robot
When the sample sketch uploaded to Arduino in the former step, you ought to get an inverted following robot. Though it needs your finger for standing, it follows your finger.
- After the upload finished, hold the body of your robot and pick it up (see picture 2)
- Connect battery snap to battery holder attached to the back side of robot
- Wheels of robot start spinning, hold both wheels tight and stop spinning (see picture 3)
- Set both wheels on desktop or floor and keep static standing to be made center of gravity of robot to be located on its wheel shafts
- After a few second, motor torque becomes down and faint noise or chirping "miii" is listened
- Then release your hands from robot gently (see picture 4) and put your finger on the top of the body of robot softly
- Move your finger forward and backward and see your robot following
- Release your finger and see your robot trying to balance but failing
:
[Tutorial for Step5 and 6]
:
[Note 7]
As turning on or resetting Arduino, the robot perceives its posture (angle of its body) and spins its wheels when the posture is changed. Then the robot has to study the proper posture in well inverted state. This robot is programmed that if it has been in static state for 0.05 seconds it deems itself well inverted.
Hence as its wheels starting spinning, you should hold both wheels tight and stop spinning. And execute line 4 to 8 above.
Further if you do not feel changes at line 5, torque down and faint noise of motors, for 10 seconds waiting, your gyro module might output wrong value temporarily or it might be inconsistent with the sample sketch in the former step.
In that case, you should see "(2) Abnormal Output of Gyro" [in Commentary for Gyro Module] in Step 1 first. And if you use some L3GD20 carrier other than Akizuki’s module, you should see "(3) Equivalent or Alternative Gyro Module" in Step 1 and Note 6 in Step 5 also.
:
[Troubleshooting 1]
If wheels of robot do not start spinning at line 3 above, some faulty wiring must be suspected first. Go back Step 4 and verify wiring carefully. Another doubt is a defective gyro module. If you suspect it, you should see "Commentary for Gyro Module" in Step 1.
On the other hand, if your robot does not follow your finger in spite of wheels starting spinning at line 3, three kinds of faulty wiring must be suspected: (1) Wires of a motor are set opposite, (2) Gyro module is set reversed, (3) Wiring to digital pins of Arduino is wrong. Go back Step 4 and verify wiring carefully.
Further if your gyro module outputs inconsistent value with the sample sketch in Step 5, your robot would not follow your finger despite correct wiring. If you suspect it, see "(1) Inconsistent Sign of Gyro Output" in Step 1. And if you use some L3GD20 carrier other than Akizuki’s module, you should see "(3) Equivalent or Alternative Gyro Module" in Step 1 and Note 6 in Step 5 also.
:
[Reference] Checking an Inverted Following Robot
Step 7: Challenge Yourself to Solve a Puzzle
Let's make your "following inversed robot" balance itself without your finger by modifying the sample sketch in Step 5. It might be a puzzle.
- Consider why it fails balancing
- Get plausible idea and modify the sample sketch
- Make your inverted robot try balancing
- If it balances itself you have solved a puzzle and your robot has become an inverted pendulum (Congratulation!)
- Or else turn back to line 1 or hesitate to see a solution in Step 8
Step 8: How to Get an Inverted Balancing Robot
Here you see how to get an inverted balancing robot. You need to modify only two lines in the sample sketch in Step 5.
- Copy 3 lines below and paste them over lines 76 and 77 in the sample sketch (overwriting them)
vE5 = sumPower; //76a
xE5 = sumSumP / 1000; //77a
// Copyright (C) 2014 ArduinoDeXXX All Rights Reserved.
- Execute Step 6 (without a finger support in lines 6 to 8)
- If center of gravity of robot is located on near its wheel shafts, your robot moves back and forward for a few seconds and gets well inverted posture
- See it keeps balancing itself
- If it moves with forward or backward bias, add to or submit from proper integer after "power" at the end of line 74 in the original sample sketch
:
[Tutorial for Step 8]
:
[Troubleshooting 2]
If your robot can not balance itself well in spite of executing Step 6 well, “low battery” in the battery holder on the back of robot should be suspected first. If it is not observed, constant values at lines 10 to 13 in the sample sketch should be changed. I think that line 12 is most critical.
Step 9: Operate Inverted Robot Via Serial Monitor
Now you have an inverted balancing robot. Then let’s control it by serial monitor. You could make it turn right/left and go forward/back.
- Update the modified sample program gotten in Step 8 according to the details below
- Upload the updated one to Arduino using IDE
- After the upload end, start serial monitor from IDE
- Select “Newline” and “115200 baud” at bottom right of serial monitor
- Make inverted robot balance itself according to Step 6 (without a finger support in lines 6 to 8)
- Input numerical values in upper left window of serial monitor and push the [Enter] key
- See action or change of action of your robot
:
[Tutorial for Step 9]
:
[Note 8]
You can control your robot dynamically by serial monitor from PC via USB cable. For example you input "00" in window of serial monitor and push the [Enter] key, then robot receive ‘0’ and ‘0’ separately. Hence it turns right at a regular angle below twice without stopping.
- A ‘0’ sent makes robot turn right at a regular angle on the spot
- A ‘1’ sent makes robot turn left at a regular angle on the spot
- A number (n) of ‘2’ sent make robot accelerate forward in proportion to the number (n)
- A number (n) of ‘3’ sent make robot accelerate backward in proportion to the number (n)
:
[Update on the sample sketch (for 4 places)]
(1) Copy the following 5 lines and paste them between lines 17 and 18 in the modified sketch gotten in Step 8.
int drct = 0;
boolean right = false;
boolean left = false;
int fwdBck = 0;
// Copyright (C) 2014 ArduinoDeXXX All Rights Reserved.
(2) Copy the following 26 lines and paste them over line 32 in the modified sketch gotten in Step 8, viz. substitute these lines for “if ( power > 0 ) {”.
if ( Serial.available() ) {
drct = Serial.read();
Serial.println(drct);
}
if( drct == 48 ) { right = true; }
else if ( drct == 49 ) { left = true; }
else if (drct == 50 ) { fwdBck++; drct = 0; }
else if (drct == 51 ) { fwdBck--; drct = 0; }
if ( right == true ) {
analogWrite( 6, 140 );
digitalWrite( 4, HIGH );
digitalWrite( 5, LOW );
analogWrite( 9, 140 );
digitalWrite( 7, LOW );
digitalWrite( 8, HIGH );
delay(40);
} else if ( left == true ) {
analogWrite( 6, 140 );
digitalWrite( 4, LOW );
digitalWrite( 5, HIGH );
analogWrite( 9, 140 );
digitalWrite( 7, HIGH );
digitalWrite( 8, LOW );
delay(40);
} else if ( power > 0 ) {
// Copyright (C) 2014 ArduinoDeXXX All Rights Reserved.
(3) Copy the following 4 lines and paste them between lines 55 and DL26 in the modified sketch gotten in Step 8.
drct = 0;
right = false;
left = false;
// Copyright (C) 2014 ArduinoDeXXX All Rights Reserved.
(4) Copy the following 2 lines and paste them over line 74 in the modified sketch gotten in Step 8, viz. substitute these lines for “sumPower = sumPower + power;”.
sumPower = sumPower + power + fwdBck * 4; // 74a
// Copyright (C) 2014 ArduinoDeXXX All Rights Reserved.
Step 10: Unplug the Cable
Substitute a battery (9V) for USB power (5V) for power supply to Arduino. Then Arduino is unplugged and your robot stands with no outer wire.
- Eject a USB cable from Arduino
- Connect the second battery snap to a battery (9V)
- Attach the battery to the back of robot by rubber band with a battery holder
- Plug the positive wire of this snap to Vin pin of Arduino
- Plug the negative wire of this snap to GND pin of Arduino
- Your robot starts spinning its wheels if the first snap is connected to battery holder
- Make your robot balance itself according to Step 6 (without a finger support in lines 6 to 8)
- See it stands with no outer wire as a completed inverted pendulum
:
[Tutorial for Step 10]
Step 11: Develop Robot Further
Let’s make your inverted robot or your knowledge evolve further. Here three ways are shown briefly. It would be hard to finish them within half a day.
:
(1) Remote Operation with No Wire
In Step 9 your robot is operated via USB cable. Now your robot is unplugged. So let’s operate it with no wire. In terms of simplicity, an infrared module would be the first choice.
:
[Demonstration of Operating Robot by a TV Remote]
:
(2) Simulating the Action of an Inverted Robot with Excel
Our inverted robot could be thought constructed from three parts: head, body and wheels. In this simplifying, an equation of motion of the robot can be written with a physics learned at High School. As getting it, the action of robot can be simulated using Excel. The near-proper values of two coefficients in Note 4 in Step 5, k1 and k2, could be gotten by this simulation.
:
(3) Capturing and Analyzing the Real Action of Inverted Robot
We can capture the state variables – posture and motion – of our robot in balancing. And it is possible to duplicate it on PC monitor in real time as a virtual 2D animation of balancing robot. Moreover, we can examine the effect of the sketch in detail by analyzing the time series of recorded state variables. An instructable in Japanese has been published, in which these capturing, duplicating and analyzing are described.
:
[Real Time 2D Animation by State Capturing]

Participated in the
Remix 2.0 Contest
23 Comments
6 years ago
Hi, Awesome tutorial. I'm really enjoying how much I'm able to learn by simply following along and building this recipe.
I've
ran into a problem though. I can't seem to get my robot to balance. In
STEP 6, it follows well, but in STEP 8, I can't get it to reliably
balance. I can only get it to balance for about 5 seconds every few
tries. I tried adjusting the k-values, but nothing seems to be doing the
trick.
Two things to notice: I'm using slightly thicker wheels
with the same radius approx (https://www.pololu.com/product/1686). Also,
my motor IC seems to be powering one motor faster than the other ever
so slightly. At full 255 PWM, the output from the IC is 1.1V for one
side and 0.8V for the the other.
Will the wheels chosen make a
great effect on the robots ability to balance? Even though I can
sometimes get the robot to balance, should I disassemble and replace the
motor IC? Any other help?
Thanks again for the tutorial and any help!
Reply 6 years ago
Hi,
I have received many messages and comments with “I made it!” to Japanese version of this article. Some of them use thicker wheels. On the other side, I have received several messages or comments also with “My robot cannot work well”.
Two typical mistakes have been seen in the latter cases: (1) wrong wiring in Step4 and (2) wrong activating for line 76 and 77 in the sample sketch in Step8.
The robot with wrong wiring cannot follow your finger in Step6. Hence I think your robot don’t have wrong wiring. And I think you can activate line 76 and 77 in the sample sketch well.
I think the output powers of driver IC are too low. At the full power, analogWrite = 255, the IC should supply 5-6V power to DC motor(s). See the top picture in Step4. Four serially connected AA batteries supply power to each motor via IC. Even a good robot cannot keep balancing, if the batteries are exhausted.
Reply 6 years ago
Thank you for the swift reply. I really appreciate how much time you're willing to put into helping random people like me.
So I tried testing all my Motor IC modules, and figured out a lesson in the process. I had assumed that my module (https://www.amazon.com/gp/product/B00XAGRQTO/ref=oh_aui_search_detailpage?ie=UTF8&psc=1) created a 5V reference on the board itself, and that I didn't need to connect 5V from the IC to the Arduino. Once I connected 5V to the IC however, I was able to achieve 6V at the motor out connection (assuming the motor wasn't connected)!
This fixed it! ...to an extent. My bot is balancing a lot better now, but not perfectly. It usually falls after 15 or twenty seconds. Also, even after plugging 5V to the IC, I'm still only achieving ~2.6V at the motors when the motors are connected and set to HIGH (255).
Any additional input? Maybe I just need to fuss with the k-values? Is my motor IC still acting strangely based on your experience?
Also, on a side note, do you have any recommendations for next step projects for learning PID and Arduino? [either by you, or by your recommendation?]
Reply 6 years ago
Now I check voltage supplied by three serially connected AA rechargeable (Ni-MH) batteries. I see 3.8V with no motor connected, and 3.6V with motor turning. I think your motor should get more than 4V when turning at full scale (analogWrite = 255).
Reply 6 years ago
Interesting. I'll drive deeper into troubleshooting this later today/tomorrow.
Even with this problem, I was able to toy with the k-values to get the robot standing! Thank you for an awesome tutorial. Very much appreciated. I plan to go through the bonus objectives over the next week as well (but I need to figure out IRControl first).
Do you have any recommendations for next step projects for learning PID, Motor Control and/or Arduino? [either by you, or by your recommendation?]
Reply 6 years ago
I have posted the third article to Instructables for advanced reader who has gotten her/his own inverted robot. Though it is written only in Japanese, you can find it in the site of Instructables.
You could read it in English using machine translation in web browser. Though I don’t know the performance of translating in Japanese to English, I think Google Chrome is good translating in English to Japanese.
Anyway, you can find many interesting projects in the site of Instructables or others. Enjoy!
Reply 6 years ago
The translation is surprisingly good, so thank you for this.
After a little more investigation, I still couldn't figure it out the low voltage at the motor IC, but after providing the rig with a 5xAA battery array I started getting much better results. I noticed that I'd usually get decent results with brand new batteries, but after just a minute or so, the performance would drop off (once the battery pack fell below 6V). Now I'm starting at 7.5V and working down to 6V (1.2x5) as the baseline.
The motor IC outputs 4.8V @ HIGH without a motor connected, but still ~3.6V with the motor connected at turning at HIGH.
Thanks again for the tutorial!
6 years ago
why did you put velocity and position equal to zero? how did you set up the K values? I am doing an inverted pendulum with another board (not arduino) and I have difficult to convert the power value in pwm could you help me to do that? I am using the LQR to get the K and I can mesure the position and the angle x=[position velocity angle velAng]; u=-K*x how can I convert the u in pwm I follow your guide but I need a procedure because we have a different hardware and with your value of couse does not work
Reply 6 years ago
> Why did you put velocity and position equal to zero?
In Step5 and 6, we can get an “inverted following robot.” which cannot balance itself. There we put the estimates of velocity and position of the robot equal to zero. On the other hand, we try to get “inverted self-balancing robot” in Step 7 and 8, where we should estimate the velocity and position of the robot correctly.
> How did you set up the K values?
The original project of this article was started with a numerical simulation on PC. See (*1) in (3) in Introduction in this article. The near-proper values of two coefficients in Note 4 in Step 5, k1 and k2, were gotten by this simulation. See (2) in Step11. The remaining coefficients, k3 and k4, could be gotten by trial and error.
7 years ago
im working from mexico and its very dificult to locate L3GD20 and im using MPU-5060 and i cant find where can i put the pin cs i be very thankfully if you can help me with that great project.
Reply 7 years ago
Hi,
I don’t know MPU5060 well, sorry. Though SPI interface is used in the sample sketch in Step5, I2C interface should be used for MPU5060 or 6050. You can find good information in other web sites with searching “MPU5060”.
7 years ago
Hello everybody, very good topic ! Thanks. I want to try this soon ...
I've question concerning the dual motor used for this robot, I've ordered the same one and before assembly I want to know the best speed for this purpose:
-Type A: 12.7:1 gear ratio - 94gf*cm 1039rpm rotations.
-Type B: 38.2:1 gear ratio - 278gf*cm 345rpm rotations.
-Type C: 114.7:1 gear ratio - 809gf*cm 115rpm rotations.
-Type D: 344.2:1 gear ratio - 2276gf*cm 38rpm rotations.
Thanks a lot.
Vincent.
Reply 7 years ago
Hi,
In this article “Double Gearbox” is assembled to make its gear ratio 114.7:1. See Step3. Though another ratio could be chosen, the values of parameter set should be corrected in the sample sketch attached in Step5 to get good robot in Step6 to 8.
In general, backlash in the gearbox would be smaller with higher ratio. And the robot with lower ratio would become more robust against shocks.
Reply 7 years ago
Hi and thanks a lot ArduinoDeXXX, I'll set to this 114.7 ratio ;=))
7 years ago
thanks for replying
I have uploaded your sketch wich the robot balances itself without using my finger. but the robot is nog working like it supposed to. at some moments the robot works only with my help but sometimes it doesn't work at all (when resetting again). I'm not entirely sure but i think my code is ok. i have read all your steps and followed all your instructions. maybe my gyroscope could sending out a wrong signal?
thanks again for helping me out
here is my code again:
byte countS = 0;
int recOmegaI[10];
int omegaI = 0;
long thetaI = 0;
long sumPower = 0;
long sumSumP = 0;
const int kAngle = 50;
const int kOmega = 500;
const long kSpeed = 60;
const long kDistance = 20;
long powerScale;
int power;
long vE5 = 0;
long xE5 = 0;
#include <SPI.h>
int ry;
long R;
void L3GD20_write(byte reg, byte val) {
digitalWrite(10, LOW);
SPI.transfer(reg);
SPI.transfer(val);
digitalWrite(10, HIGH);
}
byte L3GD20_read(byte reg) {
byte ret = 0;
digitalWrite(10, LOW);
SPI.transfer(reg | 0x80);
ret = SPI.transfer(0);
digitalWrite(10, HIGH);
return ret;
}
void setup () {
Serial .begin(115200);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
for ( int i = 0 ; i < 10 ; i++ ) { recOmegaI[i] = 0; }
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE3);
SPI.setClockDivider(SPI_CLOCK_DIV2);
L3GD20_write(0x20, B11001111);
L3GD20_write(0x23, B00000000);
delay(300);
}
void loop () {
chkAndCtl();
if ( power > 0 ) {
analogWrite( 6, power );
digitalWrite( 4, HIGH );
digitalWrite( 5, LOW );
analogWrite( 9, power );
digitalWrite( 7, HIGH );
digitalWrite( 8, LOW );
} else {
analogWrite( 6, - power );
digitalWrite( 4, LOW );
digitalWrite( 5, HIGH );
analogWrite( 9, - power );
digitalWrite( 7, LOW );
digitalWrite( 8, HIGH );
}
}
void chkAndCtl() {
R = 0;
for ( int i = 0 ; i < 45 ; i++ ) {
ry = ( (L3GD20_read(0x2B) << 8) | L3GD20_read(0x2A) );
R = R + ry;
delayMicroseconds(90);
}
omegaI = R * 0.00875 / 45;
if ( abs( omegaI ) < 2 ) { omegaI = 0; }
recOmegaI[0] = omegaI; thetaI = thetaI + omegaI; countS = 0;
for ( int i = 0 ; i < 10 ; i++ ) {
if ( abs( recOmegaI[i] ) < 4 ) { countS++; }
} if ( countS > 9 ) { thetaI = 0;
vE5 = 0;
xE5 = 0;
sumPower = 0;
sumSumP = 0;
}
for ( int i = 9 ; i > 0 ; i-- ) { recOmegaI[ i ] = recOmegaI[ i-1 ]; }
powerScale = ( kAngle * thetaI / 100 ) + ( kOmega * omegaI / 100 ) + ( kSpeed * vE5 / 1000 ) + ( kDistance * xE5 / 1000 );
power = max ( min ( 95 * powerScale / 100 , 255 ) , -255 );
sumPower = sumPower + power;
sumSumP = sumSumP + sumPower;
vE5 = sumPower;
xE5 = sumSumP / 1000;
}
Reply 7 years ago
It is hardly expected that the corrected sample sketch doesn’t work well, even though it is uploaded well. It is just a “copy and paste” and easy trimming.
Some gyro modules have gone broken in my working. But I have never heard such module in comments of my readers. In the most cases of them, some faulty wiring made robot wrong.
1. Did you check your robot working as shown in the video “[Reference] Checking an Inverted Following Robot” in Step6?
2. Can you show or upload the video of your robot working in the check above?
See the earlier comments of Maeskaz below.
7 years ago
hi
I use an L3gd20 on my robot, but your code doesn't seem to work
I tried correcting to code many times but with no positive result.
What exactly is the theory of your robot? You explain what it does, but not how it exactly works. what kind of signals does the robot use?
Maybe you can take a look at my code too? I deleted comments and corrected errors. Now there are no errors with uploading but no good result. For a second the robot seems to balance itself but after the second it immediately fails balancing.
Here is my code:
byte countS = 0;
int recOmegaI[10];
int omegaI = 0;
long thetaI = 0;
long sumPower = 0;
long sumSumP = 0;
const int kAngle = 50;
const int kOmega = 500;
const long kSpeed = 60;
const long kDistance = 20;
long powerScale;
int power;
long vE5 = 0;
long xE5 = 0;
#include <SPI.h>
int ry;
long R;
void L3GD20_write(byte reg, byte val) {
digitalWrite(10, LOW);
SPI.transfer(reg);
SPI.transfer(val);
digitalWrite(10, HIGH);
}
byte L3GD20_read(byte reg) {
byte ret = 0;
digitalWrite(10, LOW);
SPI.transfer(reg | 0x80);
ret = SPI.transfer(0);
digitalWrite(10, HIGH);
return ret;
}
void setup () {
Serial .begin(115200);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
for ( int i = 0 ; i < 10 ; i++ ) { recOmegaI[i] = 0; }
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE3);
SPI.setClockDivider(SPI_CLOCK_DIV2);
L3GD20_write(0x20, B11001111);
L3GD20_write(0x23, B00000000);
delay(300);
}
void loop () {
chkAndCtl();
if ( power > 0 ) {
analogWrite( 6, power );
digitalWrite( 4, HIGH );
digitalWrite( 5, LOW );
analogWrite( 9, power );
digitalWrite( 7, HIGH );
digitalWrite( 8, LOW );
} else {
analogWrite( 6, - power );
digitalWrite( 4, LOW );
digitalWrite( 5, HIGH );
analogWrite( 9, - power );
digitalWrite( 7, LOW );
digitalWrite( 8, HIGH );
}
}
void chkAndCtl() {
R = 0;
for ( int i = 0 ; i < 45 ; i++ ) {
ry = ( (L3GD20_read(0x2B) << 8) | L3GD20_read(0x2A) );
R = R + ry;
delayMicroseconds(90);
}
omegaI = R * 0.00875 / 45;
if ( abs( omegaI ) < 2 ) { omegaI = 0; }
recOmegaI[0] = omegaI; thetaI = thetaI + omegaI; countS = 0;
for ( int i = 0 ; i < 10 ; i++ ) {
if ( abs( recOmegaI[i] ) < 4 ) { countS++; }
} if ( countS > 9 ) { thetaI = 0;
vE5 = 0;
xE5 = 0;
sumPower = 0;
sumSumP = 0;
}
for ( int i = 9 ; i > 0 ; i-- ) { recOmegaI[ i ] = recOmegaI[ i-1 ]; }
powerScale = ( kAngle * thetaI / 100 ) + ( kOmega * omegaI / 100 ) + ( kSpeed * vE5 / 1000 ) + ( kDistance * xE5 / 1000 );
power = max ( min ( 95 * powerScale / 100 , 255 ) , -255 );
sumPower = sumPower + power;
sumSumP = sumSumP + sumPower;
}
Reply 7 years ago
Hi,
I read your sketch. I think you should read all steps in this article more carefully. Have you read Step6? Have you challenged the puzzle in Step7? And have you tried Step8?
In Step6, a following robot ought to be gotten, not a balancing robot.
7 years ago
The wiring on my robot is done right but I dont hear that "miiiii" sound also...
The problem could be my gyroscope. But it is never used for anything else than this project. And this project is the first project where I used a gyroscope. so it isn't damaged
Maybe something is wrong with your Arduino sketch? I opened your software the way it supposed to be opened (see previous comment) but my robot doesn't seem to be able to balance itself...
Reply 7 years ago
1. Did you check your robot working as shown in the video “[Reference] Checking an Inverted Following Robot” in Step6?
2. Can you show or upload the video of your robot working in the check above?
3. Can you tell me the model number of your gyro module (L3GD20 carrier)?