AttachInterrupt em uma biblioteca

Estou tendo problemas para adicionar attachInterrupt em uma biblioteca que estou criando. Pesquisei muito e percebi que isso é comum erro, mas não entendi muito bem as respostas que encontrei.

O erro em questão é este:

sketch_nov04a.ino: In function "void setup()": sketch_nov04a:10: error: argument of type "void (Teste::)()" does not match "void (*)()" 

Minha biblioteca é a seguinte :

Teste.h

#ifndef TESTE_H #define TESTE_H #include <Arduino.h> class Teste { public: volatile long lastWindIRQ; volatile byte windClicks; void wspeedIRQ(); }; #endif 

Teste.cpp

#include "Teste.h" void Teste::wspeedIRQ() { if (millis() - this.lastWindIRQ > 10) { this.lastWindIRQ = millis(); this.windClicks++; } } 

minha implementação

#include <Teste.h> Teste teste; void setup() { Serial.begin(9600); pinMode(2, INPUT); digitalWrite(2, HIGH); attachInterrupt(0, teste.wspeedIRQ, FALLING); } void loop() { Serial.println(teste.windClicks); delay(3000); } 

EDITAR : Atualizado o erro e corrigido o problema citado por Ignacio

Resposta

O problema é que wspeedIRQ() é uma função membro (isto é, faz parte da classe Teste) , mas attachInterrupt() expe cts uma função não membro (ou seja, uma função que é estática e / ou não faz parte de uma classe).

Esta é uma distinção muito importante em C ++ porque afeta como o compilador chama a função nos bastidores. Infelizmente, não há como usar uma função de membro diretamente com attachInterrupt().

No entanto, várias soluções alternativas são possíveis. O mais simples é escrever uma função de invólucro que chama a função de membro. Por exemplo:

Teste teste; // This is a non-member function... void isr() { // ...which calls the member function: teste.wspeedIRQ(); } void setup() { //... // Setup interrupt to use a non-member function attachInterrupt(0, isr, FALLING); } 

Como uma observação lateral, sua implementação de wspeedIRQ() não “compilará no momento de qualquer maneira . O motivo é que this. é inválido. É um ponteiro, então a sintaxe correta é this->.

( Na prática, você normalmente não precisa usar this para acessar os dados dos membros. C ++ descobre isso automaticamente, a menos que haja um conflito de nomenclatura.)

Resposta

Normalmente, você deve usar digitalPinToInterrupt (pin) para traduzir o pino digital real para o número de interrupção específico, não para a comparação de chave de pino attachInturrupt (,,) que é limitado a pin 2,3 em um arduino uno … ou se você gastar mais dinheiro bem … aqui está uma lista.

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 all digital pins (Only pins 2, 5, 7, 8, 10, 11, 12, 13 work with CHANGE 

delay () não funcionará os valores b / c não retornarão do millis () (não pergunte por quê) https://www.arduino.cc/en/Reference/AttachInterrupt explica como usar interrupções, como deixe-me recitar o início g

As interrupções são úteis para fazer as coisas acontecerem automaticamente em programas de microcontroladores e podem ajudar a resolver problemas de temporização. Boas tarefas para usar uma interrupção podem incluir ler um codificador rotativo ou monitorar a entrada do usuário … blá, blá

o que pete não mencionou é o que eram rotinas de serviço de interrupção … e como essas funções especiais têm limitações exclusivas, outras funções como em c ++ não … de strings c a structs, sobrecarregando, f-structs e t-templates. ISRs são os mais curtos possíveis e não devem retornar nada! se você é barato e não quer gastar mais de $ 5 em um arduino, você pode usar o sketch para usar vários isr, você pode configurá-los como prioridade

mas suas funções não-membro devem ser voláteis e globais … e millis () depende de interrupções para contar, então nunca aumentará dentro de um ISR. Visto que delay () requer interrupções para funcionar, ele não funcionará se chamado dentro de um ISR. micros () funciona inicialmente, mas começará a se comportar erraticamente após 1-2 ms. delayMicroseconds () não usa nenhum contador, então funcionará normalmente. e …. variáveis globais são usadas para passar dados entre um ISR e o programa principal. Para garantir que as variáveis compartilhadas entre um ISR e o programa principal sejam atualizadas corretamente, declare-as como voláteis.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *