TA的每日心情 | 无聊 2014-6-15 08:04 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
我在之前的一片帖子中,折腾过磷酸铁锂的均衡器(被动式充电末端均衡):
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_t chk= 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 隔离采样的可行性。
最后祝大家身体健康,折腾愉快!
|
|