Как получить и интерпретировать данные цифрового акселерометра?

Я пытаюсь подключить Arduino к цифровому акселерометру . Arduino получает команды от мобильного приложения и передает их через Bluetooth через последовательный порт оборудования. Я также разместил этот вопрос здесь.

Код:

 #include < SPI.h >

const int X8 = 0x06;
const int Y8 = 0x07;
const int Z8 = 0x08;

/*
bits
1 0  mode 00: standby, 01: measurement
5     1: spi 3 wire, 0: 4 wire
4      self test
3     2 glevel: 01 2g
1 0  mode, 00 standby, 01 measurement 
*/
const int MODE = 0x16;

const int STATUS = 0x09;

//7 полоса пропускания цифрового фильтра, 0 62,5 Гц, 1 125 Гц
const int CONTROL = 0x18;

bool isTesting = false;

const int chipSelectPin = 7;

void setup() {
    Serial.begin(9600);
    SPI.begin();
    pinMode(chipSelectPin, OUTPUT);

    //настраиваем режим ожидания, 4-проводной разъем, диапазон 2G,
    writeRegister(MODE, 0x04);

    //настраиваем скорость
    writeRegister(CONTROL, 0x00);

    delay(100);
}
void loop() {
    if (getSerial() == 't') {
        isTesting = true;
        writeRegister(MODE, 0x05); // 0000 0101- 0001 0101 0x15
        testing();

    }

}
void testing() {
    while (isTesting) {
        if ((readRegister(STATUS) & 1) == 1) {
            Serial.print((char) readRegister(X8), DEC);
            Serial.print("x");
            Serial.print((char) readRegister(Y8), DEC);
            Serial.print("y");
            Serial.print((char) readRegisterChar(Z8), DEC);
            Serial.print("z");
        }

        if (getSerial() == 'u') {
            isTesting = false;
            writeRegister(MODE, 0x04);
        }
    }
}
char getSerial() {
    if (Serial.available()) {
        char c = Serial.read();
        return c;
    }
    return 'x';
}
byte readRegister(byte thisRegister) {
    byte inByte = 0;
    SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); // часы 500 кГц
    digitalWrite(chipSelectPin, LOW);
    SPI.transfer(thisRegister << 1);
    inByte = SPI.transfer(0x00);
    digitalWrite(chipSelectPin, HIGH);
    return inByte;
}
char readRegisterChar(byte thisRegister) {
    char inChar = 0;
    SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); // часы 500 кГц
    digitalWrite(chipSelectPin, LOW);
    SPI.transfer(thisRegister << 1);
    inChar = SPI.transfer(0x00);
    digitalWrite(chipSelectPin, HIGH);
    return inChar;
}
void writeRegister(byte thisRegister, byte value) {
    SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); // часы 500 кГц
    digitalWrite(chipSelectPin, LOW);
    SPI.transfer(128 | thisRegister << 1);
    SPI.transfer(value);
    digitalWrite(chipSelectPin, HIGH);
}

Датчик допускает 10-битные значения данных, но для простоты я получаю только 8-битные данные. Данные, полученные, когда датчик находится на плоской поверхности:

xy z

5–11 74

4–19 74

2 -9 69

0 -8 68

7–16 68

7–11 73

Результаты самотестирования:

-5 -20 122

-4 -22 122

-1 -20 123

-4 -20 123

-5 -21 121

-3 -18 123

-8 -22 127

Из таблицы данных: «Когда функция самотестирования инициируется через регистр управления режимом ($16), доступ к «самотестированию» ; К каждой оси прикладывается электростатическая сила, вызывающая ее отклонение. Ось Z обрезана для отклонения 1г.";

Правильны ли данные? Как это интерпретируется? Если данные z во время самотестирования составляют 1 г, не должны ли они иметь ту же величину, что и на плоской поверхности?

Я приспособился к кодированию, чтобы получить 10 бит данных:

const int X10_LSB = 0x00;
const int X10_MSB = 0x01;
const int Y10_LSB = 0x02;
const int Y10_MSB = 0x03;
const int Z10_LSB = 0x04;
const int Z10_MSB = 0x05;

//[...]

void testing() {
        while (isTesting) {
            if ((readRegister(STATUS) & 1) == 1) {

                int xData = (readRegister(X10_MSB) << 8) | readRegister(X10_LSB);

                // проверяет, равен ли бит 9 1 и расширяется ли знак
                if ((xData & 512) == 512)
                    xData = (0b1111110000000000 | xData);
                int yData = (readRegister(Y10_MSB) << 8) | readRegister(Y10_LSB);
                if ((yData & 512) == 512)
                    yData = (0b1111110000000000 | yData);
                int zData = (readRegister(Z10_MSB) << 8) | readRegister(Z10_LSB);
                if ((zData & 512) == 512)
                    zData = (0b1111110000000000 | zData);

                Serial.print(xData);
                Serial.print("x");
                Serial.print(yData);
                Serial.print("y");
                Serial.print(zData);
                Serial.print("z");

            }

Выходные данные для измерения 2G:

4 246 -183

5 245 -183

5 245 -182

6 245 -181

Для самопроверки:

252 -20 -134

253 -21 -133

253 -21 -135

253 -20 -135

Значения для 8 и 10 бит данных не совпадают. Что я делаю не так?

Обновление: я переписал код, чтобы сначала получить 10 бит данных с младшими битами, как указано в комментарии:

Код:

     int xData =(readRegister (X10_LSB));
        xData = xData | (readRegister (X10_MSB)<<8);
        xData = xData << 6;
        int yData =(readRegister (Y10_LSB));
        yData = yData | (readRegister (Y10_MSB)<<8);
        yData = yData << 6;
        int zData = (readRegister (Z10_LSB));
        zData = zData | (readRegister (Z10_MSB)<<8);
        zData = zData << 6;

        xData /= 64;
        yData /= 64;
        zData /= 64;

Результаты работы датчика на плоской поверхности:

0–4 71

4–11 70

5–13 70

2–12 70

Результаты применения самотестирования:

-2 -19 123

-2 -19 122

-4 -20 122

-3 -21 122

Почему 8-битные и 10-битные результаты во время самотестирования возвращают одинаковые значения (около 128)? Должно ли 10-битное значение быть в 4 раза больше?

, 👍3