- Programming the microcontroller

The brain of the robot is made of Atmel Tiny2313 microcontroller. This MCU has a cool feature called In-System Programming which can be used to program memories of the MCU with almost-no-cost programmer. I used simple programmer which connects to parallel port. It is described in [2] and its schematic is below. The 74HC08 integrated circuit, which is the only part of this programmer besides the connector, costs about 50 cents. Everything can be built directly into the 25-pin LPT connector without any PCB.

programmer schematics


Fig. 4.1 – Schematics of a simple Atmel AVR programmer for parallel port


On the microcontroller side of the cable, I use pinhead female connector with my own layout as shown in fig. 4.2. Note that the cable should not be longer than about 50 cm.


ISP connector 

Fig. 4.2 – ISP connector for the controller board




The programmer works with free software called “ISP Programmer”, which is available at [3].

If parallel port is not available on your computer, you can use PonyProg software [4] with interface for serial port. The programming device is also very simple.

Note that if you use laptop with USB to Serial converter PonyProg may run very slow (10 minutes for programming the memory) – so this is not a good choice. I did not find any solution for this yet, but luckily my laptop has a parallel port and my old PC has both serial and parallel port. The simplest solution would be to buy some commercial Atmel programmer for USB, such us ISP MK II, which can cost about $40.

For controlling the robot from PC, USB to Serial converter works fine so you can use laptop with USB port and a converter.


The program for the MCU is built in AVR Studio, which is free IDE provided by Atmel [5]. AVR studio allows writing programs in assembly language only, but there is free set of tools including C compiler called WinAVR [6] available. WinAVR integrates into AVR studio seamlessly, so it is possible to write programs for the MCU in C.


So to sum it all up, the program for microcontroller is written in C and built with WinAVR tools integrated into AVR studio. First, download and install AVR studio. Then install WinAVR and it will integrate into AVR studio automatically. Then download and open the project with source code for Krabos. 



Description of the source code


The source code for MCU consists of the following files

ServoDriver.C – main source file, includes the main() function

ServoDriver.H – definitions

RoboCom.C – functions for robot movement and serial communication


The source file can be downloaded here (including AVR Studio project).

The main function performs initialization and then falls into infinite loop.

This loop does different actions based on the robot state. Possible states include Walk, TurnLeft, Stop (do nothing), etc.

In every pass through the loop one step is performed. What the step is depends on the state. For example, in Walk state one step is one complete set of movements of the servos which makes the robot do one step forward.

The state of the robot can be changed either by pressing the switch on control board or by a command from serial line. The switch can only toggle state between stopped and autonomous movement. When controlled from PC, a command arriving through serial line generates interrupt and interrupt handler routine changes the state of the robot according to this command. The change is recognized by the main loop during the next pass, so it may take some time before the robot responds to the command.



The bump sensors generate interrupt when activated (when robot touches an obstacle). The interrupt handlers only change state of the sensor in global variable (gLeftSensor or gRightSensor) and disable further interrupts from the sensor. Main loop can respond in the next pass. If the robot is in autonomous mode it will stop and turn etc. If controlled from PC, it is responsibility of the PC software to check for sensors and respond accordingly. Software controlling the robot from PC can read the sensor state by sending Get Sensor State command to the robot. The robot will send back information about the sensor (whether it is activated or not).


PWM signal for servos can be generated using 2 timers available in the MCU (each timer has 2 PWM channels). This option was tried first and works fine. It is still available in the source code if you uncomment the PWM_VER1 directive in ServoDriver.C.

However, using the timer-based PWM has some disadvantages because of which the current version of the software generates PWM in a different way and the PWM_VER1 directive is commented out.

The problem with “native” PWM generated by the timer is the resolution of the timer counter, which is only 8 bits. The period of the PWM is thus divided into 256 parts. The period should be 20 ms for the servo. The active level of the signal has however length of only 1 to 2 ms, where 1.5 ms is neutral position of the servo lever. So for the full servo movement we have 1 ms length, which is 12 units of the counter. In other words, we may change the servo position in only 12 steps across the whole movement range of the servo lever (about 60 degrees). This does not leave much room for adjusting the center position or movements of the legs. In my experiments, I ended up changing the position only by 1 unit +/- to move the legs into their position during walk.

That’s why I now use more software-based PWM which works as follows:

In timer overflow interrupt handler, a “software” counter is incremented. When this counter reaches 400, the PWM active signal starts – outputs are set to 1. Each servo has its own variable which holds the desired length of the pulse (from 20 to 40). This variable is compared with the counter and when equal, corresponding output pin is set low.

For speed and size purpose the software counter is implemented as two 8-bit variables rather than one 16 bit. When first counter reaches 256, the second starts incrementing and when it reaches 144, current period is ended and both counters reset.

The prototype robot walks fine with change of +/- 3 units, which is actually not much better than the completely timer-based PWM, but the advantage of this method is also that it allows for easy tuning of the PWM frequency (50 Hz), while the first method depends on combination of MCU clock and timer prescaler value, which are rather coarse (1, 8, 64, 256,..). The prototype with timer-based PWM used CPU clock 0.5 MHz and the PWM frequency was 30 Hz. Higher frequency in general leads to faster servo movement but also to bigger current drawn from the source battery and more heat on the voltage regulator.



Serial communication uses UART circuit integrated in the MCU, which makes it very easy. The UART is set up during initialization in main() and Rx complete interrupt is enabled. This interrupt is then generated whenever byte of data is received from the serial line.

Note that the communication speed depends on the CPU clock. It can be changed in the BAUD_RATE constant in ServoDriver.h. Preset speed is 9600, with 2 stop bits and no hardware control. The routines for initializing serial port and sending character are taken from the MCU documentation samples.


Current version of the program occupies 100% of the flash memory so, unfortunately, there is not much room for experiments. However, the design supposes that the Tiny2313 MCU will serve only as a servo driver and sensor converter. The actual movement algorithms should be implemented either on PC or on a separate “high-level” brain board which will send commands to the “low-level brain” through serial line.


Possible improvements of the MCU program (implemented probably instead of the simple autonomous algorithm which occupies memory space but is of little practical use) could be:

Saving trim values for servo position to EEPROM and adjusting them via serial line.


How to load the program to the MCU


I assume you have the control board ready, checked as described earlier and your AT Tiny 2313 is installed in the socket of this board. Parallel port programmer with the related software is used. If you use other programmer, you will need to modify some steps but in general the procedure will be the same.

Do not connect the servos to the board yet.

  • Connect power supply to the board. Preferably use source with current limit set to about 20 mA.

  • Connect the programmer cable into the parallel port of your computer.

  • Connect the other end of the cable to the ISP connector on the controller board. Connect the power supply connector for the programmer also.

  • Run the ISP Programmer program (isprog.exe).

  • First click Setup button and change the “ISP cable pinout“ to AEC ISP. See the picture. Details can be found in [2].





  • Close the Setup dialog and return to the main window.

  • Now click the Reset On button

  • Click the Read signature button. If everything works fine, the program will recognize the MCU and display its description (Atmel Tiny 2313..). If it does not, please see the Troubleshooting section below.

  • Now select the file for programming flash – this is the hex file which you can download in the download section or build yourself from the source code.

  • Click Erase button and wait till “device erased” status appears.

  • Now click the Program Flash button. Wait for it to complete.

  • Click Verify Flash button.


If no error appeared, your program is now in the MCU but we still need to change so called “Fuse bits” to configure the MCU clock frequency.

  • Click the Fuses and lock bits button

  • In the Fuses and lock bits window click the CLKDIV box so that it reads 1. Then click the Program button in the right-hand part of the window. By this you set the frequency of the MCU to 4 MHz instead of the default 0.5 MHz.


Now you can make sure the program works.

  • Click the Reset Off button and the program in MCU starts to run.

  • If you have a multi-meter with frequency measurement, check the signal on the pins for servos. There should be 100 Hz with duty cycle about 7.5 %. This is the signal which keeps the servos in neutral position.

  • Press the push-switch on the controller board. Hold it down until the green LED goes on. It should do so in a moment. With the LED on, you can measure the signal on servo outputs again. Now the robot is “walking”, so the duty cycle of the signal should change a little, from about 5 to 10%. The frequency should be stable 100 Hz.

  • If you press the push-switch again (and hold it till it happens), the LED should go off. Now the robot is stopped.


If it works as described, we are ready to connect the servos.

BUT IF YOU HAVE NOT set the neutral position of the servos earlier with servo signal generator; detach the levers with legs from the servos before connecting the servo cables to the control board!

This is because the servos probably will not be in neutral position and the legs could bump into each other as they move when the signal from MCU sends the servos to neutrals.

So after you have connected the servos and turned the power back on, they may move at first, but then they should remain in the same place. Little buzz is not a problem. It may be sign of power supply which is not able to provide enough current. That is why the robot should be powered from accumulators or powerful enough DC adapter (1 A should be fine). If you are using power supply with limited current, don’t forget to turn off the limitation!


If you now press the push-switch, the servos should start to move. You will more hear it than see it if you have detached the legs. Stop the robot by pressing (and holding) the switch again. Wait for the servos to stop moving! Do not turn the robot off by disconnecting the power. This would not stop the servos in neutral positions!

Now disconnect the power. Servos are in neutrals and we need to put the legs on them so that they are also in neutral. It is possible to attach the servo lever in different positions but the adjustment is not as fine as you could expect. So you may not be able to find the correct neutral position for legs. This is fine. Just try to attach them as close to neutral as possible. We will fine-tune (trim) the position in the software. BUT be careful not to move the servo as you push the lever on it.


With the legs attached connect the power again. The legs should not move much if you managed to put the levers on servos without disturbing the neutral position.

Now press the push-switch. The legs should start to move. If there are no collisions, put the robot down and watch it walk! Enjoy!

You may stop it and start again with the push-switch. Always hold the switch down until the LED goes on or off. Each time the robot is started, it increases the speed. When maximal speed is reached, it will start over again from slow speed.


If the legs seem to bump into each other it may have two reasons:

1 – Servo travel is too long and the legs cannot move that far. This is easy to fix in the software by changing the A and B values in the ServoPosition enum.

2 – Servos may move in reverse direction. It is possible that servos of some brand respond in opposite way than servos on the prototype. In this case exchange the A and B values in ServoPosition enum in the program.



Troubles with programming the MCU


If the ISP Prog software does not recognize the MCU (it displays “bad signature” status), the

Parallel port of your computer may need to be configured in BIOS. See the readme.txt file which comes with ISP Prog for instructions.

If BIOS does not solve the problem, there may be some bug either in the programmer cable itself or in the control board.

Measure the voltage on Reset pin of the MCU (pin 1). It should be 5V when the reset signal is off in the program. When you click the Reset On button, there should be 0V on the Reset pin. If it is not, the problem is probably in the programmer cable.

If Reset signal is ok, check that the MOSI, MISO, CLK and Reset pins of the MCU are connected with the ISP connector of the controller board.

As a last option you may want to put the MCU into breadboard, connect it to 5V, connect your programmer to the ISP pins and make sure it works. If it does work this way, the problem is not in the programmer cable but in the control board.

For more information and tips on solving problems please see the website [2].