MCUdude / MajorCore

An Arduino hardware package for ATmega8515 and ATmega162
GNU Lesser General Public License v2.1
39 stars 10 forks source link

ATmega8515 interrupt routine #5

Closed javest closed 6 years ago

javest commented 7 years ago

I'm trying to use interrupts on atmega8515

i'm trying to decode a quadrature decoder using two input pins with interrupts. The funcion"decodeEndoder()" works on attiny85. It is the correct way to attach interrupts? It seems that digitalread inside ISR routine doesn't give us the right value.

This is our code. Do you have any example of using interrupts whit your library?

#include "avr/interrupt.h";

volatile int lastEncoded = 0;
volatile int direction = 0;       // 1 = senso orario          0 = senso antiorario
volatile int clock = 0;           //manda un incremento come fronte di salita

const int encPinA = 10;
const int encPinB = 11;
const int outPinClock = 8;
const int outPinDir = 9;

unsigned char enc_dir;
unsigned char enc_last=0;
unsigned char enc_now;

void setup()
{
  pinMode(encPinA, INPUT);
  pinMode(encPinB, INPUT);
  digitalWrite(encPinA, HIGH);
  digitalWrite(encPinB,HIGH);
  pinMode(outPinClock, OUTPUT);
  pinMode(outPinDir, OUTPUT);

  attachInterrupt(digitalPinToInterrupt(encPinA),decodeEncoder,CHANGE);
  attachInterrupt(digitalPinToInterrupt(encPinB),decodeEncoder,CHANGE);
}

void loop()
{
}

// This is the ISR that is called on each interrupt
// Taken from http://bildr.org/2012/08/rotary-encoder-arduino/

void decodeEncoder()
{
  int MSB = digitalRead(encPinA); //MSB = most significant bit
  int LSB = digitalRead(encPinB); //LSB = least significant bit

  int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
  int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

  if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
  {
    digitalWrite(outPinDir,HIGH);
    digitalWrite(outPinClock, HIGH);
    digitalWrite(outPinClock, LOW);
  }

  if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
  {
    digitalWrite(outPinDir,LOW);
    digitalWrite(outPinClock, HIGH);
    digitalWrite(outPinClock, LOW);
  }
  lastEncoded = encoded; //store this value for next time

}
MCUdude commented 7 years ago

There's no reason why it should't work. Both INT0 and INT1 are working just fine; just tested it on my STK500 dev board.

Does this example code toggle PB0 when INT0 or INT1 changes state?


volatile int lastEncoded = 0;
volatile int direction = 0;       // 1 = senso orario          0 = senso antiorario
volatile int clock = 0;           //manda un incremento come fronte di salita

const int encPinA = 10;
const int encPinB = 11;
const int led = 0;

void setup()
{
  pinMode(encPinA, INPUT);
  pinMode(encPinB, INPUT);
  digitalWrite(encPinA, HIGH);
  digitalWrite(encPinB,HIGH);
  pinMode(led, OUTPUT);

  attachInterrupt(digitalPinToInterrupt(encPinA),decodeEncoder,CHANGE);
  attachInterrupt(digitalPinToInterrupt(encPinB),decodeEncoder,CHANGE);
}

void loop()
{
}

void decodeEncoder()
{
 PORTB ^= _BV(PB0);

}