Configuring Port A as digital Inputs on Mega 2560 - help pls

I am setting up PORT A as Inputs on the Mega 2560 and no matter how I change the inputs (0/1) I always get '0' when I read the port. Please clarify:

Port A pins on the Mega board are pins 22 (PA0) - 29 (PA7) - Correct?
I connect pins 22,24,26,28 to +5 via a pullup, pins 23,35,27,29 to ground.
I set up Port A: DDRA = 0b00000000;
Declare and initialize a temp variable: byte var1 = 0;
In my loop I do the following:
var1 = PORTA;
Serial.print("\n var1 ");
Serial.print(var1, BIN);

the print output is: var1 0 which is incorrect because I tied even pins 22-28 high.
So, is Port A NOT pins 22-29????
Any insight/suggestions are appreciated...

-J

I cheated. I didn't have a jumper handy, so I used the internal pullup resistors. This works for me.

void setup()
{
  Serial.begin(9600);
  DDRA = 0; // set PORTA to input
}

void loop()
{
  byte var1 = PINA; // get PORTA value
  Serial.println(var1,BIN);
  delay(1000);
}

Edit: This code reads the pins. My bad. It is PINA, not PORTA, that holds the input values.

PORTA is for writing, PINA is for reading, I believe.

Any objection to doing digitalRead?

@Nick: You are correct. PINA is the read, PORTA is the write. I was typing faster than I was thinking.

Edit: I can see why that would be handy. If you were looking for a specific pin setting combination rather than a single pin, this would be the quickest.

That's OK. I got caught by that a couple of times.

Your edit ninja'd my reply. :slight_smile:

Sorry, Nick. I don't mean to ninja edit your replies. I did it again. :blush:

lol

yes, reading pin by pin is inefficient and slow. I want to read the entire byte at once.

TYVM for the PINA ..... I read that in the atmel data sheet but forgot completely about it...(port A r/w is a hold over from a processor I was working with previously)......speaking of that.....
Can either of you point me to the 'magic code' that underlies some of the arduino port and bit r/w libraries/macros? There is way too much 'magic' being hidden at these high level port statements with no discussion about how to control pull ups/down, and how many instructions are actually used to do some of the actions. As one who has programmed in assembly for 30+ years, all the vagueness of the higher level commands make me very uneasy....

Thanks
J

three_jeeps:
Can either of you point me to the 'magic code' that underlies some of the arduino port and bit r/w libraries/macros? There is way too much 'magic' being hidden at these high level port statements with no discussion about how to control pull ups/down, and how many instructions are actually used to do some of the actions.

I just use "find in files" in my favourite editor (Crimson Editor in my case) and search for something like digitalWrite in the appropriate sub-folders.

Some of the magic is used to make things work seamlessly on different platforms (like the Tiny, Mega etc.). As for the pull-ups etc. I would read the datasheet for the processor. I usually have that PDF file open.

reading pin by pin is inefficient and slow.

It depends on your application a bit. Someone has gone to the trouble of working out which bits belong to which ports, and it saves having to get all the bit positions right every time.

After all, most people use device drivers supplied with their printers, video cards etc., treating them as "black boxes" and don't try to work out exactly how to address them. Maybe it's slightly slower, but it tends to be more reliable and easier to maintain.

Another thing you can do is view the .elf files produced by the compiler to see what machine code is generated. I do that quite often if there is some doubt about whether code has been optimized away, or whether method A is better than method B.

avr-objdump -S <path-to>/foo.elf > mylisting.txt

um, what exactly are you (or are you suggesting) editing?

If I were doing this in strictly assembly language, the data sheet is the only reference, however, it is not always clear what the mapping (code wise) is from the Atmel assembly to 'arduino-ese'...

reading pin by pin is inefficient and slow.

Yea, if one is dealing with a slow interface, then burn cycles with digitalReads, etc..... is as effective as var=PINx, however, from my pov, still inefficient. If one never programmed before, perhaps this type of simplification is 'acceptable'...until one starts doing real work.

Yes, for portability among many different platforms in a family, a perfectly acceptable abstraction.

Would love to...what tool are you using to produce the .elf files? Not the Arduino compliler?

Would love to...what tool are you using to produce the .elf files? Not the Arduino compliler?

The compiler produces them anyway. To find out the pathname hold down Shift and click the Verify button (top left). Then copy and paste the file name.

... this type of simplification is 'acceptable'...until one starts doing real work.

You are implying that something like:

PORTD |= B10000000

... is somehow more real than:

digitalWrite (7, HIGH);

I submit that the latter is easier to maintain in the future, and personally I write with a view to re-using my code later on, and having other people understand it.

The digitalWrite version is "real" and would be acceptable in all cases but the extreme ones where you are hitting speed limitations of the hardware. Sometimes this happens, I admit. As an example, a RFID security system I developed is supposed to unlock a door reasonably promptly after you present the correct card. Microsecond speed improvements are not required. So my "simpler" solution is easier to maintain, and just as real.

I don't shy away from port manipulation when the library doesn't support something I want to do.

For example, on this page:

I have this line:

  TWAR = (MY_ADDRESS << 1) | 1;  // enable broadcasts to be received

and this one:

TWBR = 12;

That's because those functions were not supported by the library. But for the rest, using pinMode, and digitalWrite worked perfectly well, and were easier to follow later on.