cwave.eu5.org
Also see: http://www.angelfire.com/dragon/letstry
cwave04 at yahoo dot com
Free Guestbook
My Guestbook

Last updated on Wed Dec 22 10:24:57 IST 2010.

Software for a robot

We shall discuss only C for microcontrollers. It is much like ordinary C with a few significant differences. We shall discuss three major points that you must know before writing any useful robot software:
  1. Input and output
  2. Infinite loops
  3. Delays

Input and output

Most of us start learing C with a "hello world" program like this:

#include <stdio.h>

main() {
  printf("Hello world!");
}

This prints "Hello world!" on the monitor. Now, this program is surely not going to work in a microcontroller, simply because there is no monitor with it. So it should not come as a great surprise that C for microcontrollers does not have printf or scanf (because there is no keyboard). And so there is no stdio.h to include either!

Microcontrollers communicate with the external world via its pins. Most microcontrollers have 4 ports (a port being a collection of 8 pins). We shall illustrate the concept with ATMEGA8515. The ports here are called PORTA, PORTB, PORTC, PORTD. Each pin of each port can be used as input or output. An example will clarify things. Here is a microcontroller version of "hello world":


#include <avr/io.h>
1
main() {
  DDRB = 255;
2
  PORTB = 29;
3
}
4

Explanation of the code:

1: This, as you can guess, is the analogue of #include-ing stdio.h.

2: DDRB (a name #defined in avr/io.h) refers to the Data Direction Register for port B. It is an unsigned char variable. To make sense out of this line write the number 255 in binary (with 8 bits):

(255)10 = (1111 1111)2 .
Since all the bits are 1's, all the pins of PORT B will become output pins.

3:  This is the line that actually produces the output. To understand the output write 29 in binary (with 8 bits):

(29)10 = (00011101)2 .
Thus here pins 0,2,3 and 4 will have 5V, while the other pins of PORT B will be at 0V. Checking this with a voltmeter (or by connecting LEDs) is an exciting project for newbies!

4: The program terminates here. But the pins will retain their final status until the microcontroller is powered off.

So now we know the analogue of printf. The next thing of interest is the analogue of scanf. Here is a code snippet that reads a value from PORTC.


unsigned char x;
1
DDRC = 0;
2
x = PINC;
3

Explanation of the code:

1: Usual C declaration.

2: This is the data direction register for PORTC.

3: This lines reads the current status of the pins of PORTC into the variable x.

However, simply writing these 3 lines inside the main function will not work. For this we need to employ a trick that is very characteristic of microcontroller software, but rarely (if ever) used in usual programming. We discuss this next.

Infinite loops

Consider the following program.

#include <stdio.h>

main() {
  while(1) {
    printf("Hello!");
  }
}

This program will flood your PC screen with "Hello!"'s. The only way to stop it is by some drastic measure (like control-alt-delete). This is an example of an infinite loop, a thing that is definitely undesirable in usual programs. On the other hand, infinite loops are essential to writing software for microcontrollers. To see this consider the following program to read some buttons connected to PORTC and accordingly lights some LEDs connected to PORTB.

#include <avr/io.h>

main() {
  DDRB = 255;
  DDRC = 0;
  
  PORTB = PINC;
}

Let's walk through this simple code. The first couple of lines sets the communication direction for PORTB and PORTC. The thirdl line reads PORTC and writes the value to PORTB. Well, that's sounds like what we wanted to do, but it is done just once (within a fraction of a millisecond since powering up the microcontroller)! You'll get no time even to look at the buttons, let alone push them! By the time your fingers reach the buttons, the program has terminated and PORTB is frozen at its last value until power down.

We need an infinite loop to keep the superfast microcontroller in pase with its sluggish human user.

#include <avr/io.h>

main() {
  DDRB = 255;
  DDRC = 0;
  
  while(1) {
    PORTB = PINC;
  }
}

All robot software must have such an infinite loop built into it.

Delays

A microcontroller runs too fast compared to human reflex. We often need to slow the microcontroller down a bit to keep up with it. This is done by using delay loops, loops that do nothing, just kill time. Here is a typical delay loop:

int i;
for(i=0;i<1000;i++);

Sometimes we need longer delays:

int i, j;
for(i=0;i<1000;i++) {
  for(j=0;j<500;j++);
}

The following program shows a delay loop in action. There are LEDs connected with all the pins of PORTB. Our aim is to use these to make a count up timer.

#include <avr/io.h>

main() {
  unsigned char count = 0;
  int i;

  DDRB = 255;
  while(1) {
    PORTB = count;
    count++;

    for(i=0;i<10000;i++);
  }        
}


PrevNext
© Arnab Chakraborty (2010)

Free counters!