Arduino Mega portmapping

Hi all,

I’ve been using the code below on an Arduino Uno, but came accros the problem of memory-shortage. Therefore i’m now switched to an Mega2560, but i’m having some trouble with portmappings.

I can’t get the rotary encoder to work now, which obviously has something to do with the port mappings.

I’ve already tried to uncomment these lines:

  PCICR |= (1 << PCIE0);    // This enables Pin Change Interrupt 0 that covers the Digital input pins of Port B.
  PCMSK0 |= (1 << PCINT0) | (1 << PCINT2);

and simultaniously comment these lines:

//  uint8_t *pcmask=digitalPinToPCMSK(8);
//  PCICR |= (1 << digitalPinToPCICRbit(8) );  
//  *pcmask |= (1 << digitalPinToPCMSKbit(8)) | (1 << digitalPinToPCMSKbit(10) );

But without any result yet

How can i fix this (probably simple) problem?

Thanks in advance!

Code:

// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 10 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_b 8 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_button A3 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button

// source Encoder Esc-button · Issue #14 · Jomelo/LCDMenuLib · GitHub
// source: GitHub - mathertel/OneButton: An Arduino library for using a single button for multiple purpose input.
OneButton button(_LCDML_CONTROL_encoder_pin_button, true);
void enter(){LCDML_BUTTON_enter();}
void quit(){LCDML_BUTTON_quit();}

// Global vars for a RoraryEncoder
static int16_t enLast = 0;
int16_t enValue;
int enSteps = 0;
boolean enUp = false;
boolean enDown = false;
// ------------------

// source: GitHub - mathertel/RotaryEncoder: RotaryEncoder Arduino Library
RotaryEncoder encoder( _LCDML_CONTROL_encoder_pin_a, _LCDML_CONTROL_encoder_pin_b );

// The Interrupt Service Routine for Pin Change Interrupt 0
// This routine will only be called on any signal change on D8 and D10: exactly where we need to check.
ISR( PCINT0_vect ) {
encoder.tick(); // just call tick() to check the state.
}

// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// init pins → do not need that; it is done in encoder initiation: RotaryEncoder encoder();
//pinMode(_LCDML_CONTROL_encoder_pin_a, INPUT_PULLUP);
//pinMode(_LCDML_CONTROL_encoder_pin_b, INPUT_PULLUP);

button.attachClick( enter );
button.attachDoubleClick( quit );

// Set up pin change interrupt for RotaryEncoder:
// You may have to modify the next 3 lines if using other pins than 8-PB0 and 10-PB2 - PORTB
// please, note both pin 8 and 10 are on the same PORTB and within the same port change interrupt mask
// Pay attention! It may require more lines for mask definition if pins are allocated to different ports.
uint8_t *pcmask=digitalPinToPCMSK( 8 );
** PCICR |= (1 << digitalPinToPCICRbit( 8 ) ); **
__ *pcmask |= (1 << digitalPinToPCMSKbit( 8 )) | (1 << digitalPinToPCMSKbit(10) );__
// alternatively the above 3 lines may be replaced by the following two lines (again, PCINT0 corresponds to PB0 pin 8, PCINT2 - to PB2 pin 10 → are both in PCMSK0 ) :
// PCICR |= (1 << PCIE0); // This enables Pin Change Interrupt 0 that covers the Digital input pins of Port B.
**// PCMSK0 |= (1 << PCINT0) | (1 << PCINT2); **
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check buttons
button.tick();

// check Encoder
enValue = encoder.getPosition();
enSteps = enValue - enLast; // I use enSteps for counting encoder clicks for catching fast rotation in main loop()
if( enValue > enLast ) {
enDown = true;
LCDML_BUTTON_down();
} else if( enValue < enLast ) {
enUp = true;
LCDML_BUTTON_up();
}
enLast = enValue;
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************

The code you posted is hard to read and it does not seem to be a full sketch.

The code uses the Pin_Change_Interrupt (PCINT) of an Arduino Uno. I would not try to change that for an Arduino Mega.
All that is needed is that "encoder.tick()" is called for both pins.
You can use a normal interrupt pin and use attachInterrupt() for two interrupt functions that call "encoder.tick()". I assume that you have to use the CHANGE interrupt.

When you must use other pins, then the EnableInterrupt library can use the PCINT pins of an Arduino Mega 2560.

I only wrote about the EnableInterrupt library to show the possibilities. Don't be tempted to make things complicated, so don't use the EnableInterrupt library. Keep it as simple as possible. The Arduino Mega 2560 has 6 normal interrupts.

This is the pinmapping of the Arduino Mega 2560: http://www.pighixxx.com/test/portfolio-items/mega/