原理篇1、锂电池充/供电与电量检测

2023-05-16

目录

    • 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键盘 目录下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

原理篇1、锂电池充/供电与电量检测 的相关文章

  • 白嫖5T空间Onedrive并搭建下载站

    更好的阅读体验欢迎访问博客白嫖5T空间Onedrive并搭建下载站 前言 白嫖一个微软E5账号不仅能自己使用office全家桶 xff0c 还能造福25个小伙伴 xff0c 何乐而不为 xff1f 这里借助onedirve的API和onei
  • 阿里云Linux(Debian) + Tomcat搭建网站

    工具 xff1a Linux 我买的是阿里云的主机Linux Debian64位的 Tomcat Java Web服务器 putty 连接远程主机的客户端 WinSCP 远程主机的可视化界面 xff0c 方便操作文件 jdk1 8 需要配置
  • 动态链接库(DLL)开发基础

    本周我的博客涉及到动态链接库的基础开发 我在刚开始学习动态链接库的开发 在网上找DLL开发基础知识教程时发现网上的资料还是太杂 xff0c 对初学者不太友好 xff0c 于是我就着手写了这篇博客 xff0c 本篇博客知识有DLL简介 DLL
  • Mybatis:使用Mybatis执行SQL多出“limit?“,原来这样就可以解决!!!

    问题展示说明 业务需要只展示分组排序后的前15条 xff0c 数据写了如下sql xff1a 启动项目访问接口后 xff0c 报如下错误 xff1a 解决办法 参考了一下MyBatis官网和其他博客发现需要清理一下之前设置过的Page缓存
  • .NET编程——利用C#实现远程桌面连接(WinForm)

    通过学习利用利用C 实现登录功能后 xff0c 本文将通过Visual Studio 2019运行实现远程桌面连接 目录 引言 前期准备 连接固定计算机 连接指定计算机 可能遇到的问题 引言 实现远程桌面有一个大前提是不可忽略的 xff0c
  • 单片机基础:什么是中断系统、中断系统如何用(附中断系统应用实例)

    中断系统 1 前言2 什么是中断3 什么是中断系统4 中断的流程5 中断的优先级控制6 中断源外部中断 7 与中断有关的特殊功能寄存器7 1 定时 计数器控制寄存器 96 TCON 96 7 2 串行口控制寄存器 96 SCON 96 7
  • 单片机基础:MCS-51单片机的硬件结构(附硬件结构框图)

    单片机硬件结构知识点非常琐碎 xff0c 通过一次两次的学习是不太可能记住的 想要熟练掌握硬件结构 xff0c 最好的方法是在实验中练习 xff0c 通过编程多见多用才能牢固的掌握 MCS 51单片机硬件结构 1 硬件系统框图2 单片机功能
  • 三种简单排序(冒泡、插入、选择)的比较和图解

    冒泡排序 这种排序方式是最容易理解的 xff0c 主体思想就是 xff1a 指针重复地走访过要排序的数列 xff0c 一次比较两个元素 xff0c 如果他们的顺序错误就把他们交换过来 走访数列的工作是重复地进行直到没有再需要交换 xff0c
  • 单片机基础:对单片机指令系统中七种寻址方式的理解

    七种寻址方式 1 立即寻址2 直接寻址3 寄存器寻址4 寄存器间接寻址4 1记录一下调试程序过程中遇到的一个错误 5 基址加变址寻址6 相对寻址7 位寻址 1 立即寻址 立即寻址就是不寻址 xff0c 直接把被操作的数据 立即数 写在指令当
  • Python课程设计:简单博客管理系统(完整代码)

    博客管理系统 1 框图及编程思路2 程序执行2 1主界面2 2登录后界面2 3注册信息保存格式2 4文章保存格式 3 代码 注意 xff1a 程序中涉及到文件路径的 xff0c 可以酌情修改电脑本地路径 这是我的Python语言的课程设计作
  • 单片机P0端口驱动数码管0-9循环显示(Proteus仿真+C语言程序)

    P0端口驱动共阳极数码管循环显示0 9 1 实验效果2 数码管3 Proteus仿真4 源代码 1 实验效果 2 数码管 一个数码管包含七段发光二极管 xff0c 通过控制每段二极管的亮灭 xff0c 继而显示出不同的数字 数码管分为共阴极
  • 数据库系统关系代数的学习

    前言 关系代数是一种抽象的查询语言 xff0c 是关系数据库查询语言的基础 xff0c 关系代数包括传统的集合运算和专门的关系运算 基本操作 并 差 笛卡尔积 投影 选择 组合操作 交 连接 自然连接 R S 除运算 良好的理解关系代数的几
  • 基于51单片机的矩阵按键学习

    一 矩阵按键 矩阵按键就是独立按键的结合体 xff0c 矩阵按键的优点是提高了I O端口的利用率 xff0c 用M 43 N个I O端口就可以控制M N个独立按键 而一个独立按键就需要一个I O端口来控制 xff0c I O端口的利用率很低
  • LCD1602液晶显示模块学习笔记

    LCD1602液晶显示模块 一 初识LCD6021 1 实物图1 2 引脚图1 3 引脚功能说明 二 显示位置三 显示内容四 指令集五 工作时序5 1 写操作时序5 2 读操作时序 六 编程思路6 1 写数据6 2 写指令6 3 初始化6
  • 微信聊天记录导出(2020新版)

    微信聊天记录导出 2020新版 首先说明 xff0c 坑的部分主要是数据库破解 项目地址 xff1a https github com fly dragon211 Wechat message analysis 1 本地备份提取聊天记录 这
  • VSC配置C C++

    记录一下配置的过程 xff0c 不然搞完就忘 还会忘记搞事情时的耐心和韧劲 一 GCC 1 下载C语言编译器 链接 xff1a MinGW w64 for 32 and 64 bit Windows Browse Files at Sour
  • Python下实现Tesseract OCR训练字符库(OpenCV-python边缘检测代替jTessBoxEditor手动矫正)

    Python 下实现 Tesseract OCR 训练字符库 xff08 OpenCV 边缘检测代替 jTessBoxEditor 手动矫正 xff09 作者 xff1a 殷越 目录 一 概述二 环境搭建1 下载 Tesseract OCR
  • 【C语言中清空文件的方法】

    C语言清空文件内容 C语言中清空文件的方法 C语言中清空文件的方法 C语言中清空文件的方法很简单 只要以 可写 的方式打开文件 xff0c 就能将这个文件清空 span class token macro property span cla
  • 服务器知识:阿里云ECS实例设置用户root密码、远程连接

    nbsp nbsp nbsp nbsp 阿里云服务器购买之后 新的实例需要设置root登录密码之后才能正常操作 不然就登录不了 重置实例登录密码的时候 适用于在新创建时未设置密码或者忘记密码的情况 对于正在运行的实例 需要在重置实例登录密码
  • 解决chkconfig设置开机启动时出现missing LSB的错误

    0x00 主要原因是脚本不符合LSB tags规范 xff0c 在 bin bash下面添加如下代码即可 以tomcat为例 span class hljs preprocessor BEGIN INIT INFO span span cl

随机推荐

  • 【MinMaxScaler函数】

    会查MinMaxScaler的基本上都应该理解数据归一化 xff0c 本质上是将数据点映射到了 0 1 区间 xff08 默认 xff09 xff0c 但实际使用的的时候也不一定是到 0 1 xff0c 你也可以指定参数feature ra
  • 【forward方法--深度学习】

    1 基本用法 在pytorch中 xff0c 使用torch nn包来构建神经网络 xff0c 我们定义的网络继承自nn Module类 而一个nn Module包含神经网络的各个层 放在 init 里面 和前向传播方式 放在forward
  • 【pycharm查看当前python版本】

    import span class token return type class name sys span span class token function print span span class token punctuatio
  • 【详解Anaconda 、多环境安装多个不同python版本以及根据需要切换python版本】

    前言 本文旨在详细介绍Anaconda 以及 如何在Anaconda上更换python版本 备注 xff1a 根据读者建议 xff0c 这里明确如下 xff1a 标题中的 在Anaconda上更换python版本 实际上是指 xff1a 通
  • PyCharm中多个方法导入包

    一 Python PyCharm和Anaconda的关系 1 Python是一种解释型 面向对象 动态数据类型的高级程序设计语言 虽然Python自带了一个解释器IDLE用来执行 py脚本 xff0c 但是却不利于我们书写调试大量的代码 常
  • 关于pycharm环境和路径配置的介绍

    python解释器路径 python项目解释器路径 用于配置python项目执行的python路径 比如 xff0c 有的项目是运行的是系统python2 7下的环境 xff1b 有的是3 4 xff1b 有的项目使用的是virtualen
  • 【如何快速判断矩阵是否相似对角化】

    快速判断矩阵是否可以相似对角化 关于如何快速判断矩阵是否可以相似对角化的方法 span class token variable span class token variable 96 span 第一步 xff1a 看是不是实对称矩阵 x
  • 【MemoryCompression内存占用过高】

    MemoryCompression内存占用过高 最近笔记本内存 xff08 16G运存 xff09 占用一直在95 43 xff0c cpu占用也在90 43 xff0c 电脑一度无法使用 96 步骤1 96 96 步骤2 96 步骤 96
  • 洛谷 P3366 【模板】最小生成树 (题解+代码)

    题目传送门 xff1a https www luogu com cn problem P3366 题解 xff1a 利用Kruskal算法求解 xff0c 这里大致说下Kruskal算法 对于一个点数为n的生成树而言 很显然 xff0c 想
  • WSL_03 WSL2 从C盘迁移到D盘

    文章目录 1 动机1 查看虚拟机状态 xff0c 并关闭要迁移的虚拟机2 迁移WSL22 1 出现的问题 xff1a 已存在具有提供的名称的分发 已解决 3 设置启动时的默认用户 xff0c 没有设置默认为root参考 1 动机 WSL2默
  • iOS开发:Block传值的运用

    在iOS开发中传值是一个非常经典的方法 有六种传值方式 属性传值 代理传值 Block传值 方法传值 单例传值 通知传值 本章就来分享一下通过Block完成两个不同界面间的传值操作 首先再来了解一下Block 简单一点说 Block就是一段
  • Ubuntu 安装 CUDA and Cudnn

    文章目录 0 查看 nvidia驱动版本1 下载Cuda2 下载cudnn参考 xff1a 0 查看 nvidia驱动版本 nvidia smi 1 下载Cuda 安装之前先安装 gcc g 43 43 gdb 官方 xff1a https
  • 傻傻分不清楚:裸纤、专线、SDH、MSTP、MSTP+、OTN、PTN、IP-RAN

    著作权归作者所有 xff1a 来自51CTO博客作者51CTOsummer的原创作品 xff0c 如需转载 xff0c 请注明出处 xff0c 否则将追究法律责任 xff08 一 xff09 裸纤 裸纤也叫裸光纤 xff0c 运营商提供一条
  • github下载慢的两种解决方式

    1 修改配置文件 cmd ping github com会显示超时 我们只需要绕过dns域名解析就行 打开DNS查询网站http tool chinaz com dns xff0c 搜索github com的域名解析服务 xff0c 选择一
  • ModuleNotFoundError: No module named ‘cv2‘解决办法

    xff08 linux系统 xff09 这里记录一个实验过程中碰到的bug xff1a 我是在linux系统上面使用conda环境 xff0c 且已经下载了opencv python xff0c 但在python文件中import cv2仍
  • mybatis-plus + PageHelper

    一 导入相关依赖 span class token operator lt span span class token operator span span class token operator span mysql 驱动包 span
  • 阿里云端口问题-配置完安全组无效

    Centos7 X安全组配置完成后仍不能访问 xff0c 此时要配置防火墙放行端口才行 使用以下命令打开端口 tcp udp 两种传输层模式 add port 61 端口号 firewall cmd zone 61 public add p
  • Anaconda教程——Ubuntu 平台

    Anaconda 使用教程 Ubuntu 平台 说明 xff1a 对应着 Python 有 2 x 版本和 3 x 版本 xff0c Anaconda 也有 Anaconda2 以及 Anaconda 3 两个版本 xff0c 考虑其流行度
  • ubuntu突然上不去网

    今天ubuntu突然上不去网了 xff08 昨天还行 xff0c 就很神奇 xff09 在一篇博客中找到了解决办法 xff0c 里面给出了三种解决办法 xff0c 详见原文连接 我用的第二种 xff0c 很简单 xff0c 亲测有效 记录下
  • 原理篇1、锂电池充/供电与电量检测

    目录 1 充电 供电电路2 电量检测电路3 电量计算4 关于IIR滤波器设计参考资料资料获取 1 充电 供电电路 键盘上的充电电路原理图 数据手册中的原理图 其中与TP5400 3脚 PROG 连接的电阻用来设置充电电流大小 电阻大小与充电