MPU6050 Aceleración / giro del ruido que se comporta de forma extraña: ¿qué podría estar haciendo esto?

3

Estoy experimentando con un acelerómetro / giroscopio de seis ejes MPU6050 con datos de Raspberry Pi a través de I2C. La respuesta de seis ejes tiene sentido en general, ya que la roto a mano, la rotación mueve el vector de gravedad correctamente por los canales del acelerómetro, y las rotaciones cortas alrededor de cada eje generan valores de giroscopio de aspecto razonable.

Pero cuando lo coloco en algo que debería aislarlo de las vibraciones y solo tomar datos durante un tiempo prolongado, veo un extraño ruido no estadístico en algunos canales.

Escribí una breve secuencia de comandos (que se muestra a continuación) que muestra los seis canales para 400 iteraciones, luego incrementa el filtro de paso bajo (siete niveles desde 0x00 a 0x06 ) y luego incrementa la ganancia tanto para aceleración como para giroscopio ( cuatro niveles; 0x00, 0x08, 0x10, 0x18 ). Entonces eso es 28 pruebas con 400 muestras cada una. La tasa de datos es de aproximadamente 55 a 60 mediciones de los seis ejes por segundo. La frecuencia característica para cada configuración del filtro de paso bajo digital de registrar mapa pdf es:

yla hoja de datos pdf .

A continuación muestro los datos que van desde - / + 32,767. Lo único que he cambiado es restar la media de las 400 mediciones en cada configuración para que solo se muestre el ruido.

A medida que aumentan los siete ajustes del filtro de paso bajo, la frecuencia disminuye y el ruido disminuye según lo esperado. Sin embargo, hay estos picos repentinos de +/- 200 a 300 recuentos de ADC. No son exactamente 256, pero en ese estadio parece un poco sospechoso.

También muestro los datos sin procesar y las desviaciones estándar por prueba en la segunda gráfica.

Pregunta: ¿Este tipo de comportamiento, este ruido no estadístico y puntiagudo, parece familiar para cualquiera? Estoy esperando un segundo giro para comparar, pero eso llevará muchos días, y me gustaría ver si hay algo que pueda hacer mientras tanto. Cada uno de los seis canales tiene un comportamiento muy diferente al ruido. Dentro del IC hay seis dispositivos MEM separados cada uno conectado a su propio ADC dedicado.

ScriptparaqueRaspberryPileaelmóduloatravésdeI2C:

#!/usr/bin/pythonimportwebimportsmbusimportmathimporttimeurls=('/','index')pwrmgmt_1=0x6bpwrmgmt_2=0x6cdlpf_set_addr=0x1agyro_scale_addr=0x1baccel_scale_addr=0x1cscales=0x00,0x08,0x10,0x18dlpfs=0x00,0x01,0x02,0x03,0x04,0x05,0x06pairs=((0x3b,0x3c),(0x3d,0x3e),(0x3f,0x40),(0x43,0x44),(0x45,0x46),(0x47,0x48))setups=[]forscaleinscales:fordlpfindlpfs:setups.append((scale,dlpf))nsetups=len(setups)bus=smbus.SMBus(1)address=0x68ic=0isetup=0nsamples=400defread_six():vals=[]forahi,aloinpairs:high=bus.read_byte_data(address,ahi)low=bus.read_byte_data(address,alo)val=(high<<8)+lowifval>=0x8000:val=-((65535-val)+1)vals.append(val)returnvalsclassindex:defGET(self):globalic,nsamplesglobalisetup,nsetups,setupsglobalaccel_scale_addr,gyro_scale_addr,dlpf_set_addrsix=read_six()six_str=str(six)[1:-1]ic+=1ifnotic%nsamples:isetup+=1scale,dlpf=setups[isetup%nsetups]bus.write_byte_data(address,accel_scale_addr,scale)bus.write_byte_data(address,gyro_scale_addr,scale)bus.write_byte_data(address,dlpf_set_addr,dlpf)returnsix_str+", " + str(isetup)

if __name__ == "__main__":

    # wake the 6050 up since it starts in sleep mode
    bus.write_byte_dta(address, pwrmgmt_1, 0)

    time.sleep(0.5)

    scale, dlpf = setups[isetup]

    bus.write_byte_data(address, accel_scale_addr, scale)
    bus.write_byte_data(address, gyro_scale_addr,  scale)
    bus.write_byte_data(address, dlpf_set_addr,    dlpf)

    print "setup scale: ", scale
    print "setup dlpf:  ", dlpf

    time.sleep(0.1)

    ic  = 0

    app = web.application(urls, globals())
    app.run()
    
pregunta uhoh

2 respuestas

2

Los errores se ven como +/- 256 +/- deriva esperada.

Esto sugiere algún tipo de error de sincronización, como leer el LSByte de una muestra y el MSByte de la siguiente o viceversa. ¿Cómo maneja esto tu giroscopio, hay alguna manera de ponerlo temporalmente en espera mientras lees datos?

También, examine los datos sin procesar alrededor de algunos de estos errores para ver si ocurre cuando una señal que se desplaza lentamente cruza un límite de MSByte. Obviamente, al enfocarte en el Y Gyro, los errores están más claramente separados del ruido.

    
respondido por el Brian Drummond
1

@BrianDrummong identificó la fuente del ruido aparente en la respuesta aceptada . La lectura de un byte a la vez sobre I2C dio lugar a un comportamiento asíncrono, de modo que los bytes hi y lo correspondieron a diferentes conversiones. El uso de bus.read_i2c_block_data() resolvió el problema de enganche. Al leer catorce bytes (siete palabras) (tres acelerómetros, temperatura, tres giroscopios) como una sola instrucción I2C, el "ruido" ha desaparecido.

def read_sevenblock():

    fourteen = bus.read_i2c_block_data(0x68, 0x3b, 14)  # Read all at once
    his, los = fourteen[0::2], fourteen[1::2]

    vals = []
    for hi, lo in zip(his, los):
        vals = (hi << 8) + lo
        if val >= 0x8000:
            val = -((65535 - val) + 1)
        vals.append(val)
    return vals

    
respondido por el uhoh

Lea otras preguntas en las etiquetas