using multiple pin change interrupts

I have a question about using interrupts and the reference pages did not really made it clear for me :

I want to use an interrupt on pin D10 en D11

At first I thought I could just use :

attachInterrupt(digitalPinToInterrupt(encoder2PinA), doEncoder2A, RISING) ;
attachInterrupt(digitalPinToInterrupt(encoder2PinB), doEncoder2B, CHANGE) ;

But that didn't work, so then I tried it with ISR() and masks :

ISR(PCINT2_vect)
{
  // interrupt on pin 10
  doEncoder2A() ;
}

ISR(PCINT3_vect)
{
  // interrupt on pin 11
  doEncoder2B() ;
}

Then I need to set the mask in the setup(), right?

// pin change interrupt
  PCMSK1 |= bit (PCINT2) ;  // we want pin 10
  PCMSK1 |= bit (PCINT3) ;  // we want pin 11
  PCIFR |= bit (PCIF0) ;    // clear any outstanding interrupts
  PCICR |= bit (PCIE0) ;    // enable pin change interrupts for D8 to D13

But also no luck. What am I overseeing?

Board Digital Pins Usable For Interrupts :

Uno, Nano, Mini, other 328-based 2, 3 Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21 Micro, Leonardo, other 32u4-based 0, 1, 2, 3, 7 Zero all digital pins, except 4 MKR1000 Rev.1 0, 1, 4, 5, 6, 7, 8, 9, A1, A2 Due all digital pins 101 all digital pins

What is your board ?

I have an Uno, but that should matter, right.

You van always attach interrupts on any pin andere that is what i'm trying.

I already have pins 2 and 3 in use with interrupts. I need 2 more pins.

stevennoppe: But also no luck. What am I overseeing?

You are going in the correct direction but you need to post a complete program.

...R PS. "overseeing" is what a supervisor does when he is checking the work of subordinates. "Overlooking" is what I do when I don't notice a mistake in my program - almost the opposite meaning :)

hehe, sorry for my bad English :slight_smile:

here is my full code, hopefully you can send me in the right direction

#include "MonsterMoto.h"

//PIN's definition
#define encoder1PinA  2
#define encoder1PinB  3

#define encoder2PinA  10
#define encoder2PinB  11

volatile int encoder1Pos = 0;
volatile boolean Past1A = 0;
volatile boolean Past1B = 0;

volatile int encoder2Pos = 0;
volatile boolean Past2A = 0;
volatile boolean Past2B = 0;

MonsterMoto drive ;

ISR(PCINT2_vect)
{
  // interrupt on pin 10
  doEncoder2A() ;
}

ISR(PCINT3_vect)
{
  // interrupt on pin 11
  doEncoder2B() ;
}

void setup() 
{
  Serial.begin(115200) ;
  
  pinMode(encoder1PinA, INPUT);
  pinMode(encoder1PinB, INPUT); 
  
  pinMode(encoder2PinA, INPUT);
  pinMode(encoder2PinB, INPUT);
  
  Past1A = (boolean)digitalRead(encoder1PinA); //initial value of channel A;
  Past1B = (boolean)digitalRead(encoder1PinB); //and channel B

  Past2A = (boolean)digitalRead(encoder2PinA); //initial value of channel A;
  Past2B = (boolean)digitalRead(encoder2PinB); //and channel B

//To speed up even more, you may define manually the ISRs
// encoder A channel on interrupt 0 (Arduino's pin 2)
  attachInterrupt(0, doEncoder1A, RISING);
// encoder B channel pin on interrupt 1 (Arduino's pin 3)
  attachInterrupt(1, doEncoder1B, CHANGE); 

  // pin change interrupt
  PCMSK1 |= bit (PCINT2) ;  // we want pin 10
  PCMSK1 |= bit (PCINT3) ;  // we want pin 11
  PCIFR |= bit (PCIF0) ;    // clear any outstanding interrupts
  PCICR |= bit (PCIE0) ;    // enable pin change interrupts for D8 to D13
  
  //attachInterrupt(digitalPinToInterrupt(encoder2PinA), doEncoder2A, RISING) ;
  //attachInterrupt(digitalPinToInterrupt(encoder2PinB), doEncoder2B, CHANGE) ;
}


void loop()
{  
 //your stuff....ENJOY! :D
 //drive.motorGo(0, CCW, 125) ;

 Serial.print("encoder 1 : ") ;
 Serial.print(encoder1Pos) ;
 Serial.print("\n") ;
 
 Serial.print("encoder 2 : ") ;
 Serial.print(encoder2Pos) ;
 Serial.print("\n") ;
}

//you may easily modify the code get quadrature..
//..but be sure this wouldn't let Arduino back! 
void doEncoder1A()
{
     Past1B ? encoder1Pos--:  encoder1Pos++;
}

void doEncoder1B()
{
     Past1B = !Past1B; 
}

void doEncoder2A()
{
     Past2B ? encoder2Pos--:  encoder2Pos++;
}

void doEncoder2B()
{
     Past2B = !Past2B; 
}

I believe you are using the wrong Pin change interrupt vector. For pins 10 and 11 you need PCINT0_vect (see Nick Gammon's Tutorial - easier to make sense of than the Atemga 328 datasheet)

Also, activity on either pin will trigger the same interrupt vector so the code in your ISR needs to use digitalRead() to figure out which pin caused the interrupt.

if you have the option it might be easier to use (say) pin 10 on PCINT0 and one of the pins (0 to 7) that use PCINT2. That way each pin would trigger a separate interrupt.

While it is not directly revelant I would put the code that you have in (for example) doEncoder2A() directly into the ISR rather than wasting CPU cycles calling that function from the ISR. (By the way I do not mean that the existing code is what you need).

...R

Robin2: You are going in the correct direction but you need to post a complete program.

...R PS. "overseeing" is what a supervisor does when he is checking the work of subordinates. "Overlooking" is what I do when I don't notice a mistake in my program - almost the opposite meaning :)

I bet this guy is german and you are not

clockw0rk: I bet this guy is german...

How much?

clockw0rk: I bet this guy is german and you are not

What has that got to do with the usage of English?

And, by the way, you are 9 months late to this party - check the dates of Replies before responding

...R