Arduino e interrupções: maneira rápida de obter valores de pinos


11

Eu uso um Arduino Uno e já o configurei para funcionar com interrupções nos pinos digitais 2, 3, 4 e 5 de acordo com uma explicação 1 que encontrei.

void setup() contém o seguinte código para configurar as interrupções.

  //Endable Interrupts for PCIE2 Arduino Pins (D0-7)
  PCICR |= (1<<PCIE2);

  //Setup pins 2,3,4,5
  PCMSK2 |= (1<<PCINT18);
  PCMSK2 |= (1<<PCINT19);
  PCMSK2 |= (1<<PCINT20);
  PCMSK2 |= (1<<PCINT21);

  //Trigger Interrupt on rising edge
  MCUCR = (1<<ISC01) | (1<<ISC01);

E agora, a função ISR (PCINT2_vect) é acionada a cada interrupção. Isso funciona como um encanto. Minha pergunta é: qual é a melhor / mais rápida maneira de descobrir qual pino foi acionado?

Encontrei algo em Re: É melhor usar o ISR (PCINT2_vect) ou attachInterrupt nos pinos 2, 3? , mas não entendo o código e ele não funciona imediatamente. Mas parece impressionante ...

Qual é a solução?

[2] http://arduino.cc/forum/index.php/topic,72496.15.html#lastPost

Editar:

No momento, estou lendo o estado do pino a partir do registro do pino de entrada:

  if (PIND & 0b00000100)
    Serial.println( "PIN 2" );
  if (PIND & 0b00001000)
    Serial.println( "PIN 3" );
  if (PIND & 0b00010000)
    Serial.println( "PIN 4" );
  if (PIND & 0b00100000)
    Serial.println( "PIN 5" );

No final, quero contar as interrupções nos pinos. Mas como posso garantir que não são contadas duas vezes?


Na eletrônica, mais pessoas provavelmente mexeram com Arduinos e outras coisas eletrônicas.
Earlz 28/09/11

Se você acha que a pergunta deveria estar ali, sinalize-a. Resolvi meus problemas de login.
madc 28/09/11

3
@Earlz: Esta é uma questão de programação, por isso é sobre tópico . O fato de ser para uma plataforma amadora é irrelevante; veja as centenas de outras perguntas sobre arduino no stackoverflow para referência.
BlueRaja - Danny Pflughoeft 30/09

Respostas:


4

Eu mesmo tenho uma primeira solução, mas não pude testar a confiabilidade, pois o hardware não está finalizado.

Primeiro, adicionei oldPins e tickCount como variáveis ​​globais:

static byte oldPins = 0;
volatile unsigned int tickCount[4] = { 0, 0, 0, 0 };

E foi assim que resolvi o ISR no momento. Melhores soluções são mais que bem-vindas.

ISR( PCINT2_vect ) {
  //Read values from digital pins 2 to 7
  const byte actPins = PIND;
  //Match this values agaist the oldPins bitmask (XOR and AND for raising edge)
  const byte setPins = (oldPins ^ actPins) & actPins;

  if (setPins & 0b00000100)
    tickCount[0]++;
  if (setPins & 0b00001000)
    tickCount[1]++;
  if (setPins & 0b00010000)
    tickCount[2]++;
  if (setPins & 0b00100000)
    tickCount[3]++;

  oldPins = actPins;
}

1
Se você estiver atualizando tickCount [] em um ISR, declare-o com o qualificador de tipo 'volátil'.
icarus74

Eu atualizei o código dentro da resposta. Para obter mais informações, consulte a documentação do arduino: arduino.cc/en/Reference/Volatile
madc
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.