Hi
I want to know how to handle ports interrupts. In my new project I'm using int0 & int1 and I want to use port interrupt for handling buttons.
What I need
AttachPortInterrupt(PORTD,buttons,RISING)
void buttons()
{
...
}
I prefer code than library because now I'm using Mega but finally I'll use Sanguino (atm644)
you can't use attachInterrupt inside class...
I'm using the ISR() function, is a little more low level but it works ;)
This is only for showing what I mean.
Yes I know that it 'll be more complex, can You show how You use it?
i use that class to read PPM channel:
InputPin.cpp
#include "InputPin.h"
#include "Utils.h"
/*
Let You read digital pin 2,4,5,6
FROM BIRONPILOT V59, tnx to ciskje
*/
//#define MAXUNSIGNEDLONGCVALUE 4294967295
#define MASKPCINT0 (1<<2)
#define MASKPCINT1 (1<<4)
#define MASKPCINT2 (1<<5)
#define MASKPCINT3 (1<<6)
//define necessary values
#define MIN_RADIO_VALUE 1100
#define MAX_RADIO_VALUE 1950
#define maxReceiverAngle 0.5f
//maxReceiverAngle is in radiant
Utils utils;
InputPin::InputPin(){
pinMode(2, INPUT); // 3 is used for esc
pinMode(4, INPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
// interrupt on pin change FROM PCINT16 to PCINT23
PCICR |= (1 << PCIE2);
PCMSK2 = (1 << PCINT18) | // digital pin2
(1 << PCINT20) | // digital pin4
(1 << PCINT21) | // digital pin5
(1 << PCINT22); // digital pin6
}
//putted here because interrupt dosn't want it in .h
unsigned long _startIn[4];
unsigned long _rawIn[4];
unsigned long _time;
byte _oldbit=0, _newbit, _changed;
volatile boolean _hasChanged=false;
ISR(PCINT2_vect) {
_time=micros();
_newbit=PIND;
_changed=_newbit^_oldbit;
if (_changed&MASKPCINT0){//if digital PIN2 has changed
if (_newbit&MASKPCINT0) { //if PIN2 now is high
_startIn[0]=_time;
}else{
_rawIn[0]=_time-_startIn[0];
}
_hasChanged=true;
}
if (_changed&MASKPCINT1){//if digital PIN4 has changed
if (_newbit&MASKPCINT1)
_startIn[1]=_time;
else
_rawIn[1]=_time-_startIn[1];
_hasChanged=true;
}
if (_changed&MASKPCINT2){//if digital PIN5 has changed
if (_newbit&MASKPCINT2)
_startIn[2]=_time;
else
_rawIn[2]=_time-_startIn[2];
_hasChanged=true;
}
if (_changed&MASKPCINT3){//if digital PIN6 has changed
if (_newbit&MASKPCINT3)
_startIn[3]=_time;
else
_rawIn[3]=_time-_startIn[3];
}
_oldbit=_newbit;
}
bool InputPin::getAndSetFalseHasChanged(){
bool temp = _hasChanged;
_hasChanged = false;
return temp;
}
int InputPin::getDuration(int i){
return _rawIn[i];
}
int InputPin::getDuration(int i, int minValue, int maxValue){
return map(_rawIn[i] , MIN_RADIO_VALUE, MAX_RADIO_VALUE, minValue, maxValue );
}
float InputPin::getAngle(int i){
return utils.mapFloat( _rawIn[i], MIN_RADIO_VALUE, MAX_RADIO_VALUE, -maxReceiverAngle, maxReceiverAngle );
}
InputPin.h
#ifndef InputPin_h
#define InputPin_h
#include "WProgram.h"
class InputPin{
public:
InputPin();
bool getAndSetFalseHasChanged(); // send the initilization handshake
int getDuration(int); //return the raw duration of high signal, input: channel
float getAngle(int); //return the duration mapped from -PI to PI, input: channel
int getDuration(int, int, int); //return the duration mapped in the range, input: channel, min value, max value
private:
};
#endif
Thank You for the code it is very usefull 
There is problem when compiling with Utils utils compiler says that Utils does not name a type (arduino 0.21)
Also how to mask outher pins not only 2.4.5.6 ? 
Utils is a my own class that you don't need. delete the include, and all function using the class utils
With help from lesto i managed to run port change interrupts on Arduino MEGA 
Here is code for Interested 
#define B_up A8
#define B_down A9
#define B_left A10
#define B_right A11
void setupPortInt()
{
pinMode(B_up, INPUT);
pinMode(B_down, INPUT);//!!! ALL THOSE PINS MUST BE GROUNDED WITH PULLDOWN RESISTORS!
pinMode(B_left, INPUT);
pinMode(B_right, INPUT);
//SETINGS FOR MEGA interrupts on port change A8-A15(PCINT16-23)
PCMSK2 |= (1 << PCINT16) | // analog a8
(1 << PCINT17) | // a9
(1 << PCINT18) | // a10
(1 << PCINT19); // a11 (
PCICR |= (1 << PCIE2);
}
//Port interrupt function
int count[4];
ISR(PCINT2_vect)
{
_time=millis();//For futher use in debouncing
if(digitalRead(A8)==HIGH) count[0]++;
if(digitalRead(A9)==HIGH) count[1]++;
if(digitalRead(A10)==HIGH) count[2]++;
if(digitalRead(A11)==HIGH) count[3]++;
}
//----------------
Just activate the interrupts with setupPortInt() and write what arduino should do in ISR function
there is a big error.
if you do
if(digitalRead(A8)==HIGH) count[0]++;
if(digitalRead(A9)==HIGH) count[1]++;
if(digitalRead(A10)==HIGH) count[2]++;
if(digitalRead(A11)==HIGH) count[3]++;
inside the ISR you have 2 problem: first of all you are doing another non-nessesary function, as with
_newbit=PIND;
_changed=_newbit^_oldbit;
you have in _changed all pin that has changed state (and all in one hit!)
seconds, digitalread is slow, and this is bad for timer.
Thanks :)
I think that my code is bad but simpler to understand for beginers :) Yours is great :)