755|1

553

帖子

3

TA的资源

纯净的硅(初级)

楼主
 

【得捷电子Follow me第2期】任务4分任务5:AI功能应用 [复制链接]

 

一、前言

 

本次follow me第二期活动的任务4提供了多个子任务,任选其一完成就可以了,主要有如下几个子任务:

 

 

本次之所以选择分任务5,是因为分任务1已经在第一期中做过了,任务2,3,4感觉需要的模块太多了,所以选择了任务5,只需要配一个传感器就能完成了,个人感觉会稍微省事一点。

 

二、传感器模块介绍

 

本次选择的传感器为seeed推出的手势传感器Grove - Gesture V1.0,外观如下:

Grove-Gesture上的传感器是PAJ7620U2,它将手势识别功能与通用I2C接口集成到一个芯片中。它可以识别9个基本手势,这些手势信息可以通过I2C总线简单地访问。

9种基本手势分别为:

 

 

Specification

Spec Name Value
Sensor PAJ7620U2
Power supply 5V
Ambient light immunity < 100k Lux
Gesture speed in Normal Mode 60°/s to 600°/s
Gesture speed in Gaming Mode 60°/s to 1200°/s
Interface type IIC interface up to 400 kbit/s
Operating Temperature -40°C to +85°C
Dimensions 20 * 20mmv
Detection range 5-10cm
I2C Address 0x73

 

需要特别注意的是,该传感器模块I2C地址为0x73

 

三、传感器的使用

 

1、硬件连接

传感器模块是I2C接口的,连接到ESP32-S3 Feather开发板的I2C接口就行,但实际上开发板上的I2C端子很小,手头没有与之配套的对插端子,所以只能使用杜邦线接在引出针脚上使用。

 

 

 

2、模块驱动

 

硬件连接完成后就可以开始进行编程获取传感器的手势。

 

目前Adafruit官方并没有提供circuitpython的PAJ7620U2驱动库,网上关于使用circuitpython驱动PAJ7620U2传感器基本上没有(至少我没有找到),MicroPython的程序倒是有几个,但是也步确定使用能用。

 

seeed倒是提供了Arduino和MicroPython的库,但至少seeed提供的库我相信肯定是没有问题的,所以直接将seeed的MicroPython库移植到了CircuitPython,其实移植起来还是非常容易的,只需要修改I2C相关的接口就可以了,其他地方完全不用动。

 

移植完成后可以成功地进行手势识别。

 

 

code.py完整代码:

import time
import board
from gesture import gesture

i2c = board.I2C()

# I2C lock
while not i2c.try_lock():
    pass

g = gesture()
g.init()
try :
    
    while True:
        g.print_gesture()
        #print(g.return_gesture())
        time.sleep(0.1)

finally:  # unlock the i2c bus when ctrl-c'ing out of the loop
    i2c.unlock()
    

 

移植完成的Paj7620驱动库:

import time
import board

i2c = board.I2C()

class gesture:
 #Registers and variables for the gesture sensor
 GES_REACTION_TIME  =.500    # You can adjust the reaction time according to the actual circumstance.
 GES_ENTRY_TIME   =.800    # When you want to recognize the Forward/Backward gestures, your gestures' reaction time must less than GES_ENTRY_TIME(0.8s). 
 GES_QUIT_TIME   =1.000
 
 BANK0 = 0
 BANK1 = 1
 
 PAJ7620_ADDR_BASE =0x00

 #REGISTER BANK SELECT
 PAJ7620_REGITER_BANK_SEL  =(PAJ7620_ADDR_BASE + 0xEF) #W

 #DEVICE ID
 PAJ7620_ID  =0x73

 #REGISTER BANK 0
 PAJ7620_ADDR_SUSPEND_CMD  =(PAJ7620_ADDR_BASE + 0x3) #W
 PAJ7620_ADDR_GES_PS_DET_MASK_0 =(PAJ7620_ADDR_BASE + 0x41) #RW
 PAJ7620_ADDR_GES_PS_DET_MASK_1 =(PAJ7620_ADDR_BASE + 0x42) #RW
 PAJ7620_ADDR_GES_PS_DET_FLAG_0 =(PAJ7620_ADDR_BASE + 0x43) #R
 PAJ7620_ADDR_GES_PS_DET_FLAG_1 =(PAJ7620_ADDR_BASE + 0x44) #R
 PAJ7620_ADDR_STATE_INDICATOR =(PAJ7620_ADDR_BASE + 0x45) #R
 PAJ7620_ADDR_PS_HIGH_THRESHOLD =(PAJ7620_ADDR_BASE + 0x69) #RW
 PAJ7620_ADDR_PS_LOW_THRESHOLD =(PAJ7620_ADDR_BASE + 0x6A) #RW
 PAJ7620_ADDR_PS_APPROACH_STATE =(PAJ7620_ADDR_BASE + 0x6B) #R
 PAJ7620_ADDR_PS_RAW_DATA  =(PAJ7620_ADDR_BASE + 0x6C) #R
                                    
 #REGISTER BANK 1                
 PAJ7620_ADDR_PS_GAIN   =(PAJ7620_ADDR_BASE + 0x44) #RW
 PAJ7620_ADDR_IDLE_S1_STEP_0  =(PAJ7620_ADDR_BASE + 0x67) #RW
 PAJ7620_ADDR_IDLE_S1_STEP_1  =(PAJ7620_ADDR_BASE + 0x68) #RW
 PAJ7620_ADDR_IDLE_S2_STEP_0  =(PAJ7620_ADDR_BASE + 0x69) #RW
 PAJ7620_ADDR_IDLE_S2_STEP_1  =(PAJ7620_ADDR_BASE + 0x6A) #RW
 PAJ7620_ADDR_OP_TO_S1_STEP_0 =(PAJ7620_ADDR_BASE + 0x6B) #RW
 PAJ7620_ADDR_OP_TO_S1_STEP_1 =(PAJ7620_ADDR_BASE + 0x6C) #RW
 PAJ7620_ADDR_OP_TO_S2_STEP_0 =(PAJ7620_ADDR_BASE + 0x6D) #RW
 PAJ7620_ADDR_OP_TO_S2_STEP_1 =(PAJ7620_ADDR_BASE + 0x6E) #RW
 PAJ7620_ADDR_OPERATION_ENABLE =(PAJ7620_ADDR_BASE + 0x72) #RW

 #PAJ7620_REGITER_BANK_SEL
 PAJ7620_BANK0=0
 PAJ7620_BANK1=1
 
 #PAJ7620_ADDR_SUSPEND_CMD
 PAJ7620_I2C_WAKEUP =1
 PAJ7620_I2C_SUSPEND =0
 
 #PAJ7620_ADDR_OPERATION_ENABLE
 PAJ7620_ENABLE=1
 PAJ7620_DISABLE=0
 
 #ADC, delete
 REG_ADDR_RESULT = 0x00
 REG_ADDR_ALERT  = 0x01
 REG_ADDR_CONFIG = 0x02
 REG_ADDR_LIMITL = 0x03
 REG_ADDR_LIMITH = 0x04
 REG_ADDR_HYST   = 0x05
 REG_ADDR_CONVL  = 0x06
 REG_ADDR_CONVH  = 0x07

 GES_RIGHT_FLAG    =1<<0
 GES_LEFT_FLAG    =1<<1
 GES_UP_FLAG     =1<<2
 GES_DOWN_FLAG    =1<<3
 GES_FORWARD_FLAG   =1<<4
 GES_BACKWARD_FLAG   =1<<5
 GES_CLOCKWISE_FLAG   =1<<6
 GES_COUNT_CLOCKWISE_FLAG =1<<7
 GES_WAVE_FLAG    =1<<0
 
 #Gesture output
 FORWARD   = 1
 BACKWARD   = 2
 RIGHT   = 3
 LEFT   = 4
 UP    = 5
 DOWN   = 6
 CLOCKWISE  = 7
 ANTI_CLOCKWISE = 8
 WAVE   = 9
 
 #Initial register state
 initRegisterArray=( [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])

 #Enable debug message
 debug=0
 
 #Initialize the sensors
 def init(self):
  time.sleep(.001)
  self.paj7620SelectBank(self.BANK0)
  self.paj7620SelectBank(self.BANK0)
  
  data0 = self.paj7620ReadReg(0, 1)[0]
  data1 = self.paj7620ReadReg(1, 1)[0]
  if self.debug:
   print("data0:",data0,"data1:",data1)
  if data0 != 0x20  :#or data1 <> 0x76:
   print("Error with sensor")
   #return 0xff
  if data0 == 0x20:
   print("wake-up finish.")
   
  for i in range(len(self.initRegisterArray)):
   self.paj7620WriteReg(self.initRegisterArray[i][0],self.initRegisterArray[i][1])
  
  self.paj7620SelectBank(self.BANK0)
  
  print("Paj7620 initialize register finished.")
  
 #Write a byte to a register on the Gesture sensor
 def paj7620WriteReg(self,addr,cmd):
  buf = bytearray([addr, cmd])
  i2c.writeto(self.PAJ7620_ID, buf)
  
 #Select a register bank on the Gesture Sensor
 def paj7620SelectBank(self,bank):
  if bank==self.BANK0:
   self.paj7620WriteReg(self.PAJ7620_REGITER_BANK_SEL, self.PAJ7620_BANK0)
   
 #Read a block of bytes of length "qty" starting at address "addr" from the Gesture sensor
 def paj7620ReadReg(self,addr,qty):
  buf = bytearray([addr])
  result = bytearray(qty)
  i2c.writeto_then_readfrom(self.PAJ7620_ID, buf, result)
  return result
 
 #Print the values from the gesture sensor
 def print_gesture(self):
  data=self.paj7620ReadReg(0x43,1)[0]
  if data==self.GES_RIGHT_FLAG:
   time.sleep(self.GES_ENTRY_TIME)
   data=self.paj7620ReadReg(0x43, 1)[0]
   if data == self.GES_FORWARD_FLAG:
    print("Forward")
    time.sleep(self.GES_QUIT_TIME)
   elif data == self.GES_BACKWARD_FLAG:
    print("Backward")
    time.sleep(self.GES_QUIT_TIME)
   else:
    print("Right")
    
  elif data==self.GES_LEFT_FLAG:
   time.sleep(self.GES_ENTRY_TIME)
   data=self.paj7620ReadReg(0x43, 1)[0]
   if data == self.GES_FORWARD_FLAG:
    print("Forward")
    time.sleep(self.GES_QUIT_TIME)
   elif data == self.GES_BACKWARD_FLAG:
    print("Backward")
    time.sleep(self.GES_QUIT_TIME)
   else:
    print("Left")  
  
  elif data==self.GES_UP_FLAG:
   time.sleep(self.GES_ENTRY_TIME)
   data=self.paj7620ReadReg(0x43, 1)[0]
   if data == self.GES_FORWARD_FLAG:
    print("Forward")
    time.sleep(self.GES_QUIT_TIME)
   elif data == self.GES_BACKWARD_FLAG:
    print("Backward")
    time.sleep(self.GES_QUIT_TIME)
   else:
    print("Up")  
    
  elif data==self.GES_DOWN_FLAG:
   time.sleep(self.GES_ENTRY_TIME)
   data=self.paj7620ReadReg(0x43, 1)[0]
   if data == self.GES_FORWARD_FLAG:
    print("Forward")
    time.sleep(self.GES_QUIT_TIME)
   elif data == self.GES_BACKWARD_FLAG:
    print("Backward")
    time.sleep(self.GES_QUIT_TIME)
   else:
    print("Down")
  
  elif data==self.GES_FORWARD_FLAG:
   print("Forward")
   time.sleep(self.GES_QUIT_TIME)
   
  elif data==self.GES_BACKWARD_FLAG:
   print("Backward")
   time.sleep(self.GES_QUIT_TIME)
   
  elif data==self.GES_CLOCKWISE_FLAG:
   print("Clockwise")
 
  elif data==self.GES_COUNT_CLOCKWISE_FLAG:
   print("anti-clockwise")
   
  else:
   data1=self.paj7620ReadReg(0x44, 1)[0]
   if (data1 == self.GES_WAVE_FLAG):
    print("wave")
 
 #Return a vlaue from the gestire sensor which can be used in a program
 #  0:nothing
 #  1:Forward
 #  2:Backward
 #  3:Right
 #  4:Left
 #  5:Up
 #  6:Down
 #  7:Clockwise
 #  8:anti-clockwise
 #  9:wave
 def return_gesture(self):

  data=self.paj7620ReadReg(0x43,1)[0]
  if data==self.GES_RIGHT_FLAG:
   time.sleep(self.GES_ENTRY_TIME)
   data=self.paj7620ReadReg(0x43, 1)[0]
   if data == self.GES_FORWARD_FLAG:
    return 1
    time.sleep(self.GES_QUIT_TIME)
   elif data == self.GES_BACKWARD_FLAG:
    return 2
    time.sleep(self.GES_QUIT_TIME)
   else:
    return 3
    
  elif data==self.GES_LEFT_FLAG:
   time.sleep(self.GES_ENTRY_TIME)
   data=self.paj7620ReadReg(0x43, 1)[0]
   if data == self.GES_FORWARD_FLAG:
    return 1
    time.sleep(self.GES_QUIT_TIME)
   elif data == self.GES_BACKWARD_FLAG:
    return 2
    time.sleep(self.GES_QUIT_TIME)
   else:
    return 4
  
  elif data==self.GES_UP_FLAG:
   time.sleep(self.GES_ENTRY_TIME)
   data=self.paj7620ReadReg(0x43, 1)[0]
   if data == self.GES_FORWARD_FLAG:
    return 1
    time.sleep(self.GES_QUIT_TIME)
   elif data == self.GES_BACKWARD_FLAG:
    return 2
    time.sleep(self.GES_QUIT_TIME)
   else:
    return 5  
    
  elif data==self.GES_DOWN_FLAG:
   time.sleep(self.GES_ENTRY_TIME)
   data=self.paj7620ReadReg(0x43, 1)[0]
   if data == self.GES_FORWARD_FLAG:
    return 1
    time.sleep(self.GES_QUIT_TIME)
   elif data == self.GES_BACKWARD_FLAG:
    return 2
    time.sleep(self.GES_QUIT_TIME)
   else:
    return 6
  
  elif data==self.GES_FORWARD_FLAG:
   return 1
   time.sleep(self.GES_QUIT_TIME)
   
  elif data==self.GES_BACKWARD_FLAG:
   return 2
   time.sleep(self.GES_QUIT_TIME)
   
  elif data==self.GES_CLOCKWISE_FLAG:
   return 7

  elif data==self.GES_COUNT_CLOCKWISE_FLAG:
   return 8
   
  else:
   data1=self.paj7620ReadReg(0x44, 1)[0]
   if (data1 == self.GES_WAVE_FLAG):
    return 9
  return 0
  
if __name__ == "__main__":
 while not i2c.try_lock():
    pass
 g=gesture()
 g.init()
 try:
     while True:
      g.print_gesture()
      time.sleep(.1)
      # print g.return_gesture()
      # time.sleep(.1)
 finally:  # unlock the i2c bus when ctrl-c'ing out of the loop
    i2c.unlock() 


 

VID_20230923_152958

 

最新回复

注意线序啊,而且这个座太小了,好像是1.0的,还要买专门的线   详情 回复 发表于 2023-9-25 10:03
点赞 关注
 
 

回复
举报

6534

帖子

9

TA的资源

版主

沙发
 

注意线序啊,而且这个座太小了,好像是1.0的,还要买专门的线

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表