Solved: Pin names/numbers on Mega2560

Hi,
pin numbers in a sketch always refer to the pins on the board. This is ok when I use an Arduino board. But when I use the controller on a self made board I have to use the names of the pins of the chip.
Well, before I solder the chip to the board I wrote a simple test program to see if the pins I want to use on my board are addressed correctly.
On my board I need the pins PA7 and PB2 of the controller chip. The sketch for testing is:

void setup() {
  pinMode(PA7, OUTPUT);
  pinMode(PB2, OUTPUT);
  while(1) {
    digitalWrite(PA7,HIGH);
    digitalWrite(PB2,HIGH);
    delay(1000);
    digitalWrite(PA7,LOW);
    digitalWrite(PB2,LOW);
    delay(1000);
  }
}
void loop() {
}

According to the circuit diagram of the Mega2560 PA7 corresponds to pin7 and PB2 corresponds to pin51. With a voltmeter I checked the two pins if they are toggling. Pin7 toggeled but pin51did not.

What is wrong here?

You cannot use PAx or PBx in digitalWrite commands. These are only bitnumbers of the corresponding PORT - eg PORTB. Therefor PA7=PB7=7, PA2=PB2=2

If you want to use digitalWrite() you must use the Arduino pin numbers. These are internally translated to portadress and bitnumber. The link of @paulpaulson shows how pinnumbers are translated to PORT/BIT.

It's always a bad Idea to directly use pinnumbers in the sketch. You should declare logical names for your used pins, and than use only this names in the sketch. Than the pinnumbers really don't matter - they are only used once when declaring the pinname - using the list above.

ok, thank you.
But now, what about the pins of an ATtiny84?
There is no Arduino board with an ATtiny84 and therefore no such pin mapping. How to write a sketch for an ATtiny84 addressing some of its pins?
Here I need a pin for a OneWire interface, one for digitalWrite(), and one for digitalRead().

Do you have a defect serach engine on your PC?

You look at the documentation for the ATtiny core you installed to get ATtiny support in the Arduino IDE.

If you use Spence Konde's "ATtinycore" to get arduino support for the ATtiny84, or Hans MCUDude's "MegaCore" to get support for "generic" ATmega2560s, they will helpfully define a set of constants "PIN_PA4" and etc that you can use to address the "native" (rather than "board") pins of the chip in the Arduino functions.

1 Like

Arduino pin 7 is H4, 51 is B2. A7 is Arduino pin 29.

You need direct port manipulation to use these, as in

  PORTH |= (1<<4) ;  // set H4 high
  PORTB &= ~(1<<2); // set B2 low
  PINB = 1<<2 ;  // toggle state of B2
  bool x = (PINB & (1<<2)) != 0 ;  // read B2 into a bool

The PORTx registers control output to that port
The PINx registers read the port (and allow toggling when written to).

Bit masks are used to select pins within the port, hence H4 uses 0x10 (which can be written 1<<4)

You can also bypass pinMode and use the DDRx register for setting mode, as in

  DDRH |= (1<<4) ; // H4 set to output
  DDRB |= (1<<2) ; // B2 set to output

  DDRB &= ~(1<<2) ;
  PORTB |= (1<<2) ;  // these two together set INPUT_PULLUP mode.

Thank you very much for your help.

Now I have two options, pinMode(), etc. with pin mapping or direct port manipulation. I didn't know that the names in the data sheet can directly be used in sketches.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.