Better servo positioning

In the “Little Johnny careful steps” post I have mentioned a better way of servo positioning. So let’s try this writeMicroseconds() stuff!

Arduino code for the test using two modes (write and writeMicroseconds  for the same movement range and speed):

#include <Servo.h>

// R = 18.5 cm
// 1 degree step = R*Pi/180 = 0.323 cm = 3.23 mm!

Servo myservo;

void setup()
myservo.write(90); // set servo to mid-point

int spos = 90;
int mode = 1;
int upos = 1500;
void loop()



Testing with analog and digital servos: simple straw is used to have big enough end point movement.


In the case of analog servo I saw 2 sometimes 3 movements / sec and in the case of digital it was 3 almost in all the cases. After viewing the  writeMicroseconds based positioning I experienced

- a much smoother positioning

- quieter servo

- less trembling

- only 3 times better than write function (originally I expected 5 times) but this could be caused by inertial mass…

All these could lead us to a better and smoother walking with less oscillation.

If you would like to know more about the implementation see some code used behind the scenes (located in your Arduino IDE install /libraries/Servo/Servo.cpp). Based on it you can use write in any code and it is able to detect if you want to use degrees or microsecs for controlling. A simple if is used: if the position you specify is less than 544 (0-180 normally) you got degree based control and finally all calls ends in writeMicroseconds lib function. When you send degrees it converts using Arduino map command: usec_value = map(degree_value, 0, 180, 544, 2400); You can check if 90 degrees lead you to 1500 usec  as a middle position. I got 1472 as result… It seems the library is prepared to handle all the extreme minimum and maximum positioning values BUT it has cost. Let’s see what we got if we have a very normal servo which is prepared to handle 1000 uS to 2000 uS (1500 middle => 1 degree = 5,555 uSec ):

Degrees / result micro seconds to control (comment about real position):

0 : 544 (under 1000 nothing happens or the servo goes to zero)
10 : 647 (same but you lost 10 degrees!)
20 : 750 (lost 20)
30 : 853 (lost 30)
40 : 956 (almost but still lost 40 degrees!)
50 : 1059 (finally got acceptable value which will position the servo to 10 degree position instead of 50!)
60 : 1162 (29 instead of 60)
70 : 1265 (47.7…)
80 : 1368 (66.24)
90 : 1472 (85 almost 90)
100 : 1575 (103.5)
110 : 1678 (122!)
120 : 1781 (140.6)
130 : 1884 (159)
140 : 1987 (177)
150 : 2090 (nothing happens or your servo goes to end position)
160 : 2193 (same and you lost another 10 degrees)
170 : 2296 (lost 20)
180 : 2400 (lost 30)

Testing code:

void setup() {

int comp=0;
void loop()
int val = 0;
int deg = 0;
Serial.print(” : “);
val = map(deg, 0, 180, 544, 2400);

It seems to be a bit shocking. If we use 544-2400 instead of the servo specific values (1000-2000uSec) we can easily loose about 70 degrees out of 180 and have absolutely invalid physical position plus a much bigger servo step length! My servo step should be 5.555 uSec/degree but using write function I have 10.311! Almost two times bigger than I want to have…

Conclusion: If you know your servo parameters you definitely have to use writeMicroseconds function and a simple map like

usec_value = map(degree_value, 0, 180, your_servo_min, your_servo_max);

(Or you just overwrite 544 and 2400 in Servo.h after reading the license and change conditions)

I must have been blinded by my very limited brain capacity to realize this conclusion only after 3 years testing… Luckily I can eliminate this small frustration with 3 beers :D

Categories: Experiments Tags: , , ,

Walking with battery pack – milestone

So here is the test result of walking with battery pack!

On one hand it means totally independent movement and for us this is a milestone. On the other hand this can cause additional load and kill all the servos (this would not mean a real milestone :) ). Our expectation was to see this small robot to walk and walk alone without any external support (no external power, no external control, nothing just Little Johnny).

Vote before you watch the video! Agony or walking?

Add battery and use internal power supply!

This was a critical part of the development. With external power source everything was easy and simple: 5V was just coming flawlessly. Adding the batteries suddenly caused unlimited number of problems:

Problem 1: where on Earth can we place 6 AA batteries in a small robot body? This is solved because my brother designed a battery holder right under the Arduino Mega almost a year ago as you can see below. Sorry :)

battery pack holder

Problem 2: how can you connect AA batteries without soldering and use as less energy and time as possible. I found a proposal to use “snail” formed wires and simple tape.

AA battery connector wire

This was really simple and quick: in 10 minutes I could connect 6 batteries and have a 2200mA 9V pack built-in to the pack holder!

half connected

Problem 3: additional load! Normal weight was 305g before this step and now it is 455g! Will the servos accept this additional load?

Problem 4: can this battery pack provide enough power for the servos – to hold the extra mass caused by the battery pack :) ?

This definitely has to be tested…

Walking on lego – round 2

Last time a simple 4-5cm thick lego obstacle could stop LJ why I simply changed step height to maximum :) Let’s see the result!

Categories: Robot HW and SW Tags: , ,

Walking on lego

The purpose of this test is to check stability and possible problems during normal walk. You will see easy and impossible scenarios :) but this small robot did not fall over and never gave up.

Categories: Robot HW and SW Tags: , ,

Little Johnny careful steps

After 9 hours development I could update the walking code and implement a “higher” but still careful step function. The gyro is not used this time to have a very clear base. Alone a simple walking algorithm was not enough and any time the robot would like to step mass center correction is required. Mass center is moved using shoulder servos and decreased body height on the opposite side. Please check the video and comment if you want! :)

The funny part is that this configuration is not able to keep walking direction. I found two major problems that need to be solved:

1. incorrect servo positioning: interesting that the used positioning function (write) from Arduino Servo Library ( needs an integer value between 0 and 180. I think as a step it is not fine enough. Luckily this lib provides another function writeMicroseconds() which can be 5 times smoother! Comparing 0-180 degrees to 1000-2000 uSeconds looks good and has much better resolution. Question if any servo can interpret 1500 us and 1501 as control signal. This change of positioning type can have effect only on one part of the robot driver: instead of servo.write(90); something like servo.writeMicroseconds(1500); could be used. Maybe this test should be the subject of the next post.

2. incorrect servo offset setup: when you mount your arm or leg on the servo gear you need to find the possible best orientation out of the very limited variations. Let’s say we have 20 teeth on the servo gear (sample pic below) which means you can change start position only by 18 degrees. If the leg is not positioned properly an offset value needs to be used any time Arduino final position is calculated. As you can see in the video Leg 4 has an offset problem and simply kicks the floor. I use 10 degrees as offset but it should be changed to 5 or 4…

servo gear


(3.) Of course different leg friction could cause a small rotation but this was too much.

Arduino to Arduino serial connection

During balancing experiment I had to remove IR sensor because it’s software library disturbed my servos. I could continue the work and change key walking and balancing parameters using keyboard but it was not too comfortable. So I had to find out how to use IR with servos without unexpected side effects. My Arduino nano volunteered to do the job. I have tested I2C and ISP low-level interfaces why I decided to use simple serial communication this time. It was much simpler than I thought.


All I needed on HW level:

- Connect Nano TX pin to Mega (main Arduino) RX1

- Nano RX pin to Mega TX1 and

- connect GNDs. That’s all.

On SW level it was also very simple. The best if you check the code itself:


#include <IRremote.h>
int RECV_PIN = 3;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()

void loop()
Serial.println(results.value, HEX);


char str[20];

void setup()

void loop()
int i=0;

if (Serial1.available()) {
delay(10); // min 8 ms required!
while(Serial1.available() && i<20)str[i++] =;
str[i++]=”; // should be = ‘[backslash][zero]‘ but WordPress removes spec chars…


From now on I have a fully separated IR sensor module :)

This is how it looks like in action:

Two Arduinos powered


One weird thing: both Nano and Mega required power supply why standard USB cable was connected to both. When I finished the testing I simply disconnected the USB cable from Arduino Nano. Without the cable it was still operating! I also could use all IR functions and serial communication! Basically two cables could keep Nano alive: GND and Mega TX1 to Nano RX. I was not aware of this possibility of power supplying :) Funny…

Only Mega powered


Get every new post delivered to your Inbox.