라이브러리의 AttachInterrupt

내가 만들고있는 라이브러리에 attachInterrupt를 추가하는 데 문제가 있습니다. 많은 연구를했는데 이것이 일반적인 현상이라는 것을 알았습니다. 실수했지만 내가 찾은 답을 잘 이해하지 못했습니다.

문제의 오류는 다음과 같습니다.

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

내 라이브러리는 다음과 같습니다. :

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++; } } 

내 구현

#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); } 

수정 : 오류를 업데이트하고 Ignacio가 인용 한 문제를 수정했습니다.

답변

문제는 wspeedIRQ()가 멤버 함수라는 것입니다 (즉, Teste 클래스의 일부). , 그러나 attachInterrupt() expe cts 비 멤버 함수 (예 : 정적 및 / 또는 클래스의 일부가 아닌 함수).

이것은 컴파일러가 백그라운드에서 함수를 호출하는 방식에 영향을 미치기 때문에 C ++에서 매우 중요한 차이점입니다. 안타깝게도 attachInterrupt()와 함께 멤버 함수를 직접 사용할 수있는 방법은 없습니다.

하지만 다양한 해결 방법이 가능합니다. 가장 간단한 방법은 멤버 함수를 호출하는 래퍼 함수를 작성하는 것입니다. 예를 들면 다음과 같습니다.

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); } 

참고로 wspeedIRQ()의 구현은 어쨌거나 현재 컴파일되지 않습니다. . 그 이유는 this.가 유효하지 않기 때문입니다. “포인터이므로 올바른 구문은 this->입니다.

( 실제로 멤버 데이터에 액세스하기 위해 일반적으로 “this를 사용할 필요가 없습니다. C ++에서”이름 충돌이 발생하지 않는 한 자동으로 파악합니다.)

Answer

일반적으로 digitalPinToInterrupt (pin)을 사용하여 실제 디지털 핀을 핀 스위치 비교 attachInturrupt (,,)가 아닌 특정 인터럽트 번호로 변환해야합니다. arduino uno의 핀 2,3으로 제한됩니다. 또는 더 많은 돈을 잘 쓰는 경우 … 여기 “목록.

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 () 작동하지 않음 b / c 값이 millis ()에서 반환되지 않음 (이유를 묻지 않음) https://www.arduino.cc/en/Reference/AttachInterrupt 내가 시작을 암송하게하는 것과 같은 inturrupts를 사용하는 방법을 설명합니다 g

인터럽트는 마이크로 컨트롤러 프로그램에서 자동으로 일이 발생하도록하는 데 유용하며 타이밍 문제를 해결하는 데 도움이 될 수 있습니다. 인터럽트를 사용하기위한 좋은 작업에는 로터리 엔코더 읽기 또는 사용자 입력 모니터링이 포함될 수 있습니다 …. blah blah

피트가 언급하지 않은 것은 인터럽트 서비스 루틴이 무엇인지 … 그리고 이러한 특수 기능이 어떤 것인지입니다. C ++에서와 같은 다른 함수는하지 않는 고유 한 제한이 있습니다 …. c- 문자열에서 구조체, f- 구조, t- 템플릿에 대한 오버로딩에 이르기까지 ISR “은 가능한 한 짧으며 아무것도 반환하지 않아야합니다! 저렴하고 arduino에 5 달러 이상을 지출하고 싶지 않다면 스케치를 사용하여 여러 isr을 사용할 수 있습니다. 우선 순위로 설정할 수 있습니다.

하지만 비 멤버 함수는 휘발성과 글로벌이어야합니다. … 그리고 millis ()는 카운트를 위해 인터럽트에 의존하므로 ISR 내에서 절대 증가하지 않습니다. delay () 작동하려면 인터럽트가 필요하므로 ISR 내부에서 호출하면 작동하지 않습니다. micros ()는 처음에 작동하지만 1-2ms 후에 비정상적으로 작동하기 시작합니다. delayMicroseconds ()는 카운터를 사용하지 않으므로 정상적으로 작동합니다. 그리고 …. 전역 변수는 ISR과 메인 프로그램간에 데이터를 전달하는 데 사용됩니다. ISR과 기본 프로그램간에 공유되는 변수가 올바르게 업데이트되도록하려면 변수를 휘발성으로 선언하십시오.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다