Arduino Interupt on Port/pin Change
4 berichten
• Pagina 1 van 1
- astrofrostbyte
- Berichten: 229
- Geregistreerd: 20 Jan 2013, 12:01
Arduino Interupt on Port/pin Change
Ik wil gebruik maken van de mogenlijkheid van de 'pin change interupt'.
Dit is niet de zelfde interupt die je gebruikt met attachInterrupt(), de Uno heeft maar 2 interupt pootje.
Ik wil een pin change interupt op 4 pinnen op portC. dit schijnt te kunnen, echter 'lijkt'het heel omslachtig/moeilijk
Iemand hier ervaring mee ? of wat code voorbeeldjes ??
Doel:
Ik heb twee rotary encoders op Pinnen C0,C1 en C2,C3 van PortC.
Deze draaien soms heel snel en asynchroon van elkaar.
Om deze met zo min mogelijk software overhead af te handelen gebruik ik een grote 'state change jumptabel'
Deze tabel bevat alle mogelijke veranderingen aan de vier pinnen en wat er dan moet gebeuren.
Pseudo Code
Dit is niet de zelfde interupt die je gebruikt met attachInterrupt(), de Uno heeft maar 2 interupt pootje.
Ik wil een pin change interupt op 4 pinnen op portC. dit schijnt te kunnen, echter 'lijkt'het heel omslachtig/moeilijk
Iemand hier ervaring mee ? of wat code voorbeeldjes ??
Doel:
Ik heb twee rotary encoders op Pinnen C0,C1 en C2,C3 van PortC.
Deze draaien soms heel snel en asynchroon van elkaar.
Om deze met zo min mogelijk software overhead af te handelen gebruik ik een grote 'state change jumptabel'
Deze tabel bevat alle mogelijke veranderingen aan de vier pinnen en wat er dan moet gebeuren.
Pseudo Code
- 1- Interupt treed op omdat 1 of meer van de vier pinnen(twee rotary encoders) veranderd is
2- We springen automatisch naar de interupt routine <- Deze sprong moet ik nog uitvogelen/coderen
3- we berekenen een positie in een array aan de hand van huidige en vorige 4 pinnen status
4- we halen met deze bepaalde sprong een code uit het array bv 'dd' decrement|decrement
Dit wil dus zeggen dat beide rotary encoders naar links zijn gedraait
5- met deze code 'dd' springen we in een case naar de uit te voeren acties ch0-- en ch1--
6 klaar.
- Code: Alles selecteren
//-------------------------------------------------------------
// All possible action, first char is Ch0, second char is ch1
// n=nothing, d=Decrement, i=Increment, e=Error
#define nn 0
#define nd 1
#define ni 2
#define ne 3
#define dn 4
#define dd 5
#define di 6
#define de 7
#define in 8
#define id 9
#define ii 10
#define ie 11
#define en 12
#define ed 13
#define ei 14
#define ee 15
//-------------------------------------------------------------
byte statechange[] = { // jumptable with all 256 possible statechanges
nn,nd,ni,ne, dn,dd,di,de, in,id,ii,ie ,en,ed,ei,ee ,
ni,nn,ne,nd, di,dn,de,dd, ii,in,ie,id ,ei,en,ee,ed ,
nd,ne,nn,ni, dd,de,dn,di, id,ie,in,ii ,ed,ee,en,ei ,
ne,ni,nd,nn, de,di,dd,dn, ie,ii,id,in ,ee,ei,ed,en ,
//--
// ... all possible , ommited for code clarity
//--
};
//-------------------------------------------------------------
byte state, newstate, oldstate;
volatile int Err, Ch0, Ch1;
//-------------------------------------------------------------
void setup() {
Serial.begin(115200);
DDRC = B00000000; // set PortC pins as inputs
// rotary encoder Ch0 on PortC, C0 (pin23), C1 (pin24)
// rotary encoder Ch1 on PortC, C2 (pin25), C3 (pin26)
}
//-------------------------------------------------------------
// 'pin change interrupt' on 4 PortC C0..C3 pins (2 rotary encoders)
void StateChange()
{ state = PINC<<4 & 0xF0; // read portC
state |= (oldstate);
oldstate = state>>4 & 0x0F;
// state contains : newstate in upper nibble, oldstate in low nibble.
switch ( statechange[state] ) //[ch0][ch1]
{ case nn: break;
case nd: Ch1--; break;
case ni: Ch1++; break;
case ne: Err++; break;
case dn: Ch0--; break;
case dd: Ch0--; Ch1--; break;
case di: Ch0--; Ch1++; break;
case de: Ch0--; Err++; break;
case in: Ch0++; break;
case id: Ch0++; Ch1--; break;
case ii: Ch0++; Ch1++; break;
case ie: Ch0++; Err++; break;
case en: Err++; break;
case ed: Err++; Ch1--; break;
case ei: Err++; Ch1++; break;
case ee: Err++; Err++; break;
}//switch
}//StateChange
//-------------------------------------------------------------
void loop() {
Serial.print("\r");
Serial.print(Ch0); Serial.print(" ");
Serial.print(Ch1); Serial.print(" ");
Serial.print(Err);
delay(100);
}
Gear: Arduino- Uno,Due,Ethernet,Mega2560 , OLS LogicAnalyser, TDS1002, Rigol DG1022, J-Link EDU, BusPirate
Advertisement
Re: Arduino Interupt on Port/pin Change
Zelf heb ik daar ook nog geen ervaring mee, maar misschien kun je hier iets mee:
http://playground.arduino.cc/Main/PcInt
http://playground.arduino.cc/Main/PcInt
- astrofrostbyte
- Berichten: 229
- Geregistreerd: 20 Jan 2013, 12:01
Re: Arduino Interupt on Port/pin Change
Thank's zit dat net een beetje door te pluizen.. ff doorbijten .. moet wel lukken denk ik. Heb de datasheet van de ATmega328 ook open staan voor al die register bitjes.
update:
De Pcint library is bijna onleesbaar , vind ik altijd wat lastig om te gebruiken als je geen idee hebt wat het beesie doet.
De onderliggende basis is eigenlijk vrij simpel:
Een goede referentie gevonden : http://arduino.cc/forum/index.php/topic,141363.0.html
Kortom de Arduino heeft Veeeel meer interupts dan standaard aangeboden wordt door de omgeving.
update:
De Pcint library is bijna onleesbaar , vind ik altijd wat lastig om te gebruiken als je geen idee hebt wat het beesie doet.
De onderliggende basis is eigenlijk vrij simpel:
- Code: Alles selecteren
void setup() {
Serial.begin(115200);
DDRC = B00000000; // set PortC pins as inputs
// rotary encoder Ch0 on PortC, C0 (pin23), C1 (pin24)
// rotary encoder Ch1 on PortC, C2 (pin25), C3 (pin26)
PCICR |= _BV(PCIE1); //Enable PCINT //PinChangeIntControlReg
PCMSK1 = B00001111; // PinChangeMaskReg
}
//-------------------------------------------------------------
// 'pin change interrupt' on 4 PortC C0..C3 pins (2 rotary encoders)
//void StateChange()
ISR(PCINT1_vect)
{ state = PINC<<4 & 0xF0; // read portC
state |= (oldstate);
// ... knip ...
Een goede referentie gevonden : http://arduino.cc/forum/index.php/topic,141363.0.html
Kortom de Arduino heeft Veeeel meer interupts dan standaard aangeboden wordt door de omgeving.
Gear: Arduino- Uno,Due,Ethernet,Mega2560 , OLS LogicAnalyser, TDS1002, Rigol DG1022, J-Link EDU, BusPirate
Re: Arduino Interupt on Port/pin Change
Daar was ik precies naar op zoek. Voor mijn brandstofmeterproject heb ik al twee interrupts nodig voor de volumetellers van de aanvoer en retourleidingen. En dan wil ik daar sinds gisteren nog een rotaryswitch aan toevoegen voor het doorlopen van een menuutje met opties voor nulstellen van div. tussenstanden. Dan moeten in de tussentijd de pulstellers wel doorgaan met tellen natuurlijk. Dit berichtje komt dus precies op tijd.
Dank je wel!
Karel
Dank je wel!
Karel
If you think education is expensive, try ignorance! (Derek Bok)
4 berichten
• Pagina 1 van 1
Wie is er online?
Gebruikers in dit forum: Geen geregistreerde gebruikers en 6 gasten