基于EV54Y39A PIC-IOT WA的手指数量检测功能开发(MPLAB+ADC)

目录

  • 项目介绍
  • 硬件介绍
  • 项目设计
    • 开发环境及工程参考
    • 总体流程图
    • 硬件基本配置
      • 光照传感器读取
      • 定时器
      • 检测逻辑
  • 功能展示
  • 项目总结

👉 【Funpack3-2】基于EV54Y39A PIC-IOT WA的手指数量检测功能开发
👉 Github: EmbeddedCamerata/PIC-IOT_finger_recognition

项目介绍

基于 Microchip 的 EV54Y39A PIC-IOT WA 开发板,通过板卡上集成的光照传感器,将板卡平放后,每秒对挥动的手指数量进行检测。在较强光源下,可准确识别挥动的手指数量。

👉 MPLAB X IDE

硬件介绍

PIC-IoT WA硬件概述:

  • 控制器包含两个主要组件:PIC微控制器(PIC24FJ128GA705)和Wi-Fi模块(WINC1510)。PIC24F是一款低功耗的16位微控制器,时钟频率为32MHz,具有集成的12位ADC。Wi-Fi模块采用Microchip的ATWINC1510,是低功耗认证的IoT网络控制器。
  • 板载ATECC608的密码协处理器。用于生成私钥和公钥,私钥用于加密发送的每条消息,而公钥可与服务提供商(如Google IoT cloud或AWS)共享。
  • 板载传感器包括TEMT6000X01光传感器和MCP9808温度传感器。光传感器连接到PIC控制器的10位ADC,温度传感器通过I2C接口测量-20℃至100℃之间的温度,典型精度为0.25℃。
  • PIC IoT WA开发板可通过微型USB端口或4.2V锂电池供电,同时具有板上编程仿真器和调试器(PKOB)支持一路串口和一个IO的逻辑分析功能。

PIC-IOT WA

项目设计

开发环境及工程参考

本项目使用 Microchip 官方的 MPLAB X IDE 开发。项目所用到的工具链、库或 packs 如下:

  1. 编译器:xc16 v1.50,这个版本的编译器确保编译通过
  2. Packs: PIC24F-GA-GB_DFP 1.9.336、PKOB nano 1.13.715
  3. MCC Content Libraries:
    1. MCC core 5.7.1
    2. PIC24 / dsPIC33 MCUs 1.171.4
    3. Board Support Library 1.12.0

总体流程图

工程总体流程
进行系统初始化以后,先启动周期为1s的定时器,该定时器自动重载,在其回调函数中打印识别的手指数目 count,之后清零并进入 STATE_IDLE。工程主体为一个 while(1) 循环的 FSM,用一个全局变量记录系统状态:

  • 每次都会先读取光照传感器的数据,并根据此次与上次读数的差值,进入其他的状态
  • 在 STATE_IDLE 中,当差值小于一个负阈值时,进入 STATE_NEGA,此时识别到光照降低,这说明有手指遮挡。其余情况没有手指遮挡,状态不转移。当定时器触发时,打印出此时的识别数目并将 count 清零,系统重新进入 STATE_IDLE。
  • 在 STATE_NEGA,当差值大于一个正阈值时,进入 STATE_POS,此时识别到光照增加,这说明手指移开了,count++。在 STATE_NEGA,若保持光照读数相对稳定,这说明该手指还未完全经过传感器,状态不转移。当定时器触发时,打印出此时的识别数目并将 count 清零,系统重新进入 STATE_IDLE。
  • 在 STATE_POS 中,只有当差值又一次小于负阈值时,进入 STATE_NEGA,此时识别到光照降低,这说明又有手指遮挡。若保持光照读数相对稳定或增加,这说明并没有新的手指遮挡。当定时器触发时,打印出此时的识别数目并将 count 清零,系统重新进入 STATE_IDLE。

由于测量周期是1s,即便测量状态没有变化,定时器回调也会将状态、变量全部重置。在 FSM 中,只需要处理有效的测量的统计逻辑即可。

硬件基本配置

根据手册可知,板载光照传感器与ADC AN8(RB12)相连。检测的周期设计为1秒,如此,需要一个定时器 TMR1。其次,还需要串口以供调试与结果显示。在MCC中,IO口设置如下图所示:

外设配置
RB10/11供调试使用。串口设置为9600 8N1,RC8 UITX 需要勾选“Start High”,勾选“Redirect printf to UART”。

光照传感器读取

需要修改一下默认的 ADC1 配置。根据下方提示,修改“Conversion Clock”为2即可。

ADC1配置修改
根据生成的ADC示例,可以修改实现光照传感器数据的读取。

uint16_t get_light_sensor(void)
{int i;uint16_t conversion;ADC1_Enable();ADC1_ChannelSelect(LIGHT_SENSOR);ADC1_SoftwareTriggerEnable();//Provide Delayfor(i = 0; i < 1000; i++){}ADC1_SoftwareTriggerDisable();while(!ADC1_IsConversionComplete(LIGHT_SENSOR));conversion = ADC1_ConversionResultGet(LIGHT_SENSOR);ADC1_Disable();return conversion;
}

定时器

如下图所示配置,设置 TMR1 为1s周期定时器。

1s周期定时器设置
在定时器的回调函数 periodic_handler 中,打印 count 手指数目,而后清零并将状态设置为 APP_STATE_IDLE。在主循环之前创建定时器,定时器超时设置为 0xF423,在主循环内需要调用 timeout_callNextCallback() 以检查回调。

static uint32_t periodic_handler(void)
{printf("Finger count: %d\n", count);appState = APP_STATE_IDLE;count = 0;return 0xF423;
}int main(void)
{// initialize the deviceSYSTEM_Initialize();timerStruct_t periodic_timer = {periodic_handler, NULL};timeout_create(&periodic_timer, 0xF423);while (1){timeout_callNextCallback();main_app();}return 1;
}

检测逻辑

当手指遮挡时,光照减小,前后两次读数的差值为负数,反之为正数。因此,设置一个合适的阈值 LIGHT_TRIGGER_THRES,用于判断是否发生了这两种变化,同时也可以过滤掉读数不稳定的影响。该值需要根据实际环境进行调整。

#define LIGHT_TRIGGER_THRES     (50)

系统分为三个状态,用全局变量 appState 记录。同时,需要几个参数记录传感器的数值以及手指数目。

typedef enum {APP_STATE_IDLE,APP_STATE_DETECTED_NEGA,APP_STATE_DETECTED_POS
} appStates_e;static appStates_e appState = APP_STATE_IDLE;
static uint16_t light1 = 0;
static uint16_t light2 = 0;
static float light_prev1 = 0.;
static int count = 0;

反复读取光照传感器数据,读取最近的两次数据取平均值作为此次测量的结果,并与上次读数作差。根据该差值进行状态跳转:

  1. 处于 APP_STATE_IDLE 时,当差值 delta 小于负阈值 LIGHT_TRIGGER_THRES 时,进入 APP_STATE_DETECTED_NEGA,此时检测到有手指遮挡,光照降低。其余情况下,均不会有手指遮挡,状态不转移。
  2. 处于 APP_STATE_DETECTED_NEGA 时,当 delta 大于正阈值 LIGHT_TRIGGER_THRES 时,进入 APP_STATE_DETECTED_POS,此时说明手指移开了,计数+1。其余情况下,手指还未完全经过传感器,因此差值不够大(可以过滤毛刺情况)或者为负,状态均不转移。
  3. 处于 APP_STATE_DETECTED_POS 时,当 delta 又一次小于负阈值 LIGHT_TRIGGER_THRES 时,进入 APP_STATE_DETECTED_NEGA,此时又有手指遮挡。其余情况下,说明光照无较大变化或者光照变强,这说明没有手指遮挡或手指逐渐远离,状态均不跳转。
  4. 测量周期为1s,定时器超时后,将打印出计数结果 count 并清零,同时状态转移至 APP_STATE_IDLE,进行下一次测量。
void main_app(void)
{float delta;float light;light1 = get_light_sensor();light2 = get_light_sensor();light = (light1 + light2) / 2;delta = light - light_prev1;light_prev1 = light;switch(appState) {case APP_STATE_IDLE:{if (delta < -LIGHT_TRIGGER_THRES) {appState = APP_STATE_DETECTED_NEGA;}break;}case APP_STATE_DETECTED_NEGA:{if (delta > LIGHT_TRIGGER_THRES) {count++;appState = APP_STATE_DETECTED_POS;}break;}case APP_STATE_DETECTED_POS:{if (delta < -LIGHT_TRIGGER_THRES) {appState = APP_STATE_DETECTED_NEGA;}break;}}
}

功能展示

下载程序后将板卡平放,注意需要保证环境光照较强,需要根据实际情况调整阈值 LIGHT_TRIGGER_THRES。本测试在室内,并用手机手电筒照射光照传感器的环境下进行。测试需要挥动手指,结果输出有延迟,测试效果参见视频更直观。

挥动两根手指测试结果
挥动三根手指测试结果
👉 详细展示参见:B站:基于EV54Y39A PIC-IOT WA的手指数量检测功能开发

项目总结

本次项目通过光照传感器、定时器与状态机,可在一定场景下准确识别挥动的手指数量,可以根据实际场景调整参数,以达到最佳效果。MPLAB IDE 一言难尽,打开 MCC 没个半天是不可能的,这个板卡的有些配置还有坑,例如,编译器需要选择 v1.50 而不能是最新版的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/19466.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter基础 -- Dart 语言 -- 注释函数表达式

目录 1. 注释 1.1 单行注释 1.2 多行注释 1.3 文档注释 2. 函数 2.1 定义 2.2 可选参数 2.3 可选参数 默认值 2.4 命名参数 默认值 2.5 函数内定义 2.6 Funcation 返回函数对象 2.7 匿名函数 2.8 作用域 3. 操作符 3.1 操作符表 3.2 算术操作符 3.3 相等相关的…

上海亚商投顾:沪指冲高回落 两市成交金额仅剩7000亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日冲高回落&#xff0c;午后一度集体翻绿&#xff0c;临近尾盘小幅回升。光伏产业链再度走强&#…

aws 在ecs外部实例上运行gpu负载

参考资料 https://docs.amazonaws.cn/zh_cn/AmazonECS/latest/developerguide/ecs-gpu.htmlhttps://docs.amazonaws.cn/AWSEC2/latest/UserGuide/accelerated-computing-instances.html#gpu-instanceshttps://docs.amazonaws.cn/AWSEC2/latest/UserGuide/install-nvidia-drive…

LeetCode 63.不同路径Ⅱ

思路&#xff1a; 在有障碍物的地方增加一个判断即可 class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int dp[105][105];int mobstacleGrid.size();int nobstacleGrid[0].size();for(int i0;i<m;i){for(int j0…

K8s集群之 存储卷 PV PVC

目录 默写 1 如何将pod创建在指定的Node节点上 2 污点的种类(在node上设置) 一 挂载存储​​​​​​​ 1 emptyDir存储卷 2 hostPath存储卷 ①在 node01 节点上创建挂载目录 ② 在 node02 节点上创建挂载目录 ③ 创建 Pod 资源 ④ 在master上检测一下&#xff1a;…

C++ vector 模拟实现

vector的底层也是一个动态数组&#xff0c;他与 string 的区别就是&#xff0c;string 是专门用来存储字符类数据的&#xff0c;为了兼容C语言&#xff0c;使用C语言的接口&#xff0c;在string的动态数组内都会都开一块空间用来存 \0 &#xff0c;而vector则不会。 首先我们要…

【Linux多线程】认识多线程创建线程

文章目录 什么是多线程为什么称linux下的线程是轻量级进程呢&#xff1f; 线程的优点线程的缺点线程异常线程和进程创建线程1.pthread_create2.pthread_self 什么是多线程 进程是正在运行的程序的实例&#xff0c;而线程&#xff08;thread&#xff09;是进程中的一个执行路线…

Springboot邮件发送配置

Springboot邮件发送配置 pom.xml依赖&#xff1a; <dependency><groupId>org.eclipse.angus</groupId><artifactId>jakarta.mail</artifactId><version>2.0.3</version> </dependency> <dependency><groupId>or…

跨域的解决方案

1. 计算机更改跨域 1.C盘->Windows->System32->drivers->etc 2.修改hosts 文件2. Chrome浏览器的跨域设置 操作步骤&#xff1a;1.打开我的电脑——C盘 新建一个文件夹&#xff0c;命名为MyChromeDevUserData2.右键——Chrome——快捷方式——目标&#xff0c;在…

ChatGPT成知名度最高生成式AI产品,使用频率却不高

5月29日&#xff0c;牛津大学、路透社新闻研究所联合发布了一份生成式AI&#xff08;AIGC&#xff09;调查报告。 在今年3月28日—4月30日对美国、英国、法国、日本、丹麦和阿根廷的大约12,217人进行了调查&#xff0c;深度调研他们对生成式AI产品的应用情况。 结果显示&…

ElementUI之el-table标题列中显示el-tooltip

ElementUI之el-table标题列中显示el-tooltip 文章目录 ElementUI之el-table标题列中显示el-tooltip1. el-table标题列中显示el-tooltip2. 实现代码3. 展示效果 1. el-table标题列中显示el-tooltip 在el-table-column标签内添加具名插槽v-slot:header 在el-tooltip标签中使用具…

【几何】输入0-360度任意的角度,求上面直线与椭圆相切点的坐标计算公式

输入0-360度任意的角度,求上面直线与椭圆相切点的坐标计算公式 使用积分计算 使用到的公式有椭圆公式: x 2 a 2 + y 2 b 2 = 1 \frac{x^2}{a^2}+\frac{y^2}{b^2} = 1 a2x2​+b2y2​=1 平面旋转公式 X r = cos ⁡ θ ∗ ( X s − X O ) − sin ⁡ θ ∗ ( Y s − Y O ) + X …

端午节粽子龙舟主题互动趣味小游戏效果是什么

端午三天乐&#xff0c;无论节日当天还是之前&#xff0c;行业商家都可以自己的品牌为主借势营销&#xff0c;趣味活动形式玩法和内容呈现达成多种效果&#xff0c;品牌传播、公众号涨粉、线下互动、商品促销、用户促活等。 在【雨科】平台拥有多款端午节互动小游戏类型&#…

网易狼人杀 设置点击自动发言

我们玩网易狼人杀 刚开始 都会发现 要按住麦克风才能发言 不得不说 相当的麻烦 我们可以点击如下图 右上角这个设置的齿轮 新弹出的设置面板上 勾选这个点击发言 然后 我们只需要 点一下 就可以进入发言状态 然后 再点一下即可停止发言 会方便非常多

zabbix事件告警监控:如何实现对相同部件触发器告警及恢复的强关联

有一定Zabbix使用经验的小伙伴可能会发现&#xff0c;接收告警事件时&#xff0c;其中可能包含着大量不同的部件名&#xff0c;同一部件的事件在逻辑上具有很强关联性&#xff0c;理论上应保持一致的告警/恢复状态&#xff0c;但Zabbix默认并未对它们进行关联&#xff0c;直接后…

AIGC降重:如何2分钟降低论文AI率和查重率?推荐使用SpeedAI科研小助手

确保学术论文的独立性与诚信性&#xff0c;对于学业的成就及学位的获取至关重要&#xff0c;其中&#xff0c;论文的人工智能查重与降低AIGC相似度扮演着核心角色。 常规的查重手段主要围绕查重软件的运用和个体的自行审查&#xff1b;而降重则通常通过语句重组、同义替换、内…

单细胞分析(Signac): PBMC scATAC-seq 基因组区域可视化

引言 在本教学指南中&#xff0c;我们将探讨由10x Genomics公司提供的人类外周血单核细胞&#xff08;PBMCs&#xff09;的单细胞ATAC-seq数据集。 加载包 首先加载 Signac、Seurat 和我们将用于分析人类数据的其他一些包。 if (!requireNamespace("EnsDb.Hsapiens.v75&qu…

ModuleNotFoundError: No module named ‘osgeo‘

显示无osgeo模块 pip install osgeo显示失败 方法&#xff1a; 确保你已经安装了正确的依赖项&#xff0c;例如GDAL、GEOS和PROJ等。 方法1&#xff1a;pip install gdal 失败 方法2&#xff1a;官网下载失败&#xff0c;下载地址&#xff1a;https://www.lfd.uci.edu/~gohl…

设置自动刷新数据透视表的数据源

数据透视表数据源的自动刷新 一般情况操作&#xff1a; 自动刷新操作&#xff1a; 1、定义名称名称 引用位置&#xff1a;OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),COUNTA(Sheet1!$1:$1)) 2、数据透视表的数据源更改为【源数据】—— 即前面定义的名称 3、数据——全部…

区块链技术和应用二

前言 学习长安链的一些基本原理 官网&#xff1a;长安链开源文档 b站课程&#xff1a;区块链基础与应用 一、共识算法 1.1 POW工作量证明 最长链共识&#xff0c;没听明白 1.2 51%攻击 二、区块链的发展 2.1 区块链1.0到3.0 2.2 共有链、联盟链、私有链 2.3 发展趋势 2.4 扩…