2016-09-08 6 views
0

PWM 신호 인 입력 신호를 읽으려고합니다. 나의 연구에서 나는 여기에 발견 된 몇 가지 유용한 기사를 발견했다 : http://www.instructables.com/id/Arduino-Frequency-Detection/?ALLSTEPS 그리고 여기 : http://www.camelsoftware.com/2015/12/25/reading-pwm-signals-from-an-rc-receiver-with-arduino/. 첫 번째 기사는 내 경험 수준을 약간 넘어서며 매우 잘 수행되는 것으로 보였지만 우노 이외의 다른 것을 사용하면 도움이되지 않습니다. 두 번째 방법은 내가 더 잘 이해할 수있는 방법을 보여줍니다.arduino를 사용하여 인터럽트로 신호 읽기

나는 다소 성공적으로 다음 코드를 사용하고 있습니다 :

#define input_pin 2 

volatile unsigned long timer_start; 
volatile int pulse_time; 

volatile int last_interrupt_time; 
void calcSignal() 
{ 
    last_interrupt_time = micros(); 

    if(digitalRead(input_pin) == HIGH) 
    { 
     timer_start = micros(); 
    } 
    else { 
     if(timer_start != 0) 
     { 
      //record the pulse time 
      pulse_time = ((volatile int)micros() - timer_start); 
      //restart the timer 
      timer_start = 0; 
     } 
    } 
} 


void setup() 
{ 
    timer_start = 0; 
    attachInterrupt(0, calcSignal, CHANGE); 
    Serial.begin(115200); 
} 

void loop() 
{ 
    Serial.println(pulse_time); 
    delay(20); 
} 

내 응용 프로그램이 설치 문제는 인터럽트는 현실적으로 내가 기간을 알아야 상태의 변화에 ​​의해 유발된다 얼마나 오래 그리고 얼마나 오래. 다양한 듀티 사이클 (https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM)으로 이상적인 신호 그림을 볼 수 있습니다. 나는 인터럽트 모드를 CHANGE에서 LOW와 HIGH로 변경하려고 시도했지만, 시리얼 모니터에서만 0을 출력하기 때문에 신용 할만한 결과를 얻지 못했다. 누락 된 라이브러리 나 사용할 수있는 대체 라이브러리/메소드가 있습니까? 나는 프로그래밍에 다소 익숙하다. 그래서 나는 약간의 이해를 가지고 있지만 결코 프로그래머가 아니다.

+0

궁금해 - 어떻게합니까 PWM 핸들 0 %와 100 % PWM 비율을 측정하는이 방법은? 감사합니다, –

+0

@MichaelVincent 100 % PWM 신호를 시도하지는 않았지만 0 % 신호 (연결되지 않은 입력)를 시도하고 직렬 모니터에 0의 스트림을 인쇄합니다. – paperstsoap

+0

감사합니다. 나는 당신의 코드에 논리적 인 문제가있을 것이라고 생각한다. 그것은 결코 일어나지 않거나 거의 발생하지 않을 수도 있습니다. 77 %의 듀티 사이클에서 PWM 입력이 있다고 가정 해보십시오. 입력이 낮아지면 새 시작 시간을 잡고 PWM 듀티 사이클이 0 %가됩니다. pulse_time이 0으로 업데이트되거나 77 %를 계속 표시합니까? 나는 문제가 존재한다면, mactro의 코드에도 있다고 생각한다. 친절한 의견, –

답변

0

어떻게 이런 일에 대해 :이 한주기 HI/LO을 측정 할 수 없습니다 그러나

unsigned long  timeout = 100000L; // reasonable timeout around 100ms? 
unsigned long  high_us = pulseIn(pinNo, HIGH, timeout); 
unsigned long  low_us = pulseIn(pinNo, LOW, timeout); 
unsigned long thousandths = (high_us*1000)/(high_us+low_us); 

. 그 중 두 가지를 측정합니다 : >HI< lo hi >LO<.

그리고 원하는 것이 아니라면 AVR 데이터 시트를 파고 타이머 입력 캡처 인터럽트가 작동하도록 시도 할 수 있습니다.

0

난 당신이 또 다른 타이머를 추가하여, 당신의 방법으로 갈 수 있다고 생각 :

void calcSignal() { 
    if(digitalRead(input_pin) == HIGH) 
    { // transition from LOW to HIGH 
     timerH_start = micros(); 
     //record the pulse time 
     pulse_time_L = ((volatile int)micros() - timerL_start); 
    } 
    else { // transition from HIGH to LOW 
     timerL_start = micros(); 
     //record the pulse time 
     pulse_time_H = ((volatile int)micros() - timerH_start);  
    } 
} 
+0

이 방법은 내가하고 싶은 일의 올바른 길에있는 것처럼 보입니다. 나는 오늘 그것을 어지럽히고 내가 얻은 것을 보게 될 것이다. 고맙습니다. – paperstsoap