原理篇1、锂电池充/供电与电量检测
目录
- 1、充电、供电电路
- 2、电量检测电路
- 3、电量计算
- 4、关于IIR滤波器设计
- 参考资料
- 资料获取
1、充电、供电电路
键盘上的充电电路原理图
数据手册中的原理图
其中与TP5400 3脚(PROG)连接的电阻用来设置充电电流大小。
电阻大小与充电电流的关系:
充电指示灯显示状态
TP5400的 1 脚(Vout)只有5V/1A的输出能力。
在设计电路的时候之间将5V输出用来给键盘供电,由于输出功率原因,只能限制了WS2812灯珠的显示亮度。
WS2812灯珠的亮度限制在 keyboard.h 的第185~188行定义
#define LIGHT_BRGIGHTNESS_MAX 4 //亮度放大倍数
#define LIGHT_R_MAX 10 //R值最大值 用来限定电流大小
#define LIGHT_G_MAX 10 //G值最大值 用来限定电流大小
#define LIGHT_B_MAX 10 //B值最大值 用来限定电流大小
2、电量检测电路
键盘上的电量检测电路原理图
电量检测使用ESP32的GPI/O 35引脚,若要更改请选择GPI/O号大于30的引脚。
电量检测引脚在 keyboard.h 的第176行定义
#define BAT_PIN 35 //电量检测引脚
因为ADC驱动器API支持ADC1(8个通道,GPI/O 32-39)和ADC2(10个通道,GPI/O 0、2、4、12-15、25-27)。但是Wi-Fi驱动程序使用了ADC2。因此,在开启WiFi后只能使用ADC1(GPI/O 32-39)。
.
.
当时设计的电路并不完善,后来才考虑到功耗问题,由于经济原因就没有另做一个版本的了。
以下是重新设计的电路,仅供参考。
在上图中,使用一个PMOS管控制电池与分压电路的通断,并将PMOS的G极上拉,额外使用一个GPIO引脚连接 ADC_EN ,通过输出高低电平可主动控制电池与电路的通断。也使得ESP32断电或者进入DeepSleep模式时使电池与分压电路断开,减小工作电流。
WS2812的供电电路也可以使用MOS管进行电源隔离。
在上图中,使用一个NMOS管控制 TP5400 的5V输出与 WS2812 的5V输入电路通断,并将NMOS的G极下拉。
额外使用一个GPIO引脚连接 WS2812_EN (可与POWER_EN相连,这样只使用一个GPIO引脚),通过输出高低电平可主动控制电池与电路的通断。
也使得ESP32断电或者进入DeepSleep模式时使电池与分压电路断开,减小工作电流。
.
.
.
3、电量计算
关于电量的校准方法已经在 readme.txt 内的 "二、使用说明"中写明。
电量百分比的计算方法如下(在scan.ino 第49行):
int adcpower = (((int)get_power() - BAT_MIN) * 100) / (BAT_SUB);
set_bat((uint8_t)adcpower);
直接获取电量百分比方法:
uint8_t get_bat();
电量百分比的计算已经在 键盘扫描任务 中完成,直接调用get_bat()
即可获得电量百分比。
.
.
.
4、关于IIR滤波器设计
在设计原理图时已经在分压电路输出部分加了一个一阶RC低通滤波电路,但是效果不理想,所以在程序中对ADC采样数据增加了IIR滤波处理。
具体实现内容在 power.ino 文件中。
实现原理是创建一个滤波任务,定时器,信号量,队列。
定时器每隔 4ms 释放信号量。
void IRAM_ATTR adc_iir_callback()
{xSemaphoreGiveFromISR(adc_iir_Semaphore, NULL);
}
滤波任务获取信号量,成功获取后进行滤波计算,并将滤波结果放入队列中供其他任务读取。
for (;;)
{if (xSemaphoreTake(adc_iir_Semaphore, portMAX_DELAY) == pdTRUE){x37v[0] = x37v[1];x37v[1] = x37v[2];x37v[2] = (double)analogRead(BAT_PIN);y37v[0] = y37v[1];y37v[1] = y37v[2];y37v[2] = power_iir_a0 * x37v[2] + power_iir_a1 * x37v[1] + power_iir_a2 * x37v[0] - (power_iir_b1)*y37v[1] - (power_iir_b2)*y37v[0];power_iir = y37v[2];xQueueOverwrite(POWER_IIR_QUEUE, &power_iir);}
}
程序中默认的参数:
使用定时器0,滤波阶数为2阶,采样频率Fs=250Hz,截止频率Fc=1Hz。
IIR滤波参数在 power.ino 第32~37行定义
#define power_iir_a0 0.000155148423475699032397095988855539872
#define power_iir_a1 0.000310296846951398064794191977711079744
#define power_iir_a2 0.000155148423475699032397095988855539872
#define power_iir_b0 1
#define power_iir_b1 -1.964460580205231954309397224278654903173
#define power_iir_b2 0.965081173899134947546940566098783165216
.
.
自定义滤波器
参数获取方法
需要使用MATLAB生产滤波系数,以下是滤波系数的生成方法 (自行安装 MATLAB 软件)。
1、在MATLAB命令行中输入 fdatool 然后回车,等待打开滤波器设计工具箱。
参数设置好后点击Design filter按钮,将按要求设计滤波器。
以上是设计采样频率为250Hz,截止频率为0.5Hz的2阶低通巴特沃斯型IIR滤波器的参数设置。
在工具栏上点击Filter Coefficients图标或者在菜单栏上选择Analysis→Filter Coefficients可以查看生成的滤波器系数 (默认情况下,Filter Coefficients把结果分成多个2阶Section显示,其中还有增益。增益的目的是为了保证计算的精度和系统的稳定性) 。
选择 Edit → Convert to Single Section ,这时候系数变成我们熟悉的形式:
将得到的系数复制粘贴到 power.ino 第32~37行的定义中。
.
修改过程中需要注意的是,改变阶数和采样频率时,需要对代码码进行修改。
以下是修改方法。
.
当改变了阶数
阶数不同,滤波器的系统函数不同,所以MATLAB工具得出的系数的个数也不同,原因复杂,自行百度。
如改为3阶,则是
从上到下分别对应a0 ~ a3 ,b0 ~ b3的值。
对应的也需要改变滤波任务中的计算公式
如果将阶数改为1阶,则计算公式为:
//保存滤波结果double power_iir = 0.0;//1阶 电源滤波double y37v[2] = {0.0, 0.0};double x37v[2] = {0.0, 0.0};for (;;){if (xSemaphoreTake(adc_iir_Semaphore, 0) == pdTRUE){x37v[0] = x37v[1];x37v[1] = (double)analogRead(BAT_PIN);y37v[0] = y37v[1];y37v[1] = power_iir_a0 * x37v[1] + power_iir_a1 * x37v[0] - (power_iir_b1)*y37v[0];power_iir = y37v[3];xQueueOverwrite(POWER_IIR_QUEUE, &power_iir);}}
如果改为3阶,则计算公式为:
//保存滤波结果double power_iir = 0.0;//3阶 电源滤波double y37v[4] = {0.0, 0.0, 0.0, 0.0};double x37v[4] = {0.0, 0.0, 0.0, 0.0};for (;;){if (xSemaphoreTake(adc_iir_Semaphore, 0) == pdTRUE){x37v[0] = x37v[1];x37v[1] = x37v[2];x37v[2] = x37v[3];x37v[3] = (double)analogRead(BAT_PIN);y37v[0] = y37v[1];y37v[1] = y37v[2];y37v[2] = y37v[3];y37v[3] = power_iir_a0 * x37v[3] + power_iir_a1 * x37v[2] + power_iir_a2 * x37v[1] + power_iir_a3 * x37v[0] - (power_iir_b1)*y37v[2] - (power_iir_b2)*y37v[1] - (power_iir_b3)*y37v[0];power_iir = y37v[3];xQueueOverwrite(POWER_IIR_QUEUE, &power_iir);}}
可按以上示例自行选择并设计阶数,需要注意的是,阶数越高,计算过程越复杂。
.
.
当改变了采样频率Fs
使用MATLAB设计滤波器系数时,如果选择采样频率为500Hz,相当于ESP32的ADC引脚每秒钟采样500次,此时应该修改定时器的参数,使定时器每隔2ms释放一次信号量。
修改方法:
在 power.ino 文件中的第135行
将4000修改为2000。
将
timerAlarmWrite(Timer, 4000, true); //4000us -> 4ms 采样频率250Hz
改为
timerAlarmWrite(Timer, 2000, true); //2000us -> 2ms 采样频率500Hz
.
需要注意的是,修改的采样频率是有上限的,ADC采样频率不可能一直提高,而且IIR滤波器任务的运行频率也受限制,建议在250Hz~500Hz即可。
.
.
.
参考资料
1、TP5400数据手册
http://proecb478.pic1.ysjianzhan.cn/upload/TP5400.pdf
2、博客园博主XXX已失联的 IIR数字滤波器的实现(C语言)
https://www.cnblogs.com/21207-iHome/p/7059144.html
.
.
资料获取
全部工程文件进ESP32工程群(483217976)自行下载,所有文件在 ESP32键盘 目录下。
原理篇1、锂电池充/供电与电量检测相关推荐
- 锂电池放空后充不进电_常见锂电池充不进去电怎么办
常见锂电池充不进去电怎么办 在日常生活中我们都会遇到锂电池充不进电的情况,这个不同的设备遇到的情况不一样,相应的解决办法就会不同.下面细数几种锂电池充不进去电怎么办的解决方法,希望能帮到大家. 常遇到 ...
- Android APM 系列一(原理篇)
图片来自 https://unsplash.com 一. 前言 性能问题是导致 App 用户流失的罪魁祸首之一,如果用户在使用我们 App 的时候遇到诸如页面卡顿.响应速度慢.发热严重.流量电量消耗大 ...
- 《CDN 之我见》系列二:原理篇(缓存、安全)
2019独角兽企业重金招聘Python工程师标准>>> <CDN之我见>共由三个篇章组成,分为原理篇.详解篇和陨坑篇.本篇章适合那些从未接触过.或仅了解一些 CDN 专业 ...
- 检查压缩包是否损坏_修复损坏的gzip压缩文件之原理篇
接修复损坏的gzip压缩文件之原理篇,再次引用GZIP结构图: 已知修复一个损坏的gzip文件的关键环节在于找到下一个正常压缩包的起始点.根据结构图中的信息可知,每个压缩包的开始结构中有是否到达尾部标 ...
- Tomcat 原理篇
TOMCAT 原理篇 一.Tomcat 组成(Tomcat 由以下组件组成) 1.server a) Server是一个Catalina Servlet容器: b) Server 可以包含一个或多个s ...
- React Native JSBundle拆包之原理篇
概述 RN作为一款非常优秀的移动端跨平台开发框架,在近几年得到众多开发者的认可.纵观现在接入RN的大厂,如qq音乐.菜鸟.去哪儿,无疑不是将RN作为重点技术栈进行研发. 不过,熟悉RN的开发者也知道, ...
- 通过“四大行为”对WCF的扩展[原理篇]
整个WCF框架由两个基本的层次构成,即服务模型层和信道层.对信道层的扩展主要通过针对绑定的扩展实现,具体来说就是自定义绑定元素,以及相关的信道管理器(信道监听器和信道工厂).信道来改变对消息的处理和传 ...
- 《CDN 之我见》原理篇——CDN的由来与调度
2019独角兽企业重金招聘Python工程师标准>>> CDN是将源站内容分发至全国所有的节点,从而缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性的技术.它能够有效 ...
- 原理篇 | 推荐系统之矩阵分解模型
导语:本系列文章一共有三篇,分别是 <科普篇 | 推荐系统之矩阵分解模型> <原理篇 | 推荐系统之矩阵分解模型> <实践篇 | 推荐系统之矩阵分解模型> 第一篇用 ...
最新文章
- 【C/C++】计时函数比较
- 部分常用算法分析总结
- webspere php,Project Zero、WebSphere sMash、PHP和JAVA的整合
- SAP Spartacus central configuration - B2cStorefrontModule
- [10] AOP的注解配置
- dbus PHP,安装dbus-python的简要教程
- python 的 virtualenv 环境搭建及 sublime 手动创建运行环境
- R语言批量生成CaseWhen的解决方案
- html img动态设置图片大小,Js动态设置Img大小
- excel合并两列内容_你真的会用Excel“数据合并”吗?学会这4招准点下班
- 爬虫笔记-Bugku秋名山老司机(入门)
- android kodi,XBMC之Android硬解之路
- java jdk15.0.1环境配置(图文教程)
- python 类 实例_Python类的实例详解
- 在64位Windows的VS软件中使用C/C++调用gnuplot画图
- Mysql 利用存储过程 实现单据号码(单号)生成器(万能版)
- cache数据库入门教程
- Spring RMI反序列化漏洞分析
- 二维码生成api接口调用示例
- 智能新物种!斐讯京东新品日:不可错过的高颜值科技美物