¿Por qué mi girómetro FXAS21002 devuelve un WHO_AM_I defectuoso?

0

Estoy intentando usar el giroscopio FXAS21002C en BRKT-STBC-AGM04 tablero de distribución .

Como primera prueba, intenté leer el registro de WHO_AM_I en 0x0C, que se supone debe dar 0xD7 como resultado de acuerdo con la documentación. Pero en cambio estoy leyendo 0x00.

Supervisé la comunicación I2C y no estoy notando ninguna irregularidad allí. El FXAS21002C está respondiendo con ACK. etc

(La línea superior es SCL; la línea inferior es SDA; ambas se ajustaron a 3.3V)

Laconversaciónaquíes:010000000000011000010000010000000001

YestoyejecutandoelsiguientecódigoenmiArduinoUno:

#include<Wire.h>#include<math.h>#include"Arduino.h"

#define GyrAddress 0x20

#define pullupPin 4

#define gyr_WHO_AM_I 0x0C
#define gyr_WHO_AM_I_RSP 0xD7

#define I2C_address GyrAddress
#define WHO_AM_I gyr_WHO_AM_I
#define WHO_AM_I_RSP gyr_WHO_AM_I_RSP

uint8_t readRegister(uint8_t address) {
    uint8_t output;

    Wire.beginTransmission(I2C_address);
    Wire.write(address);
    Wire.endTransmission();

    delayMicroseconds(4);

    Wire.requestFrom(I2C_address, 1);
    while (Wire.available()) {
        Serial.println("reading a thing");
        output = Wire.read();
    }

    return output;
}

void writeRegister(uint8_t address, uint8_t value){
    Wire.beginTransmission(I2C_address);
    Wire.write(address);
    Wire.write(value);
    Wire.endTransmission();
}

bool initialize() {
    Wire.begin();
    Wire.setClock(400000);        // I2C fast mode, 400kHz
    uint8_t reg;
    if ((reg = readRegister(WHO_AM_I)) != WHO_AM_I_RSP) { //Could not find MAG3110

        Serial.println(reg);
        Serial.println(WHO_AM_I_RSP);
        Serial.println("Could not find gyro connected!");
        return false;
    } else //Successfully initialized
    {
        Serial.println("found gyro!");
        return true;
    }
}

void setup() {
    pinMode(pullupPin, INPUT_PULLUP);
    Serial.begin(57600);

    Serial.println("begun");

    Serial.println(initialize());
}

int pullup;
void loop() {
    // test code to rerun when I press a button.
    int input = digitalRead(pullupPin); 
    if(input ^ pullup){
      pullup = input;
      if(input){
        Serial.println(initialize());
      }
    }
}

Esquema de mi configuración actual:

¿Alguien sabe por qué el FXAS21002C no está devolviendo la respuesta WHO_AM_I que figura en la documentación?

    
pregunta Pepijn Willekens

1 respuesta

1

Posiblemente se requiera una respuesta errónea y se requieren más lecturas ...

Del manual de giroscopios (p.15)

  

Una transición de BAJO a ALTO en la línea SDA mientras SCL es alto se define como una parada   señal de condición (SP). Una escritura o escritura de ráfaga siempre es terminada por el maestro   Emisión de la señal SP. Un maestro debe terminar adecuadamente una lectura por no   reconociendo un byte en el momento apropiado en el protocolo. Un maestro también puede emitir   una señal de inicio repetida (SR) durante una transferencia.

y (re: lectura de un solo byte)

  

La MCU transmite un SR, seguido de   el byte que contiene la dirección del esclavo y el bit R / W establecido en "1" para una lectura

Al poner esto junto con su diagrama de alcance, está escribiendo la dirección de WHOAMI y luego emitiendo una señal de SP (STOP), en lugar de una señal de SR (inicio repetido).

Esto parece terminar la transacción ...

OMI, la documentación está incompleta y debe complementarse con la especificación del protocolo I2C (UM10204), que, emitida por una empresa rival, Freescale no tiene ninguna prisa para ayudarlo a encontrar con algo tan útil como link .

Consulte la página 9 de UM10204:

  

El bus permanece ocupado si se genera un START (Sr) repetido en lugar de una condición STOP. En   A este respecto, las condiciones de inicio (S) y inicio (inicio) repetidas son funcionalmente idénticas.

(creo que la diferencia entre SR y STOP es que el nivel de SDA es alto, mientras que SCL sigue siendo bajo, por lo que el siguiente flanco descendente de SDA comienza la siguiente transferencia: confirmada por la Figura 6 en la página 10)

Por lo tanto, en su código de registro de lectura

Wire.beginTransmission(I2C_address);
Wire.write(address);
Wire.endTransmission();

delayMicroseconds(4);
Wire.requestFrom(I2C_address, 1);

Creo que Wire.endTransmission() es incorrecto y necesitas alguna otra función (o posiblemente ninguna) para continuar la transmisión y recopilar los datos.

Ahí es donde entra la lectura adicional; Me resulta más fácil programar mis Arduinos en Ada, así que no puedo ayudarte a encontrar la función correcta en la biblioteca de Arduino.

Pero una búsqueda rápida muestra la documentación de transmisión de fin que dice

  

A partir de Arduino 1.0.1, endTransmission () acepta un argumento booleano que cambia su comportamiento para la compatibilidad con ciertos dispositivos I2C.

     

Si es verdadero, endTransmission () envía un mensaje de detención después de la transmisión,   liberando el bus I2C.

     

Si es falso, endTransmission () envía un mensaje de reinicio después de   transmisión. El autobús no será lanzado, lo que impide que otro   Dispositivo maestro de transmitir entre mensajes. Esto permite una   dispositivo maestro para enviar múltiples transmisiones mientras está en control.

     

El valor predeterminado es verdadero. Sintaxis

     

Wire.endTransmission ()
  Wire.endTransmission (detener)

     

Parámetros

     

detener: booleano. true enviará un mensaje de parada, liberando el bus después de   transmisión. false enviará un reinicio, manteniendo la conexión.   activo.

    
respondido por el Brian Drummond

Lea otras preguntas en las etiquetas