Bom dia pessoal.

Estou tentando controlar 4 motores RC com arduino. Se eu tentar enviar "O mesmo comando" para

todos servos, eles respondem certinho, porém se tento por rotações diferentes em cada um, o sistema se perde. Tipo não obedece mais, fica louco. Tipo, no comando, servo.write, ponho "0" e o RC continua girando como bem intender.

Acredito que não seja problema de software, porque individualmente o sistema responde bem, e tb se eu ficar monitorando a porta serial, vejo q os valor enviados para o servo estão certos, porém o resultado no servo não.

Estou usando um arduino duemilenove ate chegar o meu Mega. Não sei se esse problema pode ser uma carrência no duemilenove e no mega não vai ter....

Alguém ja enfrentou um problema parecido?

Toda ajuda sera bem vinda... Grato.

Exibições: 1909

Responder esta

Respostas a este tópico

Sabe que agora que vc comentou, me toquei q realmente este problema começou a dar qnd comecei a monitorar a porta serial, ou seja, cabo usb conectado. Hj a noite testarei e relatarei.

Mto Obrigado.

O problema não é exatamente o cabo USB, e sim a corrente máxima fornecida pela placa mãe (acho que fica em torno de 500mA no máximo por USB). Usando uma fonte externa vc tem correntes maiores, e com isso consegue alimentar mais. É necessário ficar atento à corrente máxima que o arduino consegue suportar em cada porta (se não me engano são apenas 50mA). Se for uma carga maior, precisa de um transistor ai.

É por isso, que em alguns casos, seu circuito não funciona quando alimentado pela USB, e funciona quando liga fonte externa. E é por isso que em HDs externos antigos usavam aquele cabo USB duplo.

Mais ou menos por ai...

Abraços!

Certo, mas na verdade, eu alimento os motores por uma bateria externa, e o controle do motor é feito por uma ESC. Portanto, apenas ligo 1 saida PWM na ESC e controlo ela pela biblioteca servo.h. E alimento o arduino por USB ou por bateria externa tb.

Mas vou verificar as correntes.

Obrigado pela ajuda

Pois eh...

Tirei o USB e pus uma fonte externa e nao resolveu.

Conferi as correntes e estao detro do esperado.

Sera que eh o arduino que nao consegue "gerenciar" 4 RC motor ao mesmo tempo?

Grato

Se as correntes estão dentro do esperado, e mesmo assim não funcionou... Imagino que com arduino consegue sim controlar, mas não to imaginando o que poderia ser.

Vamos ver se mais alguém por aqui sabe.

Interessante a questão.

Abraços!

Pois é..

Um ponto que acho muito curioso, é que se eu colocar o mesmo valor dentro de servo.write pra todos eles, funciona tranquilamente, apartir do momento que mudo o valor, de um para outro,ele se perde.

Vou tentar pegar outro arduino para fazer testes...

Qualquer resultado posto aqui

Olha! Tenho um braço robótico que montei, controlado apelas por um "Standalone", e acionado por um painel de botões.

São pelo menos 8 servos, e funcionam de boa usando o mesmo comando que você usa.

Olhe as Conexões dos Servos ao fundo, o fio da alimentação externa(amarelo/Branco) e os cabos pro painel analogico (Sup.Direito).

Joga um código e/ou esquema ai no tópico pro pessoal dar uma olhada.

Segue o codigo.

Este programa foi feito para medir o valor do giroscopio, e compensar a rotacao. Eh um programa teste. O giroscopio me da medidas de 400 a 600 sendo 500 o valor quando ele esta alinhado na horizontal.

Nao postei o esquema, pq basicamente ele consiste em um potenciometro e um giroscipo nas portas analogicas e em 4 pinos PWM, cada um deles ligado a uma ESC de controle do motor.

Peco desculpas pelos erros de acentuacao pois estou escrevendo em um teclado USA.

CODE:

#include <Servo.h>
int val; //leitura de potenciometro
int rot;  //valor convertido do val
int rot1; //rotacao servo1
int rot2; //rotacao servo2
int rot3; //rotacao servo3
int rot4; //rotacao servo4
int pot = A0; //potenciometro
Servo myservo1; //servo 1
Servo myservo2; //servo 2
Servo myservo3; //servo 3
Servo myservo4; //servo 4
const int xpin = A2; //pino giroscopio x                 
const int ypin = A3; //pino giroscopio y                 
const int zpin = A4;
int eixox; //leitura eixo x
int eixoy; //leitura eixo y
int incx; //teste eixo x
int incy; //teste eixo y
int incxl = 500; //valor de eixo x alinhado
int incyl = 500; //valor de eixo y alinhado

void setup()
{
  //declaracao dos servos
  myservo1.attach(10);
  myservo2.attach(5);
  myservo3.attach(6);
  myservo4.attach(9);
 
}

void loop()
{
  val = analogRead(pot); //leitura do potenciometro
  rot = map(val, 0, 1023, 0, 180); //converter range do pot 0a 1023 para escrita nos servos 0 180
  eixox = analogRead(xpin); //leitura eixo x
  eixoy = analogRead(ypin); //leitura eixo y
  // giroscopio marca valores de 400 a 600 sendo 400 a inclinacao 90graus a esquerda
  //e 600 inclinacao de 90graus para direita
  if (eixox > incxl){ //teste se inclinacao x esta para direita
    incx = eixox - incxl; //calculo para isolar apenas o valor em modulo da inclinacao
    rot2 = rot + incx; //correcao da rotacao para compecao inclinacao
    rot4 = rot - incx; //correcao da rotacao para compecao inclinacao
  }
  if (eixox < incxl){ //teste para inclinacao x para esquerda
    incx = incxl - eixox;
    incx = incx / 2;
    rot2 = rot - incx;
    rot4 = rot + incx;
  }


  if (eixoy > incyl){ //teste para inclinacao y para direita
    incy = eixoy - incyl;
    rot1 = rot + incy;
    rot3 = rot - incy;
  }
  if (eixoy < incyl){ //teste para inclinacao y para esquerda
    incy = incyl - eixoy;
    incy = incy / 2;
    rot1 = rot - incy;
    rot3 = rot + incy;
  }
 //cada esc responde um pouco diferente para o comando
 //abaixo esta a correcao de cada esc
  rot1 = rot1;
  rot2 = rot2 + 1;
  rot3 = rot3 + 7;
  rot4 = rot4 + 7;
  //se valor de rot menor de 50
  //que e' o valor minimo para os motores comecarem a girar,
  //todas as rotacoes sao zeradas, para nao ter nenhuma girando
  //gracas ao posivel incremento da inclinacao
  if (rot < 50){  
    rot1 = 0;
    rot2 = 0;
    rot3 = 0;
    rot4 = 0;
  }

//escrita dos valores nos motores
  myservo1.write(rot1);
  delay(15);
  myservo2.write(rot2);
  delay(15);
  myservo3.write(rot3);
  delay(15);
  myservo4.write(rot4);
  delay(15);
}

Ah, esqueci de disser. Estou fazendo um quadcoptero, por isso o sensor de inclinação.

Já fez um teste sem esse seu algoritmo de correção? Só o básico mesmo, de enviar 4 valores diferentes pros servos.

Tas usando 4 miniservos adaptados pra rotação continua como propulsores, é isso? Ta dando a rotação necessária? Fiquei curioso.

Na verdade, nao testei dar valor diferentes sem este algoritmo. Vou testar..

Na verdade são motores RC semelhante a este:

http://produto.mercadolivre.com.br/MLB-221154714-motor-eletrico-rc-...

e controlo ele usando uma ESC :

http://produto.mercadolivre.com.br/MLB-216892355-esc-30a-controlado...

Eu trato a ESC como se fosse um servo mesmo, e o valor que dou no servo.write é transformado em rotação.

No final de semana, posto umas fotos do conjunto.

Agradeço a atenção

Olá Rogério, estou tentando criar algo semelhante ao seu projeto poderíamos nos unir pra tentar obter bons resultados, eu acredito que você esteja enfrentando também os mesmos problemas que estou enfrentando e acredito que você também irá cruzar alguns caminhos que fiz.

Bem, essa biblioteca servo para um braço robótico ela é excelente, mas para um quadricoptero ou um drone, que é o meu projeto, já não é tão eficiente. Pelo menos, foi  a conclusão que tive em fazer algumas pesquisas e descobri que a biblioteca Servotime2 controla bem melhor a potencia de um motor.

Mas seu caminho também não é ruim, pois é possível obter êxito. O que irá determinar o sucesso é a calibragem dos motores na aceleração e desaceleração para manter todo o sistema estável em resposta a os dados de um acelerômetro ou giroscópio.

Eu sugiro a você a tentar construir primeiro uma espécie de pêndulo ou balança, em que dois motores tentem acelerar e desacelerar para manter o equilíbrio, assim você evitará acidentes e prejuízo na destruição de componentes. E é o que estou tentando fazer na faze desse projeto.

Acredito que você esteja seguindo a minha linha de pensamento, ou seja, iniciando quase do zero, o que também prevê a não utilização dessas placas controladoras com 3 giroscópios, pois assim perderia a graça

Segue o link do que eu fiz até agora:

http://labdegaragem.com/video/experimento-01-drone

Canal de Video:

http://www.youtube.com/user/mestreD05brinquedos/videos

 Bem, ainda estou trabalhando somente com o acelerômetro para verificar se somente ele é necessário para manter um sistema estável em seu vôo.

Uma coisa que verifiquei é que o giroscópio seja o componente melhor indicado para o que queremos criar, pois ele sente a inclinação e volta ao seu estado inicial o que o acelerômetro já não faz. Mas a medição da inclinação pelo acelerômetro é bem mais eficiente do que o giroscópio.

O código que estou usando é para 3 motores, ou seja, estou tentando criar um Tricoptero.

No código abaixo eu uso apenas dois motores e o valor y do acelerômetro para tentar estabilizar uma espécie de pêndulo

// Este código tem a finalidade de controlar de maneira
// estavel o vôo de um Drone pra que ele envie
// um artefato de Guerra Bacteriologica até uma determinada
// Localização

#include <ServoTimer2.h>  
// Define os pinos para os Motores
#define X  12
#define Y  11
#define Z  10
// A Biblioteca ServoTimer permite
// Declarar variáveis para até oito Motores
ServoTimer2 Motor01;    
ServoTimer2 Motor02;
ServoTimer2 Motor03;
//-------------- Gyro : declaração variaveis do Giro ---
int valor = 0;
// -------------- Gyro ------------
float velocidade_angular =0;
//-----------------------------------------------------
//       Acelerometro
// Define os pinos analogicos para o acelerômetro
//-----------------------------------------------------
    int xpin = 0;  // eixo x para o pino analogico 0
    int ypin = 1;  // eixo y para o pino analogico 1
    int zpin = 2;  // eixo z para o pino analogico 2
    
// Valores de calibração para ficar de acordo
// coma animação 3d do flash

    #define xOffset 630
    #define yOffset 260
    #define zOffset 600
//------------------------------------------
// setando para zero os valores das variaveis dos eixos
// do acelerometro e das variáveis de tempo
    long  xRaw = 0, yRaw = 0, zRaw = 0;
    unsigned long timeold_fast = 0, timeold_med = 0;
//---------------------------------------------------------
// ---- Variavel que indica o acionamento dos motores------
// 0 para desligar motores
// 1 para ligar motores
//----------------------------------------------------------
    int ligar =1;
//-----------------------------------------------------------
//função que faz o calculo da posição do acelerômetro
void A2Ddata(unsigned int n)
{
 long tempX = 0, tempY = 0, tempZ = 0;
 for(unsigned int k = 1; k <= n; k++){
   //Leitura dos pinos 0,1,2 da leitura
   // dos 3 eixos do acelerômetro
   tempX += analogRead(xpin);
   tempY += analogRead(ypin);
   tempZ += analogRead(zpin);
 }
 // Segue o calculo dos valores finais dos 3 eixos
 // do acelerômetro
 xRaw = tempX/n-xOffset;
 
 yRaw = tempY/n-yOffset;
 
 zRaw = tempZ/n-zOffset;
}

//------------------------------------------
void setup()
{
// Anexando os motores ao código  
  Motor01.attach(X);     
  Motor02.attach(Y);
  Motor03.attach(Z);
//--------------------------------------
// Chamada da função do acelerômetro
//-------------------------------------
  A2Ddata(100);
  Serial.begin(19200);
}


void loop()
{
  int val, val1, val2;
 
 //-------------------Acelerometro
   if (millis()-timeold_fast != 5)
   {
   timeold_fast = millis();
   A2Ddata(100);
   }
 //-------------------------------
 //        Ligar Motores Esquerdo e Direito
 //--------------------------------
        if (ligar != 0)
            {
               for (val= 1500; val < 1598; val +=1)
               {
                  Motor01.write(val);//Motor Esquerdo
                  Motor02.write(val);//Motor Direito
                  Serial.print(val);
                 Serial.print("");
                 Serial.println();
                  delay(100);
               }
           
            }
          ligar = 0;
  //--------------------------------
       if (yRaw > 101)
          {
            yRaw = 100;
          }
            if (yRaw < 31)
          {
            yRaw = 30;
          }
 //--------------------------------
  // Execução Motor Esquerdo
  //---------------------------------
  // yRaw eixo Y do acelerômetro
  // -112, menor valor de descida da asa esquerda
  // 213, Maior subida da asa esquerda
  // 1997 Velocidade aumenta quando asa desce
  // 1993 Velocidade diminui quando asa sobe
  // É feita uma proporção dos valores
  //------------------------------------------------
  // val1 val2 - variavel que recebe valor de proporção resultante
  // entre os valores do acelerometro e velocidade do motor
  //-----------------------------------------------------
  // Melhor valor até agora
  //  val1 = map (yRaw, -20,100,1596,1592);//Esquerdo
  //   val2 = map (yRaw, 40,213,1594,1598);//Direito
  // Esquerdo
   
           val1 = map (yRaw, 20,90,1597,1594);
  // A linha abaixo manda o pulso para o motor esquerdo
  if (val1 > 1601)
    {
      val1 = 1600;
    }
           Motor01.write(val1);
  //--------------------------------
  // Execução Motor Direito
  //--------------------------------
  // yRaw eixo Y do acelerômetro
  // 40, menor valor de descida da asa Direita
  // 213, Maior subida da asa Direita
  // 1996 Velocidade aumenta quando asa desce
  // 1993 Velocidade diminui quando asa sobe
  // É feita uma proporção dos valores
//-------------------------------------------------
          val2 = map (yRaw, 20,90,1594,1600);
  // A linha abaixo manda o pulso para o motor direito
        if (val2 > 1601)
    {
      val2 = 1600;
    }
 
 
          Motor02.write(val2);
  //------- Informações de Dados----- Acelerômetro ----------   
    
   Serial.print(xRaw);
   Serial.print(",");
   Serial.print(yRaw);
   Serial.print(",");
   Serial.print(zRaw);
   Serial.print(",");
  //------- Informações de Dados----- Gyroscopio ----------
   Serial.print(velocidade_angular);
   Serial.print(",");
//----Informações de Dados - Motores -----------------------
   Serial.print (val1);//esq
   Serial.print (",");
   Serial.print (val2);//dir
   Serial.print (",");
   Serial.println();
}

 

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço