Библиотека ADXL345 для системной платы sparkfun turbo, которая дает неверные показания - PullRequest
0 голосов
/ 18 января 2020

Я использую ADXL345, используя I2 C как на турбо-плате sparkfun redboard (процессор samd21g18), так и на старом arduino uno (процессор mega16u2). Библиотека и эскиз, которые я использую на обеих платах, одинаковы, за исключением того, что последовательный порт заменен на SerialUSB для размещения на доске.

Проблема заключается в том, что uno интерпретирует регистры xyz (2 байта). на ось в регистрах 0x32 - 0x37) как 16-битный комплимент (в соответствии с таблицей данных), а красная доска - нет. Вывод uno является правильным, а вывод на красной доске, который является неправильным, является положительным целочисленным выводом.

На рисунке ниже показан вывод для красной доски слева и uno справа для одинакового относительного положения ADXL345).

enter image description here

Я полагаю, что код ошибки находится в следующем коде библиотеки.

/*********************** READING ACCELERATION ***********************/
/*    Reads Acceleration into Three Variables:  x, y and z          */

void ADXL345::readAccel(int *xyz){
    readAccel(xyz, xyz + 1, xyz + 2);
}

void ADXL345::readAccel(int *x, int *y, int *z) {
    readFrom(ADXL345_DATAX0, ADXL345_TO_READ, _buff);   // Read Accel Data from ADXL345

    // Each Axis @ All g Ranges: 10 Bit Resolution (2 Bytes)
    *x = (((int)_buff[1]) << 8) | _buff[0];
    *y = (((int)_buff[3]) << 8) | _buff[2];
    *z = (((int)_buff[5]) << 8) | _buff[4];
}

Код эскиза выглядит следующим образом:

#include <SparkFun_ADXL345.h>


/*********** COMMUNICATION SELECTION ***********/
/*    Comment Out The One You Are Not Using    */
//ADXL345 adxl = ADXL345(10);           // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
ADXL345 adxl = ADXL345();             // USE FOR I2C COMMUNICATION

/****************** INTERRUPT ******************/
/*      Uncomment If Attaching Interrupt       */
//int interruptPin = 2;                 // Setup pin 2 to be the interrupt pin (for most Arduino Boards)


/******************** SETUP ********************/
/*          Configure ADXL345 Settings         */
void setup(){

  SerialUSB.begin(9600);                 // Start the SerialUSB terminal
  SerialUSB.println("SparkFun ADXL345 Accelerometer Hook Up Guide Example");
  SerialUSB.println();

  adxl.powerOn();                     // Power on the ADXL345

  adxl.setRangeSetting(2);           // Give the range settings
                                      // Accepted values are 2g, 4g, 8g or 16g
                                      // Higher Values = Wider Measurement Range
                                      // Lower Values = Greater Sensitivity

} 
/****************** MAIN CODE ******************/
/*     Accelerometer Readings and Interrupt    */
void loop(){

  // Accelerometer Readings
  int x,y,z;   
  adxl.readAccel(&x, &y, &z);         // Read the accelerometer values and store them in variables declared above x,y,z

  // Output Results to SerialUSB
  /* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */  
  SerialUSB.print(x);
  SerialUSB.print(", ");
  SerialUSB.print(y);
  SerialUSB.print(", ");
  SerialUSB.println(z);
  adxl.printAllRegister();
  delay(10); 
}

Код, который объявляет _buff [], который находится в заголовке .h file:

private:
    void writeTo(byte address, byte val);
    void writeToI2C(byte address, byte val);
    void writeToSPI(byte address, byte val);
    void readFrom(byte address, int num, byte buff[]);
    void readFromI2C(byte address, int num, byte buff[]);
    void readFromSPI(byte address, int num, byte buff[]);
    void setRegisterBit(byte regAdress, int bitPos, bool state);
    bool getRegisterBit(byte regAdress, int bitPos);
    byte _buff[6] ;     //  6 Bytes Buffer
    int _CS = 10;
    bool I2C = true;
    unsigned long SPIfreq = 5000000;

Я полагаю, что библиотеку для redboard нужно изменить, чтобы считывать выходные регистры 0x32-0x37 как 16-битный комплимент. Я новичок в этой среде программирования, поэтому любая помощь приветствуется.

Спасибо - Джерри

1 Ответ

0 голосов
/ 18 января 2020

Я подозреваю из примечаний платы Sparkfun (https://www.sparkfun.com/products/14812), что проблема в том, что Redboard Turbo представляет собой 32-битный процессор с 32-битным int вместо 16-битного int. На таком процессоре все 16-битные значения, хранящиеся в int, положительны.

Чтобы проверить мою теорию, запустите следующий эскиз на Redbo Turbo:

void setup() {
  Serial.begin(9600);
  while (!Serial) {}

  Serial.print("sizeof(int) = ");
  Serial.println(sizeof(int));
}

void loop() {
}

На моем Arduino Uno - 16-битная среда - в выходных данных говорится, что значение int составляет два байта (16 бит)

sizeof(int) = 2

Если вместо этого Redbo Turbo печатает

sizeof(int) = 4

, то его значение int составляет 4 байта ( 32 бита).

Я подозреваю, что библиотека не была написана для 32-битных процессоров и может показывать несколько проблем в Redboard Turbo. Чтобы исправить конкретную функцию readAccel (), переписайте ее, чтобы расширить 16-битное число до 32 бит: чтобы убедиться, что смещение байтов происходит со значением без знака, поскольку смещение влево числа со знаком может привести к неожиданным результатам на некоторых процессорах.

...