t3486784401 发表于 2020-3-24 20:10

【原创】做个隔离ADC采集器监视铁锂充电

我在之前的一片帖子中,折腾过磷酸铁锂的均衡器(被动式充电末端均衡):
http://www.shoudian.org/forum.php?mod=viewthread&tid=1506689

但是充电过程究竟怎样心里还是没底。索性用 Arduino 做一套电压采样器,这样就可以知道充电曲线了。
由于充电电源、监视电脑之间可能存在 GND 电位差异,这干脆做成隔离式采集,共模电压随便搞。
实际可采集差模电压范围就是78M05工作范围:7~40V,带反接保护。

整个隔离 ADC 采集器做成 Arduino 扩展板的形态,直接用 Proteus 画的 PCB,原理图都懒得搞:


JLC 五块打样,选个红色代表高功率警示:


焊接过程从低到高,使用 ATTINY13 作ADC+主控,两片 817 光耦用作数据链路隔离:




最后灌入 T13 的程序,就可以配合 UNO 基板工作了:



至此获得了一块隔离ADC采集器,直接挂在 6S 充电回路上(装有之前设计的均衡器):


最后终于获得了 1P6S 磷酸铁锂的充电曲线(我的均衡器设定 3.5V 截止),
电池充满前电压-时间曲线出现了若干阶梯台,说明末端均衡器逐个通道开启,工作正常。


-----------------------------------------------------------------------------------------------------------

最后附上核心的通信代码(光耦隔离通信),是 URX/UTX 两根线的同步通信。

ATTINY13端(Slave):
void OptSlaveSend(WORD dat)
{
    // 执行隔离通信从机发送: MSB, ..., LSB, P, N (, H, H,...)
    BYTE i, chk=0x2;      // chk.b1/b0= N/P
    OPTO_URX(CLR);
    OPTO_URX(DRO);
   
    // 依次发送数据
    for(i=0; i<16; i++)
    {
      if(!OptWaitClock())
      {
            OPTO_URX(SET);
            return;
      }
      if(dat&BIT(15))
      {
            OPTO_URX(SET);
            chk= ~chk;      // EOR Operate
      }
      else
      {
            OPTO_URX(CLR);
            NOP();          // to balance EOR
      }
      dat<<= 1;
    }
   
    // 发送校验位
    for(i=0; i<2; i++)
    {
      if(!OptWaitClock())
      {
            OPTO_URX(SET);
            return;
      }
      if(chk&BIT(0))
      {
            OPTO_URX(SET);
      }
      else
      {
            OPTO_URX(CLR);
      }
      chk>>=1;
    }
   
    // 等待最终超时复位
    while(OptWaitClock())
    {
      OPTO_URX(SET);      // 多余数据为补H
    }
    OPTO_URX(SET);
}

UNO端(Master):
uint16_t OptoSample(bool *pOK= NULL)
{
    // Query OptoADC Shield, Read 16bit Data
    // pOK: Receive Checksum if not NULL
    uint16_t dat= 0;
    uint8_tchk= 0x2, tmp= 0;
    // #1: Query & Wait
    PULSE_UTX();                        // Query
    uint32_t tov= millis()+1000;      // Overflow Time
    while(digitalRead(URX))
    {
      if(millis()>=tov)
      {
            // Time overflow: Error
            if(pOK) *pOK= 0;
            return 0;
      }
    }
    delay(3);                           // to fit Low-Speed T13
    // #2: Read Data & Checksum
    for(uint8_t i=0; i<16; i++)
    {
      PULSE_UTX();                  // Clock
      dat<<= 1;
      if(digitalRead(URX))
      {
            dat|= 0x1;
            chk^= 0x3;                  // P,N: Toggle
      }
    }
    PULSE_UTX();
    tmp|= digitalRead(URX)? 0x1:0x0;    // Chk-P
    PULSE_UTX();
    tmp|= digitalRead(URX)? 0x2:0x0;    // Chk-N
    // #3: Do Checksum if necessary
    if(pOK)
    {
      *pOK= chk==tmp? 1:0;
    }
    return dat;
}

PC上位机我就不贴了,接收个串口存数据(比助手多个电压换算+显示)。

-----------------------------------------------------------------------------------------------------------

所谓生命在于折腾,本来这事用我的带 USB 万用表也行,做个扩展板验证下 T13 隔离采样的可行性。

最后祝大家身体健康,折腾愉快!


L555T_007 发表于 2020-3-24 20:16

还以为是6节都独立测量呢

t3486784401 发表于 2020-3-24 20:23

L555T_007 发表于 2020-3-24 20:16
还以为是6节都独立测量呢

78M05 拆掉,板子多焊几块堆叠起来就可以独立测量了。

板子设计时就是堆叠结构,单个UNO底座可以插N层,不过软件得更复杂些,要加入通道寻址。

王有才才 发表于 2020-3-24 20:43

厉害厉害厉害厉害

星星海 发表于 2020-3-24 22:18

佩服大佬超强的技艺~

海盗杰克 发表于 2020-3-25 09:09

顶技术贴!

wang737 发表于 2020-3-25 10:11

给你看下这个老外也在开发的你可以参考国外正在众筹的,每节的温度电流容量都能实时显示在软件上


t3486784401 发表于 2020-3-25 10:23

wang737 发表于 2020-3-25 10:11
给你看下这个老外也在开发的你可以参考国外正在众筹的,每节的温度电流容量都能实时显示在软件上




目测也是每路一套隔离 ADC,有好方案推荐不?

modelmy 发表于 2020-3-25 12:06

BQ7693003DBTR不香吗

t3486784401 发表于 2020-3-26 12:42

modelmy 发表于 2020-3-25 12:06
BQ7693003DBTR不香吗

香,产品必备
页: [1]
查看完整版本: 【原创】做个隔离ADC采集器监视铁锂充电