1.简介
基于瑞萨R7FA4M2AD3CFP进行设计,对接PAJ7620U2手势识别模块实现一款手势识别网关。
2.实现功能
1.在瑞萨R7FA4M2AD3CFP开发板上适配PAJ7620U2手势识别传感器
2.实现一键配网功能(ESP8266EX模组)并将手势识别状态通过MQTT上报服务器
PS:整体上实现了,但是还有很大优化空间。
3.硬件说明
主要包含三个部分R7FA4M2AD3CFP开发板、手势识别传感器PAJ7620U2模块、ESP8266模组,接线照片如下:
3.1.手势识别传感器PAJ7620U2接线
手势识别传感器和R7FA4M2AD3CFP开发板通过I2C通讯,手势识别传感器PAJ7620U2的VCC、GND、SCL、SDA、INT分别接R7FA4M2AD3CFP主板上的5V、GND、P301、P302、GND
3.2.联网模组ESP8266接线
ESP8266模组和R7FA4M2AD3CFP开发板通过串口通讯,ESP8266模组的VCC、GND、TXD、RXD分别接R7FA4M2AD3CFP主板上PM0D2接口的PIN12、PIN10、PIN5、PIN3(模组固件烧录MQTT(1112)ESP8266-4M.bin)
4.FSP Configuration说明
4.1 手势识别传感器PAJ7620U2配置
PIN 配置如下图:
Stacks配置如下图:
4.2 联网模组ESP8266配置
PIN 配置如下图:
Stacks配置如下图:
4.3 串口打印配置
PIN 配置如下图:
Stacks配置如下图:
Clock配置如下图:
heap配置
5软件模块说明
代码目录结构如下:
5.1 手势识别传感器PAJ7620U2相关代码
实现了9种手势的识别,主要代码如下,详细参考附件:
#include "paj7620u2/paj7620u2.h"
#include "stdio.h"
#define DEBUG 0
#define GES_ENTRY_TIME 300
#define GES_QUIT_TIME 600
static unsigned short Gesture_Data = 0;
static uint16_t timeout_ms = 1000;
static i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;
void PAJ7620U2_i2c_master_callback(i2c_master_callback_args_t *p_args)
{
i2c_event = p_args->event;
if (I2C_MASTER_EVENT_ABORTED == p_args->event)
{
printf("\nGesture Sensor PAJ7620U2_i2c_master_callback =%d\n",p_args->event);
}
}
uint8_t PAJ7620U2_I2C_readByte(uint8_t addr)
{
fsp_err_t err=0;
uint8_t r_buf;
err = R_SCI_I2C_Write(&PAJ7620U2_i2c_ctrl,&addr,1,0);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
timeout_ms--;
}
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 1000;
err = R_SCI_I2C_Read(&PAJ7620U2_i2c_ctrl,&r_buf,1,1);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_RX_COMPLETE != i2c_event) && timeout_ms>0)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
timeout_ms--;
}
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 1000;
if (err == FSP_SUCCESS) {
#if DEBUG
printf("PAJ7620U2_I2C_readByte 0x%X\n", r_buf);
#endif
return r_buf;
}
return 0;
}
uint16_t PAJ7620U2_I2C_readU16(uint8_t addr)
{
uint16_t x;
fsp_err_t err;
uint8_t read_buf[2];
err = R_SCI_I2C_Write(&PAJ7620U2_i2c_ctrl,&addr,1,0);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
timeout_ms--;
}
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 1000;
err = R_SCI_I2C_Read(&PAJ7620U2_i2c_ctrl,&read_buf[0],2,1);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_RX_COMPLETE != i2c_event) && timeout_ms>0)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
timeout_ms--;
}
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 1000;
if (err == FSP_SUCCESS) {
#if DEBUG
printf("PAJ7620U2_I2C_readU16 0x%X,0x%X\n", read_buf[0],read_buf[1]);
#endif
x = ((uint16_t)((read_buf[1] <<8) + read_buf[0]));
}
return x;
}
void PAJ7620U2_I2C_writeByte(uint8_t addr, uint8_t data)
{
fsp_err_t err;
uint8_t dataSend[2] = {addr,data};
err = R_SCI_I2C_Write(&PAJ7620U2_i2c_ctrl,dataSend,2,1);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
timeout_ms--;
}
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 1000;
}
uint8_t PAJ7620U2_init(void)
{
uint8_t i,State;
fsp_err_t err;
printf("\nGesture Sensor start\n");
err = R_SCI_I2C_Open(&PAJ7620U2_i2c_ctrl, &PAJ7620U2_i2c_cfg);
assert(FSP_SUCCESS == err);
if (err != FSP_SUCCESS) return err;
printf("\nGesture Sensor Delay start\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
State =PAJ7620U2_I2C_readByte(0x00);
printf("\nGesture Sensor State =%x\n",State);
if (State != 0x20) return 0xff;
PAJ7620U2_I2C_writeByte(PAJ_BANK_SELECT, 0);
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
for (i=0;i< Init_Array;i++)
{
PAJ7620U2_I2C_writeByte(Init_Register_Array[i][0], Init_Register_Array[i][1]);
}
printf("\nGesture Register OK\n");
PAJ7620U2_I2C_writeByte(PAJ_BANK_SELECT, 0);
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
for (i = 0; i < Gesture_Array_SIZE; i++)
{
PAJ7620U2_I2C_writeByte(Init_Gesture_Array[i][0], Init_Gesture_Array[i][1]);
}
printf("\nGesture OK\n");
return 0;
}
uint16_t PAJ7620U2_Checkstatus_Loop(void)
{
Gesture_Data = PAJ7620U2_I2C_readU16(PAJ_INT_FLAG1);
if(Gesture_Data){
#if DEBUG
printf("\nGesture Sensor Gesture_Data = 0x%x\n",Gesture_Data);
#endif
switch (Gesture_Data)
{
case PAJ_UP:
R_BSP_SoftwareDelay(GES_ENTRY_TIME,BSP_DELAY_UNITS_MILLISECONDS);
Gesture_Data = PAJ7620U2_I2C_readByte(PAJ_INT_FLAG1);
#if DEBUG
printf("\nGesture Sensor after GES_ENTRY_TIME Gesture_Data = 0x%x\n",Gesture_Data);
#endif
if(Gesture_Data == PAJ_FORWARD)
{
printf("\r\n Forward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_FORWARD;
}
else if(Gesture_Data == PAJ_BACKWARD)
{
printf("\r\n Backward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_BACKWARD;
}
else
{
printf("\r\n Up\r\n");
return PAJ_UP;
}
break;
case PAJ_DOWN:
R_BSP_SoftwareDelay(GES_ENTRY_TIME,BSP_DELAY_UNITS_MILLISECONDS);
Gesture_Data = PAJ7620U2_I2C_readByte(PAJ_INT_FLAG1);
#if DEBUG
printf("\nGesture Sensor after GES_ENTRY_TIME Gesture_Data = 0x%x\n",Gesture_Data);
#endif
if(Gesture_Data == PAJ_FORWARD)
{
printf("\r\n Forward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_FORWARD;
}
else if(Gesture_Data == PAJ_BACKWARD)
{
printf("\r\n Backward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_BACKWARD;
}
else
{
printf("\r\n Down\r\n");
return PAJ_DOWN;
}
break;
case PAJ_LEFT:
R_BSP_SoftwareDelay(GES_ENTRY_TIME,BSP_DELAY_UNITS_MILLISECONDS);
Gesture_Data = PAJ7620U2_I2C_readByte(PAJ_INT_FLAG1);
#if DEBUG
printf("\nGesture Sensor after GES_ENTRY_TIME Gesture_Data = 0x%x\n",Gesture_Data);
#endif
if(Gesture_Data == PAJ_FORWARD)
{
printf("\r\n Forward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_FORWARD;
}
else if(Gesture_Data == PAJ_BACKWARD)
{
printf("\r\n Backward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_BACKWARD;
}
else
{
printf("\r\n Left\r\n");
return PAJ_LEFT;
}
break;
case PAJ_RIGHT:
R_BSP_SoftwareDelay(GES_ENTRY_TIME,BSP_DELAY_UNITS_MILLISECONDS);
Gesture_Data = PAJ7620U2_I2C_readByte(PAJ_INT_FLAG1);
#if DEBUG
printf("\nGesture Sensor after GES_ENTRY_TIME Gesture_Data = 0x%x\n",Gesture_Data);
#endif
if(Gesture_Data == PAJ_FORWARD)
{
printf("\r\n Forward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_FORWARD;
}
else if(Gesture_Data == PAJ_BACKWARD)
{
printf("\r\n Backward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_BACKWARD;
}
else
{
printf("\r\n Right\r\n");
return PAJ_RIGHT;
}
break;
case PAJ_FORWARD:
printf("\r\n Forward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_FORWARD;
break;
case PAJ_BACKWARD:
printf("\r\n Backward\r\n");
R_BSP_SoftwareDelay(GES_QUIT_TIME,BSP_DELAY_UNITS_MILLISECONDS);
return PAJ_BACKWARD;
break;
case PAJ_CLOCKWISE:
printf("\r\n Clockwise\r\n");
return PAJ_CLOCKWISE;
break;
case PAJ_COUNT_CLOCKWISE:
printf("\r\n AntiClockwise\r\n");
return PAJ_COUNT_CLOCKWISE;
break;
case PAJ_WAVE:
printf("\r\n wave\r\n");
return PAJ_WAVE;
break;
default:
break;
}
}
return Gesture_Data;
}
5.2 ESP8266 AT控制代码
这部分代码参考DA16200实现,如果没有配置可以用安信科技公众号进行一键配网(会一直等待一键配网),具体可以百度ESP8266一键配网参考文章,也有实现了AT指令配网代码,代码内容在esp8266_AT.c和esp8266_wifi_mqtt.c,有兴趣的可以下载附件参考。
5.3 串口打印代码
这部分代码论坛上大佬们分享很多,可以参考其他文章。
6.待优化
1.目前手势识别仍然还需要调优。
2.USB升级未实现。
演示视频如附件。第一次使用瑞萨平台,重在分享,不足之处多多指正。
*附件:Gesture_Gateway - 2023.03.05.zip