LusoRobótica - Robótica em Português

Robótica => Projectos de robótica => Projectos em desenvolvimento => Tópico iniciado por: Nunito em 12 de Outubro de 2014, 10:32

Título: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 12 de Outubro de 2014, 10:32
Bom dia.

Estou já numa fase de testes dos componentes electrónicos, estando incluído o sensor MPU6050, ponte H com L298, e Arduino Nano v3.
Fiz umas pesquisas pelo google, GitHub, Instructables, etc, para dar inicio a este projecto.
Realizei os meus primeiros testes ao sensor MPU6050, com sucesso.
Entrei na pesquisa dos filtros Kalman, tentei perceber como funcionam.
Aproveitei um código opensource para dar inicio às minhas próprias modificações.
De seguida encontro algumas dificuldades em obter um controlo com motores de passo, que decidi aplicar no meu robot.
Abri um exemplo do arduino para o motor de passo, consegui colocar a funcionar.
Agora estou com dificuldades em gerir o controlo do motor de passo através de PWM juntamente com o PID.
Tenho uma função void para controlar os motores, e gostaria de obter alguma ajuda para controlar através do PWM.
Já vi pelos fóruns que há pessoal a comentar controlar o PWM através do INPUTS do L298, outros falam em controlar através dos ENABLE´s.
Todas as sugestões são bem-vindas.

Cumprimentos, Nuno
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: jm_araujo em 12 de Outubro de 2014, 14:48
Agora estou com dificuldades em gerir o controlo do motor de passo através de PWM juntamente com o PID.
Tenho uma função void para controlar os motores, e gostaria de obter alguma ajuda para controlar através do PWM.
Já vi pelos fóruns que há pessoal a comentar controlar o PWM através do INPUTS do L298, outros falam em controlar através dos ENABLE´s.

Não percebi patavina, não me fez muito sentido o que escreveste.
Podias tentar explicar melhor o que queres fazer?
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Electropepper em 12 de Outubro de 2014, 15:36
Já somos dois jm_araujo.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 12 de Outubro de 2014, 20:48
O que quero fazer é com que os motores não acelerem logo à rotação máxima quando o MPU6050 está com pouquíssima inclinação.
Eu mal inclino o sensor os motores eles começam a receber o PWM mas se inclino mais um pouco de nada, vão a rotação máxima.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Njay em 12 de Outubro de 2014, 21:05
Falaste numa ponte H mas um motor de passo, se é mesmo isso que tens, precisa de pelo menos 2 pontes H, e não se controla a sua rotação com PWM, pelo que parece-me é que ainda não sabes bem do que falas. Daí que a minha sugestão é leres alguma referência na net sobre como funciona e como se controla um motor de passo (o Jones on Stepping Motors (http://homepage.cs.uiowa.edu/~jones/step/) é uma referência sobejamente conhecida, mas podes começar por alguma coisa menos completa), leres a datasheet do L298 e perceberes o que é que ele faz, e depois voltares cá com as dúvidas... se entretanto ainda as tiveres :)
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 12 de Outubro de 2014, 21:12
Falaste numa ponte H mas um motor de passo, se é mesmo isso que tens, precisa de pelo menos 2 pontes H, e não se controla a sua rotação com PWM, pelo que parece-me é que ainda não sabes bem do que falas. Daí que a minha sugestão é leres alguma referência na net sobre como funciona e como se controla um motor de passo (o Jones on Stepping Motors (http://homepage.cs.uiowa.edu/~jones/step/) é uma referência sobejamente conhecida, mas podes começar por alguma coisa menos completa), leres a datasheet do L298 e perceberes o que é que ele faz, e depois voltares cá com as dúvidas... se entretanto ainda as tiveres :)
Já tinha conseguido chegar lá que o L298 tem duas pontes H incorporadas.  :)
Sei como funciona um motor de passo, mas está aqui a falhar alguma coisa ou eu não estou a explicar bem.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Njay em 12 de Outubro de 2014, 21:21
Então mostra-nos lá que motor de passo aí tens e explica-nos lá, por palavras tuas, como é que funciona esse motor.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 12 de Outubro de 2014, 21:56
É um motor de passo com duas fases.
Funciona com os pulsos dados nas bobines, por exemplo A+ > A- depois B+ > -B

Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Njay em 12 de Outubro de 2014, 22:30
É um motor de passo com duas fases.
Ou seja um motor de passo bipolar (deduzo eu), como se designa normalmente.

Citar
Funciona com os pulsos dados nas bobines, por exemplo A+ > A- depois B+ > -B
Explica lá melhor essa parte. O que quer dizer ">" e A+ ... ? Quantos fios tem o motor? Consegues explicar o que fazer com esses fios para o motor rodar?
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 12 de Outubro de 2014, 22:35
Ou seja um motor de passo bipolar (deduzo eu), como se designa normalmente.
É um unipolar com 6 fios mas eu estou a utilizar como bipolar utilizando apenas 4 fios deixando o fio do centro das bobines sem ligação.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 12 de Outubro de 2014, 22:37
Explica lá melhor essa parte. O que quer dizer ">" e A+ ... ? Quantos fios tem o motor? Consegues explicar o que fazer com esses fios para o motor rodar?
A corrente circula do inicio da bobine A+ para o A-  de seguida circula do B+ para o B-.
Estes ">" era apenas para identificar a direcção da corrente.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Njay em 12 de Outubro de 2014, 22:44
Pronto, então e agora, como é que o L298 te ajuda nessa tarefa de meter a corrente a circular nos sentidos certos pelas phases? Como é que controlas o L298 para ele fazer o que queres? Como é que dizes ao gajo "olha, mete lá corrente a circular do fio A+ para o fio A-" etc?
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: senso em 12 de Outubro de 2014, 23:00
Se calhar um driver de steppers dedicados com controlo step/dir seria uma melhor aposta, usas um timer para gerar o sinal do step e terás(provavelmente) um melhor controlo do motor.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 12 de Outubro de 2014, 23:09
Pronto, então e agora, como é que o L298 te ajuda nessa tarefa de meter a corrente a circular nos sentidos certos pelas phases? Como é que controlas o L298 para ele fazer o que queres? Como é que dizes ao gajo "olha, mete lá corrente a circular do fio A+ para o fio A-" etc?
ENA e ENB HIGH
IN1 HIGH
IN2 LOW
IN3 LOW
IN4 HIGH

Deu um primeiro passo, depois é seguir a lógica da batata com o L298  :)

IN1 HIGH
IN2 LOW
IN3 LOW
IN4 HIGH

Segundo passo...
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Njay em 12 de Outubro de 2014, 23:12
Então pronto, já sabes o que fazer no teu código. Qual era a dúvida afinal?
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: jm_araujo em 12 de Outubro de 2014, 23:48
Também não entendo a dúvida. Se é um motor passo-a-passo, se queres que rode mais devagar, dás menos passos. Usar PWM com um motor de passo não faz qualquer sentido (exceto para ficar com menos força nos passos?!!?!?!)
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: StarRider em 13 de Outubro de 2014, 09:54
Boas,

O L298 é excelente para controlar servo motors com PWM, já para steppers é um pouco "estranho".

Uso PWM para controlar steppers em vários projectos com um driver/IC com interface SD, se bem que
acaba por não ser PWM "puro" uma vez que o duty é fixo e o que varia é o período, no fundo é  mais
uma forma de simplificar a implementação uma vez que o hardware do LEON (ou mesmo dos STM) tem
algumas características do PWM que torna a coisa mais leve em termos de processamento do que uma
implementação com um timer e interrupts.

Abraços,
PA
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: senso em 13 de Outubro de 2014, 11:50
Acho que é complicado um micro que não tenha um timer que não te deixe variar o periodo/frequência do mesmo..
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 13 de Outubro de 2014, 19:34
Também não entendo a dúvida. Se é um motor passo-a-passo, se queres que rode mais devagar, dás menos passos. Usar PWM com um motor de passo não faz qualquer sentido (exceto para ficar com menos força nos passos?!!?!?!)
Este video de um colega que participa neste forum vai ajudar a compreender a minha dúvida.
Como é que ele varia a aceleração dos motores de passo?
http://youtu.be/YLNWpxRAM1Y (http://youtu.be/YLNWpxRAM1Y)
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: senso em 13 de Outubro de 2014, 19:36
Dando menos passos por segundo.
Num driver com interface SD é dar menos pulsos no pino de step, no caso de um driver burro como o L298 andas mais devagar na tua tabela de passos, para esse uso, continuo a achar que um driver de preferencia com micro-stepping e limite de currente seria muito melhor escolha.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 13 de Outubro de 2014, 19:51
Dando menos passos por segundo.
Num driver com interface SD é dar menos pulsos no pino de step, no caso de um driver burro como o L298 andas mais devagar na tua tabela de passos, para esse uso, continuo a achar que um driver de preferencia com micro-stepping e limite de currente seria muito melhor escolha.
Eu comprei estas boards de L298, vou tentar utilizar isto que tenho, não estou a pensar investir mais.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: senso em 13 de Outubro de 2014, 21:22
Um step-stick ou lá como lhe chamam esta semana, que é o que usam nas impressoras 3d, usam chips dedicados para controlo de steppers e compras a meia duzia de € cada uma no ebay, mas seja como for, é só implementar a tabela de passos(ou não, é basicamente um shift á direita ou á esquerda de um bit e dar a volta), e usar uma interrupção usando um timer no modo de frequencia variavel(qualquer modo em que o top seja um OCRxx) e está feito, cada interrupt dás um passo, para variar velocidade varias o OCRxx que controla a frequencia, para saltos muito maiores de frequencia usas o prescaler do timer, mas dificilmente precisas de uma gama de frequencia assim tão grande.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Njay em 14 de Outubro de 2014, 01:52
Tens 2 tempos que podes variar: 1) a duração do impulso e 2) o intervalo entre impulsos. Ao acelerares podes ter que mexer na duração do impulso (assumindo um esquema simples sem  monitorização da corrente de fase).

Se não precisas de fazer mais nada enquanto movimentas o motor, podes fazer tudo no ciclo principal sem meter interrupções e contadores ao barulho.

Se tiveres mais coisas para fazer ao mesmo tempo mas não quiseres ainda lidar com interrupções, também podes usar multitarefa cooperativa (aqui (http://embeddeddreams.com/site/2011/07/10/how-to-do-several-things-at-the-same-time/) e a parte 2 aqui (http://embeddeddreams.com/site/2011/07/23/more-on-doing-several-things-at-the-same-time)), mas os teus tempos devem ser um pouco apertados, precisas provavelmente de uma resolução de relógio de 1 ou 2 ms.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 14 de Outubro de 2014, 15:01
Tens 2 tempos que podes variar: 1) a duração do impulso e 2) o intervalo entre impulsos. Ao acelerares podes ter que mexer na duração do impulso (assumindo um esquema simples sem  monitorização da corrente de fase).
Estes impulsos que falas são os que dou com os IN1(HIGH) etc...
E a duração dos impulsos, os delays em ms, certo?
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Njay em 14 de Outubro de 2014, 16:21
Ya. A duração do impulso contribui para o controlo do torque do motor, mais tempo ligado -> mais torque. Mas se estiver demasiado tempo ligado o motor aquece demais. Para um esquema simples de controlo (ou seja, sem controlo da corrente), eu começo por um valor "qualquer" conservador, e depois optimizo-o, reduzindo-o até encontrar o ponto em que o motor deixa de conseguir responder a tempo e ficando a uma margem de segurança desse valor. Por exemplo posso começar por dar impulsos de 5ms e depois vou reduzindo esse tempo até o motor deixar de funcionar bem na aplicação em causa (perde passos); aí volto para o anterior valor em que o motor funcionava bem e fica assim. Claro que tudo isto tem certas assunções, como o motor estar correctamente dimensionado para a aplicação em causa.
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 15 de Outubro de 2014, 09:31
Bom dia, não há ninguém por aqui que tenha duas drives A4988 (http://www.pololu.com/product/1182) para venda? Podem ser usadas a funcionar de preferencia :)

Cumprimentos, Nuno


Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: StarRider em 15 de Outubro de 2014, 09:48
Bom dia, não há ninguém por aqui que tenha duas drives [http://www.pololu.com/product/1182]A4988[/url] para venda? Podem ser usadas a funcionar de preferencia :)

Cumprimentos, Nuno

Boas,

Tenho algumas breakouts com o A4988 clones das da Pololu, se tiveres interessado apita por PM.

Abraços,
PA
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 16 de Outubro de 2014, 14:52
Tenho algumas breakouts com o A4988 clones das da Pololu, se tiveres interessado apita por PM.

Eu vou ver se me desenrasco com as breakouts do L298, senão depois entro em contacto.
Obrigado!
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 17 de Outubro de 2014, 19:52
Boa noite.

Estou a realizar uns testes com 2 motores DC ligados ao L298, o que está a acontecer é que num sentido os motores estão a arrancar através da programação que tenho "speed = map(speed,0,255,0,-255)" mas quando inclino o MPU6050 para o outro lado lentamente, os motores em sentido reverso eles não estão a arrancar seguindo o speed, estão a fazer on/off.
Será que alguém me pode dar umas dicas do que está a acontecer.

Cumprimentos,
Título: Re: FlyerRobot - Equilíbrio Automático
Enviado por: Nunito em 17 de Outubro de 2014, 22:51
Boa noite.

Estou a realizar uns testes com 2 motores DC ligados ao L298, o que está a acontecer é que num sentido os motores estão a arrancar através da programação que tenho "speed = map(speed,0,255,0,-255)" mas quando inclino o MPU6050 para o outro lado lentamente, os motores em sentido reverso eles não estão a arrancar seguindo o speed, estão a fazer on/off.
Será que alguém me pode dar umas dicas do que está a acontecer.

Cumprimentos,
Estava a fazer testes com o sensor ao contrário, tava da ideia que poderia trabalhar com ele da forma que estava o sensor para cima.
Já funciona como deve ser, mas por vezes aparece um erro na comunicação I2C "i2c read failed:4"

Cumprimentos
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 20 de Outubro de 2014, 10:41
Bom dia.
Como poderei eu colocar os motores a acelerar mais ou menos conforme a inclinação do MPU6050.
Alguém para me dar umas dicas, estou com alguma dificuldade em perceber.

Cumprimentos, Nuno
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: jm_araujo em 20 de Outubro de 2014, 10:58
Com um driver com com controlo Step/Dir conseguias usando só um timer.

Com o LM298 eu faria da seguinte maneira:

Acho que chega para começar.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 20 de Outubro de 2014, 13:34
Com um driver com com controlo Step/Dir conseguias usando só um timer.

Com o LM298 eu faria da seguinte maneira:
  • Primeiro não me preocupava para já em desligar o motor entre passos, primeiro põe-no a andar como queres, podes ir controlando se aquece demais à mão e quando tiveres a funcionar tratas disso (se necessário)
  • Uma função que dá um passo no motor. Aceita como único parâmetro a direção da rotação. Guarda o estado atual das saídas do LM298 e salta para a seguinte (ou anterior) por forma a dar o passo
  • Um interrupt controlado por um timer que chama a tal função. A direção pode ser uma var global alterada pela função que interpreta os dados do MPU6050. Se só tiveres timers "rapidos", podes implementar um divisor extra (um acumulador) que só chama a cada N interrupções
  • Na função que trata os dados do MPU conforme o valor lido altera a frequência do timer ligado ao interrupt conforme a velocidade pretendida e a direção.

Acho que chega para começar.
Obrigado pelas dicas, eu agora deixei os motores de passo de lado e estou a efectuar os testes com dois motores DC com engrenagens.
Acho que assim consigo entender melhor a evolução da programação.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: jm_araujo em 20 de Outubro de 2014, 14:19
Motores DC é mais simples.
Controlas diretamente por PWM. No Arduino tens o analogWrite (http://arduino.cc/en/Reference/analogWrite) que trata de tudo.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 22 de Outubro de 2014, 18:27
Boa tarde.

Estou em fases de testes com a programação, aparecem-me muitas vezes um erro " FIFO Overflow"
Alguém me sabe dizer o porquê disto acontecer, a minha ideia é que deverá ser o arduino Nano v3 que estou a utilizar, que não consegue responder.
Está a funcionar bem ao inclinar o MPU6050, mas por vezes dá este erro e o L298 começa a passar-se, recebe impulsos nos Inputs todos.
Estou a carregar um video para mostrar.
http://youtu.be/receCmiFZC0 (http://youtu.be/receCmiFZC0)
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: metRo_ em 22 de Outubro de 2014, 19:02
Leste a datasheet do sensor?
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 22 de Outubro de 2014, 19:32
Leste a datasheet do sensor?
Vi que é o nome de uma interrupção e um registo de 1024 bytes.
Sinceramente nunca estudei acerca de interrupções, daí as minhas dificuldades.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: metRo_ em 22 de Outubro de 2014, 20:29
Do que me lembro muitos desses sensores gravam os valores numa FIFO onde tu depois tens que ir ler. Deves ter isso configurado para manter os valores até serem lidos. Neste caso o ideal é configurares isso para ele escrever por cima quando tiver cheio assim evitas esse erro e tens o valor da posição mais actual. Isto supondo o que erro que estás a ter é vindo do sensor!
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 22 de Outubro de 2014, 21:04
Citar
    if (!dmpReady) return;
    while (!mpuInterrupt && fifoCount < packetSize)
    {
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    fifoCount = mpu.getFIFOCount(); Verifica FIFO overflow

    if ((mpuIntStatus & 0x10) || fifoCount == 1024)
    {
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!));
    }
    else if (mpuIntStatus & 0x02)
    {
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        fifoCount -= packetSize;
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: senso em 22 de Outubro de 2014, 23:04
Não esquecer que o Arduino Nano só tem 2Kb de RAM, se os pinos se passam provavelmente para além de problemas no sensor deves estar a rebentar pela stack fora devido a uso excessivo de ram.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 22 de Outubro de 2014, 23:15
Não esquecer que o Arduino Nano só tem 2Kb de RAM, se os pinos se passam provavelmente para além de problemas no sensor deves estar a rebentar pela stack fora devido a uso excessivo de ram.

Pois, vou testar com o UNO.
Obrigado pela dica.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: senso em 22 de Outubro de 2014, 23:26
É exactamente o mesmo chip, vá o uno é um atmega32u4 que tem mais 512 bytes de RAM, mas são usados para o USB, por isso é muito relativo essa ram extra.

Não podes postar o código todo?
E já agora compila o código carregado no shift antes de pressionar no botão de compilar, dá-te o uso da flash e ram(estática, chamadas a funções e variaveis/arrays não globais não são contabilizados).

Sem esquecer que só usar serial são logo 128bytes que vão ao ar, se bem me recordo isso usa buffers de send e receive de 64 bytes para cada lado, biblioteca i2c vai usar mais, depois as bibliotecas para arduino é variaveis com fartura para tudo e mais alguma coisa, com muitas cópias locais da mesma coisa.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 22 de Outubro de 2014, 23:31
É exactamente o mesmo chip, vá o uno é um atmega32u4 que tem mais 512 bytes de RAM, mas são usados para o USB, por isso é muito relativo essa ram extra.

Não podes postar o código todo?
E já agora compila o código carregado no shift antes de pressionar no botão de compilar, dá-te o uso da flash e ram(estática, chamadas a funções e variaveis/arrays não globais não são contabilizados).

Sem esquecer que só usar serial são logo 128bytes que vão ao ar, se bem me recordo isso usa buffers de send e receive de 64 bytes para cada lado, biblioteca i2c vai usar mais, depois as bibliotecas para arduino é variaveis com fartura para tudo e mais alguma coisa, com muitas cópias locais da mesma coisa.
Pois só dei conta quando testei agora com o UNO, o UNO tem o mesmo chip  :) , dá os mesmos erros.
Não queria estar a colcoar o código todo para não confundir a malta aqui no tópico.
Essa do shift aprendi agora  :)
Não me deixa complar com o shift apertado, diz que não encontra nenhuma porta USB.

Citar
#include <PID_v1.h>
#include <LMotorController.h>
#include "I2Cdev.h"

#include "MPU6050_6Axis_MotionApps20.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif


#define LOG_INPUT 0
#define MANUAL_TUNING 0
#define LOG_PID_CONSTANTS 0 //MANUAL_TUNING must be 1
#define MOVE_BACK_FORTH 0

#define MIN_ABS_SPEED 30

//MPU
MPU6050 mpu;

//#define LED_PIN 13

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q; // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector


//PID


#if MANUAL_TUNING
  double kp , ki, kd;
  double prevKp, prevKi, prevKd;
#endif
double originalSetpoint = 174.29;
double setpoint = originalSetpoint;
double movingAngleOffset = 0.3;
double input, output;
int moveState=0; //0 = balance; 1 = back; 2 = forth

#if MANUAL_TUNING
  PID pid(&input, &output, &setpoint, 0, 0, 0, DIRECT);
#else
  PID pid(&input, &output, &setpoint, 70, 240, 2, DIRECT); // originais 70, 240, 1.9
#endif


//MOTOR CONTROLLER


int ENA = 6;
int ENB = 7;
int IN1 = 8;
int IN2 = 9;
int IN3 = 10;
int IN4 = 11;


LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, 0.6, 1);


//timers


long time1Hz = 0;
long time5Hz = 0;


volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
{
    mpuInterrupt = true;
}


void setup()
{
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 12; // 400kHz I2C clock (200kHz if CPU is 8MHz) original 24
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(200, true); // original 400
    #endif

    // initialize serial communication
    // (115200 chosen because it is required for Teapot Demo output, but it's
    // really up to you depending on your project)
    Serial.begin(57600);
    while (!Serial); // wait for Leonardo enumeration, others continue immediately

    // initialize device
    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();

    // verify connection
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

    // load and configure the DMP
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

    // supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

    // make sure it worked (returns 0 if so)
    if (devStatus == 0)
    {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

        // get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();
       
        //setup PID
       
        pid.SetMode(AUTOMATIC);
        pid.SetSampleTime(10);
        pid.SetOutputLimits(-255, 255); 
    }
    else
    {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }
        // configure LED for output
        // pinMode(LED_PIN, OUTPUT);
}


void loop()
{
    // if programming failed, don't try to do anything
    if (!dmpReady) return;

    // wait for MPU interrupt or extra packet(s) available
    while (!mpuInterrupt && fifoCount < packetSize)
    {
        //no mpu data - performing PID calculations and output to motors
       
        pid.Compute();
        motorController.move(output, MIN_ABS_SPEED);
       
        unsigned long currentMillis = millis();

        if (currentMillis - time1Hz >= 1000)
        {
            loopAt1Hz();
            time1Hz = currentMillis;
        }
       
        if (currentMillis - time5Hz >= 5000)
        {
            loopAt5Hz();
            time5Hz = currentMillis;
        }
    }

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024)
    {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
    }
    else if (mpuIntStatus & 0x02)
    {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);
       
        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;


        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        #if LOG_INPUT
            Serial.print("ypr\t");
            Serial.print(ypr[0] * 180/M_PI);
            Serial.print("\t");
            Serial.print(ypr[1] * 180/M_PI);
            Serial.print("\t");
            Serial.println(ypr[2] * 180/M_PI);
        #endif
        input = ypr[1] * 180/M_PI + 180;
   }
}


void loopAt1Hz()
{
#if MANUAL_TUNING
    setPIDTuningValues();
#endif
}


void loopAt5Hz()
{
    #if MOVE_BACK_FORTH
        moveBackForth();
    #endif
}


//move back and forth


void moveBackForth()
{
    moveState++;
    if (moveState > 2) moveState = 0;
   
    if (moveState == 0)
      setpoint = originalSetpoint;
    else if (moveState == 1)
      setpoint = originalSetpoint - movingAngleOffset;
    else
      setpoint = originalSetpoint + movingAngleOffset;
}


//PID Tuning (3 potentiometers)

#if MANUAL_TUNING
void setPIDTuningValues()
{
    readPIDTuningValues();
   
    if (kp != prevKp || ki != prevKi || kd != prevKd)
    {
#if LOG_PID_CONSTANTS
        Serial.print(kp);Serial.print(", ");Serial.print(ki);Serial.print(", ");Serial.println(kd);
#endif

        pid.SetTunings(kp, ki, kd);
        prevKp = kp; prevKi = ki; prevKd = kd;
    }
}


void readPIDTuningValues()
{
    int potKp = analogRead(A0);
    int potKi = analogRead(A1);
    int potKd = analogRead(A2);
       
    kp = map(potKp, 0, 1023, 0, 25000) / 100.0; //0 - 250
    ki = map(potKi, 0, 1023, 0, 100000) / 100.0; //0 - 1000
    kd = map(potKd, 0, 1023, 0, 500) / 100.0; //0 - 5
}
#endif

Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: senso em 23 de Outubro de 2014, 00:02
Tens de ter a placa ligada porque depois de compilar ele tenta fazer o upload.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 23 de Outubro de 2014, 12:43
Tens de ter a placa ligada porque depois de compilar ele tenta fazer o upload.
Não me está a deixar compilar na mesma.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Electropepper em 23 de Outubro de 2014, 13:20
Mostra aqui o erro.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 23 de Outubro de 2014, 13:29
Mostra aqui o erro.
Estou a utilizar como AVRISP MKII.
Binary sketch size: 18.998 bytes (of a 32.256 byte maximum)
avrdude: usbdev_open(): did not find any USB device "usb"
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Electropepper em 23 de Outubro de 2014, 13:38
Isso já é diferente provavelmente está a compilar não está é a fazer o upload.
Tens de escolher a placa certa tambem(o arduino).
Se estás em linux o user que estás a usar tem de ter as permissões correctas.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 23 de Outubro de 2014, 13:45
Isso já é diferente provavelmente está a compilar não está é a fazer o upload.
Tens de escolher a placa certa tambem(o arduino).
Se estás em linux o user que estás a usar tem de ter as permissões correctas.
Está tudo ok.
Placa, drives, acho estranho é que ao compilar sem apertar o Shift, funciona 5*****
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: metRo_ em 23 de Outubro de 2014, 14:22
a minha questão é, porque raio apertavas o shift? :S
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 23 de Outubro de 2014, 15:44
a minha questão é, porque raio apertavas o shift? :S
Sorry  :) entendi que querias dizer carregando no shift

"...E já agora compila o código carregado no shift antes de pressionar no botão de compilar, dá-te o uso da flash e ram(estática, chamadas a funções e variaveis/arrays não globais não são contabilizados)...
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 24 de Outubro de 2014, 15:31
Boa tarde.

Estou com uma longa espera para receber dados do DMP.
Initializing I2C devices...
Testing device connections...
MPU6050 connection successful
Initializing DMP...
Enabling DMP...
Enabling interrupt detection (Arduino external interrupt 0)...
DMP ready! Waiting for first interrupt...

Pino da interrupção bem ligado, pin 2.
Nome da interrupção para UNO bem definida, Int 0.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: senso em 24 de Outubro de 2014, 23:36
Carregando no shift o IDE do Arduino dá informação da flash e ram usada, isso funcionava, mas tambem não uso o IDE á anos quando ia na versão 20 ou 21.

O tempo que ele demora a gerar uma interrupção depende de como tens isso configurado, sample rate, tamanho do buffer, se está a gerar int pelo buffer e não por uma deteção de queda livre ou tap/double tap, é ler a datasheet.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 26 de Outubro de 2014, 12:40
Mas porque que raio o código funciona bem sem ligar a alimentação dos motores na breakout L298, quando vou ligo as 4 pilhas o código no arduino está a fazer crash.
A alimentação não tem nada a ver entre ambas, Breakout/Arduino.
Apenas tenho o GND em comum.

Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 27 de Outubro de 2014, 13:16
Que conselhos têm para evitar interferências provocadas pelos motores, mais propriamente quando eles invertem o sentido de rotação.
Estas interferências estão a afectar a comunicação I2C entre o arduino e o MPU6050.
Coloquei condensadores entre os pólos dos motores.
Já melhorou alguma coisa, aconteçe o freeze quando inverte o sentido de rotação, por isso o problema está mesmo vindo dos motores.
Também coloquei umas pullup de 2.2k  entre o SDA/SCL e os 5V.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: senso em 27 de Outubro de 2014, 13:47
Decoupling, condensadores por todo o lado, arrumação sensivel da fiarada, não passar nada perto dos motores, muito provavelmente a bateria vai-se abaixo e tens ai ruideira a passar pelo fio de massa, experimenta uma ferrite a ligar as duas massas ou muito rapidamente, uma resistência de meia duzia de ohms.
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Njay em 27 de Outubro de 2014, 18:44
Depende muito da tua configuração fisica do sistema e dos componentes (controladores de potência, placa controladora, etc).
Título: Re: FlyeRobot - Equilíbrio Automático
Enviado por: Nunito em 28 de Outubro de 2014, 17:51
Resolvi a coisa como o senso falou.
Coloquei três condensadores em cada motor.
Um condensador electrolítico na entrada da fonte de alimentação dos motores no L298.
Por ultimo coloquei um anel de ferrite na massa que vai ao arduino e uma resistência assim muito rápido.

A coisa nunca mais falhou  :)
Vou colocar imagens/vídeos do projecto.
https://www.youtube.com/watch?v=FQ1BYuI-lzU (https://www.youtube.com/watch?v=FQ1BYuI-lzU)