Сквозная переда данных с одного канала на другой

Amrel
Offline
Зарегистрирован: 12.11.2013

Помогите пожалуйста, не могу реализовать функцию сквозной передачи с одного канала на другой, а именно: я на канал 9 завел сигнал с приемника радио аппаратуры "футаба" - то есть сигнал для серво привода, мне его нужно передать на канал 10 без изменений.

void loop()
{
  val = digitalRead(9);      // считываем значение с канала
  digitalWrite(10, val);     // устанавливаем значение на канал
}

 

При этом серво привод управляется, но не точно и постоянно подергивается, я думаю это из-за того что сигнал не является цифровым.

а так:

void loop()
{
  val = analogRead(9);     
  analogWrite(10, val);   
}

Ничего не происходит.

Подскажите пожалуйста как правильно реализовать это.


vk007
Offline
Зарегистрирован: 16.06.2015

Не понимаю зачем здесь ардуина если сигнал надо передать без изменений? Для такого случая кусок провода самое то.

Als
Offline
Зарегистрирован: 17.05.2015

Amrel пишет:

При этом серво привод управляется, но не точно и постоянно подергивается, я думаю это из-за того что сигнал не является цифровым.

Там положение серво определяется скважностью ШИМ частотой примерно 500Гц. Функции digitalRead, digitalWrite для этого медленные. Нужно использовать прямой доступ к портам атмеги.

 

Amrel
Offline
Зарегистрирован: 12.11.2013

Als пишет:

Amrel пишет:

При этом серво привод управляется, но не точно и постоянно подергивается, я думаю это из-за того что сигнал не является цифровым.

 Нужно использовать прямой доступ к портам атмеги.

Модно по подробнее, пожалуйста.

Amrel
Offline
Зарегистрирован: 12.11.2013

vk007 пишет:

Не понимаю зачем здесь ардуина если сигнал надо передать без изменений? Для такого случая кусок провода самое то.

Ардуина в зависимости от ситуации: то передает без изменений, то управляет серво приводом сама.

vk007
Offline
Зарегистрирован: 16.06.2015

Ну тогда может лучше так?

Включаем ключ, когда идет внешнее управление, а на время управления от ардуины выключаем его.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

если передавать тоже самое то тогда непонятно нафига))) провод посоветовали уже

+ теперь понятно

Amrel
Offline
Зарегистрирован: 12.11.2013

vk007 пишет:

Ну тогда может лучше так?

Включаем ключ, когда идет внешнее управление, а на время управления от ардуины выключаем его.

Я тоже склоняюсь к этому варианту, но что использовать электронный ключ или реле?
Желательно электронный ключ, но какой именно выбрать? посоветуйте пожалуйста. 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
#define PPM_pin      A0
byte PPM;
unsigned long time;


void setup(){
  Serial.begin(115200);
  pinMode(PPM_pin, INPUT);
}

void loop(){
  PPM_read();
  Serial.println(PPM);
  delay(200);
  
}

//=============================================================================
//                           Считывание сигнала PPM
//=============================================================================
void PPM_read(){
  while(digitalRead(PPM_pin) == 0);
  time = micros();
  while(digitalRead(PPM_pin) == 1);
  time = micros()-time;
  if (time>535 && time<2385) PPM = map_X(time, 536, 2384, 0, 180);
  //Serial.println(time);
}


//=============================================================================
//                          Переделанная функция MAP
//=============================================================================
int map_X(int x, long in_min, long in_max, int out_min, int out_max){
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

пользуйся

Als
Offline
Зарегистрирован: 17.05.2015

Amrel пишет:

Желательно электронный ключ, но какой именно выбрать? посоветуйте пожалуйста. 

Почти любой. Я для подобных целей купил у китайцев 2n7000. Он и в линейном режиме работает хорошо.

Amrel
Offline
Зарегистрирован: 12.11.2013

jeka_tm пишет:

#define PPM_pin      A0
byte PPM;
unsigned long time;


void setup(){
  Serial.begin(115200);
  pinMode(PPM_pin, INPUT);
}

void loop(){
  PPM_read();
  Serial.println(PPM);
  delay(200);
  
}

//=============================================================================
//                           Считывание сигнала PPM
//=============================================================================
void PPM_read(){
  while(digitalRead(PPM_pin) == 0);
  time = micros();
  while(digitalRead(PPM_pin) == 1);
  time = micros()-time;
  if (time>535 && time<2385) PPM = map_X(time, 536, 2384, 0, 180);
  //Serial.println(time);
}


//=============================================================================
//                          Переделанная функция MAP
//=============================================================================
int map_X(int x, long in_min, long in_max, int out_min, int out_max){
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

пользуйся


 

Огромное спасибо. А почему такое большое время отклика?

maksim
Offline
Зарегистрирован: 12.02.2012
   delay(200);

 

Amrel
Offline
Зарегистрирован: 12.11.2013

maksim пишет:

   delay(200);

Спасибо, не увидел сразу... 

Amrel
Offline
Зарегистрирован: 12.11.2013

jeka_tm пишет:

#define PPM_pin      A0
byte PPM;
unsigned long time;


void setup(){
  Serial.begin(115200);
  pinMode(PPM_pin, INPUT);
}

void loop(){
  PPM_read();
  Serial.println(PPM);
  delay(200);
  
}

//=============================================================================
//                           Считывание сигнала PPM
//=============================================================================
void PPM_read(){
  while(digitalRead(PPM_pin) == 0);
  time = micros();
  while(digitalRead(PPM_pin) == 1);
  time = micros()-time;
  if (time>535 && time<2385) PPM = map_X(time, 536, 2384, 0, 180);
  //Serial.println(time);
}


//=============================================================================
//                          Переделанная функция MAP
//=============================================================================
int map_X(int x, long in_min, long in_max, int out_min, int out_max){
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

пользуйся

Нашел как измерить длину сигнала проще:

int ch1 = pulseIn (chA,HIGH); // Считывает длину сигнала на заданном порту chA

Но и тот и другой метод имеет сильные временные задержки если опрашивать 4 и более портов.

Можно было бы разнести каждое ожидание в разные потоки, но ардуино не имеет многопоточности. Что посоветуете это можно как либо решить? считывать несколько PPM сигналов без временных задержек?

 

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

проще? да это почти тоже самое)))

только еще проверяет длительность на минимальные и максимальные значения и сразу пересчитывает в PPM. функция map немного уменьшена, так как писал код для тиньки, а там оперативки очень мало

без временных задержек это по прерыванию

Amrel
Offline
Зарегистрирован: 12.11.2013

jeka_tm пишет:

без временных задержек это по прерыванию

jeka_tm, подскажите пожалуйста по какому событию делать прерывания? по digitalRead(PPM_pin) == 1?

Amrel
Offline
Зарегистрирован: 12.11.2013

jeka_tm пишет:

без временных задержек это по прерыванию

Как то так?

#define PPM_pin 8
byte PPM;
unsigned long time;

void setup()
{
  attachInterrupt(8, bl, RISING); blink().
}

void loop()
{
 }

void bl ()
{
  while(digitalRead(PPM_pin) == 0);
  time = micros();
  while(digitalRead(PPM_pin) == 1);
  time = micros()-time;
  if (time>535 && time<2385) PPM = map_X(time, 536, 2384, 0, 180);
  //Serial.println(time);
}

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

неа. а вообще таким способом ты мксимум 2 канала сделаешь

но думаешь в нужную сторону. нужно использовать режим change. срабатывает на любое изменение. и измерять время между вызовами прерывания, если соответствует нужному диапазону значит можно использовать и пересчитывать

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

2.....    или больше......
Что-то было, помню, про PinChangeInterrupt......
А как превалось - обрабатываем  то что засквозило со входа    и  сквозим на выход.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ну вот. можно и больше. только разобраться с правильным использованием PinChangeInterrupt