Port Manipulation Arduino Nano Every

I am trying to "port" the following code from nano to nano every. The nano code uses PIND to read pinA (digital pin 2) and pinB (digital pin 3) on line 11 of the code below.

But as I understand it PIND doesn't work for ATmega4809 on the nano every.

Was hoping someone might be able to help me understand how I could change the code to work on the nano every.

Thanks!

static int pinA = 2; // Our first hardware interrupt pin is digital pin 2
static int pinB = 3; // Our second hardware interrupt pin is digital pin 3
volatile byte aFlag = 0; 
volatile byte bFlag = 0; 
volatile byte encoderPos = 0; 
volatile byte oldEncPos = 0; 
volatile byte reading = 0; 

void PinA(){
  cli(); //stop interrupts happening before we read pin values
  reading =PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB's values
  if(reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    encoderPos --; //decrement the encoder's position count
    bFlag = 0; //reset flags for the next turn
    aFlag = 0; //reset flags for the next turn
  }
  else if (reading == B00000100) bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
  sei(); //restart interrupts
}

Pin D2 is is on PORTA, pin 0, so PINA,0, D3 is PORTF,5, PINF,5.

For the code fragment you've supplied, it will probably be something similar to this:

static int pinA = 2; // Our first hardware interrupt pin is digital pin 2
static int pinB = 3; // Our second hardware interrupt pin is digital pin 3
volatile byte aFlag = 0;
volatile byte bFlag = 0;
volatile byte encoderPos = 0;
volatile byte oldEncPos = 0;
volatile byte reading = 0;

void PinA(){
  cli(); //stop interrupts happening before we read pin values
  // reading =PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB's values
  // if(reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
  if ( ( PORTA.IN & PIN0_bm ) && ( PORTF.IN & PIN5_bm ) && aFlag )  { // if D2 && D3 check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    encoderPos --; //decrement the encoder's position count
    bFlag = 0; //reset flags for the next turn
    aFlag = 0; //reset flags for the next turn
  }
  // else if (reading == B00000100) bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
  else if ( PORTA.IN & PIN0_bm ) bFlag = 1; // if D2, signal that we're expecting pinB to signal the transition to detent from free rotation
  sei(); //restart interrupts
}

However, you may get away with just digitalRead( pinA ) and digitalRead( pinB ) instead of the direct port manipulation

1 Like

Thank you both!

That worked great and now I understand the port mappings and how they map to the arduino pins between different arduino devices. Good little lesson in how to read the ATmega4809 datasheet too.