Quick cover (simple code for the Orangutan)

Hi i bought the orangutan mega8 controller, and befre i bought it, its page at pololu had a coupkle of basic example programs… I am very new to this, and was wondering if someone could write the most basic of basic programs, that sounded the buzzer, and when a switch is pressed ligths the led. I am pretty sure if i see that, i will then be able to sustain my own learniing with that as a start…
I have this…

#include <avr/io.h>

int main()
{
while(1)
{
DDRB = (0<<PB3);
DDRD = (1<<PD3); // set PD3 as an output
if PORTB |=(1<<PB3)
{
PORTD |= (1<<PD3);
}


}
}

Does it make any sense…
Thank you to anyone who replies

alex

Hello.

There are a few problems I see with your code that I’d like to first address:

DDRB = (0<<PB3);
Bitshifting zero doesn’t actually accomplish anything as 0 << x is always still just 0. This line is equivalent to DDRB = 0;

DDRD = (1 << PD3);
This line does what you want, but it could have unwanted side effects. You see, while you’re setting PD3 to be an output, you’re simultaneously setting all other pins on port D to be inputs. Typically, if you only want to affect the I/O state of a single pin, you want to use an operation like &= or |= in a way that will leave the rest of the pins of the port unchanged.

To set bit n of a byte while leaving the rest of the bits unchanged, you would use: byte |= (1 << n);
To clear bit n of a byte while leaving the rest of the bits unchanged, you would use: byte &= ~(1 << n);

This kind of bit manipulation can seem confusing at first. If it doesn’t quite make sense to you, I strongly suggest you take a look at the fantastic explanation Nexisnet wrote in the second post of this thread.

if PORTB |=(1<<PB3)
This if statement is syntactically incorrect in that it’s missing parentheses around the argument. Furthermore, the argument is actually changing the value of PORTB rather than just checking to see what the value is.

The following code should cause the buzzer on your Orangutan to make sound. If your Orangutan is running at 1 MHz, you should either uncheck its divide-by-8 fuse so that it runs at 8 MHz, or modify my code below by replacing the line

#define F_CPU 8000000

with

#define F_CPU 1000000

#include <avr/io.h>
#define F_CPU 8000000  // The Orangutan has an 8 MHz clock
#include <util/delay.h>  // uses F_CPU to provide delay routines

// This function delays by sitting in a loop for time_ms milliseconds
void delay_ms(unsigned int time_ms)
{
  while (time_ms != 0)
  {
    _delay_ms(1);    // delay for 1 ms (_delay_ms comes from <util/delay.h>)
    time_ms--;
  }
}

int main()
{
  DDRB |= 1 << PB0;  // make PB0 (buzzer pin) an output
  while (1)
  {
    PORTB |= 1 << PB0;  // make PB0 (buzzer pin) high
    delay_ms(5);
    PORTB &= ~(1 << PB0);  // make PB0 (buzzer pin) low
    delay_ms(5);
  }
  return 0;
}

The following code should turn on the user LED when button SW3 is pressed:

#include <avr/io.h>

int main()
{
  DDRB &= ~(1 << PB3);  // make PB3 (button SW3 pin) an input
  DDRD |= 1 << PD1;  // make PD1 (LED pin) an output
  while (1)
  {
    // to check a pin's input value, use PIN register masked for desired bit
    if (PINB & (1 << PB3))  // if PB3 pin is high (i.e. if button SW3 is pressed)
      PORTD |= 1 << PD1;  // make pin PD1 high (turn on user LED)
    else
      PORTD &= ~(1 << PD1);  // make pin PD1 low (turn off USER LED)
  } 

  return 0;
}

Hi, guys.
Obviusly both pieces of code above compile correctly - i am just writing them over the same hex file each time, but on neither occasion does anything happen. What i do know is that even though the schematic says the ld is pd1 if i write a small program to set pd3 to 1, the LED lights. Does anyone know of a situation where the pins and schematic havent agreed…?

Could i have made a mistake when soldering the two new resistors on to get it to work with the avrispmkII. I mean it does work, but could i have changed the pins or something?

EDIT:

I decided to play with the buzzer program to see if there was a different problem. I have tried to make it so that the apparent LED on PD3 will turn on when the buzzer goes off:

#include <avr/io.h>
#define F_CPU 1000000  // The Orangutan has an 1 MHz clock
#include <util/delay.h>  // uses F_CPU to provide delay routines

// This function delays by sitting in a loop for time_ms milliseconds
void delay_ms(unsigned int time_ms)
{
  while (time_ms != 0)
  {
    _delay_ms(1);    // delay for 1 ms (_delay_ms comes from <util/delay.h>)
    time_ms--;
  }
}

int main()
{
  DDRB |= (1 << PB2);  // make PB0 (buzzer pin) an output
  DDRD |= (1 << PD3);
  while (1)
  {
  PORTD |=(0<< PD3);
    PORTB |= (1 << PB2);  // make PB0 (buzzer pin) high
    delay_ms(5);
	PORTD &= ~(1<< PD3);
    PORTB &= ~(1 << PB2);  // make PB0 (buzzer pin) low
    delay_ms(5);
  }
  return 0;
}

The led just stays on constantly. When i made my first program, that just lit the led on pin PD3, i didnt know about PORTD being needed to turn on the LED, i just used DDRD, and it worked. I am wondering whether the same thing is happening here, and because of the line DDRD |= (1 << PD3); the led is staying on constantly. DOes this make any sense to anyone???

The DDRx registers only control the data direction of an I/O pin (is it an input or an output). It’s the PORT value for that pin that determines the pin state. If DDR makes the pin an output, the PORT value determines if the pin is driven high or low. If DDR makes the pin an input, the PORT value determines if the pin is weakly pulled high or if it’s floating.

I believe the reason you see the LED staying on constantly is because the time it spends turned off is so short (only 5 ms). In essence, it’s making it look like you have the LED turned on at half intensity because your eye cannot perceive flickering at such a high rate. Try changing the delays to be much longer, like 200 or even 500 ms (i.e. use the line: delay_ms(200);).

Also, I notice in your code you are using PB2 for the buzzer instead of PB0. Is there a reason you made this change?

I won’t have access to an Orangutan until monday, so I can’t actually test any of my sample code myself.

- Ben

Hey Sorry i dont know why i changed that, theres nothing i know od on PB2. But this code:

#include <avr/io.h>
#define F_CPU 1000000  // The Orangutan has an 1 MHz clock
#include <util/delay.h>  // uses F_CPU to provide delay routines

// This function delays by sitting in a loop for time_ms milliseconds
void delay_ms(unsigned int time_ms)
{
  while (time_ms != 0)
  {
    _delay_ms(1);    // delay for 1 ms (_delay_ms comes from <util/delay.h>)
    time_ms--;
  }
}

int main()
{
  DDRD |= (1 << PD3);  // make PB0 (buzzer pin) an output
  
while (1)
  {
    PORTD |= (1 << PD3);  // make PB0 (buzzer pin) high
    delay_ms(500);
    PORTD &= ~(0 << PD3);  // make PB0 (buzzer pin) low
    delay_ms(500);
  }
  return 0;
}
[/code]
(ignoring the comments, because it is now controlling the LED) still leaves the LED on constantly, and its PD3, which accordin to schematic isnt an led...

EDIT: This is strange though, I have fiddled with another piece of code, very similar to the one you gave me and the one above, and it does flash the LED

[code]// F_CPU tells util/delay.h our clock frequency
#define F_CPU 8000000UL	// Orangutan frequency (8MHz)
//#define F_CPU 20000000UL	// Baby Orangutan frequency (20MHz)
#include <avr/io.h>
#include <util/delay.h>

void delayms( uint16_t millis ) {
	while ( millis ) {
		_delay_ms( 1 );
		millis--;
	}
}

int main( void ) {
	DDRD |= 1 << PD1;			// set LED pin PD1 to output
	while ( 1 ) {
		PORTD &= ~( 1 << PD1 );	// LED off
		delayms( 50 );			// delay 50 ms
		PORTD |= 1 << PD1; 		// LED on
		delayms( 50 );			// delay 50 ms
	}
	return 0;
}

That works. The only difference is that that one is using PD1. So why on PD3 does it stay on, so if i change it to the buzzer, do you think it will buzz???

EDIT AGAIN::

Yeah changing to the buzzer, and it suddenly works!

// F_CPU tells util/delay.h our clock frequency
#define F_CPU 8000000UL	// Orangutan frequency (8MHz)
//#define F_CPU 20000000UL	// Baby Orangutan frequency (20MHz)
#include <avr/io.h>
#include <util/delay.h>

void delayms( uint16_t millis ) {
	while ( millis ) {
		_delay_ms( 1 );
		millis--;
	}
}

int main( void ) {
	DDRB |= 1 << PB0;			// set buzzer pin PB0 to output
	while ( 1 ) {
		PORTB &= ~( 1 << PB0 );	// buzzer off
		delayms( 5 );			// delay 50 ms
		PORTB |= 1 << PB0; 		// buzzer on
		delayms( 5 );			// delay 50 ms
	}
	return 0;
}

Cool, is that odd, it worked this time and not before???
Thanks for you help, now i’m going to folow your code for the switch example…

I’m not sure why the code that changes PD3 would have any affect on the LED; that seems very odd to me.

The main difference between the piece of code that works and the piece of code that doesn’t, barring some weird error on my part, is that the one that works has #define F_CPU 8000000 and the one that doesn’t has #define F_CPU 1000000. F_CPU is used by the delay routines in <util/delay.h> so that they know what your AVR’s clock speed is and so that they can delay for the appropriate period of time. If your AVR is running at 8 MHz, you don’t want to have #F_CPU as 1000000. Try changing F_CPU to 8000000 in the code samples I first posted in this thread and see if that has any affect on them.

- Ben