ADXL345 читает только ceros

Я пытаюсь соединить ADXL 345 с tm4c1294nctpd с использованием energia. Конфигурация контактов следующая: SDA с контактом PB3 и SCL с контактом PB2 (порт I2C0), с использованием J1 (3.3 V) и J21 (5 В) и GND. При последовательном мониторе энергии выходы x=0,y=0, z=0, , схема имеет подтягивающий резистор в выводах SDA и SCL,

Адрес датчика 0x53. Я понимаю, что я делаю устройство подчиненным протоколу I2C ( Wire.begin(ADXAddress);)

Код

 #include "Wire.h"

#define Power_Register 0x2D
#define BW_rate 0x2C
#define Int_enable 0x2E
#define dataFormat 0x31
#define X_Axis_Register_DATAX0 0x32
#define X_Axis_Register_DATAX1 0x33
#define Y_Axis_Register_DATAY0 0x34 
#define Y_Axis_Register_DATAY1 0x35
#define Z_Axis_Register_DATAZ0 0x36
#define Z_Axis_Register_DATAZ1 0x37
#define fifoCntrl 0x38

int ADXAddress = 0x53;
int X0,X1,X_out;
int Y0,Y1,Y_out;
int Z1,Z0,Z_out;
float Xa,Ya,Za;

void setup() {
  Wire.setModule(0);
  Wire.begin(ADXAddress);   
  Serial.begin(9600);    
  delay(100);
  Wire.beginTransmission(ADXAddress);
  Wire.write(Power_Register);
  Wire.write(8);
  Wire.write(BW_rate);
  Wire.write(10);
  Wire.write(dataFormat);
  Wire.write(11);
  Wire.write(fifoCntrl);
  Wire.write(0);

  Wire.endTransmission();


}


void loop() {

 Wire.beginTransmission(ADXAddress);
 Wire.write(X_Axis_Register_DATAX0);
 Wire.write(X_Axis_Register_DATAX1);  
 Wire.endTransmission();
 Wire.requestFrom(ADXAddress,2);
 if(Wire.available()<=2) {   
   X0 = Wire.read();
   X1 = Wire.read();
   X1=X1<<8;
   X_out =X0+X1;

 }

 Wire.beginTransmission(ADXAddress); 
 Wire.write(Y_Axis_Register_DATAY0);
 Wire.write(Y_Axis_Register_DATAY1);  
 Wire.endTransmission(); 
 Wire.requestFrom(ADXAddress,2);
 if(Wire.available()<=2) { 
   Y0 = Wire.read();
   Y1 = Wire.read();
   Y1=Y1<<8;
   Y_out =Y0+Y1;
 }

 Wire.beginTransmission(ADXAddress); 
 Wire.write(Z_Axis_Register_DATAZ0);
 Wire.write(Z_Axis_Register_DATAZ1);  
 Wire.endTransmission(); 
 Wire.requestFrom(ADXAddress,2);
 if(Wire.available()<=2) { 
   Z0 = Wire.read();
   Z1 = Wire.read();
   Z1=Z1<<8;
   Z_out =Z0+Z1;

 }

 Serial.print("Xa= ");
 Serial.print(Xa);Serial.print("\t");
 Serial.print("Ya= ");
 Serial.print(Ya);Serial.print("\t");
 Serial.print("Za= ");
 Serial.println(Za);


 delay(1000);
 Serial.println();
}

person ttyacm0a    schedule 28.10.2019    source источник
comment
Используете ли вы какую-либо плату для ADXL345? Что вы подразумеваете под ... использованием J1 (3,3 В) и J21 (5 В)...? Ваша проблема, вероятно, связана с аппаратным обеспечением, было бы лучше, если бы вы немного лучше объяснили, как вы подключаете свою схему.   -  person Marcos G.    schedule 28.10.2019


Ответы (1)


Если вы записываете в случайные регистры I2C, вам необходимо перезапустить передачу. Просто сделайте функцию, чтобы сделать это проще.

void writeReg ( int reg, int value )
{
    Wire.beginTransmission(ADXAddress);
    Wire.write(reg);
    Wire.write(value);
    Wire.endTransmission();
}

void setup() 
{
  Wire.setModule(0);
  Wire.begin(ADXAddress);   
  Serial.begin(9600);    
  delay(100);

  writeReg(Power_Register,8);
  writeReg(BW_rate,10); // <-- should this be 0x10 ?
  writeReg(dataFormat,11); // <-- should this be 0x11 ?
  writeReg(fifoCntrl,0);  // <-- this isn't strictly needed as fifoCntrl will be 0 at power on reset anyway

}

Во-вторых, учебник, который вы использовали (я видел его в Интернете), на самом деле не на 100% правильный. При чтении регистра он должен записать только один байт, а не два перед чтением, один раз для установки указателя регистра. Упростите свой код, чтобы сделать еще одну функцию для чтения, чтобы код было легче читать.

int readAxis ( int reg )
{
   Wire.beginTransmission(ADXAddress);
   Wire.write(reg);
   Wire.endTransmission();
   Wire.requestFrom(ADXAddress,2);

   int d0 = Wire.read();
   int d1 = Wire.read();

   return (d1<<8) + d0;
}

void loop ()
{
    X_out = readAxis(X_Axis_Register_DATAX0); // this will read TWO bytes starting from X0 register (LSB + MSB)
    Y_out = readAxis(X_Axis_Register_DATAY0);
    Z_out = readAxis(X_Axis_Register_DATAZ0);
    :

В-третьих, вы на самом деле ничего не печатаете, потому что забыли установить значения Xa, Ya, Za.

:

Xa = (float)X_out/RANGE;
Ya = (float)Y_out/RANGE;
Za = (float)Z_out/RANGE;


Serial.print("Xa= ");
Serial.print(Xa);Serial.print("\t");
Serial.print("Ya= ");
Serial.print(Ya);Serial.print("\t");
Serial.print("Za= ");
Serial.println(Za);

Вам нужно будет определить RANGE на основе полной шкалы выбранного вами выхода ADXL (в терминах G). Пожалуйста, проверьте техническое описание ADXL в вашем режиме работы (т. е. это режим работы 2G или 16G и т. д., каковы значения полной шкалы для каждого из них?)

#define ADXL_FULLSCALE 4096   // 2^(13 bits- 1 signed bit)
#define ADXL_FULLSCALE_G 16   // +/- 16 G operation
#define RANGE (ADXL_FULLSCALE /ADXL_FULLSCALE_G )
person pm101    schedule 28.10.2019