DRON v.1

gmurvs
Offline
Зарегистрирован: 15.04.2014

Видео работы http://www.ex.ua/158011847237

Цель.

Отработка навыка построения управления электрооборудованием автомобиля :)

План по развитию.

Добавить радиопередатчик NRF24, сделать пульт управления, запрограммировать и отладить логику.

Комплектация.

Автомобиль без Р/У.

Контроллер - Arduino Nano.

Питание - 2 АКБ (сумарно 12 В).

Два драйвера L293DNE (один управляет двумя двигателями, другой - сервой).

Питание микроконтроллера от стабилизатора на 5 В.

Код управления.



int dronmode = 0;

int lPin = 3;
int rPin = 10;
int fPin = 6;
int bPin = 5;

byte FBPowerMax = 50;
byte FBPowerMin = 10;
byte FBPowerRateStep = 10;
byte FBPowerRate = 40;
byte randomFBPowerRate;

byte LRPowerMax = 150;
byte LRPowerMin = 50;
byte LRPowerRate = 100;

boolean demoMode;

long timer;


typedef struct dron_data_struct
{
  byte left;
  byte right;
  byte forward;
  byte backward;
};

dron_data_struct dronstate;


int movementmode = 1;
int switchtimermodeTime = 5000;
int currenttime = 0;

void setup()  {
  TCCR1B = TCCR1B & 0b11111000 | 0x01;
  TCCR2B = TCCR2B & 0b11111000 | 0x01;
  Serial.begin(9600);

  delay(5000);
  demoMode = true;
  timer = millis()+2000;

} 

void loop()  { 

  if (Serial.available()){
    String ttydata = Serial.readString();

    int switchcase = 1000;
    if (ttydata == "s") switchcase = 0;
    if (ttydata == "f") switchcase = 1;
    if (ttydata == "b") switchcase = 2;
    if (ttydata == "l") switchcase = 3;
    if (ttydata == "r") switchcase = 4;
    if (ttydata == "m") switchcase = 5;
    if (ttydata == "pu") switchcase = 6;
    if (ttydata == "pd") switchcase = 7;
    if (ttydata == "demo") switchcase = 8;//demo

    switch (switchcase) {
    case 0:
      dronmode = 0;
      break;
    case 1:
      dronmode = 1;
      break;
    case 2:
      dronmode = 2;
      break;
    case 3:
      dronmode = 3;
      break;
    case 4:
      dronmode = 4;
      break;
    case 5:
      dronmode = 5;
      break;
    case 6:
      dronmode = 6;
      break;
    case 7:
      dronmode = 7;
      break;
    case 8:
      demoMode = true;
      timer = millis()+2000;
      break;
    }
  }

  switch (dronmode) {
  case 0://DRON STOP
    dronstate.backward = 0;
    dronstate.forward = 0;
    break;
  case 1: //FORWARD
    dronstate.backward = 0;
    dronstate.forward = 1;
    break;
  case 2://BACKWARD
    dronstate.backward = 1;
    dronstate.forward = 0;
    break;
  case 3:
    dronstate.right = 0;
    dronstate.left = 1;
    break;
  case 4:
    dronstate.right = 1;
    dronstate.left = 0;
    break;
  case 5:
    dronstate.right = 0;
    dronstate.left = 0;
    break;
  case 6: //speed up
    if ( (FBPowerRate + FBPowerRateStep) < FBPowerMax)
    {
      FBPowerRate = FBPowerRate + FBPowerRateStep;
    }
    else
    {
      FBPowerRate = FBPowerMax;
    }    
    dronmode = 10001;
    break;
  case 7: //speed dw
    if ((FBPowerRate-FBPowerRateStep) > FBPowerMin )
    {
      FBPowerRate = FBPowerRate - FBPowerRateStep;
    }
    else
    {
      FBPowerRate = FBPowerMin;
    }
    dronmode = 10001;
    break;

  }

  byte lpinpwm = dronstate.left * LRPowerRate;
  byte rpinpwm = dronstate.right * LRPowerRate;
  byte fpinpwm = dronstate.forward * (FBPowerRate + randomFBPowerRate);
  byte bpinpwm = dronstate.backward * (FBPowerRate + randomFBPowerRate);

  analogWrite(lPin, lpinpwm);
  analogWrite(rPin, rpinpwm);
  analogWrite(fPin, fpinpwm);
  analogWrite(bPin, bpinpwm);

  if (demoMode){

    if (timer < millis())
    {
      timer = millis() + 500;
      dronmode = random(6);
      randomFBPowerRate = random(10, 30);
    }
  }
}









 

 

zhenious
Offline
Зарегистрирован: 03.07.2014

А что происходит, если НЕ Serial.available() в строке 051 ?

Через каждые 500 мс дрон случайно куда-нибудь движется, если включен DemoMode?

 

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

ссылка не открывается

gmurvs
Offline
Зарегистрирован: 15.04.2014

Сериал использую для отладки, а так да - каждые 500 мс дрон демонстрирует свои возможности для детей и кота. Мощность движков зажата ШИМ-мом, иначе разобьется, не дождавшись апгрейда. Ссылку проверил, работает.

zhenious
Offline
Зарегистрирован: 03.07.2014

Роскомнадзор внес украинский файлообмениик Ex.ua в реестр страниц, содержащих запрещенную к распространению на местности России информацию.
Нужно отметить, что и до решения русского ведомства Ex.ua был недоступен на местности России и иных государств(не считая Украины)без применения прокси либо Tor.

zhenious
Offline
Зарегистрирован: 03.07.2014

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

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

человек выложил на украинском ресурсе и думает из россии к нему есть доступ

или это специально? для всех кроме россии. неужели и сюда добралась политика

есть же youtube для видео

gmurvs
Offline
Зарегистрирован: 15.04.2014

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

 

http://youtu.be/2w_rBUMYzuQ

zhenious
Offline
Зарегистрирован: 03.07.2014

да, хороший эксперимент получился со случайным движением

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

может я не понял. а где случайное движение?

gmurvs
Offline
Зарегистрирован: 15.04.2014

Автомобиль дополнился радиомодулем NRF24 и получил обновленную программу без "демо" режима. Пульт управления - Комп->Arduino Nano -> NRF24. Теперь через постоянные интервалы милливремени пульт выдает команды автомобилю, которые можно забивать в сериале. На пульте пока сделал одну лишь кнопку "хальт". Планы - дополнить его индикаторами заряда АКБ автомобиля, парой тумблеров (вперед/стоп/назад, налево/выровнять/вправо), и парой потенциометров для управления скоростью и усилием на руле.

Если кому интересно - код:

//ПУЛЬТ УПРАВЛЕНИЯ

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"


unsigned long  tikmill;
int tikmilldelta = 500;

float t0;

boolean ds;
boolean bs;
int buttonState;
unsigned long dstimer;
unsigned long lifetimer;

int led=8;
int buttonPin = A2;

RF24 radio(9,10);

const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

typedef struct dron_data
{
  byte mode; // активный режим работы программы
  byte command; // код последней полученной управляющей команды
  float data; //телеметрия
};

dron_data NRF_Read;
dron_data NRF_Send;


void setup(void)
{
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
  pinMode(led, OUTPUT);

  buttonState = digitalRead(buttonPin);

  if (buttonState == 1) {
    while (buttonState == 1){
      digitalWrite(led, HIGH);
      delay(500);
      digitalWrite(led, LOW);
      delay(500);
    }
  }

  digitalWrite(led, LOW);

  printf_begin();

  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.setRetries(15,15);
  //radio.disableCRC();
  //radio.setPALevel(RF24_PA_HIGH);
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
  radio.startListening();
  radio.printDetails();
}

void loop(void)
{

  if (tikmill < millis()){
    radio.stopListening();
    radio.write( &NRF_Send, sizeof(NRF_Send) ); 
    radio.startListening();
    tikmill = millis() + tikmilldelta;
    digitalWrite(led, LOW);
  }

  byte dronCommand = 255;

  if (Serial.available()){
    String ttydata = Serial.readString();
    if (ttydata == "s") dronCommand = 0;
    if (ttydata == "f") dronCommand = 1;
    if (ttydata == "b") dronCommand = 2;
    if (ttydata == "l") dronCommand = 3;
    if (ttydata == "r") dronCommand = 4;
    if (ttydata == "m") dronCommand = 5;
    if (ttydata == "pu") dronCommand = 6;
    if (ttydata == "pd") dronCommand = 7;
    NRF_Send.command = dronCommand;

  }

  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    if (!bs){
      bs = true;
      NRF_Send.command = 0;
      tikmill = 0;
    }
  }


  if ( radio.available() )
  {
    digitalWrite(led, HIGH);
    radio.read( &NRF_Read, sizeof(NRF_Read) );
    Serial.print(" dronMode=");
    Serial.print(NRF_Read.mode);
    Serial.print(" dronReceivedCommand=");
    Serial.print(NRF_Read.command);
    Serial.print(" dronData=");
    Serial.print(NRF_Read.data);
    if (NRF_Read.command > 0) Serial.print(" ___________________COMMAND_IS_RECEIVED_____________");
    Serial.println("");
  }
}

//DRON v.2

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

RF24 radio(7,10);

const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

unsigned long lifetimer;

typedef struct dron_data
{
  byte mode;
  byte command;
  float data;
};

dron_data NRF_Read;
dron_data NRF_Send;

boolean dronAnswer;

int dronmode = 0;

int lPin = 3;
int rPin = 9;
int fPin = 6;
int bPin = 5;

byte FBPowerMax = 200;
byte FBPowerMin = 10;
byte FBPowerRateStep = 10;
byte FBPowerRate = 50;
byte randomFBPowerRate;

byte LRPowerMax = 150;
byte LRPowerMin = 50;
byte LRPowerRate = 100;

long timer;


typedef struct dron_data_struct
{
  byte left;
  byte right;
  byte forward;
  byte backward;
};

dron_data_struct dronstate;

void setup()  {
  TCCR1B = TCCR1B & 0b11111000 | 0x01;
  TCCR2B = TCCR2B & 0b11111000 | 0x01;
  Serial.begin(9600);

  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.setRetries(15,15);
  radio.setPALevel(RF24_PA_HIGH);

  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
  radio.startListening();
  radio.printDetails();

} 

void loop()  { 
  if (dronAnswer){
    radio.stopListening();
    NRF_Send.command = NRF_Read.command;
    NRF_Send.mode = dronmode;
    radio.write( &NRF_Send, sizeof(NRF_Read) );
    radio.startListening();
    dronAnswer = false;
  }

  byte dronCommand = 255;

  if ( radio.available() )
  {
    radio.read( &NRF_Read, sizeof(NRF_Read) );
    dronmode = NRF_Read.command;
    dronAnswer = true;
  }

  if (Serial.available()){
    String ttydata = Serial.readString();
    if (ttydata == "s") dronmode = 0;
    if (ttydata == "f") dronmode = 1;
    if (ttydata == "b") dronmode = 2;
    if (ttydata == "l") dronmode = 3;
    if (ttydata == "r") dronmode = 4;
    if (ttydata == "m") dronmode = 5;
    if (ttydata == "pu") dronmode = 6;
    if (ttydata == "pd") dronmode = 7;
  }

  switch (dronmode) {
  case 0://DRON STOP
    dronstate.backward = 0;
    dronstate.forward = 0;
    break;
  case 1: //FORWARD
    dronstate.backward = 0;
    dronstate.forward = 1;
    break;
  case 2://BACKWARD
    dronstate.backward = 1;
    dronstate.forward = 0;
    break;
  case 3:
    dronstate.right = 0;
    dronstate.left = 1;
    break;
  case 4:
    dronstate.right = 1;
    dronstate.left = 0;
    break;
  case 5:
    dronstate.right = 0;
    dronstate.left = 0;
    break;
  case 6: //speed up
    if ( (FBPowerRate + FBPowerRateStep) < FBPowerMax)
    {
      FBPowerRate = FBPowerRate + FBPowerRateStep;
    }
    else
    {
      FBPowerRate = FBPowerMax;
    }    
    dronmode = 10001;
    break;
  case 7: //speed dw
    if ((FBPowerRate-FBPowerRateStep) > FBPowerMin )
    {
      FBPowerRate = FBPowerRate - FBPowerRateStep;
    }
    else
    {
      FBPowerRate = FBPowerMin;
    }
    dronmode = 10001;
    break;
  }

  byte lpinpwm = dronstate.left * LRPowerRate;
  byte rpinpwm = dronstate.right * LRPowerRate;
  byte fpinpwm = dronstate.forward * (FBPowerRate + randomFBPowerRate);
  byte bpinpwm = dronstate.backward * (FBPowerRate + randomFBPowerRate);

  analogWrite(lPin, lpinpwm);
  analogWrite(rPin, rpinpwm);
  analogWrite(fPin, fpinpwm);
  analogWrite(bPin, bpinpwm);
}

На 12 В резво гоняет!

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

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

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

спасибо. можете приложить фото двигателя который у вас стоит?

и еще. не боитесь что щетки сгорят от 12В? машинка вроде на 6В.  я фото изза этого и спросил, чтобы понять какие там щетки стоят

gmurvs
Offline
Зарегистрирован: 15.04.2014

Сорри, но "ходовую" не разбирал. Что там за моторы - можно только догадываться, скорее всего самое бюджетное. Оригинальное питание 6 В было, а то, что щетки могут сгореть - это их (щеток) проблемы. Скорей бы сгорели, хороший повод посмотреть, как там все устроено, и будет потребность улучшить дрона :).

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

ага. кажись они и есть самые дешевые

только у меня от 7,5-8,4В сгорели через какое то время. но купить такой двигатель не проблема

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

gmurvs
Offline
Зарегистрирован: 15.04.2014

В процессе отработки схемы радиоуправления столкнулся с проблемой - МК (Nano) пульта управления гарантированно зависал с таким куском кода:

if (tikmill < millis()){
    radio.stopListening();
    radio.write( &NRF_Send, sizeof(NRF_Send) );
    radio.startListening();
    tikmill = millis() + tikmilldelta;
    digitalWrite(led, LOW);
}

Методом перебора проблему удалось обойти отказом от использования IF  ! Теперь, в алгоритме изменение - МК постоянно в loop-e шлет дрону команды, а не через определенный интервал.

В качестве эксперимента брал "чистый" МК без всяких внешних устройств, прогружал в него скетч - он так же зависал в течение минуты работы.

В итоге код до безобразия упростил, and it works, but I don't know how.

//ПУЛЬТ УПРАВЛЕНИЯ

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"


byte buttonState;
byte dronCommand;
int led=8;
int buttonPin = A2;
int tik;
int tikD = 100;



byte FBPowerMax = 255;
byte FBPowerMin = 30;
byte FBPowerRateStep = 5;
byte FBPowerRate = 60;
byte randomFBPowerRate;

byte LRPowerMax = 175;
byte LRPowerMin = 150;
byte LRPowerRate = 100;


RF24 radio(9,10);

const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

typedef struct dron_data
{
  byte lpinpwm;
  byte rpinpwm;
  byte fpinpwm;
  byte bpinpwm;
};

dron_data NRF_Read;
dron_data NRF_Send;
dron_data dronstate;


void setup(void)
{
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
  pinMode(led, OUTPUT);

  buttonState = digitalRead(buttonPin);

  if (buttonState == 1) {
    while (buttonState == 1){
      digitalWrite(led, HIGH);
      delay(500);
      digitalWrite(led, LOW);
      delay(500);
    }
  }

  digitalWrite(led, LOW);

  printf_begin();
  radio.begin();
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
  radio.printDetails();
}

void loop(void)
{
    radio.stopListening();
    radio.write( &NRF_Send, sizeof(NRF_Send) );
    radio.startListening();
    digitalWrite(led, LOW);

  if (Serial.available()){
    String ttydata = Serial.readString();
    if (ttydata == "s") dronCommand = 0;
    if (ttydata == "f") dronCommand = 1;
    if (ttydata == "b") dronCommand = 2;
    if (ttydata == "l") dronCommand = 3;
    if (ttydata == "r") dronCommand = 4;
    if (ttydata == "m") dronCommand = 5;
    if (ttydata == "pu") dronCommand = 6;
    if (ttydata == "pd") dronCommand = 7;
  }

  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) dronCommand = 0;


  switch (dronCommand) {
  case 0://DRON STOP
    dronstate.fpinpwm = 0;
    dronstate.bpinpwm = 0;
    break;
  case 1: //FORWARD
    dronstate.bpinpwm = 0;
    dronstate.fpinpwm = 1;
    break;
  case 2://BACKWARD
    dronstate.fpinpwm = 0; 
    dronstate.bpinpwm = 1;
    break;
  case 3:
    dronstate.rpinpwm = 0;
    dronstate.lpinpwm = 1;
    break;
  case 4:
    dronstate.lpinpwm = 0;
    dronstate.rpinpwm = 1;
    break;
  case 5:
    dronstate.lpinpwm = 0;
    dronstate.rpinpwm = 0;
    break;
  case 6: //speed up
    if ( (FBPowerRate + FBPowerRateStep) < FBPowerMax)
    {
      FBPowerRate = FBPowerRate + FBPowerRateStep;
    }
    else
    {
      FBPowerRate = FBPowerMax;
    } 
    break;
  case 7: //speed dw
    if ((FBPowerRate-FBPowerRateStep) > FBPowerMin )
    {
      FBPowerRate = FBPowerRate - FBPowerRateStep;
    }
    else
    {
      FBPowerRate = FBPowerMin;
    }
    break;

  }

  NRF_Send.lpinpwm = dronstate.lpinpwm * LRPowerRate;
  NRF_Send.rpinpwm = dronstate.rpinpwm * LRPowerRate;
  NRF_Send.fpinpwm = dronstate.fpinpwm * FBPowerRate;
  NRF_Send.bpinpwm = dronstate.bpinpwm * FBPowerRate;

  if ( radio.available() )  {
    digitalWrite(led, HIGH);
    radio.read( &NRF_Read, sizeof(NRF_Read) );
    /*Serial.print(" lpinpwm=");
    Serial.print(NRF_Read.lpinpwm);
    Serial.print(" rpinpwm=");
    Serial.print(NRF_Read.rpinpwm);
    Serial.print(" fpinpwm=");
    Serial.print(NRF_Read.fpinpwm);
    Serial.print(" bpinpwm=");
    Serial.print(NRF_Read.bpinpwm);
    Serial.println("");
    */
  }

}

 

//DRON v.2

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

RF24 radio(7,10);

const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

typedef struct dron_data
{
  byte lpinpwm;
  byte rpinpwm;
  byte fpinpwm;
  byte bpinpwm;
};

dron_data dronstate;
boolean dronAnswer;

byte lPin = 3;
byte rPin = 9;
byte fPin = 6;
byte bPin = 5;

int dronTime;
int dronTimeW = 2000;

void setup()  {
  radio.begin();
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
  radio.startListening();
} 

void loop()  { 
  if (dronAnswer){
    radio.stopListening();
    radio.write( &dronstate, sizeof(dronstate) );
    radio.startListening();
    dronAnswer = false;
    dronTime = millis() + dronTimeW;
  }
  if ( radio.available() )  {
    radio.read( &dronstate, sizeof(dronstate) );
    dronstateTarget = dronstate;
    dronAnswer = true;
  }
  else
  {
    if (dronTime < millis()){
      dronstate.lpinpwm = 0;
      dronstate.rpinpwm = 0;
      dronstate.fpinpwm = 0;
      dronstate.bpinpwm = 0;
    }
  }
  analogWrite(rPin, dronstate.rpinpwm);
  analogWrite(lPin, dronstate.lpinpwm);
  analogWrite(fPin, dronstate.fpinpwm);
  analogWrite(bPin, dronstate.bpinpwm);
}

 

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

возник вопрос. открываете 2 канала на прием и передачу. все нормально работает?

gmurvs
Offline
Зарегистрирован: 15.04.2014

Я правильно понял, в коде дрона нужно изменить каналы передачи/приема?

ПУЛЬТ

radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);

ДРОН

radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1,pipes[0]);

Спасибо за подсказку, попробую.

 

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

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

вот и хотел узнать как у вас все работает и все ли хорошо

gmurvs
Offline
Зарегистрирован: 15.04.2014

..Мдаа. А ведь такой ошибочный код все еще работает на другом моем проекте (летательный аппарат), на котором я долго возился в обеспечении устойчивости связи. Столько было танцев с бубнами - кондеры на питание, стабилизаторы питания, компоновка, код.. Если б оно вообще тогда не заработало - был бы стимул разобраться с примерами из RF24 внимательнее ;-)

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

так там и так работает? интересно почему

gmurvs
Offline
Зарегистрирован: 15.04.2014

Да, работает  и так. Чудеса да и только, я ранее описывал тот проект http://arduino.ru/forum/programmirovanie/nrf24l01?page=10#comment-64263

Тогда проблему с неустойчивой связью свалил на плохое питание :), и решил лишь за счет стабилизации питания. Но в дроне номер с использованием одних и тех же каналов не прошел, либо наконец-то проявил себя.

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

все равно странно. менять пробовали как в 18 посте? 

рукой трогать чтобы работало. да. странно

gmurvs
Offline
Зарегистрирован: 15.04.2014

Попробую, понаблюдаю и отпишусь на днях.

gmurvs
Offline
Зарегистрирован: 15.04.2014

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

Спишу это обстоятельство на особенность использования МК с радиомодулем.

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

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

начните с односторонней связи

слать например числа из цикла чтобы отследить изменения

gmurvs
Offline
Зарегистрирован: 15.04.2014

С этим проблем нет - с передачей и приемом.

Но есть два вопроса:

1. почему связь между модулями есть в случае, когда неверно указываются одни и те же каналы в МК-х. Зачем каналы специально обрабатывать, если оно и так работает :?)

  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);

2. почему зависает МК при выполнении кода (и не важно, есть NRF24, нет его)

if (tik < millis()){  radio.stopListening();
  radio.write( &NRF_Send, sizeof(NRF_Send) );
  radio.startListening();
  digitalWrite(led, LOW);

tik = millis() + tikD;

}

и все работает стабильно при коде без IF

  radio.write( &NRF_Send, sizeof(NRF_Send) );
  radio.startListening();
  digitalWrite(led, LOW);

 

Мистика.

gmurvs
Offline
Зарегистрирован: 15.04.2014

Сделал пульт (Nano + nRF24 + два тумблера (вперед-стоять-назад, влево-ровно-вправо) + два потенциометра (скорость, угол поворота передних колес)). Оптимизировал для него код:

//ПУЛЬТ УПРАВЛЕНИЯ

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

byte buttonState;
byte dronCommand;
byte pinTB = A0;
byte pinTF = A1;
byte pinStopBttn = A2;
byte pinFBSpeed = A3;
byte pinLRPower = A4;
byte pinTL = A5;
byte pinTR = A6;
byte pinLed = 8;

RF24 radio(9,10);

const uint64_t pipes[2] = {
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

typedef struct dron_data
{
  byte lpinpwm;
  byte rpinpwm;
  byte fpinpwm;
  byte bpinpwm;
};

dron_data NRF_Read;
dron_data NRF_Send;

void setup(void)
{
  pinMode(pinStopBttn, INPUT);
  pinMode(pinLed, OUTPUT);
  pinMode(pinTF, INPUT);
  pinMode(pinTB, INPUT);
  pinMode(pinFBSpeed, INPUT);

  printf_begin();
  radio.begin();
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
  radio.printDetails();
}

void loop(void)
{
  radio.stopListening();
  radio.write( &NRF_Send, sizeof(NRF_Send) );
  radio.startListening();
  digitalWrite(pinLed, LOW);

  int valTF = map(analogRead(pinTF),0,1023,0,1);
  int valTB = map(analogRead(pinTB),0,1023,0,1);
  int valFBPower = map(analogRead(pinFBSpeed),0,1023,0,255);
  int valStopBttn =  map(analogRead(pinStopBttn),0,1023,0,255);
  int valTR =  map(analogRead(pinTR),0,1023,0,1);
  int valTL =  map(analogRead(pinTL),0,1023,0,1);
  int valLRPower =  map(analogRead(pinLRPower),0,1023,0,255);

  NRF_Send.lpinpwm = valTL * valLRPower;
  NRF_Send.rpinpwm = valTR * valLRPower;
  NRF_Send.fpinpwm = valTF * valFBPower;
  NRF_Send.bpinpwm = valTB * valFBPower;

  if (valStopBttn > 50) { //останов дрона если кнопка зажата
    NRF_Send.fpinpwm = 0;
    NRF_Send.bpinpwm = 0;
  }

  if ( radio.available() )  {
    digitalWrite(pinLed, HIGH);
    radio.read( &NRF_Read, sizeof(NRF_Read) );
  }

  delay(100);
}

 

gmurvs
Offline
Зарегистрирован: 15.04.2014

Ранее задокументированные упражнения с дроном позволили таки наладить управление им, но аппарат при движении дергался, а через небольшое время работы управление переставало работать вообще. Допил программного обеспечения пульта

//ПУЛЬТ УПРАВЛЕНИЯ

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

byte pinTB = A0;
byte pinTF = A1;
byte pinStopBttn = A2;
byte pinFBSpeed = A3;
byte pinLRPower = A4;
byte pinTL = A5;
byte pinTR = A6;
byte pinLed = 8;

RF24 radio(9,10);

const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

typedef struct dron_data
{
  byte addr;
  byte lpinpwm;
  byte rpinpwm;
  byte fpinpwm;
  byte bpinpwm;
};

dron_data NRF_Read;
dron_data NRF_Send;

void setup(void)
{
  pinMode(pinStopBttn, INPUT);
  pinMode(pinLed, OUTPUT);
  pinMode(pinTF, INPUT);
  pinMode(pinTB, INPUT);
  pinMode(pinFBSpeed, INPUT);
  
  radio.begin();
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.setRetries(15,15);                // Max delay between retries & number of retries
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();
  NRF_Send.addr = 113;
}

void loop(void)
{
  if (radio.available()){
    radio.read( &NRF_Read, sizeof(NRF_Read));
    if (NRF_Read.addr == 113){
      digitalWrite(pinLed, HIGH);
    }
  }

  int valTF = map(analogRead(pinTF),0,1023,0,1);
  int valTB = map(analogRead(pinTB),0,1023,0,1);
  int valFBPower = map(analogRead(pinFBSpeed),0,1023,0,255);
  int valStopBttn =  map(analogRead(pinStopBttn),0,1023,0,255);
  int valTR =  map(analogRead(pinTR),0,1023,0,1);
  int valTL =  map(analogRead(pinTL),0,1023,0,1);
  int valLRPower =  map(analogRead(pinLRPower),0,1023,0,255);

  NRF_Send.lpinpwm = valTL * valLRPower;
  NRF_Send.rpinpwm = valTR * valLRPower;
  NRF_Send.fpinpwm = valTF * valFBPower;
  NRF_Send.bpinpwm = valTB * valFBPower;

  if (valStopBttn > 50) { //останов дрона если кнопка зажата
    NRF_Send.fpinpwm = 0;
    NRF_Send.bpinpwm = 0;
  }

  radio.stopListening();
  radio.write( &NRF_Send, sizeof(NRF_Send) );
  radio.startListening();
  digitalWrite(pinLed, LOW);
  
    delay(100);

}

и дрона

//DRON v.2

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

RF24 radio(7,10);

const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

typedef struct dron_data
{
  byte addr;
  byte lpinpwm;
  byte rpinpwm;
  byte fpinpwm;
  byte bpinpwm;
};

dron_data dronstateTarget;

byte lPin = 3;
byte rPin = 9;
byte fPin = 6;
byte bPin = 5;

void setup()  {
  radio.begin();
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.setRetries(15,15);                // Max delay between retries & number of retries
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();
} 

void loop()  { 
  if (radio.available()){
    radio.read( &dronstateTarget, sizeof(dronstateTarget) );
    if (113 == dronstateTarget.addr){
      radio.stopListening();
      radio.write( &dronstateTarget, sizeof(dronstateTarget) );
      radio.startListening();
    }
  }
  analogWrite(rPin, dronstateTarget.rpinpwm);
  analogWrite(lPin, dronstateTarget.lpinpwm);
  analogWrite(fPin, dronstateTarget.fpinpwm);
  analogWrite(bPin, dronstateTarget.bpinpwm);
}

позволил добиться стабильной работы лишь в случае, когда пульт питается от USB-порта компа. Попытки запитать МК от различных блоков питания ничем хорошим не заканчились, проблему с питанием таким образом удалось локализовать. Рабочим оказался следующий вариант - с АКБ 5В питание подается на +5В МК.

gmurvs
Offline
Зарегистрирован: 15.04.2014

Видео работы.

http://youtu.be/YhaRagsUNgk

Сейчас один драйвер L293D управляет двумя моторами (полный привод).

Так вот, при его нагреве мощность падает (на видео есть моменты, когда дрон либо не может забраться на препятствие, либо его запросто перелетает).

Для устранения этой неприятности поставлю по отдельному драйверу на каждый мотор и попробую приладить к ним радиаторы.

gmurvs
Offline
Зарегистрирован: 15.04.2014

До отдельного драйвера руки не дошли, но из микросхем L293D сделал бутерброд, упаковал в итоге все в корпус, чтобы все было "как было", и в таком состоянии машина отгоняла полчаса по пересеченной местности.

 

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

Vikirmih
Vikirmih аватар
Offline
Зарегистрирован: 16.03.2015

на модули NRF24 по питанию нужно прямо на плате припоять конденсаторы.