Prueba del acelerómetro MMA7260 con PIC y PyQwt II

En esta ocasión me basaré en la clase QwtDial para crear algo parecido a un indicador de actitud.
De la guía de usuario de qwt:
“La clase QwtDial proporciona un control de intervalo redondeado.
QwtDial esta diseñado para ser una clase base para los indicadores (dial) como velocímetros, brújulas, relojes:
Un dial contiene una escala y una aguja indicando el valor actual del dual. Dependiendo del Modo uno de ellos es fijo y el otro esta rotando…”
De la descripción anterior podemos sacar la conclusión de que un dial se compone de dos elementos básicos: una escala y una aguja. Estos elementos se dibujan “a mano”, es decir, las líneas que componen el dial, los números, las figuras, los colores. No se puede escoger directamente que indicador queremos, sino que tenemos que dibujarlo. Esto es algo complicado pues hay que tener los conceptos básicos de geometría presentes y dominarlos.
La otra opción es tomar las clases de los ejemplos incluidos y ajustarlas a nuestras necesidades, que es lo que hice en este caso. Copié a un archivo clases.py las clases que necesitaba para el indicador de actitud (el tercer indicador de la imagen anterior) que son:
EnumList: Función que es llamada dentro de las clases necesarias.
AttitudeIndicator: Esta clase dibuja el círculo y las escalas del indicador.
AttitudeIndicatorNeedle: Esta clase dibuja la aguja central, que para el indicador de actitud, es un triangulo rojo.

Interfaz gráfica

La interfaz gráfica contendrá un indicador de actitud y una imagen que indicará la condición de caída libre. Un vertical layout contendrá al indicador de actitud. Un frame contendrá un label Free fall, un label con la imagen y el indicador de actitud. Todo esta hecho en qtdesigner:

Código en Python

Clases.py

testanalogdial.py

Primero creamos el objeto AttitudeIndicator que dibuja el dial con las escalas y la aguja definidas en clases.py. Al ponerlo a solo lectura, no acepta los eventos del teclado y del mouse. El gradiente es la cantidad de cielo o tierra que muestra, si es –1 apunta totalmente hacia la tierra. Ajustando el ángulo, cambiamos el ángulo de la línea horizontal que parte en dos al indicador.
Decodificando los datos
def decodeData(self):
        data = self.ptoSerial.readline()
        if (len(data) <7):
            print "Error"
            return 0, 0, False
        
        x = ord(data[1])
        y = ord(data[3])
        z = ord(data[5])

        x = x - 20
        angX = (1.463 * x) -180
        gradY = ((1.587 * y) - 200) / 100

        if z > 200 :
            freeFall = True
        else:
            freeFall = False
        return angX, -gradY,  freeFall
El formato de los datos que se esperan, es el mismo que el de ejemplos anteriores. El firmware es el mismo. La variable angX define el ángulo al que se mueve la línea horizontal (avion miniatura no dibujado para mantenerlo simple). La fórmula se obtiene con una regla de tres:
  • Los valores de aceleración se almacenan en variables de 8 bits (0-255).
  • El mínimo de aceleración normal (sin que haya un golpe fuerte, solo moviendo el acelerómetro) es de 71.
  • El máximo de aceleración normal es de 195.
  • Para saber el valor de cada grado se saca la diferencia entre el máximo y el mínimo y se divide entre 180, que es el rango de grados de –X (-90° a 0°) a X (0° a 90°). El resultado es de 1.463. Un grado equivale a 1.463 unidades de aceleración (en este caso inclinación).
La variable gradY define la altura de la línea horizontal (horizonte de referencia) que divide al cielo de la tierra. La formula se obtiene de la siguiente manera:
  • El valor mínimo de aceleración normal es de 65.
  • El valor máximo de aceleración normal es de 191.
  • La diferencia entre el máximo y el mínimo es de 126.
  • Los valores posibles de gradY van de –1.00 a 1.00.
  • Suponiendo que de –1.00 a 1.00 hay 200 valores. Dividiendo 200/126 tenemos 1.587.
  • El –gradY es por que para invertir el movimiento del horizonte.
Ahora ¿por que el –180 del primero y el –200 /100 del segundo?. Eso lo saque a prueba y error.
Para saber si el sensor esta en caída libre, solo fijamos un valor umbral para el eje z. En este caso 200.
Al ejecutar el programa obtenemos la siguiente ventana:

Con esto termina este ejemplo.
Descargar ejemplo.

0 comentarios:

Publicar un comentario