2016-09-08 2 views
0

Я пытаюсь прочитать входной сигнал от источника, который является сигналом ШИМ. В своем исследовании я нашел несколько полезных статей, которые можно найти здесь: 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/. Первая статья немного выше моего уровня опыта, и было бы не полезно, если бы я использовал что-то другое, чем uno, хотя, похоже, он работает очень хорошо. Второй показывает метод, который я смог лучше понять.Чтение сигнала с прерываниями с использованием 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

Просто интересно - как это делает метод измерения PWM ручки 0% и 100% отношения ШИМ? Спасибо, –

+0

@MichaelVincent Я не пробовал 100% -ный сигнал pwm, но я пробовал сигнал 0% (отключенный вход), и он печатает поток нулей на последовательном мониторе. – paperstsoap

+0

Спасибо. Я думаю, что с вашим кодом может возникнуть логическая проблема. Это может никогда не произойти или встречаться редко. Представьте, что у вас есть вход PWM, например, на 77%. Вход идет низко, вы захватываете новое время начала, затем рабочий цикл PWM переходит в 0%. Будет ли обновлено pulse_time, чтобы показать 0, или он будет продолжать показывать 77%? Я думаю, что проблема, если она существует, также находится в коде макта. С уважением, –

ответ

0

А что-то вроде этого:

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 hi >LO<.

И если это не то, что вы хотите, вы можете вникнуть в AVR DataSheet и попытаться заставить прерывания ввода таймера работать.

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

Смежные вопросы