前言
开发板:Arduino Uno Rev3 创客主板 开发环境:Arduino IDE 开发语言:Arduino 语言(类C语言) 模块:PAJ7620U2
源码参考官方例程,并加以功能修改。 paj7620官方例程:https://www.arduino.cc/reference/en/libraries/gesture-paj7620/ wire库官方文档:https://www.arduino.cc/en/Reference/Wire
功能介绍:
一共定义了 9种模式,分别为 全关、全开、LED1亮、LED1灭、LED2亮、LED2灭、LED1闪烁、LED2闪烁和LED流动闪烁。
#define ALL_OFF 0
#define ALL_ON 1
#define LED1_ON 2
#define LED1_OFF 3
#define LED2_ON 4
#define LED2_OFF 5
#define LED1_TWINKLE 6
#define LED2_TWINKLE 7
#define LED_FLOW 8
一共是9种手势的识别,分别为 向右挥,向左挥,向上挥,向下挥,靠近,后退,顺时针,逆时针和挥手。
#define GES_RIGHT_FLAG PAJ7620_VAL(1,0)
#define GES_LEFT_FLAG PAJ7620_VAL(1,1)
#define GES_UP_FLAG PAJ7620_VAL(1,2)
#define GES_DOWN_FLAG PAJ7620_VAL(1,3)
#define GES_FORWARD_FLAG PAJ7620_VAL(1,4)
#define GES_BACKWARD_FLAG PAJ7620_VAL(1,5)
#define GES_CLOCKWISE_FLAG PAJ7620_VAL(1,6)
#define GES_COUNT_CLOCKWISE_FLAG PAJ7620_VAL(1,7)
#define GES_WAVE_FLAG PAJ7620_VAL(1,0)
手势和模式的对应关系
向左挥 LED1(左边的灯即LED1)亮灭
向右挥 LED2(右边的灯即LED2)亮灭
向上挥 全亮
向下挥 全灭
靠近 全灭
后退 全亮
顺时针 LED1闪烁
逆时针 LED2闪烁
挥手 LED流水闪烁
接线
2 3口接灯负极(灯正极串 1k欧电阻 接5v)
UNO PAJ7620U2
3.3V -》 VCC
GND -》 GND
SCL -》 SCL
SDA -》 SDA
效果图
温馨提示:效果随便看看就好(因为gif上传限制,所以gif帧数和画质都比较渣) 看久了 有点晕
左挥 LED1亮 右挥 LED2亮 左挥 LED1灭 右挥 LED2灭 上挥 全亮, 下挥 全灭 逆时针 LED2闪烁,顺时针 LED1闪烁,下挥 全灭 挥手 LED流水闪烁 远离 全亮,靠近 全灭
源码
paj7620_9gestures.ino
#include <Wire.h>
#include "paj7620.h"
#define GES_REACTION_TIME 500
#define GES_ENTRY_TIME 800
#define GES_QUIT_TIME 1000
#define ALL_OFF 0
#define ALL_ON 1
#define LED1_ON 2
#define LED1_OFF 3
#define LED2_ON 4
#define LED2_OFF 5
#define LED1_TWINKLE 6
#define LED2_TWINKLE 7
#define LED_FLOW 8
int LED1 = 2;
int LED2 = 3;
int mode = 0;
void setup()
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
uint8_t error = 0;
Serial.begin(9600);
Serial.println("\nPAJ7620U2 TEST DEMO: Recognize 9 gestures.");
error = paj7620Init();
if (error)
{
Serial.print("INIT ERROR,CODE:");
Serial.println(error);
}
else
{
Serial.println("INIT OK");
}
Serial.println("Please input your gestures:\n");
}
void loop()
{
uint8_t data = 0, data1 = 0, error;
uint8_t temp = 0;
error = paj7620ReadReg(0x43, 1, &data);
if (!error)
{
switch (data)
{
case GES_RIGHT_FLAG:
delay(GES_ENTRY_TIME);
paj7620ReadReg(0x43, 1, &data);
if (data == GES_FORWARD_FLAG)
{
Serial.println("Forward");
mode = ALL_OFF;
delay(GES_QUIT_TIME);
}
else if (data == GES_BACKWARD_FLAG)
{
Serial.println("Backward");
mode = ALL_ON;
delay(GES_QUIT_TIME);
}
else
{
Serial.println("Right");
temp = digitalRead(LED2);
if(temp == 0) mode = LED2_OFF;
else mode = LED2_ON;
}
break;
case GES_LEFT_FLAG:
delay(GES_ENTRY_TIME);
paj7620ReadReg(0x43, 1, &data);
if (data == GES_FORWARD_FLAG)
{
Serial.println("Forward");
mode = ALL_OFF;
delay(GES_QUIT_TIME);
}
else if (data == GES_BACKWARD_FLAG)
{
Serial.println("Backward");
mode = ALL_ON;
delay(GES_QUIT_TIME);
}
else
{
Serial.println("Left");
temp = digitalRead(LED1);
if(temp == 0) mode = LED1_OFF;
else mode = LED1_ON;
}
break;
case GES_UP_FLAG:
delay(GES_ENTRY_TIME);
paj7620ReadReg(0x43, 1, &data);
if (data == GES_FORWARD_FLAG)
{
Serial.println("Forward");
mode = ALL_OFF;
delay(GES_QUIT_TIME);
}
else if (data == GES_BACKWARD_FLAG)
{
Serial.println("Backward");
mode = ALL_ON;
delay(GES_QUIT_TIME);
}
else
{
Serial.println("Up");
mode = ALL_ON;
}
break;
case GES_DOWN_FLAG:
delay(GES_ENTRY_TIME);
paj7620ReadReg(0x43, 1, &data);
if (data == GES_FORWARD_FLAG)
{
Serial.println("Forward");
mode = ALL_OFF;
delay(GES_QUIT_TIME);
}
else if (data == GES_BACKWARD_FLAG)
{
Serial.println("Backward");
mode = ALL_ON;
delay(GES_QUIT_TIME);
}
else
{
Serial.println("Down");
mode = ALL_OFF;
}
break;
case GES_FORWARD_FLAG:
Serial.println("Forward");
mode = ALL_OFF;
delay(GES_QUIT_TIME);
break;
case GES_BACKWARD_FLAG:
Serial.println("Backward");
mode = ALL_ON;
delay(GES_QUIT_TIME);
break;
case GES_CLOCKWISE_FLAG:
Serial.println("Clockwise");
mode = LED1_TWINKLE;
break;
case GES_COUNT_CLOCKWISE_FLAG:
Serial.println("anti-clockwise");
mode = LED2_TWINKLE;
break;
default:
paj7620ReadReg(0x44, 1, &data1);
if (data1 == GES_WAVE_FLAG)
{
Serial.println("wave");
mode = LED_FLOW;
}
break;
}
}
switch (mode)
{
case ALL_OFF:
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
break;
case ALL_ON:
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
break;
case LED1_ON:
digitalWrite(LED1, LOW);
break;
case LED1_OFF:
digitalWrite(LED1, HIGH);
break;
case LED2_ON:
digitalWrite(LED2, LOW);
break;
case LED2_OFF:
digitalWrite(LED2, HIGH);
break;
case LED1_TWINKLE:
temp = digitalRead(LED1);
temp = temp > 0 ? 0 : 1;
digitalWrite(LED1, temp);
break;
case LED2_TWINKLE:
temp = digitalRead(LED2);
temp = temp > 0 ? 0 : 1;
digitalWrite(LED2, temp);
break;
case LED_FLOW:
temp = digitalRead(LED1);
digitalWrite(LED2, temp);
temp = temp > 0 ? 0 : 1;
digitalWrite(LED1, temp);
break;
default:
break;
}
delay(500);
}
paj7620.cpp
#include <Wire.h>
#include "paj7620.h"
#include <Arduino.h>
unsigned char initRegisterArray[][2] = {
{0xEF, 0x00},
{0x32, 0x29},
{0x33, 0x01},
{0x34, 0x00},
{0x35, 0x01},
{0x36, 0x00},
{0x37, 0x07},
{0x38, 0x17},
{0x39, 0x06},
{0x3A, 0x12},
{0x3F, 0x00},
{0x40, 0x02},
{0x41, 0xFF},
{0x42, 0x01},
{0x46, 0x2D},
{0x47, 0x0F},
{0x48, 0x3C},
{0x49, 0x00},
{0x4A, 0x1E},
{0x4B, 0x00},
{0x4C, 0x20},
{0x4D, 0x00},
{0x4E, 0x1A},
{0x4F, 0x14},
{0x50, 0x00},
{0x51, 0x10},
{0x52, 0x00},
{0x5C, 0x02},
{0x5D, 0x00},
{0x5E, 0x10},
{0x5F, 0x3F},
{0x60, 0x27},
{0x61, 0x28},
{0x62, 0x00},
{0x63, 0x03},
{0x64, 0xF7},
{0x65, 0x03},
{0x66, 0xD9},
{0x67, 0x03},
{0x68, 0x01},
{0x69, 0xC8},
{0x6A, 0x40},
{0x6D, 0x04},
{0x6E, 0x00},
{0x6F, 0x00},
{0x70, 0x80},
{0x71, 0x00},
{0x72, 0x00},
{0x73, 0x00},
{0x74, 0xF0},
{0x75, 0x00},
{0x80, 0x42},
{0x81, 0x44},
{0x82, 0x04},
{0x83, 0x20},
{0x84, 0x20},
{0x85, 0x00},
{0x86, 0x10},
{0x87, 0x00},
{0x88, 0x05},
{0x89, 0x18},
{0x8A, 0x10},
{0x8B, 0x01},
{0x8C, 0x37},
{0x8D, 0x00},
{0x8E, 0xF0},
{0x8F, 0x81},
{0x90, 0x06},
{0x91, 0x06},
{0x92, 0x1E},
{0x93, 0x0D},
{0x94, 0x0A},
{0x95, 0x0A},
{0x96, 0x0C},
{0x97, 0x05},
{0x98, 0x0A},
{0x99, 0x41},
{0x9A, 0x14},
{0x9B, 0x0A},
{0x9C, 0x3F},
{0x9D, 0x33},
{0x9E, 0xAE},
{0x9F, 0xF9},
{0xA0, 0x48},
{0xA1, 0x13},
{0xA2, 0x10},
{0xA3, 0x08},
{0xA4, 0x30},
{0xA5, 0x19},
{0xA6, 0x10},
{0xA7, 0x08},
{0xA8, 0x24},
{0xA9, 0x04},
{0xAA, 0x1E},
{0xAB, 0x1E},
{0xCC, 0x19},
{0xCD, 0x0B},
{0xCE, 0x13},
{0xCF, 0x64},
{0xD0, 0x21},
{0xD1, 0x0F},
{0xD2, 0x88},
{0xE0, 0x01},
{0xE1, 0x04},
{0xE2, 0x41},
{0xE3, 0xD6},
{0xE4, 0x00},
{0xE5, 0x0C},
{0xE6, 0x0A},
{0xE7, 0x00},
{0xE8, 0x00},
{0xE9, 0x00},
{0xEE, 0x07},
{0xEF, 0x01},
{0x00, 0x1E},
{0x01, 0x1E},
{0x02, 0x0F},
{0x03, 0x10},
{0x04, 0x02},
{0x05, 0x00},
{0x06, 0xB0},
{0x07, 0x04},
{0x08, 0x0D},
{0x09, 0x0E},
{0x0A, 0x9C},
{0x0B, 0x04},
{0x0C, 0x05},
{0x0D, 0x0F},
{0x0E, 0x02},
{0x0F, 0x12},
{0x10, 0x02},
{0x11, 0x02},
{0x12, 0x00},
{0x13, 0x01},
{0x14, 0x05},
{0x15, 0x07},
{0x16, 0x05},
{0x17, 0x07},
{0x18, 0x01},
{0x19, 0x04},
{0x1A, 0x05},
{0x1B, 0x0C},
{0x1C, 0x2A},
{0x1D, 0x01},
{0x1E, 0x00},
{0x21, 0x00},
{0x22, 0x00},
{0x23, 0x00},
{0x25, 0x01},
{0x26, 0x00},
{0x27, 0x39},
{0x28, 0x7F},
{0x29, 0x08},
{0x30, 0x03},
{0x31, 0x00},
{0x32, 0x1A},
{0x33, 0x1A},
{0x34, 0x07},
{0x35, 0x07},
{0x36, 0x01},
{0x37, 0xFF},
{0x38, 0x36},
{0x39, 0x07},
{0x3A, 0x00},
{0x3E, 0xFF},
{0x3F, 0x00},
{0x40, 0x77},
{0x41, 0x40},
{0x42, 0x00},
{0x43, 0x30},
{0x44, 0xA0},
{0x45, 0x5C},
{0x46, 0x00},
{0x47, 0x00},
{0x48, 0x58},
{0x4A, 0x1E},
{0x4B, 0x1E},
{0x4C, 0x00},
{0x4D, 0x00},
{0x4E, 0xA0},
{0x4F, 0x80},
{0x50, 0x00},
{0x51, 0x00},
{0x52, 0x00},
{0x53, 0x00},
{0x54, 0x00},
{0x57, 0x80},
{0x59, 0x10},
{0x5A, 0x08},
{0x5B, 0x94},
{0x5C, 0xE8},
{0x5D, 0x08},
{0x5E, 0x3D},
{0x5F, 0x99},
{0x60, 0x45},
{0x61, 0x40},
{0x63, 0x2D},
{0x64, 0x02},
{0x65, 0x96},
{0x66, 0x00},
{0x67, 0x97},
{0x68, 0x01},
{0x69, 0xCD},
{0x6A, 0x01},
{0x6B, 0xB0},
{0x6C, 0x04},
{0x6D, 0x2C},
{0x6E, 0x01},
{0x6F, 0x32},
{0x71, 0x00},
{0x72, 0x01},
{0x73, 0x35},
{0x74, 0x00},
{0x75, 0x33},
{0x76, 0x31},
{0x77, 0x01},
{0x7C, 0x84},
{0x7D, 0x03},
{0x7E, 0x01},
};
uint8_t paj7620WriteReg(uint8_t addr, uint8_t cmd)
{
char ret = 1;
Wire.beginTransmission(PAJ7620_ID);
Wire.write(addr);
Wire.write(cmd);
ret = Wire.endTransmission();
if (0 != ret)
{
if (1 == ret)
{
Serial.print("[paj7620WriteReg error] data too long to fit in transmit buffer\n");
}
else if (2 == ret)
{
Serial.print("[paj7620WriteReg error] received NACK on transmit of address\n");
}
else if (3 == ret)
{
Serial.print("[paj7620WriteReg error] received NACK on transmit of data\n");
}
else if (4 == ret)
{
Serial.print("[paj7620WriteReg error] other error\n");
}
}
return ret;
}
uint8_t paj7620ReadReg(uint8_t addr, uint8_t qty, uint8_t data[])
{
uint8_t ret;
Wire.beginTransmission(PAJ7620_ID);
Wire.write(addr);
ret = Wire.endTransmission();
if (0 != ret)
{
if (1 == ret)
{
Serial.print("[paj7620ReadReg error] data too long to fit in transmit buffer\n");
}
else if (2 == ret)
{
Serial.print("[paj7620ReadReg error] received NACK on transmit of address\n");
}
else if (3 == ret)
{
Serial.print("[paj7620ReadReg error] received NACK on transmit of data\n");
}
else if (4 == ret)
{
Serial.print("[paj7620ReadReg error] other error\n");
}
return ret;
}
Wire.requestFrom((int)PAJ7620_ID, (int)qty);
while (Wire.available())
{
*data = Wire.read();
#ifdef debug
Serial.print("addr:");
Serial.print(addr++, HEX);
Serial.print(" data:");
Serial.println(*data, HEX);
#endif
data++;
}
return 0;
}
void paj7620SelectBank(bank_e bank)
{
switch (bank) {
case BANK0:
paj7620WriteReg(PAJ7620_REGITER_BANK_SEL, PAJ7620_BANK0);
break;
case BANK1:
paj7620WriteReg(PAJ7620_REGITER_BANK_SEL, PAJ7620_BANK1);
break;
default:
break;
}
}
uint8_t paj7620Init(void)
{
int i = 0;
uint8_t error;
uint8_t data0 = 0, data1 = 0;
delayMicroseconds(700);
Wire.begin();
Serial.println("INIT SENSOR...");
paj7620SelectBank(BANK0);
paj7620SelectBank(BANK0);
error = paj7620ReadReg(0, 1, &data0);
if (error)
{
Serial.println("read data0 error!");
return error;
}
error = paj7620ReadReg(1, 1, &data1);
if (error)
{
Serial.println("read data1 error!");
return error;
}
Serial.print("Addr0 =");
Serial.print(data0 , HEX);
Serial.print(", Addr1 =");
Serial.println(data1 , HEX);
if ( (data0 != 0x20 ) || (data1 != 0x76) )
{
Serial.println("data0 or data1 error!");
return 0xff;
}
if ( data0 == 0x20 )
{
Serial.println("wake-up finish.");
}
for (i = 0; i < INIT_REG_ARRAY_SIZE; i++)
{
paj7620WriteReg(initRegisterArray[i][0], initRegisterArray[i][1]);
}
paj7620SelectBank(BANK0);
Serial.println("Paj7620 initialize register finished.");
return 0;
}
paj7620.h
#ifndef __PAJ7620_H__
#define __PAJ7620_H__
#define BIT(x) 1 << x
#define PAJ7620_VAL(val, maskbit) ( val << maskbit )
#define PAJ7620_ADDR_BASE 0x00
#define PAJ7620_REGITER_BANK_SEL (PAJ7620_ADDR_BASE + 0xEF)
#define PAJ7620_ID 0x73
#define PAJ7620_ADDR_SUSPEND_CMD (PAJ7620_ADDR_BASE + 0x3)
#define PAJ7620_ADDR_GES_PS_DET_MASK_0 (PAJ7620_ADDR_BASE + 0x41)
#define PAJ7620_ADDR_GES_PS_DET_MASK_1 (PAJ7620_ADDR_BASE + 0x42)
#define PAJ7620_ADDR_GES_PS_DET_FLAG_0 (PAJ7620_ADDR_BASE + 0x43)
#define PAJ7620_ADDR_GES_PS_DET_FLAG_1 (PAJ7620_ADDR_BASE + 0x44)
#define PAJ7620_ADDR_STATE_INDICATOR (PAJ7620_ADDR_BASE + 0x45)
#define PAJ7620_ADDR_PS_HIGH_THRESHOLD (PAJ7620_ADDR_BASE + 0x69)
#define PAJ7620_ADDR_PS_LOW_THRESHOLD (PAJ7620_ADDR_BASE + 0x6A)
#define PAJ7620_ADDR_PS_APPROACH_STATE (PAJ7620_ADDR_BASE + 0x6B)
#define PAJ7620_ADDR_PS_RAW_DATA (PAJ7620_ADDR_BASE + 0x6C)
#define PAJ7620_ADDR_PS_GAIN (PAJ7620_ADDR_BASE + 0x44)
#define PAJ7620_ADDR_IDLE_S1_STEP_0 (PAJ7620_ADDR_BASE + 0x67)
#define PAJ7620_ADDR_IDLE_S1_STEP_1 (PAJ7620_ADDR_BASE + 0x68)
#define PAJ7620_ADDR_IDLE_S2_STEP_0 (PAJ7620_ADDR_BASE + 0x69)
#define PAJ7620_ADDR_IDLE_S2_STEP_1 (PAJ7620_ADDR_BASE + 0x6A)
#define PAJ7620_ADDR_OP_TO_S1_STEP_0 (PAJ7620_ADDR_BASE + 0x6B)
#define PAJ7620_ADDR_OP_TO_S1_STEP_1 (PAJ7620_ADDR_BASE + 0x6C)
#define PAJ7620_ADDR_OP_TO_S2_STEP_0 (PAJ7620_ADDR_BASE + 0x6D)
#define PAJ7620_ADDR_OP_TO_S2_STEP_1 (PAJ7620_ADDR_BASE + 0x6E)
#define PAJ7620_ADDR_OPERATION_ENABLE (PAJ7620_ADDR_BASE + 0x72)
#define PAJ7620_BANK0 PAJ7620_VAL(0,0)
#define PAJ7620_BANK1 PAJ7620_VAL(1,0)
#define PAJ7620_I2C_WAKEUP PAJ7620_VAL(1,0)
#define PAJ7620_I2C_SUSPEND PAJ7620_VAL(0,0)
#define PAJ7620_ENABLE PAJ7620_VAL(1,0)
#define PAJ7620_DISABLE PAJ7620_VAL(0,0)
typedef enum {
BANK0 = 0,
BANK1,
} bank_e;
#define GES_RIGHT_FLAG PAJ7620_VAL(1,0)
#define GES_LEFT_FLAG PAJ7620_VAL(1,1)
#define GES_UP_FLAG PAJ7620_VAL(1,2)
#define GES_DOWN_FLAG PAJ7620_VAL(1,3)
#define GES_FORWARD_FLAG PAJ7620_VAL(1,4)
#define GES_BACKWARD_FLAG PAJ7620_VAL(1,5)
#define GES_CLOCKWISE_FLAG PAJ7620_VAL(1,6)
#define GES_COUNT_CLOCKWISE_FLAG PAJ7620_VAL(1,7)
#define GES_WAVE_FLAG PAJ7620_VAL(1,0)
#define INIT_REG_ARRAY_SIZE (sizeof(initRegisterArray)/sizeof(initRegisterArray[0]))
uint8_t paj7620Init(void);
uint8_t paj7620WriteReg(uint8_t addr, uint8_t cmd);
uint8_t paj7620ReadReg(uint8_t addr, uint8_t qty, uint8_t data[]);
void paj7620SelectBank(bank_e bank);
#endif
参考图
原理图
架构框图
Pin定义
机械设计
其他
|