Los datos del acelerómetro BMA180 en arduino son esporádicos

He estado tratando de obtener un BMA180 (ya estoy en mi segundo) para enviar un flujo continuo de datos de aceleración a través de un puerto serie (eventualmente bluetooth, pero ese es un problema para otro día). Miré y traté de emular numerosos ejemplos y constantemente me encontré con el problema de los datos que llegaban "a trompicones". Un paquete, espere uno o dos segundos, algunos paquetes más, etc., etc. Por lo general, esto termina con los datos deteniéndose todos juntos después de 5, 10, 50 fragmentos.

Mi cableado es como se muestra aquí pero tengo VIO desconectado. Cuando VIO está vinculado a 3.3V, mi salida es todo 0. :cableado de enganche entre placa y arduino

Este es mi código, que está adaptado de varias otras fuentes:

#include <Wire.h>
#define DEVICE ((byte)0x40)  
#define DATA_X0      0x02   
#define AXIS_SHIFT   2   
#define DELAY_RATE   500

int counter = 0;


static void readFrom(byte address, byte num, byte *buff) {
  Wire.beginTransmission(DEVICE); 
  Wire.write(address);      
  Wire.endTransmission(); 

  Wire.requestFrom(DEVICE, num);  
  num = Wire.available();

  while(num-- > 0) {
    *(buff++) = Wire.read(); // receive a byte
  }
}

void setup()
{
  Wire.begin();          // join i2c bus (address optional for master)
  Serial.begin(115200);  // start serial for output
  Serial.flush();
  delay(15);
}

void loop()
{
  digitalWrite(13, HIGH); 
  int axis[5] = {0x0101, 0, 0, 0, 0};
  readFrom(DATA_X0, 6, (byte*)(axis+1)); 

  axis[1] = axis[1] ;
  axis[2] = axis[2] ;
  axis[3] = axis[3] ;

  axis[4] = axis[1] + axis[2] + axis[3];
  Serial.println("");
  Serial.println(axis[1]);
  Serial.println(axis[2]);
  Serial.println(axis[3]);
  Serial.println(axis[4]);
  counter++;

  delay(100);              
  digitalWrite(13, LOW);  
  delay(100);             
}

Esto es lo que obtengo al ingresar al monitor en serie, en extraños impulsos esporádicos:

-879
321
17077
16519

-411
345
16761
16695

249
0
0
249

........etc...... Sospecho que el fragmento 249 /0 /0/ 249 es la temperatura porque subirá y bajará un poco, aunque la aplicación de la lámpara de mi escritorio hizo que cesaran todos los datos . estoy desconcertado El LED 'L' en el arduino parpadea cuando los paquetes se expulsan, así que creo que no es un problema del puerto serie. Realmente apreciaría cualquier idea aquí.

¿Qué es un "BMA180"?
@LeonHeller Son las 3:30 de Atlanta a Boston, ¿no?
Lo siento mucho. Es un acelerómetro. Ver aquí: sparkfun.com/products/9723
@Kardasis, ¿tiene VIO desconectado tanto de la placa de cambio de nivel como del módulo real?
Alguien olvidó el enlace de la hoja de datos, entiendo la frustración, pero ¿dos votos negativos? ¿Podría alguien explicar? Parece que alguien está tratando de resolver un problema electrónico, incluso si está comenzando. Para el nivel de defensa de las preguntas fuera de tema, me parece asombroso.
@kortuk Voté negativo debido a la falta de detalles. No pensé que justificaba una votación reñida. Ahora que se ha agregado el detalle, mi voto negativo se ha deshecho.
VIO está conectado a la placa de cambio de nivel. 3.3V en el lado BMA180 y 5V en el lado arduino.
Todo el circuito me parece mal. La placa BMA180 tiene un pinout que me grita "SPI". Sin embargo, está conectado a los pines I²C del Arduino. Eso no tiene sentido, a menos que el BMA180 pueda funcionar tanto en modo I²C como SPI. ¿Puede? ¿Cómo le dices cuál usar?
@Majenko: aparentemente lo pones en modo I2C vinculando CS alto y SDO bajo.
FYI: he usado esta placa de conexión sin conversión de nivel en las líneas de bus I2C y no falló;) Creo que las resistencias que puedes ver en la placa se encargan de eso.

Respuestas (1)

I2C es un bus de datos bidireccional. Parece que está utilizando un traductor de nivel unidireccional (probablemente http://www.sparkfun.com/products/8745 ) cableado de tal manera que solo puede pasar datos del lado de bajo voltaje al de alto voltaje, y no al revés. . Esto evitará que envíe comandos al acelerómetro para solicitar datos, por lo que solo verá algo si decide producir datos por sí mismo. (EDITAR: aparentemente la conversión es al menos algo bidireccional)

Además, debe atar el VIO alto. Al dejarlo flotando, probablemente esté permitiendo que el ruido active el chip de alguna manera para producir datos ocasionalmente.

También tenga en cuenta que I2C requiere resistencias pullup.

Cambiar a SPI podría ser una opción, ya que en ese caso cada pin no sería direccional, sin embargo, necesita controlar 3 salidas del lado de 5v a 3.3v (/CS, SCK, MOSI) y su traductor existente solo admite 2. Usted podría construir algo para el tercero a partir de discretos.

Si dejó CS y SDO desconectados, es posible que pueda operar el chip en modo independiente donde produciría datos de manera confiable por sí mismo, pero luego tendría que hacer que el programa sea capaz de capturar los datos cada vez que aparezcan, tal vez usando un interrupción (o un ciclo de sondeo si puede garantizar que no sucede nada más).

Aquí hay un tutorial sobre cómo modificar el propio Arduino para que se ejecute en 3.3v, eliminando así el problema de conversión de nivel: http://www.adafruit.com/blog/2011/04/19/tutorial-tuesday-converting-an-arduino- a-3-3v/

La página de sparkfun para el convertidor de nivel dice que es compatible con I2C y estoy bastante seguro de que las solicitudes llegan al chip (al menos a veces) porque los datos que salen son datos de aceleración correctos en x, y, z), simplemente no viene de manera predecible o continua. En cuanto a las resistencias pull-up, creo que están integradas en el convertidor de nivel lógico.
@Kardasis: posiblemente, pero debe conectar el VIO para un funcionamiento confiable. Que obtenga 0 cuando lo haga indica que no está realizando correctamente una solicitud de datos; lo más probable es que cuando obtenga datos sea "por accidente"
¡O CHICO! Tienes razón sobre el VIO. Lo que no notaste es que soy un total n00b / yutz y el LED que conecté desde el pin SDI a tierra aparentemente tiraba del pin hacia abajo. Uggggg. Gracias por la ayuda.