目的
M5StackのCoreMP135にて、タッチパネルにタッチした結果を取得します。
1. デバイスファイル:
Linuxでは、タッチパネルは/dev/input/event0やevent1などのファイルにマッピングされています。以下のコマンドで、デバイスファイルを特定します。
CoreMP135でコマンドを実行し、/dev/input/event0にマッピングされていることが確認できました。
$ cat /proc/bus/input/devices
I: Bus=0018 Vendor=0000 Product=0000 Version=0000
N: Name="EP0110M09"
P: Phys=
S: Sysfs=/devices/platform/soc/4c004000.i2c/i2c-0/0-0038/input/input0
U: Uniq=
H: Handlers=event0
B: PROP=2
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=2608000 3
2. デバイスファイルのオープン:
特定したデバイスファイルをオープンします。
C++では、以下のようになります。
int fd = open("/dev/input/event0", O_RDONLY);
if (fd == -1) {
perror("Error opening device");
exit(EXIT_FAILURE);
}
input_event構造体からタッチパネルの状態を取得します。input_event構造体は、Linuxのイベント入力するシステムで、ユーザースペースにイベント情報を伝達するために使用されます。
#include <linux/input.h>
struct input_event {
struct timeval time; // イベントのタイムスタンプ
__u16 type; // イベントタイプ
__u16 code; // イベントコード
__s32 value; // イベント値
};
struct timeval time:
- イベントが発生した時刻を表すタイムスタンプです。
- 秒とマイクロ秒の精度で時間を記録します。
__u16 type:
- イベントの種類を示す16ビットの符号なし整数です。
- 主な種類には以下があります:
- EV_KEY: キーやボタンのイベント
- EV_REL: 相対座標の変化(例:マウスの移動)
- EV_ABS: 絶対座標の変化(例:タッチスクリーンの位置)
- EV_SYN: 同期イベント
__u16 code:
- イベントの具体的な内容を示す16ビットの符号なし整数です。
- typeに応じて意味が変わります。例えば:
- EV_KEY の場合:KEY_A, BTN_LEFT など
- EV_ABS の場合:ABS_X, ABS_Y, ABS_PRESSURE など
__s32 value:
- イベントの値を表す32ビットの符号付き整数です。
- codeに応じて意味が変わります。例えば:
- EV_KEY の場合:0(離す)、1(押す)、2(長押し)
- EV_ABS の場合:絶対座標の値
タッチスクリーンのイベントの場合は、
- type: EV_ABS
- code: ABS_X(X座標)またはABS_Y(Y座標)
- value: 座標の値(ピクセル単位など)
という情報を得ることができます。
3. イベントの読み取り:
input_event構造体を使用してイベントを読み取ります。
このコードは、/dev/input/event0からタッチパネルイベントを読み取り、X座標、Y座標、圧力、タッチの状態(プッシュ/リリース)を出力します。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#define DEVICE_PATH "/dev/input/event0"
int main() {
struct input_event ev;
int fd = open(DEVICE_PATH, O_RDONLY);
if (fd == -1) {
perror("Error opening device");
return EXIT_FAILURE;
}
while (1) {
ssize_t n = read(fd, &ev, sizeof(struct input_event));
if (n == (ssize_t)-1) {
perror("Error reading event");
break;
}
if (n != sizeof(struct input_event)) {
fprintf(stderr, "Error: incorrect read size\n");
break;
}
if (ev.type == EV_ABS) {
switch (ev.code) {
case ABS_X:
printf("X: %d\n", ev.value);
break;
case ABS_Y:
printf("Y: %d\n", ev.value);
break;
case ABS_PRESSURE:
printf("Pressure: %d\n", ev.value);
break;
}
} else if (ev.type == EV_KEY && ev.code == BTN_TOUCH) {
printf("Touch: %s\n", ev.value ? "Down" : "Up");
}
}
close(fd);
return EXIT_SUCCESS;
}
注意点:
- デバイスファイルへのアクセス権限が必要です(通常はroot権限が必要)
参考