G2025_廃品リチウム電池の放電実験

2025111

6:22

G2025_lpc812_junk_lithium_battery_discharge

 

改良中ですが、最新のプロジェクトです  LPC812_LIT_DISC.zip

 

Version:0.9 StartHTML:00000000 EndHTML:00000000 StartFragment:00000000 EndFragment:00000000 解凍してLPC812フォルダの中に保存する

 

概要

 

 

放電の基本回路

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

放電回路のテスト

 

 

電圧モニタ回路の考察

 

 

2.558 / 10000 = 0.0003

1.418 / 0.0003 = 4,726.6667

並列で 4.717KΩ

 

1/R = 1/R2 + 1/R3  ->  1/R3 = 1/R - 1/R2

 

1/4717 = 0.0002

1/10000=0.0001

 

0.0002 - 0.0001 = 0.0001

 1/0.0001 = 10,000.0

 

AD変換の内部抵抗は 10KΩかもしれない

 

 

 

根本的なミス

 

 

放電測定のプロジェクトを作成ます

 

 

 

モニタ用の初期コード

 

///////////////////////////////////////////////////////

//

//        LPC812 LIT_DISC

//                2025.11.05 水曜 goma0099  リチウム電池放電特性の測定

///////////////////////////////////////////////////////

 

#include "LPC8xx.h"            //ヘッダファイルの読み込み

#include "\LPC\LPC812\KYO\type.h"

#include "stdlib.h"        // atoi()

#include "string.h"        // memcpy()

 

//#include "gpio.h"

 

//        改造された共用関数を一箇所にまとめて最新がインクルードされるように

#include "\LPC\LPC812\KYO\lpc8xx_uart.h"

#include "\LPC\LPC812\KYO\lpc8xx_uart.c"

#include "\LPC\LPC812\KYO\lpc8xx_i2c.h"

#include "\LPC\LPC812\KYO\lpc8xx_i2c.c"

 

#include "\LPC\LPC812\KYO\lpc812_kyo.h"

#include "\LPC\lpc_kyo.h"

 

 

void SwitchMatrix_Init()

{

    /* Enable SWM clock */

    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);

 

    /* Pin Assign 8 bit Configuration */

    /* U0_TXD */

    /* U0_RXD */

    LPC_SWM->PINASSIGN0 = 0xffff0004UL;

    /* I2C0_SDA */

    LPC_SWM->PINASSIGN7 = 0x11ffffffUL;

    /* I2C0_SCL */

    LPC_SWM->PINASSIGN8 = 0xffffff0dUL;

 

    /* Pin Assign 1 bit Configuration */

    /* RESET */

    LPC_SWM->PINENABLE0 = 0xffffffbfUL;

}

 

//                インターバル割り込み関数を msec 待ち時間関数に活用しています

void SysTick_Handler(void)

{

if(--Goma_msec_wait_cnt == 0)

{        NVIC_DisableIRQ(SysTick_IRQn);                // 割り込み無効

}

}

 

// ばらつき対策のため平均値を計算します

int16_t av_get(int8_t prm_cs_pin,int8_t prm_ch,int8_t prm_av_max)

{

uint32_t i;

uint32_t ad_dat = 0;

uint32_t gokei = 0;

uint32_t av_max = prm_av_max;

 

if(av_max <= 0) av_max = 1;        // 補正

if(100 < av_max) av_max = 100;

 

for(i=0 ; i<av_max ; i++)

{

gokei += mcp3208_read(prm_cs_pin,(uint8_t)prm_ch);

wait_sec('m',10);

}

ad_dat = gokei / av_max;

 

return((uint16_t)ad_dat);

}

 

 

int main(void)

{

uint32_t cnt;

uint16_t ad_dat[2];

int8_t cs_pin;                // PIOの定義忘れがあり時間ロスしました

// 忘れ防止の為、明示的にします

 

    // スイッチ・マトリックス設定

    SwitchMatrix_Init();

 

    SPI_CLK_pin = 6;

    SPI_SOMI_pin = 7;

    SPI_MOSI_pin = 8;

    cs_pin = 9;

 

    //ポートの方向決定

    pin_set_output(SPI_CLK_pin);         // MCP3208 CLK

    pin_set_input(SPI_SOMI_pin);        // MCP3208 OUTPUT

    pin_set_output(SPI_MOSI_pin);         // MCP3208 INPUT

    pin_set_output(cs_pin);                 // MCP3208 CS        定義忘れがあり時間ロスしました

 

 

    //////////////////////////////////////

    //        周期割り込みの初期化

    //////////////////////////////////////

SystemCoreClockUpdate();

SysTick_Config( SYSTICK_DELAY );

LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);

 

    UARTInit(LPC_USART0,115200);   // UART初期化関数( bpsに設定)

 

    // i2c通信は未使用なので、初期化は省いています

 

//UART_puts("speed 115200 \r\n");

 

while(1)

    {

            wait_sec('m',2000);

 

for(cnt=0 ; cnt<2 ; cnt++)

{

// ばらつきを補正するため 10 回測定して平均します

ad_dat[cnt] = av_get(cs_pin,cnt,10);

}

 

// 放電対象の電池が未接続の場合はモニタしない

if(100 < ad_dat[0])

{

UART_puts("V=");

UART_putdec(ad_dat[0]);

UART_puts("  ");

UART_puts("A=");

UART_putdec(ad_dat[1]);

UART_puts("\r\n");

 

}

 

    }

}

 

解放電圧4.25 電池のモニタ結果

 

 

 

AD変換値から電圧、電流を計算します

 

4200*1000/3814=1101.2061

V = (AD *1101) /1000  mV

 

581*1000/1505=386.0465

A = (AD*386)/1000 mA

 

 

 

 

放電タイミングをマイコンから制御します

 

 

 

 

 

 

 

 

充電開始制御が完成したので、モニタから調整します

 

 

           実測        計算値 

電流    504mA    319 mA

電圧 3594 mV   3610 mV

 

下記の換算で、手持ちのB35テスターと適合しました

 

 

充電制御回路の為、放電テストの電池を外しても 1733 mV より下がりません

 

 

プロジェクトの最新コード

 

 

///////////////////////////////////////////////////////

//

//        LPC812 LIT_DISC

//                2025.11.05 水曜 goma0099  リチウム電池放電特性の測定

///////////////////////////////////////////////////////

 

#include "LPC8xx.h"            //ヘッダファイルの読み込み

#include "\LPC\LPC812\KYO\type.h"

#include "stdlib.h"        // atoi()

#include "string.h"        // memcpy()

 

//#include "gpio.h"

 

//        改造された共用関数を一箇所にまとめて最新がインクルードされるように

#include "\LPC\LPC812\KYO\lpc8xx_uart.h"

#include "\LPC\LPC812\KYO\lpc8xx_uart.c"

#include "\LPC\LPC812\KYO\lpc8xx_i2c.h"

#include "\LPC\LPC812\KYO\lpc8xx_i2c.c"

 

#include "\LPC\LPC812\KYO\lpc812_kyo.h"

#include "\LPC\lpc_kyo.h"

 

 

void SwitchMatrix_Init()

{

    /* Enable SWM clock */

    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);

 

    /* Pin Assign 8 bit Configuration */

    /* U0_TXD */

    /* U0_RXD */

    LPC_SWM->PINASSIGN0 = 0xffff0004UL;

    /* I2C0_SDA */

    LPC_SWM->PINASSIGN7 = 0x11ffffffUL;

    /* I2C0_SCL */

    LPC_SWM->PINASSIGN8 = 0xffffff0dUL;

 

    /* Pin Assign 1 bit Configuration */

    /* RESET */

    LPC_SWM->PINENABLE0 = 0xffffffbfUL;

}

 

//                インターバル割り込み関数を msec 待ち時間関数に活用しています

void SysTick_Handler(void)

{

if(--Goma_msec_wait_cnt == 0)

{        NVIC_DisableIRQ(SysTick_IRQn);                // 割り込み無効

}

}

 

// ばらつき対策のため平均値を計算します

int16_t av_get(int8_t prm_cs_pin,int8_t prm_ch,int8_t prm_av_max)

{

uint32_t i;

uint32_t ad_dat = 0;

uint32_t gokei = 0;

uint32_t av_max = prm_av_max;

 

if(av_max <= 0) av_max = 1;        // 補正

if(100 < av_max) av_max = 100;

 

for(i=0 ; i<av_max ; i++)

{

gokei += mcp3208_read(prm_cs_pin,(uint8_t)prm_ch);

wait_sec('m',5);

}

ad_dat = gokei / av_max;

 

return((uint16_t)ad_dat);

}

 

uint32_t mon_dsp(

uint32_t prm_volt_all,

uint32_t prm_amp_all,

uint32_t prm_volt_dat_all,

uint32_t prm_amp_dat_all

)

{

uint32_t volt;

uint32_t amp;

uint32_t volt_dat;

uint32_t amp_dat;

 

volt = prm_volt_all / 60;

amp = prm_amp_all / 60;

 

volt_dat = prm_volt_dat_all / 60;

amp_dat = prm_amp_dat_all / 60;

 

UART_puts("V=,");

UART_putdec(volt);

UART_puts(",mV   ,");

UART_putdec(volt_dat);

UART_puts(",A=,");

UART_putdec(amp);

UART_puts(",mA  ,");

UART_putdec(amp_dat);

UART_puts("\r\n");

 

return(volt);

}

 

 

int main(void)

{

uint16_t ad_dat[2];

uint8_t cs_pin;                // PIOの定義忘れがあり時間ロスしました

// 忘れ防止の為、明示的にします

uint8_t        sw_pin;

uint32_t i;

uint32_t volt;

uint32_t amp;

uint32_t min_cnt;

uint32_t volt_all;

uint32_t amp_all;

uint32_t volt_dat_all;

uint32_t amp_dat_all;

uint32_t volt_end;                // 放電終了判定

uint32_t volt_start;        // 放電開始基準

uint32_t volt_open;                // 解放電圧保持

uint32_t disc_cnt;                // 放電持続カウンター

uint8_t disc_mod;        // 0:放電前(解放電圧) 1:放電開始 2:放電終了

 

    // スイッチ・マトリックス設定

    SwitchMatrix_Init();

 

    SPI_CLK_pin = 6;

    SPI_SOMI_pin = 7;

    SPI_MOSI_pin = 8;

    cs_pin = 9;

    sw_pin = 10;

 

    //ポートの方向決定

    pin_set_output(SPI_CLK_pin);         // MCP3208 CLK

    pin_set_input(SPI_SOMI_pin);        // MCP3208 OUTPUT

    pin_set_output(SPI_MOSI_pin);         // MCP3208 INPUT

    pin_set_output(cs_pin);                 // MCP3208 CS        定義忘れがあり時間ロスしました

    pin_set_output(sw_pin);

 

    //////////////////////////////////////

    //        周期割り込みの初期化

    //////////////////////////////////////

SystemCoreClockUpdate();

SysTick_Config( SYSTICK_DELAY );

LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);

 

    UARTInit(LPC_USART0,115200);   // UART初期化関数( bpsに設定)

 

    // i2c通信は未使用なので、初期化は省いています

 

//UART_puts("speed 115200 \r\n");

 

pin_out(sw_pin,0,'m',0);        // 放電制御OFF

 

volt_end = 3000;                // 放電最終電圧

volt_start = 3800;                // 放電開始基準 解放電圧がこれ以上で放電開始します

 

    disc_mod = 0;

 

while(1)

    {

ad_dat[0] = av_get(cs_pin,0,3);                // 電圧

ad_dat[1] = av_get(cs_pin,1,3);                // 電流

 

// テスターの誤差にも適合させるため、テスターは固定する必要があります

// 32bit を出来るだけ有効にするため、係数は5桁を利用しています

// この定数は、この電子回路にだけ特化されます 新しい回路では別の調整が必要です

 

volt = (ad_dat[0]*109490)/100000;

amp = (ad_dat[1]*38250)/100000;

 

switch(disc_mod)

{

case 0:                // 放電前

            wait_sec('m',960);        // 通常周期

            //UART_putdec(volt);

            //UART_puts("\r\n");

 

if(volt_start <= volt)

{

UART_puts("Start Dischage \r\n");

volt_open = volt;        // 解放電圧記録

 

disc_cnt = 0;

 

min_cnt = 0;

    volt_all = amp_all = 0;

    volt_dat_all = amp_dat_all = 0;

 

disc_mod = 1;

            pin_out(sw_pin,1,'m',0);        // 放電制御ON

}

break;

case 1:                // 放電開始

            wait_sec('m',960);        // 通常周期

++min_cnt;

volt_all = volt_all + volt;

amp_all = amp_all + amp;

volt_dat_all = volt_dat_all + ad_dat[0];

amp_dat_all = amp_dat_all + ad_dat[0];

 

if(59 <= min_cnt)

{

++min_cnt;

++disc_cnt;

 

i = mon_dsp(volt_all,amp_all,volt_dat_all,amp_dat_all);                // 1分モニタ

 

if(i < volt_end)

{

UART_puts("Dischage min max =,");

            UART_putdec(disc_cnt);

            UART_puts("\r\n");

 

            disc_mod = 2;

            pin_out(sw_pin,0,'m',0);        // 放電制御OFF

}

 

 

    // 最初の1

    if(disc_cnt == 1)

    {

            i = volt_open - (volt_all / 60);

            UART_puts("Farst Drop Volt =");

            UART_putdec(i);

            UART_puts(" mV \r\n");

    }

 

min_cnt = 0;

    volt_all = amp_all = 0;

    volt_dat_all = amp_dat_all = 0;

}

 

break;

case 2:                // 放電終了

            wait_sec('m',960);        // 通常周期

 

            if(volt < 2000)

            {

                    // 電池が取り外されたと判断し、モードを初期化します

                    disc_mod = 0;

            }

break;

}

 

    }

}

 

実験途中のモニタ画面と考察

 

 

 

テストを継続する前に、通信モニタプログラムを改造します

 

goma0099.com/PDF/G3012a_pc_lpc_micon_uart_part_2.htm

 

 

 

 

 

 

 

 

 

 

管理番号 38 のリチウム電池

 

 

 

 

管理番号 26 番のリチウム電池

 

 

 

スイッチング 素子 K4017 の電圧降下を改善する

 

 

管理番号 13

 

 

 

 

 

マイコンのモニタ書式の変更