With the X2:

  • The ports on the board have a0-8 and d0-8 so i assume the 16 i/o ports on the boarts are a and d only. Whats up with the portc stuff? like DDRC &= ~(1 << PC5); what does that do?

  • Are they any other pins that I cant use like the PA6 and PA7 (power etc.)

  • Since I will be using sensors how does the adc come into play?
    ADCSRA |= 1 << ADSC; // start conversion
    while (ADCSRA & (1 << ADSC)); // wait here for conversion to finish

Also I am used to each port having an address. In the example code I have i see address like:
else if ( !( pind & 0x20 ))
playNote( A(4) + 2, 100 );
But in the manual i see the 0x20 is portA input pins. Not like PA09.


Many of your questions are answered by the ATmega644 datasheet, which I strongly recommend you take a look at. The 3x16 header on the right side of the X2’s bottom board gives you access to pins PA0 - PA7 (not 8) and PD0 - PD7. The mega644 actually has four ports: A, B, C, and D. Port C connects to the user LEDs, pushbuttons, and the LCD data lines (see the quickstart sheet for a block diagram and schematic). Most of port B is used for LCD, buzzer, and motor control, but pins PB2 and PB4 are unused and can be accessed via labeled pads on the bottom board.

The line DDRC &= ~(1 << PC5) sets pin PC5 as a digital input. PC5 is an LCD data line and it also connects to a user LED.

By default, pins PA6 and PA7 are connected to a battery-monitoring voltage divider and the user trimmer potentiometer, respectively, through solder jumpers on the underside of the bottom board. If these solder jumpers are in place, I recommend you avoid connecting external devices to these two pins. If you want to use these pins for something else, use a soldering iron to break the solder jumpers on the PCB. The X2 schematic shows you which pins are connected to the various on-board components. Pins PA0 - PA5, PD0 - PD7, PB2, and PB4 are reserved solely for user I/O and are not connected to any of the X2’s hardware.

I’m not sure what you’re asking with regard to the ADC. Port A pins can be used as digital I/Os or analog inputs (or both). The mega644 datasheet explains how to use the ADC to read the analog voltages on these pins, and the Orangutan X2 test code (under the resources tab of the product page) gives an example of using the ADC. If you have sensors that output an analog voltage, you will want to plug them into port A pins and use the ADC.

All of the mega644 registers have addresses, but you rarely need to concern yourself with them since they can be referenced via convenient macros when you include <avr/io.h>. In the line:

if (PIND & 0x20)

0x20 isn’t an address, it’s a bitmask. The address is PIND, which comes from <avr/io.h>. The line is requesting the byte that represents the digital input values of the eight port D pins, which is then bitwise-anded with 0x20 (0b00100000). This lets me check the value of bit 5 of PIND (i.e. the digital input value of pin PD5). If the bitwise-and results in 0, pin PD5 is reading low, otherwise pin PD5 is reading high. Does this make sense?

- Ben

I get what you are saything. Thanks.

0x20 (0b00100000) ** THe value in the brackets mean what exactly? It is not the decimal value of hex 20.

- I read the datasheet but It can be a bit confusing since I am a beginner. In last microcontroller we only concerned ourselves with the pins alone. IN this manual I see port D pins (Fines). What is port D bit 7 (OC2A/PCINT31)? Each port stand alone right? Why bits 7-0?

Each port is controlled by a series of 8-bit registers (DDRx, PORTx, and PINx), where each bit of these registers corresponds to a particular pin. For example, the DDRD register is single byte (8 bits) that controls whether the eight pins of port D are inputs or outputs. If bit n of DDRD is set, pin PDn is an output. If bit n of DDRD is cleared, pin PDn is an input. When working with these registers, it might help to write out their values in binary so you can explicitly see the effect the value will have on the pins of that port. That’s what I did in my previous post with the line:

0x20 (0b00100000)

The value in parentheses is the binary representation of 0x20.

32 in base 10 (decimal) is 0x20 in base 16 (hexidecimal) and 0b00100000 in base 2 (binary).

Instead of addresses for each pin, you have an address for an entire port and you control individual pins through bit manipulation of that port. Does this answer your questions?

- Ben

Yes it does Thanks.

Ok… heres another question.

I have a ultransonic range finder. I am attempting to use one port for input and one for output. The output to send a signal out to see if there is an object present. The input would be the result.

How exactly do perform an output function. I see all these forums for input but not output. I am assuming i have to use portA for my sensor input.

You don’t need to use one port for input and one port for output. You control the input/output state for each pin using the DDRx register. If you want a pin to be an output, set its associated DDRx bit to 1. If you want a pin to be an input, set its associated DDRx bit to 0. For example, lets say you want to use pin PD0 as an input and PD1 as an output. You would accomplish this by setting and clearing the appropriate bits of the DDRD register:

DDRD &= ~(1 << PD0); // clear the PD0 bit of DDRD to make PD0 an input
DDRD |= 1 << PD1; // set the PD1 bit of DDRD to make PD1 an output

The above lines are examples of bit manipulation. You will use formulations like this a lot, so you should make sure you’re comfortable with them. If it doesn’t make sense to you, there are a number of good guides and tutorials online that can do a good job of explaining what’s going on.

You can control the output state of PD1 using the PORTD register. Setting the PD1 bit of PORTD will drive pin PD1 high while clearing the PD1 bit of PORTD will drive pin PD1 low:

PORTD &= ~(1 << PD1); // clear the PD1 bit of PORTD to drive pin PD1 low
PORTD |= 1 << PD1; // set the PD1 bit of PORTD to drive pin PD1 high

To read the digital input value of pin PD0, you would use the PIND register. The PD0 bit of PIND holds the input state of PD0. You can check this value by masking PIND for the PD0 bit:

if (PIND & (1 << PD0))
// pin PD0 is reading as high
// pin PD0 is reading as low

In general, when it comes to digital I/O, you can use the ports interchangeably as they all function the same way.

- Ben

All of a sudden my board tells me this:
WARNING: FLASH byte address 0x0082 is 0xE8 (should be 0xEA)… FAILED!

Now i cant go into programming mode

My attempts to fix it has been unsuccessful*

Can you provide more details? What were you doing when it stopped working? Are any of the LEDs on the board flashing? What happens when you try to put it in programming mode?

- Ben

Well i saw this port example on orangutan.lib and tried to program it onto the board then I saw the message for the 1st time. (After that I noticed it was for the atmega 128 )

Before that my battery died while it was powered on.

Before the battery incident It was fine I loaded a simple program I wrote to the board.

-The thing is only the test code will program without errors. i.e. the test code is currently on the board.

-Everything else is fine. The user leds are on (no flashing lights), I see my orange-ish light when I go in programming mode etc.

Getting isp parameter… SD=0x00 … OKOK
Reading FLASH input file… OK
Setting mode and device parameters… OK!
Entering programming mode… OK!
Erasing device… OK!
Programming FLASH … OK!
Reading FLASH … OK!
WARNING: FLASH byte address 0x0082 is 0xE8 (should be 0xEA)… FAILED!
Leaving programming mode… OK!

Did your battery die in the middle of programming?

Are you saying that you can program your X2 with the test code without problems?

- Ben

Yes the test code from online programs with no hiccups. But if I try to program with the melodies example that message comes up.

No it didnt die during programming. It just died when it powered up doing nothing.
Also previous runnings of the testcode gave port a and d = 1111111 but not port d says 00111111

How are you powering your X2? Do you have anything connected to pins PD0 and PD1?

With a 2.2 Amps (12V) battery rechargeable .
I have nothing connected to my d0 or d1 (no ports at all)

** I commented things out of the test code and the problem persists for that program too. So… please help.

If you put your X2 into programming mode and then go to the “Fuses” tab in AVR Studio’s AVRISP dialog, what do you see for the fuse bytes? It should be:

HIGH: 0xD9
LOW: 0xF6

While looking at this tab, be very careful not to change anything; altering the fuse settings can permanently damage your X2.

In the past have you been able to successfully program your X2 with the melodies demo, or have you gotten this programming verification error every time you’ve tried this particular program?

- Ben

Edit: which problem persists for the test code? Can you post the exact error message? Did you recently touch the board and zap it with static electricity?

Yes i see the:
HIGH: 0xD9
LOW: 0xF6

Yes I have programmed before successfully. It just today this problem appeared.

I’m not sure if you saw the questions I added to the end of my previous post, so I’ll post them again:

Which problem persists for the test code? Can you post the exact error message? Is there any chance you recently touched the board and zapped it with static electricity?

- Ben

When I plugged the battery in earlier I did see a gash. But it did program after. (Just remembered)

The test code just has the same error message from before. The"warning"
WARNING: FLASH byte address 0x0082 is 0xE8 (should be 0xE0)… FAILED!
***ISP mode error
I didnt feel any static electricity though.

When you say that you saw a “gash”, do you mean that there was a visible spark? Are you sure you plugged the battery in the right way to the correct pads? Did you recently connect anything to any of the user I/O pins? If so, what did you connect to which pins.

- Ben

Yes a visible spark.
I am pretty sure I plugged it in the correct way.
I plugged an led in a0 and another port below I cant remember.