0

ジャイロスコープからのデータの読み取りに取り組んでおり、データを正常に取得していますが、値は期待どおりではありません。これは、解決策を探し回った後のコーディングのエラーが原因だと考えています。ここに次のような投稿を思いつきました。

出力レジスタを正しく読み取っていることを確認してください。データは 2 の補数の 16 ビット値です (つまり、MSB は符号ビットで、値は 15 ビットです)。

これは私にとって非常に紛らわしく、コーディングが想定どおりに値を読み取っているかどうかはわかりません。I2C ライブラリを使用してwiringPi、Arduino の既存のコードを Raspberry Pi で実行できるように変換しています。以下にコードを示します。2 の補数で 16 ビット値を読み取る適切な試みが見られるかどうか、誰かが教えてくれることを願っています。関数内getGyroValuesは、これが起こっているのを見ることができる唯一の場所です。私のコードは値を正しく読み取っていますか?

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>

#include <wiringPi.h>
#include <wiringPiI2C.h>

#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23


int fd;
int x = 0;
int y = 0;
int z = 0;
int main (){



    fd = wiringPiI2CSetup(0x69); // I2C address of gyro
    wiringPiI2CWriteReg8(fd, CTRL_REG1, 0x1F); //Turn on all axes, disable power down
    wiringPiI2CWriteReg8(fd, CTRL_REG3, 0x08); //Enable control ready signal
    wiringPiI2CWriteReg8(fd, CTRL_REG4, 0x80); // Set scale (500 deg/sec)
    delay(100);                    // Wait to synchronize

void getGyroValues (){
    int MSB, LSB;

    LSB = wiringPiI2CReadReg16(fd, 0x28);
    MSB = wiringPiI2CReadReg16(fd, 0x29);
    x = ((MSB << 8) | LSB);

    MSB = wiringPiI2CReadReg16(fd, 0x2B);
    LSB = wiringPiI2CReadReg16(fd, 0x2A);
    y = ((MSB << 8) | LSB);

    MSB = wiringPiI2CReadReg16(fd, 0x2D);
    LSB = wiringPiI2CReadReg16(fd, 0x2C);
    z = ((MSB << 8) | LSB);
}

    for (int i=0;i<10;i++){
    getGyroValues();
    // In following Divinding by 114 reduces noise
    printf("Value of X is: %d\n", x / 114);
    printf("Value of Y is: %d\n", y / 114);
    printf("Value of Z is: %d\n", z / 114);
    int t = wiringPiI2CReadReg8(fd, 0x26);
    t = (t*1.8)+32;//convert Celcius to Fareinheit
    int a = wiringPiI2CReadReg16(fd,0x2B);
    int b = wiringPiI2CReadReg16(fd,0x2A);
    printf("Y_L equals: %d\n", a);
    printf("Y_H equals: %d\n", b);
    int c = wiringPiI2CReadReg16(fd,0x28);
    int d = wiringPiI2CReadReg16(fd,0x29);
    printf("X_L equals: %d\n", c);
    printf("X_H equals: %d\n", d);
    int e = wiringPiI2CReadReg16(fd,0x2C);
    int f = wiringPiI2CReadReg16(fd,0x2D);
    printf("Z_L equals: %d\n", e);
    printf("Z_H equals: %d\n", f); 

    printf("The temperature is: %d\n\n\n", t); 
    delay(500);
}
};
4

2 に答える 2

1

わかりやすくするために Alexey Frunze の方法を使用しますが、ここではテストのないバージョンを示します (状況によっては、より高速なインライン コードにコンパイルされる可能性があります)。このパターンは、他のサイズの符号なしビット パターンでも機能します。たとえば、12 ビット整数を処理するには を使用0x0800し、17 ビット整数には を使用0x10000します。

出力を表示するために、小さなドライバーにバンドルしましたmain

#include <stdio.h>

int comb(unsigned char msb, unsigned char lsb) {
        long t = ((long)msb << 8) | lsb;
        if (t >= 32768)
                t -= 65536;
        return t;
}

int comb2(unsigned char msb, unsigned char lsb) {
        unsigned long t = ((unsigned long)msb << 8) | lsb;
        t ^= 0x8000UL;
        return (int)((long)t - (long)0x8000);
}

int main(void) {
        printf("%6s %6s\n", "comb", "comb2");
        printf("%6d %6d\n", comb(0, 0), comb2(0, 0));
        printf("%6d %6d\n", comb(127, 255), comb2(127, 255));
        printf("%6d %6d\n", comb(128, 0), comb2(128, 0));
        printf("%6d %6d\n", comb(255, 255), comb2(255, 255));
        return 0;
}
于 2013-03-04T02:44:49.693 に答える
1

2 の補数 16 ビット整数の半分を int に表す最上位バイトと最下位バイトを簡単に結合する方法を次に示します。

int Bytes2Short(unsigned char msb, unsigned char lsb)
{
  long t = msb * 0x100L + lsb;
  if (t >= 32768)
    t -= 65536;
  return (int)t;
}
于 2013-03-03T22:44:50.167 に答える