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
-
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
-
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?
-
Já somos dois jm_araujo.
-
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.
-
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 :)
-
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.
-
Então mostra-nos lá que motor de passo aí tens e explica-nos lá, por palavras tuas, como é que funciona esse motor.
-
É um motor de passo com duas fases.
Funciona com os pulsos dados nas bobines, por exemplo A+ > A- depois B+ > -B
-
É um motor de passo com duas fases.
Ou seja um motor de passo bipolar (deduzo eu), como se designa normalmente.
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?
-
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.
-
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.
-
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?
-
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.
-
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...
-
Então pronto, já sabes o que fazer no teu código. Qual era a dúvida afinal?
-
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?!!?!?!)
-
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
-
Acho que é complicado um micro que não tenha um timer que não te deixe variar o periodo/frequência do mesmo..
-
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)
-
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.
-
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.
-
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.
-
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.
-
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?
-
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.
-
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
-
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
-
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!
-
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,
-
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
-
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
-
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.
-
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.
-
Motores DC é mais simples.
Controlas diretamente por PWM. No Arduino tens o analogWrite (http://arduino.cc/en/Reference/analogWrite) que trata de tudo.
-
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)
-
Leste a datasheet do sensor?
-
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.
-
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!
-
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);
-
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.
-
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.
-
É 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.
-
É 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.
#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
-
Tens de ter a placa ligada porque depois de compilar ele tenta fazer o upload.
-
Tens de ter a placa ligada porque depois de compilar ele tenta fazer o upload.
Não me está a deixar compilar na mesma.
-
Mostra aqui o erro.
-
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"
-
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.
-
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*****
-
a minha questão é, porque raio apertavas o shift? :S
-
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)...
-
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.
-
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.
-
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.
-
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.
-
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.
-
Depende muito da tua configuração fisica do sistema e dos componentes (controladores de potência, placa controladora, etc).
-
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)