Управление электродвигателями с помощью радио передатчика

ArdoMax659
Offline
Зарегистрирован: 06.11.2017

Всем привет!

Имеется Arduino Nano, H-мост L298N, два стандартных электродвигателя, приемник FrSky X8R, Li-Po батарея 7.4V.

Задача: с помощью двух каналов управлять двумя двигателями, где первый канал используется как газ вперед и назад, а второй канал для поворотов с помощью разности скоростей.

Питание от батареи параллельно подаю на ресивер, Arduino и H-мост. Считывание радиосигнала ШИМ с помощью прерываний. В принципе всё работает как планировалось, но с повышением оборотов двигателей сигнал как бы пропадает иногда и получается, что двигатели дёргаются. Если двигатели отключить от цепи, то приём и обработка сигнала проходят без проблем.

Уже пару дней не могу понять в чём проблема, в интернете полно схем и примеров с кодом, но в основном для джойстиков, а не для радио ресиверов. У меня джойстика нет, но есть потенцометер, с ним всё работает нормально.

В чём может быть проблема?

Спасибо!

 

 

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

скетч и схему подключения в студию, без них разговор не имеет смысла.

ArdoMax659
Offline
Зарегистрирован: 06.11.2017
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7

#define THROTTLE_IN_PIN 2
#define STEERING_IN_PIN 3

#define THROTTLE_FLAG 1
#define STEERING_FLAG 2

#define SRC_NEUTRAL 1500
#define TRC_NEUTRAL 1500
#define pERROR 100  

volatile uint8_t  bUpdateFlagsShared = 0;

volatile uint16_t unThrottleInShared = TRC_NEUTRAL;
volatile uint16_t unSteeringInShared = SRC_NEUTRAL;

int OldX = 500;
int OldY = 500;

volatile uint32_t ulThrottleStart = 0;
volatile uint32_t ulSteeringStart = 0;

int motorSpeedA = 0;
int motorSpeedB = 0;

void setup() 
{
  Serial.begin(9600);
  
  attachInterrupt(0, calcThrottle, CHANGE);
  attachInterrupt(1, calcSteering, CHANGE);
  
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  
}

void loop() 
{

  static uint16_t unThrottleIn;
  static uint16_t unSteeringIn;
 
  static uint8_t  bUpdateFlags;

  if (bUpdateFlagsShared)
  {
    noInterrupts(); 

    bUpdateFlags = bUpdateFlagsShared;

    if(bUpdateFlags & THROTTLE_FLAG)
      unThrottleIn = unThrottleInShared;

    if(bUpdateFlags & STEERING_FLAG)
      unSteeringIn = unSteeringInShared;

    bUpdateFlagsShared = 0;

    interrupts(); 
  }

  unThrottleIn = constrain(unThrottleIn, 980, 2020);
  unSteeringIn = constrain(unSteeringIn, 980, 2020);

  int yVal = map(unThrottleIn, 980, 2020, -pERROR, 1023+pERROR); 
  int xVal = map(unSteeringIn, 980, 2020, -pERROR, 1023+pERROR);

  yVal = constrain(yVal, 0, 1023);
  xVal = constrain(xVal, 0, 1023);
 
  int yAxis = yVal;//OldY-3*(OldY-yVal)/abs(OldY-yVal); 
  int xAxis = xVal;//OldX-3*(OldX-xVal)/abs(OldX-xVal); 

  Serial.print(yAxis);
  Serial.print(' ');
  Serial.println(xAxis);

  if (yAxis < 470) 
  {

    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);

    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);

    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }
  else if (yAxis > 550) 
  {

    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);

    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);

    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  }
  else 
  {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }
  
  if (xAxis < 470) 
  {

  }
  else if (xAxis > 550) 
  {

  }

  if (motorSpeedA < 70) 
    motorSpeedA = 0;
  
  if (motorSpeedB < 70) 
    motorSpeedB = 0;

  OldX = xAxis;
  OldY = yAxis;
  
  analogWrite(enA, motorSpeedA); 
  analogWrite(enB, motorSpeedB); 
}

void calcThrottle()
{
  if (digitalRead(THROTTLE_IN_PIN) == HIGH)
  {
    ulThrottleStart = micros();
  }
  else
  {
    unThrottleInShared = (uint16_t)(micros() - ulThrottleStart);   
    
    ulThrottleStart = 0;
    bUpdateFlagsShared |= THROTTLE_FLAG;
  }
}

void calcSteering()
{
  if (digitalRead(STEERING_IN_PIN) == HIGH)
  {
    ulSteeringStart = micros();
  }
  else
  {
    unSteeringInShared = (uint16_t)(micros() - ulSteeringStart);

    ulSteeringStart = 0;
    bUpdateFlagsShared |= STEERING_FLAG;
  }
}

 

ArdoMax659
Offline
Зарегистрирован: 06.11.2017

ArdoMax659
Offline
Зарегистрирован: 06.11.2017

Может быть кто-нибудь может воспроизвести схему и проверить есть ли проблема?

Я думаю, что проблема со стороны обработки сигнала в Arduino, так как передатчик работает отлично. Также я подключал серво напрямую кприемнику, всё работает как надо. Я пробовал использовать pulseIn сначала, но проблема была та же, поэтому я стал использовать прерывания. Но, видимо, проблема в другом.

 

vvadim
Offline
Зарегистрирован: 23.05.2012

приёмник редкий , здесь впервые вижу.

наверно на форумах моделистов быстрее помогут

ArdoMax659
Offline
Зарегистрирован: 06.11.2017

Ну если с другим приёмником будет всё гладко, то значит в моём проблема. У меня только этот есть, я бы сам с другим попробовал.

Гриша
Offline
Зарегистрирован: 27.04.2014

на движках конденсаторы нужны от помех, на НАНЕ в месте подключения проводов нужен конденсатор высокочастотный. Это минимум, Да, я знаю что они там есть, но их реально не хватает. 

дроссель можно подобрать на питание движка, как считать не знаю, но он в этой схеме нужен (маленького номинала), (даже проволоку на сопротивление можно намотать - весит много и не удобно, готовый лучше)

если совсем по простому