Percent display battery level

Percent display battery level

Lithium batteries are used more and more widely, but how to convert the voltage data we can only collect into percentage power data? This article provides a simple algorithm.

platform

Hardware: Jetson-nano
Software: Ubuntu18.04
Sensor: Voltage sensor based on the principle of resistance divider, product link (https://detail.tmall.com/item.htm?id=520840133787)[https://detail.tmall .com/item.htm?id=520840133787]

sampling
  1. Only run the system, collect the voltage every ten seconds, assuming this process is uniform discharge
  2. From the fully charged start to run until the battery is too low to stop, the voltage sampling interval is [8.5, 12.5]
  3. Since the interval between 9.5 and 8.5 is only 10 minutes apart, 9.6V is selected as 1% of electricity
Percentage model
  1. The total discharge time is about 10 hours
  2. Set the voltage (12.5V) at the beginning of the first hour corresponding to 100% power
  3. Set the voltage at the end of the 10th hour (9.6V) to correspond to 1% of the battery
  4. The voltage at the end of the 5th hour is 50% battery
  5. By analogy, the progress of the discharge time is used as the percentage of the power to correspond to the sampled voltage value
  6. The accuracy of the voltage value is 1 digit after the decimal point, a total of 30 different sampling values, the sampling time corresponding to different sampling values ​​can be counted
  7. This article selects the maximum sampling time (that is, the first sampling time) as the battery power percentage corresponding to the voltage value
simulation
  1. Use Matlab to view the relationship between voltage and discharge progress
close all;clear;clc
% 载入数据
x = load('data/battery.txt');
x = x(1:3850)';
% 建立比例关系
y = [1:-1/3850:1/3850];
% 统计
data = [10 * (x - 9.5); y]';
data_sum = zeros(30, 1);
data_count = zeros(30, 1);
data_min = zeros(30, 1);
for i = 1:size(x,2)
    idx = round(data(i,1));
    data_sum(idx) = data_sum(idx) + data(i,2);
    data_max(idx) = max([data_min(idx) data(i,2)])
    data_count(idx) = data_count(idx) + 1;
end
data_avg = data_sum ./ data_count;
% 按平均值计算
pct = round(100*data_avg)
% 按最大值计算 
pct_max = round(100*data_max)
% 拟合效果
figure(1)
plot(x, y)
figure(2)
m = [9.6:0.1:12.5];
plot(m, pct_max)
  1. Sample mapInsert picture description here

  2. Map after selecting the maximum value
    Insert picture description here

  3. Calculation results

[9.6-10.5]:  1,  1,  2,  4,  8,  11, 16, 19,  27,  34, 
[10.6-11.5]: 45, 52, 55, 58, 62, 64, 68, 71,  76,  78, 
[11.6-12.5]: 81, 84, 87, 92, 93, 98, 99, 100, 100, 100
  1. Voltage to power conversion
# 电池电压对应的电量百分比,对应: 9.6V-12.5V
battery_pct = (1, 1, 2, 4, 8, 11, 16, 19, 27, 34, 45, 52, 55, 58, 62, 64, 68, 71,
               76, 78, 81, 84, 87, 92, 93, 98, 99, 100, 100, 100)
last_bat = 125
while alive:
    # 电压转换为百分比
    bat = round(get_battery())
    if bat == 0:
        continue
    if bat < 96:
        bat = 96
    elif bat > 125:
        bat = 125
    if last_bat + 5> bat > last_bat:
        bat = last_bat
    else:
        last_bat = bat
    pct = battery_pct[bat - 96]
    batstr = '%d%%' % pct
    time.sleep(10)
Follow-up optimization plan
  1. Improve the sampling accuracy and sampling frequency, which can make the battery display more accurate and smooth
  2. Exclude outliers in statistics
  3. Low-pass filtering is added when converting voltage to electric quantity to eliminate some interference

Guess you like

Origin blog.csdn.net/ManWZD/article/details/105652958