Neo FreeRunner: 3 軸加速度感測器程式實作

jollen 發表於 November 10, 2008 12:29 PM

Neo FreeRunner 搭載二個「3 軸加速度感測器」,這是一個很有趣的硬體,他可 以偵測手機的移動狀態,配合應用程式,可以實作出有趣的小玩具。以 iPhone 為 例,它有一個很人性化的功能,當手機 90 度轉向時,視窗也會跟著 90 度轉換, 這樣的功能就是透過「加速度感測器」晶片來完成的。

Neo FreeRunner 有二個 3 軸加速度感測器,當手機移動時,可以利用程式讀取每 一個軸的加速度值。讀取加速度感測器的方法是透過 Linux 的 input layer:

    /dev/input/event{2,3}

Process 透過這二個裝置檔讀取 input layer 的資料,kernel 會回傳一筆加速度感測器的資料給 process,該筆資料的 data type 為 struct input_event,即 kernel 的 input event 資料結構。程式的做法是,每次讀取一筆加速度感測器資料,再判斷資料的類型,以及各軸的加速度值。

程式寫法如下:

    #include <linux/input.h>

    int main(void)
    {

        struct input_event motion;

        fd = open("/dev/input/event3", S_IRUSR);

        while (1) {
            read(fd, &motion, sizeof(motion));
        }
    }

struct input_event 資料結構的定義如下:

    struct input_event {
        struct timeval time;
        __u16 type;
        __u16 code;
        __s32 value;
    };

讀出的資料如下:

  • motion.time: 讀取到該筆資料的時間
  • motion.type: 值為 2 時,表示該筆資料為加速度值
  • motion.code: 表示讀取的加速度方向,0 = x 軸、1 = y 軸、2 = z 軸
  • motion.value: 該軸的加速度值,正負號代表「正負方向」

本範例讀取 FreeRunner 上的第二個 3 軸加速度感測器,x/y/z 軸所代表的方向如下圖。

(Source: Openmoko Wiki)

如果想要讀取 x 軸的加速度:

    int x;

    /* 資料有效且為 x 軸 */
    if (motion.type == 2 && motion.code == 0) {
        x = motion.value;
    }

若 x 為負值,表示手機往左邊的方向移動。再舉一個例子,讀取 y 軸的加速度:

    int y;

    /* 資料有效且為 y 軸 */
    if (motion.type == 2 && motion.code == 1) {
        y = motion.value;
    }

若 y 軸的加速度為正值,表示手機往下移動。更多有關 FreeRunner 加速度感測器(accelerometer)的資訊,可參閱 Openmoko wiki [Accelerometer data retrieval]。

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw