社区导航

 
查看: 1295|回复: 13

[原创] EEWORLD DIY——基于ArduinoUNO的USB电量计

[复制链接]

51

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-12-13 17:35:24 | 显示全部楼层 |阅读模式
本帖最后由 XinChao 于 2017-12-13 17:50 编辑

EEWORLD DIY——
基于Arduino UNO的USB电量计

00.jpg


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
功能简介

        可以用来测试手机、充电宝等USB设备的充放电电压、电流、电量,以及充放电时间,并记录显示。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
硬件原理


使用的硬件
        Arduino UNO开发板,IIC接口的SSD1306 OLED显示屏,按键等。

整机电路
        如下图,USB电源输入直接用Arduino UNO开发板的USB接口。OLED显示屏插在开发板任意4个数字接口上,自制的USB电压电流检测模块插在电源接口和模拟接口上,两个按键用两个数字接口。
02.jpg

USB电压电流检测模块
        如下图,原理很简单,5V的电源用两个100K的电阻分压到一半送A0口检测,负极串了一个0.39欧姆的采样电阻,接到A1口检测。用洞洞板做的模块,USB座输出5V电源。
        PS:别问我为什么用0.39的电阻,我是不会告诉你我只有0.39电阻的。。。
16.JPG
10.jpg

测试用的放电模块
        二十多个510的电阻并联组成,大约200mA的放电电流。通过跳线可切换100mA和200mA两档。
11.jpg

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
开发环境

        Arduino IDE 1.8.3
20.jpg

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
工作原理


        这次用的是Arduino平台,软硬件开发都很简单。

OLED
        SSD1306 OLED显示屏为IIC接口,Arduino UNO开发板有硬件IIC,但是为固定的接口,为了方便接口的分配,我使用了软件模拟IIC,这样OLED屏就可以使用开发板上的任意接口了。

KEY
        用了两个按键接到Arduino UNO开发板的数字接口,软件中配置相应接口为上拉输入模式。在主循环中读取按键状态。两个按键实际只用了一个,用来清除测量数据。

ADC
        用了两路A0和A1,A0用于检测输出电压,A1检测采样电阻电压,计算电流。

EEPROM
        使用Arduino UNO开发板上MCU芯片MEGA328P内部的EEPROM,共1024个字节,用来存储两个参数,用了12个字节。

UART
        向电脑发送测试信息。

LED
        用Arduino UNO开发板上的一个LED来表示电量测量状态,测量时每秒闪一次。

软件流程
        软件的流程比较简单,就不画流程图了:复位后完成各种初始化(串口、按键、显示屏等),读取保存的参数,然后进入主循环,主循环中检测按键和秒时间标志SecondFlag,有按键按下时清零测量数据,有秒时间标志SecondFlag时更新显示并保存数据。

        秒时间标志SecondFlag由定时器中断产生,定时器定时100ms,每次中断读取ADC的值,到达10次(1秒)时计算ADC的平均值,计算电压、电流和电量,设置秒时间标志SecondFlag。

自动测量电量
        当检测到的电流特别小时(小于10mA),认为没有进行电量测量,此时不计时,只有电量大于1mA时才开始计时并计算电量。

数据保存
        每秒数据更新后都会保存电量和时间两个参数,防止测量中断时再复位后可以读出参数继续测量。比如在测试充电宝放电电量时,当充电宝电放完之后系统就会断电,这样的话重新上电时就能看到充电宝放电的电量和放电时间。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
测试

1、开机
        上电开机,OLED显示屏会显示开机欢迎画面,然后显示电压、电流、电量和时间。

        如果开发板的电源输入口接电脑的话,同时会从串口向电脑输出开机信息。然后每秒显示一次检测到的电压、电流、电量和时间。
40.jpg

2、电压检测
        如下图所示,检测到的电压为4.98V,和用万用表测得值4.99V相比还算可以,误差不算太大。
30.jpg

3、电流检测
        测得0.187A时万用表读数202.4mA,0.083A时万用表读数108.8mA,小电流时误差比较大,但还可以接受。。。
        我的采样电阻是普通电阻,换成高精度低温漂的电阻会更精确。
31.jpg
32.jpg

4、断电数据保存
        在测试中如果MCU复位,或者电路断开,重新上电时会读取保存的已测试时间和电量的数据。
        如下图中显示Hello表示MCU复位,Read Data表示读取到了保存的参数。
41.jpg

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
演示视频

        动图比较大,请耐心等待图片加载。。。

1、开机
        开机先显示开机欢迎画面,然后显示电压、电流、电量和时间。
ys1-kj.gif

2、开始测量
        没有插入USB接口时,显示电流为0,时间不走。
        当插入USB充电宝时,检测到了电流,开始计时。
ys2-cl.gif

3、按键
        按键前显示已充电两分钟,电量7mAh,按键后电量和时间都清零,重新开始计量。
ys3-q0.gif

4、断电
        当断电重新上电时,会读取已保存的数据,继续计算电量,而不是从零开始。
ys4-rs.gif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
源代码

XinChao-Arduino-ELE-171213a.zip (38 KB, 下载次数: 10)


回复

使用道具 举报

324

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-12-13 21:21:12 | 显示全部楼层
两个按键是怎么接上去的
来个近图

点评

很简单,焊3根针上。 中间接地,两边接IO,IO芯片内部上拉。 [attachimg]334059[/attachimg][attachimg]334060[/attachimg]  详情 回复 发表于 2017-12-14 08:45


回复

使用道具 举报

324

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-12-13 21:21:57 | 显示全部楼层
时间使用定时器产生,时间久了溢出了怎么办?

点评

MCU的定时器只定时100ms,不会溢出。就算会溢出,也可以定时短一点,再用变量累加。当然这样定时误差会大点,要想精确的话可以加RTC芯片。 计算电量的秒计时用了一个32位的变量,最大可以计时136年,我想应该够用了  详情 回复 发表于 2017-12-14 08:54


回复

使用道具 举报

51

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2017-12-14 08:45:41 | 显示全部楼层
sanhuasr 发表于 2017-12-13 21:21
两个按键是怎么接上去的
来个近图

很简单,焊3根针上。
中间接地,两边接IO,IO芯片内部上拉。
k1.jpg k2.jpg

点评

第一次见这种新颖的做法,感觉中间也可以加个电阻  详情 回复 发表于 2017-12-14 19:33


回复

使用道具 举报

51

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2017-12-14 08:54:25 | 显示全部楼层
sanhuasr 发表于 2017-12-13 21:21
时间使用定时器产生,时间久了溢出了怎么办?

MCU的定时器只定时100ms,不会溢出。就算会溢出,也可以定时短一点,再用变量累加。当然这样定时误差会大点,要想精确的话可以加RTC芯片。
计算电量的秒计时用了一个32位的变量,最大可以计时136年,我想应该够用了吧。。。

点评

是说OLED的时间还是串口输出的秒?OLED的时间连续走时可以走多久? 因为我之前要在保存的数据前加时间,使用了RTC芯片,如果你这种方法可取,后面设计就用你这种  详情 回复 发表于 2017-12-14 19:36


回复

使用道具 举报

324

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-12-14 19:33:18 | 显示全部楼层
XinChao 发表于 2017-12-14 08:45
很简单,焊3根针上。
中间接地,两边接IO,IO芯片内部上拉。

第一次见这种新颖的做法,感觉中间也可以加个电阻

点评

呵呵 只为电路最简单 软件上用芯片内部的上拉电阻就行了  详情 回复 发表于 2017-12-15 08:33


回复

使用道具 举报

324

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-12-14 19:36:31 | 显示全部楼层
XinChao 发表于 2017-12-14 08:54
MCU的定时器只定时100ms,不会溢出。就算会溢出,也可以定时短一点,再用变量累加。当然这样定时误差会大 ...

是说OLED的时间还是串口输出的秒?OLED的时间连续走时可以走多久?
因为我之前要在保存的数据前加时间,使用了RTC芯片,如果你这种方法可取,后面设计就用你这种

点评

OLED上显示的时间,和串口输出的秒,都是秒计时用的32位的变量。 你可以算下32位最大4294967295秒=1193046小时=49710天=136年。 其实好多MCU比如STM32内部的RTC就是一个32位的定时器。  详情 回复 发表于 2017-12-15 08:40


回复

使用道具 举报

51

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2017-12-15 08:33:47 | 显示全部楼层
sanhuasr 发表于 2017-12-14 19:33
第一次见这种新颖的做法,感觉中间也可以加个电阻

呵呵 只为电路最简单 软件上用芯片内部的上拉电阻就行了


回复

使用道具 举报

51

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2017-12-15 08:40:53 | 显示全部楼层
sanhuasr 发表于 2017-12-14 19:36
是说OLED的时间还是串口输出的秒?OLED的时间连续走时可以走多久?
因为我之前要在保存的数据前加时间, ...

OLED上显示的时间,和串口输出的秒,都是秒计时用的32位的变量。
你可以算下32位最大4294967295秒=1193046小时=49710天=136年。
其实好多MCU比如STM32内部的RTC就是一个32位的定时器。

点评

就是说每次上电只能接着之前的时间走,这个时间你是放到了flash里面,  详情 回复 发表于 2017-12-15 21:32


回复

使用道具 举报

324

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-12-15 21:32:22 | 显示全部楼层
XinChao 发表于 2017-12-15 08:40
OLED上显示的时间,和串口输出的秒,都是秒计时用的32位的变量。
你可以算下32位最大4294967295秒=11930 ...

就是说每次上电只能接着之前的时间走,这个时间你是放到了flash里面,

点评

是的  详情 回复 发表于 2017-12-18 08:42


回复

使用道具 举报

51

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2017-12-18 08:42:33 | 显示全部楼层
sanhuasr 发表于 2017-12-15 21:32
就是说每次上电只能接着之前的时间走,这个时间你是放到了flash里面,

是的


回复

使用道具 举报

540

TA的帖子

20

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2018-1-8 09:57:38 | 显示全部楼层
d感觉在哪里见过一样。

点评

用nxp的824做过类似功能的,但这个mcu、显示屏、软件开发平台都不一样。  详情 回复 发表于 2018-1-9 09:14


回复

使用道具 举报

51

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2018-1-9 09:14:39 | 显示全部楼层
ketose 发表于 2018-1-8 09:57
d感觉在哪里见过一样。

用nxp的824做过类似功能的,但这个mcu、显示屏、软件开发平台都不一样。


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2018-6-29 22:48:33 | 显示全部楼层
这是每秒都写入EEPROM 吗? 但是EEPROM不是只能写1000000次吗? 不是坏的快。


回复

使用道具 举报

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

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2018-9-25 09:41 , Processed in 0.446493 second(s), 18 queries , Gzip On, Redis On.

快速回复 返回顶部 返回列表