傳感器介紹
PAJ7620傳感器是原相科技(Pixart)的一款內部集成光學陣列式傳感器,以使復雜的手勢和光標模式輸出,內部集成了九種手勢的識別:上、下、左、右、向前、向后、順時針、逆時針以及揮動的手勢動作識別、模塊以i2c通信,傳感器功能很強大,更詳細模塊說明的可參考數據手冊。手冊過大無法上傳附件,需要可私信我,我做了pdf目錄標簽,方便定位查看。
手勢傳感器可以用來做大量豐富的應用開發,我在網上找到這樣的應用場景圖片,如下:
還有有些oppo手機的手勢隔空操作,可以翻轉桌面和圖片等操作,估計也是手勢傳感器來實現的。
驅動思路和原理
paj7620的驅動步驟在手冊的programing sequence and function application里有詳細的步驟說明,我在這里就總結一下注意事項。傳感器的讀時序中間有stop信號,因此在封裝讀函數需要調用兩次i2c_transfer,,在下面的代碼會看到。
<ignore_js_op>
設備樹編寫:
講完傳感器的介紹后,我們首先開始在設備樹文件描述手勢傳感器,手勢傳感器是i2c協議通信的,我選擇roc-rk3308的i2c1組進行通信,因此可以如下描述即可。
&i2c1 {
clock-frequency = <400000>;
status = "okay";
paj7620: paj7620@73 {
compatible = "pxi,paj7620";
reg = <0x73>;
};
};
從設備的地址可在數據手冊上找到,它是7bit的地址0x73。
設備驅動編寫:
這里我采用輪徇的方式去獲取傳感器的手勢動作狀態,並且將手勢傳感器實現成一個輸入設備,因此可以用一個結構體這樣描述它
struct gesture_sensor{
struct i2c_client *client; //記錄i2c的client
struct delayed_work poll_work; //工作隊列
struct input_dev *inputdev; //輸入設備
};
根據傳感器的時序進行封裝paj7620的i2c讀寫函數
//paj7620寫寄存器
static int paj_write_reg(struct i2c_client *client ,unsigned char addr,unsigned char data)
{
unsigned char buf[2]={addr,data};
return i2c_master_send(client,buf,2);
}
//paj7620讀寄存器
//paj7620的讀中間是p(停止)信號,因此要將read操作分成兩次transfer
static unsigned char paj_read_reg(struct i2c_client *client ,unsigned char addr)
{
int ret;
struct i2c_msg msg[2];
unsigned char data;
msg[0].addr=client->addr;
msg[0].flags =0;//寫
msg[0].len=1;
msg[0].buf=&addr;
ret=i2c_transfer(client->adapter,msg,1);
if(ret<0)
{
printk("i2c_transfer read error %d\n",ret);
return ret;
}
msg[1].addr = client->addr;
msg[1].flags |= I2C_M_RD;//讀
msg[1].len = 1;
msg[1].buf = &data;
ret = i2c_transfer(client->adapter,&msg[1], 1);
if(ret < 0)
{
printk("i2c_transfer read error %d\n",ret);
return ret;
}
return data;
}
在工作隊列中將數據獲取,並且上報給用戶層。代碼太長,此處將不粘貼,詳細的代碼可參考附件或私信我。
功能測試:
在這里,我做了一個應用層的demo來獲取手勢數據,在串口終端里運行gesturedemo,我們進行手勢動作識別測試,效果如下,可以獲取9種識別的手勢:
# gesturedemo /dev/input/event1 gesture:down gesture:up gesture:left gesture:right gesture:forward gesture:backward gesture:clockwise gesture:count clockwise gesture:wave
進入Firefly開發者社區可下載Demo
