Ola galera!!!!!!!!!
https://www.youtube.com/watch?v=ePW57SFFOks&feature=youtu.be
Estou agora demonstrando o funcionamento do Acelerômetro MMA7361.
Confesso que eu tive muita dificaldade em trabalhar com este cara.
Na internet só falava de outros acelerômetros mas eu achei esse componenete muito bom.
Achei uns códigos e fucei bastante e coloquei o bicho pra funcionar. 'ALELUIA IRMÃO!!!!!!!!!!!!'
Aqui está a especificação dos pinos:
Ao montar o circuito, repare que será necessário ligar o pino 3.3 Volts do Arduino Uno R3 ao pino AREF, para que tenhamos uma tensão de referência. Sem ele, a leitura dos dados fica totalmente prejudicada:
Se possível, recomendo a ligação fora da protoboard ou então a utilização de um mini protoboard, como mostrado no circuito, isso vai facilitar bastante na hora de testar os movimentos com o módulo.
Para teste vou usar um dos 3 programas exemplo que vem na própria biblioteca do MMA7361, o programa G_FORCE. Carregue o programa no Arduino, movimente o sensor e veja no serial monitor como se comportam as variações dos eixos X, Y, Z, e a gravidade (G).
Observando que um acelerômetro sobre a superfície terrestre está submetido à aceleração da gravidade, 1g ou -9,81g no eixo Z quando não está submetido a nenhum a inclinação ou aceleração linear, pode-se estimar a leitura do celerômetro.
Existem várias formulas matemáticas para demostrar o funcionamento do acelerômetro mas só vou apresentar as que eu usei no código se não vai ficar muito extenso o papo.
Eu estou usando o fator de correção PITCH e ROLL.
O fator multiplicativo converte os ângulos de graus para radianos é de PI/180°.
Obtidos os ângulos de rotação, os vetores de estimação (Vert, H1 e H2) são atualizados por meio da aplicação da função “rotate3D”, que aplica nestes vetores uma matriz de rotação tridimensional em torno do eixo X T e do eixo Y T, denotada por Mxy.
Neste ponto, o algoritmo já calculou uma estimação vetorial da orientação do sistema, que pode ser exibida graficamente em um computador ou em uma tela de cristal líquido acoplada ao sistema. Para se fazer uso de atuadores mecânicos (no caso deste trabalho, servomotores), porém, é necessário calcular o valor numérico dos ângulos pitch e roll.
//Roll & Pitch equacoes para posicionamento espacial
roll = (atan2(-fYg, fZg)*180.0)/M_PI;
pitch = (atan2(fXg, sqrt(fYg*fYg + fZg*fZg))*180.0)/M_PI;
Abaixo vocês podem observa o código usado no Arduino:
#include <AcceleroMMA7361.h>
AcceleroMMA7361 accelero;
double fXg = 0;
double fYg = 0;
double fZg = 0;
const float alpha = 0.3;
void setup()
{
Serial.begin(9600);
// SL ST 0G GS X Y Z
accelero.begin(13, 12, 11, 10, A0, A1, A2);
accelero.setARefVoltage(3.3); //Voltagem de referencia 3,3 Volts
accelero.setSensitivity(LOW); //Setando a sensibilidade para +/-6G
accelero.calibrate();
}
void loop()
{
double pitch;
double roll;
double Xg;
double Yg;
double Zg;
Xg = accelero.getXAccel();
Yg = accelero.getYAccel();
Zg = accelero.getZAccel();
//Filtro
fXg = Xg * alpha + (fXg * (1.2 - alpha));
fYg = Yg * alpha + (fYg * (1.2 - alpha));
fZg = Zg * alpha + (fZg * (1.2 - alpha));
//Roll & Pitch equacoes para posicionamento espacial
roll = (atan2(-fYg, fZg)*180.0)/M_PI;
pitch = (atan2(fXg, sqrt(fYg*fYg + fZg*fZg))*180.0)/M_PI;
Serial.print(pitch);
Serial.print(":");
Serial.println(roll);
delay(10);
}
O código no Processing vocês vem abaixo:
import processing.serial.*;
Serial fd;
int pitch = 0;
int roll = 0;
void setup ()
{
size(640, 360, P3D);
//Conexao com a porta
fd = new Serial(this, "/dev/ttyUSB0", 9600);
fd.bufferUntil('\n');
noStroke();
colorMode(RGB, 1);
}
void draw ()
{
//Set background
background(0);
pushMatrix();
translate(width/2, height/2, -30);
//Roatcao
rotateX(((float)roll ) * PI / 180);
rotateZ(((float)pitch) * PI / 180);
print("Pitch: ");
print(pitch);
print(", Roll: ");
println(roll);
scale(90);
beginShape(QUADS);
fill(0, 1, 1); vertex(-1, 1, 1);
fill(1, 1, 1); vertex( 1, 1, 1);
fill(1, 0, 1); vertex( 1, -1, 1);
fill(0, 0, 1); vertex(-1, -1, 1);
fill(1, 1, 1); vertex( 1, 1, 1);
fill(1, 1, 0); vertex( 1, 1, -1);
fill(1, 0, 0); vertex( 1, -1, -1);
fill(1, 0, 1); vertex( 1, -1, 1);
fill(1, 1, 0); vertex( 1, 1, -1);
fill(0, 1, 0); vertex(-1, 1, -1);
fill(0, 0, 0); vertex(-1, -1, -1);
fill(1, 0, 0); vertex( 1, -1, -1);
fill(0, 1, 0); vertex(-1, 1, -1);
fill(0, 1, 1); vertex(-1, 1, 1);
fill(0, 0, 1); vertex(-1, -1, 1);
fill(0, 0, 0); vertex(-1, -1, -1);
fill(0, 1, 0); vertex(-1, 1, -1);
fill(1, 1, 0); vertex( 1, 1, -1);
fill(1, 1, 1); vertex( 1, 1, 1);
fill(0, 1, 1); vertex(-1, 1, 1);
fill(0, 0, 0); vertex(-1, -1, -1);
fill(1, 0, 0); vertex( 1, -1, -1);
fill(1, 0, 1); vertex( 1, -1, 1);
fill(0, 0, 1); vertex(-1, -1, 1);
endShape();
popMatrix();
}
// Interrupcao serial
void serialEvent (Serial fd)
{
String rpstr = null;
try {
rpstr = fd.readStringUntil(10);
if (rpstr != null) {
String[] list = split(rpstr, ':');
pitch = ((int)float(list[0]));
roll = ((int)float(list[1]));
}
} catch( ArrayIndexOutOfBoundsException e ) {
print("Erro!!!!!!\n");
}
}
Podem copiar e colar sem dó. Está funcionando perfeitamente.
Comentar
Ola Christiano. Fiz uns testes, mas sem muito progresso. Os valores lidos ficaram em torno de 500 para os eixos que estavam na horizontal e 600 para o que estava na vertical. Então, eu dividi por 100 e subtrai 5. Os valores ficaram próximos de 1, mas ainda assim valores meio malucos. As vezes chegava quase a 2. Será que tem alguma coisa a ver com a rotação? Vc poderia me dar uma explicação sobre as variáveis alpha, pitch e roll?
Há, agora entendi. Então, baseado nos números que vc me forneceu, conclui-se que, g é inversamente proporcional a tensão lida no AD. Quando g aumenta a tensão cai. É o contrário do que eu estava pensando. Vou fazer uns testes pra ver. Obrigado pela dica.
AD é o pino de leitura analógica do Arduino(A0, A1, A2...). AD( Analógico para Digital).
Agora complicou. Esse "AD" pra mim é grego. Será que vc teria alguma literatura pra me indicar pra eu me aprofundar mais nesse assunto?
Esses valores são referências. Quando ele está no 0G está só lendo o AD do Arduino e está com o valor 660.
Exemplificando. Quando o AD está lendo um valor 660 no eixo X, a gravidade está exercendo neste eixo 0G de força gravitacional.
Eu estava pensando que era assim:
Como este acelerômetro mede de -3g a +3g
0 Volts (leitura 0) => -3g
3,3 Volts (leitura 1023) => 3g
Mas não funcionou. Estou achando que é defeito do acelerômettro,
De qualquer forma, de onde vc tirou esses valores? Por exemplo:
X Axis:
-1G = 754
0G = 660
1G = 567
Você deve transformar este valor de leitura que a porta analógica ler (que vai de 0 a 1023), para a força G que é 1. Um, é a leitura para em que a força da gravidade da terra exerce para um determinado eixo do seu acelerômetro.
Primeiro você fará a leitura do acelerômetro normalmente.
sv1 = analogRead(0);
sv2 = analogRead(1);
sv3 = analogRead(2);
Depois você irá comparar os valores:
Z Axis:
-1G = 750
0G = 660
1G = 565
X Axis:
-1G = 754
0G = 660
1G = 567
Y Axis:
-1G = 770
0G = 677
1G = 588
Pegando a tensão de referência que você usa:
VoltsRx = sv1 * 3.3V / 1023 =~ 1.89V
VoltsRy = sv2 * 3.3V / 1023 =~ 2.03V
VoltsRz = sv3 * 3.3V / 1023 =~ 1.81V
Agora pegamos a voltagem do 0(Zero Gravitacional) ou delta volts:
DeltaVoltsRx = VoltsRx – 1.65V = 0.24V
DeltaVoltsRy = VoltsRy – 1.65V = 0.38V
DeltaVoltsRz = VoltsRz – 1.65V = 0.16V
Agora aqui você precisa saber a sensibilidade do seu acelerômetro para fazer está parte:
Rx = DeltaVoltsRx / Sensibilidade do acelerômetro
Rx = 0.24V / 0.4785V/g =~ 0.5g
Ry = 0.38V / 0.4785V/g =~ 0.79g
Rz = 0.16V / 0.4785V/g =~ 0.33g
Ai está sua força G.
Lembre-se de fazer um algorítimo para calibragem do seu acelerômetro quando for ligar seu arduino.
Eu não conheço este modelo, mas o velho Google sabe.
Christiano, no ADLX 335 não tem nenhuma libe, eu pego a leitura dele direto nas entradas analógicas:
sv1 = analogRead(0);
delay(2);
sv2 = analogRead(1);
delay(2);
sv3 = analogRead(2);
No 435 tem uma libe SPI.h, mas eu acho que é pra comunicação I²C. Eu baixei um sketch do site da spakfun, mas não funcionou. Também ficou apresentando números malucos.
Libe ? = Library (Biblioteca)
A libe do meu acelerômetro é está: AcceleroMMA7361.h (arquivo header)
Ai eu coloco:
#include <AcceleroMMA7361.h>
Ai você terá que abrir o do seu acelerômetro e ver qual a função que retorna o valor da força g
No meu caso são estes:
accelero.getXAccel();
accelero.getYAccel();
accelero.getZAccel();
Cada um retorna o valor que a gravidade está influenciando sobre os três eixos.
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por
Você precisa ser um membro de Laboratorio de Garagem (arduino, eletrônica, robotica, hacking) para adicionar comentários!
Entrar em Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)