Измерение длины импульсов импульсов сервопривода.

Olscraft
Offline
Зарегистрирован: 19.09.2020

Здравствуйте! Я хочу управлять устройством через радиаппаратуру, приёмник выдаёт на выходе сигнал как для сервопривода. Как я понял в сигнале сервопривода изменяется только длина импульсов, а частота неизменна. Вопрос в том как её измерить, прост нигде ничего подобного не нашёл.

Буду рад любой помощи.

b707
Онлайн
Зарегистрирован: 26.05.2017

Ищите тему " измерение частоты ШИМ" , хотя речь идет о частоте - принцип тот же

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

С помощью pulseIn

int duration;
void setup(){
    pinMode(3, INPUT);
    pinMode(4, OUTPUT);
}

void loop(){
    duration = pulseIn(3, HIGH, 5);
    digitalWrite(4, LOW);
    if (duration > 1900)  {
        digitalWrite(4, HIGH);
     }
}

https://fpv-freun.de/en/avr-projects/72-rc-schalter-mit-attiny-13

5 (или 10) там нужно добавить потому что на тини13 без него не компилится

 

Olscraft
Offline
Зарегистрирован: 19.09.2020
int duration;
void setup(){
  pinMode(3, INPUT);

  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  digitalWrite(10, LOW);
  Serial.begin(9600);
}

void loop(){
  duration = pulseIn(3, HIGH, 5);
  digitalWrite(11, LOW);
  Serial.println(duration);
  if (duration > 1900)  {
    digitalWrite(11, HIGH);
  }
}

#2 У меня почему-то не работает. Я добавил вывод значения duration в консоль, и оно всегда равно нулю.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/

pulseIn(pin, value, timeout)
...
timeout (optional): the number of microseconds to wait for the pulse to start; default is one second. Allowed data types: unsigned long.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Поставьте ожидание 1000 для проверки

Olscraft
Offline
Зарегистрирован: 19.09.2020
int duration;
void setup(){
  pinMode(3, INPUT);//к приёмнику
  pinMode(11, OUTPUT);//выход
  digitalWrite(10, LOW);
  Serial.begin(9600);
}

void loop(){
  duration = pulseIn(3, HIGH);/*
  ожидает пока на заданном порту не появиться HIGH.
  Когда HIGH получен, включается таймер, который будет остановлен
  когда на порту будет LOW
  */
  digitalWrite(11, LOW);
  Serial.println(duration);
  if (duration > 1900)  {
    digitalWrite(11, HIGH);
  }
}

Заработало! Нужно было убрать таймаут.

b707
Онлайн
Зарегистрирован: 26.05.2017

Вы не "убрали" таймаут, а поставили его дефолтно 1 секунду. С вашим типом переменной duration это глупо, ведь у вас длина импульса не может быть больше 32 миллисекунд
И, кстати, если реальный импульс на вашей серве превысит 32.7 мс - ваш код начнет показывать погоду на марсе вместо длины импульса, подумайте об этом

nik182
Offline
Зарегистрирован: 04.05.2015

У сервы импульс от 800 до 2400 мкс. Так что инт вполне для этой задачи.

b707
Онлайн
Зарегистрирован: 26.05.2017

Ну ок, инт нормально, но таймаут 1 сек будет тормозить программу

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

 это надо делать правильно вот пример на два канала (для аппаратуры управления)

/*
 * Измерение PWM через micros()
 * Используется 0 прерывание (пин D2)
 */
volatile unsigned int rc1_data = 0;
volatile unsigned long start_timeRC1 = 0;
volatile byte flag_RC1 = 0;

/******Обработчик прерывания по возрастанию и спаду сигнала с приёмника RC******/
void Rc1() {
if(digitalRead(2) == HIGH && flag_RC1==0){
     //сохраняем значение времени начала импульса
start_timeRC1 = micros();
flag_RC1=1;
    }
if(digitalRead(2) == LOW && flag_RC1==1){
    //сохраняем значение длительности импульса канала 1
rc1_data = micros() - start_timeRC1; 
flag_RC1=0; 
    }
   }//END RC1


void setup() {
  Serial.begin(115200);
// Привязываем к Pin2 прерывание по фронту и спаду сигнала
attachInterrupt(0, Rc1, CHANGE);
}

void loop() {
 Serial.println(rc1_data);
 delay(1000);
}

 

nik182
Offline
Зарегистрирован: 04.05.2015

b707 пишет:
Ну ок, инт нормально, но таймаут 1 сек будет тормозить программу

Нет, не будет. Пока идут импульсы таймаут вообще не при делах. Если импульсов нет, то нет разницы нет где висит программа. Приход первого импульса опять обнулит таймаут и программа сразу отреагирует. Тормозов не будет. Но для вообще универсальности таймаут всё же было бы хорошо установить где то как 30000. Особенно если в лупе будет ещё что то кроме светодиодиков.