Ignora lo que dice stevenvh en su primer párrafo. Es la manera incorrecta de resolver el problema. Él está midiendo cos (ángulo), y dice que es básicamente inútil.
stevenvh ha arreglado su primer párrafo.
Para medir la inclinación con un acelerómetro, debe medir la aceleración horizontal , de modo que una inclinación positiva dé una lectura de aceleración positiva y una inclinación negativa dé una lectura de aceleración negativa. Ahora tu lectura es proporcional al pecado (ángulo).
TomandoestedispositivoADXLcomoejemplo.Cuandoestáacostadosobrelamesa,elejeZlee1g,mientrasqueXeYleen0g.Silogiras0,5ºalrededordelejeY,entonceslalecturadelejeZapenascambiará,perolalecturadelejeXcambiaránotablemente.
Supongamosquetenemosunacelerómetroconunasensibilidadde±1g,conunasalidade12bits,queofreceunrangode-2048..2047.
Entonces,a0º,medimos0gyobtenemosunasalidadeADCde0.A0.5ºmedimossen(0.5)g=0.0087g.LoquenosdaráunasalidadeADCde0.0087*2047=17.
Porlotanto,deberíapodermedirlosprimeros0.5ºdesdeelnivelconunacelerómetrode±1gyunADCde12bits,siemprequelocalibrecorrectamente.
Elproblemaesquesuprecisióndisminuyeamedidaquegirafueradenivel.Aquíesdondeentraunsegundoacelerómetro.Paralidiarconunarotacióncompletade360º,debeusardosacelerómetrosortogonales.(Porejemplo,undispositivode2ejes).
Uselaseñaldecadaunoparacalcularelángulo,luegotomeelpromedioponderadodeesosángulos,cadaunoponderadoporlaamplituddelaseñaldelotro.
floatAngle_radians(floatx,floaty)const{floatangle;if(fabs(x)>fabs(y)){angle=atan(y/x);if(x<0.0f)angle+=PI;}else{angle=PI*0.5f-(float)atan(x/y);if(y<0.0f)angle+=PI;}if(angle<0.0f)angle+=PI*2;if(angle>PI*2)angle-=PI*2;returnangle;}floatx_acc=ADC_read(x_axis_channel)//readxaxis(horizontal)floaty_acc=ADC_read(y_axis_channel)//readyaxis(vertical)x_acc*=1.0/2047;//scaletorange-1..+1y_acc*=1.0/2047;angle=angle_radians(x_acc,y_acc);
Agregado:comomencionanlosmarkrages,generalmentetambiénhayunafunciónllamadaatan2(),quehaceexactamenteesto:
angle=atan2(x_acc,y_acc);
Añadido:respondiendoalaspreguntasdeTheNewbie.
¿Entonces,básicamentealusarunacelerómetrodeejedoble/triplehaymejoresposibilidadesdeobtenerlaprecisióncorrectaconelpromedioyelfiltrado?
No,estoydiciendoqueparaobtenerunalecturaprecisaentodoelrangode360º,tienesparausardosejes.Unejeirádesdelaprecisiónmáximaen0ºhastalaprecisiónceroen90º.Elotroejeharálocontrario.
¿Podríamostrarmeunejemplodeuncálculodeprecisiónparalahojadedatosadjunta?
SuparteeselMMA8451Q,quecontieneunADCde14bits,estádisponibleenunaversión2g,queda4096cuentas/g.Estoeseldobledelaresolucióndemiejemploanterior.Sinembargo,laprecisiónnoestodoacercadelaresolución.TambiéndebetenerencuentaeldesplazamientoCero-g.
Cuando su dispositivo está plano sobre la mesa, un eje debe leer exactamente cero, pero no lo hará. Habrá un ligero desplazamiento. De acuerdo con la hoja de datos, esto puede ser de hasta ± 30 mg. ¡Esto es equivalente a un error de ángulo de 1.7º! Deberá tener en cuenta este error de compensación. Lo haces por calibración.
Tome un plato grueso de vidrio o granito pulido, y coloque un cojinete de bolas grande sobre él. Ajuste el ángulo del vidrio hasta que el rodamiento no ruede más. Esto es bastante nivel ahora.
Coloque su dispositivo plano sobre el vidrio y tome nota de la lectura de los sensores horizontales. Darán lecturas cercanas a cero. Ahora puede cargar estas lecturas en el dispositivo, y las restará de sus propias lecturas.
Unaúltimapreguntaeselruido.Laslecturasdelsensornoseránperfectamenteestables.Coneldispositivoestacionario,laslecturasprobablementefluctúenmuylevemente.Puedereducirelruidotomandovariaslecturasdesensores(16talvez)ypromediándolos.Porsupuesto,estoreducelatasadeactualizacióndesusensorreal.
Consulte puerta de Guy NXT para ver un buen artículo sobre la calibración del acelerómetro y el ruido del sensor.