加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

用chatGPT開發(fā)電量SOC功能

11/25 13:30
685
閱讀需 14 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

今天開發(fā)一個(gè)小設(shè)備,需要顯示一下當(dāng)前電量,從ADC中獲取到了原始采樣值,換算出來電壓值以后就不想搬磚了。

所以,找個(gè)免費(fèi)勞動力,把后面的代碼寫一下吧。

直接下任務(wù),不用先打招呼,也不用客套,甚至你都不需要給他講太細(xì),罵著他也好好的給你執(zhí)行。

using System;
class Program{    static void Main(string[] args)    {        // 示例輸入電壓        double voltage = 3.7; // 單位: V        double soc = CalculateSOC(voltage);
        Console.WriteLine($"電壓: {voltage}V, SOC: {soc:F2}%");    }
    static double CalculateSOC(double voltage)    {        // 常見鋰電池開路電壓與SOC的近似關(guān)系        // 數(shù)據(jù)可以根據(jù)具體電池調(diào)整,這里用一個(gè)常見的線性插值示例        double[] voltagePoints = { 3.0, 3.2, 3.4, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2 }; // 電壓點(diǎn)        double[] socPoints = { 0, 10, 20, 40, 50, 60, 70, 85, 95, 100 }; // 對應(yīng)SOC點(diǎn) (%)
        // 邊界處理        if (voltage <= voltagePoints[0]) return socPoints[0];        if (voltage >= voltagePoints[voltagePoints.Length - 1]) return socPoints[socPoints.Length - 1];
        // 插值計(jì)算SOC        for (int i = 0; i < voltagePoints.Length - 1; i++)        {            if (voltage >= voltagePoints[i] && voltage <= voltagePoints[i + 1])            {                // 線性插值公式                double slope = (socPoints[i + 1] - socPoints[i]) / (voltagePoints[i + 1] - voltagePoints[i]);                return socPoints[i] + slope * (voltage - voltagePoints[i]);            }        }
        // 默認(rèn)返回0(正常情況下不會到達(dá)這里)        return 0;    }}

不說太細(xì)還真不行,因?yàn)樗芰μ珡?qiáng)了,以至于給我的是一個(gè)C#代碼,而需要的是一個(gè)跑在單片機(jī)上的C語言代碼。我只能罵他一下了。

#include <stdio.h>
int calculateSOC(int voltage);
int main() {    // 示例輸入電壓值(單位: mV)    int voltage = 3700; // 3.7V = 3700mV    int soc = calculateSOC(voltage);
    printf("電壓: %dmV, SOC: %d%%n", voltage, soc);    return 0;}
int calculateSOC(int voltage) {    // 使用整數(shù)表示電壓 (單位: mV) 和 SOC (%)    int voltagePoints[] = { 3000, 3200, 3400, 3600, 3700, 3800, 3900, 4000, 4100, 4200 }; // 電壓點(diǎn) (單位: mV)    int socPoints[] = { 0, 10, 20, 40, 50, 60, 70, 85, 95, 100 }; // 對應(yīng)SOC點(diǎn) (%)    int numPoints = sizeof(voltagePoints) / sizeof(voltagePoints[0]);
    // 邊界處理    if (voltage <= voltagePoints[0]) return socPoints[0];    if (voltage >= voltagePoints[numPoints - 1]) return socPoints[numPoints - 1];
    // 插值計(jì)算SOC    for (int i = 0; i < numPoints - 1; i++) {        if (voltage >= voltagePoints[i] && voltage <= voltagePoints[i + 1]) {            // 線性插值公式,完全用整數(shù)計(jì)算            int deltaVoltage = voltagePoints[i + 1] - voltagePoints[i];            int deltaSOC = socPoints[i + 1] - socPoints[i];            int voltageOffset = voltage - voltagePoints[i];
            // 計(jì)算插值的SOC,返回整數(shù)            return socPoints[i] + (voltageOffset * deltaSOC) / deltaVoltage;        }    }
    // 默認(rèn)返回0(正常情況下不會到達(dá)這里)    return 0;}

他懂得蠻多的,一聽說是單片機(jī),不單把C#語言改成了C語言,然后還知道把浮點(diǎn)運(yùn)算全部轉(zhuǎn)換成整形數(shù)來運(yùn)算,提高效率。

貼心的注釋,以及簡單的使用教程,接口調(diào)用都碼的明明白白。

電量顯示似乎還有點(diǎn)問題,負(fù)載變化的時(shí)候,電壓不穩(wěn)定,電量百分百總是跳動。

以下是他的回答,我不貼圖了,粘貼蚊子到這里吧。

1. 內(nèi)阻模型補(bǔ)償

利用電池的內(nèi)阻模型,根據(jù)當(dāng)前電流(I)和內(nèi)阻(R)計(jì)算出補(bǔ)償后的開路電壓:

#include <stdio.h>
int calculateSOC(int voltage, int current);int compensateVoltage(int voltage, int current, int resistance);
int main() {    // 示例輸入,電壓和電流以整數(shù)表示    int voltage = 3650; // 3.65V = 3650mV (負(fù)載電壓)    int current = 2000; // 2000mA = 2A    int soc;
    // 根據(jù)電壓電流計(jì)算SOC    soc = calculateSOC(voltage, current);
    printf("負(fù)載電壓: %dmV, 電流: %dmA, SOC: %d (0.1%% 精度)n", voltage, current, soc);    return 0;}
// 補(bǔ)償后的SOC計(jì)算int calculateSOC(int voltage, int current) {    // 定義內(nèi)阻值(單位: mΩ)    int resistance = 50; // 內(nèi)阻50mΩ,可根據(jù)電池類型調(diào)整
    // 補(bǔ)償后的電壓(估算開路電壓)    int compensatedVoltage = compensateVoltage(voltage, current, resistance);
    // 使用補(bǔ)償后的電壓計(jì)算SOC    int voltagePoints[] = { 3000, 3200, 3400, 3600, 3700, 3800, 3900, 4000, 4100, 4200 }; // 電壓點(diǎn) (單位: mV)    int socPoints[] = { 0, 100, 200, 400, 500, 600, 700, 850, 950, 1000 }; // 對應(yīng)SOC點(diǎn) (擴(kuò)大10倍, 單位: 0.1%)    int numPoints = sizeof(voltagePoints) / sizeof(voltagePoints[0]);
    // 邊界處理    if (compensatedVoltage <= voltagePoints[0]) return socPoints[0];    if (compensatedVoltage >= voltagePoints[numPoints - 1]) return socPoints[numPoints - 1];
    // 插值計(jì)算SOC    for (int i = 0; i < numPoints - 1; i++) {        if (compensatedVoltage >= voltagePoints[i] && compensatedVoltage <= voltagePoints[i + 1]) {            int deltaVoltage = voltagePoints[i + 1] - voltagePoints[i];            int deltaSOC = socPoints[i + 1] - socPoints[i];            int voltageOffset = compensatedVoltage - voltagePoints[i];            return socPoints[i] + (voltageOffset * deltaSOC) / deltaVoltage;        }    }
    return 0; // 默認(rèn)返回0}
// 電壓補(bǔ)償函數(shù)int compensateVoltage(int voltage, int current, int resistance) {    // 使用 I * R 進(jìn)行電壓補(bǔ)償    // resistance 單位為 mΩ,current 單位為 mA,計(jì)算結(jié)果單位為 mV    return voltage + (current * resistance) / 1000;}

2. 動態(tài)內(nèi)阻調(diào)整

鋰電池的內(nèi)阻(R)會隨著SOC和溫度的變化而變化,可以通過查表或?qū)崟r(shí)監(jiān)控內(nèi)阻調(diào)整補(bǔ)償系數(shù):

低SOC(<20%)或高SOC(>80%):內(nèi)阻通常較大。

溫度低時(shí)(如<0°C):內(nèi)阻顯著增大。

實(shí)現(xiàn)建議:

使用一個(gè)二維查表機(jī)制,根據(jù)SOC和溫度動態(tài)調(diào)整 resistance 的值。

在上面的 compensateVoltage 函數(shù)中替換固定內(nèi)阻值為動態(tài)值。

3. 時(shí)間加權(quán)平均

如果負(fù)載波動較大,可以通過時(shí)間加權(quán)平均法平滑SOC計(jì)算:

SOCsmooth=α?SOCnew+(1?α)?SOCold

其中,α 是平滑因子(0-1之間,通常取0.1到0.3)。

4. 擴(kuò)展方法:結(jié)合電流積分法

負(fù)載電流(Coulomb計(jì)數(shù)法)與電壓估算法結(jié)合,可以在動態(tài)負(fù)載情況下得到更穩(wěn)定的SOC值:

使用補(bǔ)償后的電壓計(jì)算初步SOC。

通過電流積分法對SOC進(jìn)行調(diào)整(例如長期負(fù)載或高電流放電時(shí))。

總結(jié)

通過對負(fù)載電壓的補(bǔ)償,可以有效減小負(fù)載變化對SOC估算的影響。結(jié)合動態(tài)內(nèi)阻調(diào)整或平滑方法,能夠進(jìn)一步提高SOC計(jì)算的穩(wěn)定性和準(zhǔn)確性。

哎,搬磚這事以后就不能自己干。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

多年硬件從業(yè)經(jīng)驗(yàn),專注分享從研發(fā)到供應(yīng)鏈,再到精益制造過程中的經(jīng)驗(yàn)和感悟!