Noduino OpenPlant
(→Notes) |
(→Notes) |
||
第352行: | 第352行: | ||
* 移除 iBee AP2112 (dev pwr switch): deep sleep current 370uA | * 移除 iBee AP2112 (dev pwr switch): deep sleep current 370uA | ||
* 移除另一个 iBee AP2112 (Vbat LDO): deep sleep current 40uA | * 移除另一个 iBee AP2112 (Vbat LDO): deep sleep current 40uA | ||
+ | |||
* 增加两个 AP2112 (Vbat LDO 和 dev pwr switch): deep sleep current 79uA | * 增加两个 AP2112 (Vbat LDO 和 dev pwr switch): deep sleep current 79uA |
2019年5月27日 (一) 14:48的版本
目录 |
1 Overview
2019-05-13:
2 太阳能补电
2.1 太阳能电池的 I-V特性
太阳能电池一般由 PN 结组成,PN 结中的光能 (光子) 通过导致电子和空穴的重新组合而产生电流。由于 PN 结的特性类似于二极管的特性,我们一般以下图中所示的电路作为太阳能电池特性的一个简化模型:
电流源 Iph 产生的电流和太阳能电池上的光量度成正比。在没有负载连接的时候,几乎所有产生的电流都流过二极管 D,其正向电压决定着太阳能电池的开路电压 (Voc)。该电压会因各种类型太阳能电池的特性不同而有所差异。但是,对于大多数硅电池而言,这一电压都在 0.5V 到 0.6V 之间,这也是 PN 结二极管的正常正向电压。
在实际太阳能电池应用中,并联电阻 Rp 的泄漏电流很小,而 Rs 则会产生连接损耗。下图展示了太阳能电池在输出上的特性。由于串联电阻 Rs 的原因,电压会稍有下降。然而,有时如果通过内部二极管的电流太小,会导致偏置不够,并且穿过它的电压会随着负载电流的增加而急剧下降。最后,如果所有电流都只流过负载而不流过二极管,输出电压就会变为零。这个电流被称为太阳能电池的短路电流 Isc。Isc 和 Voc 都是定义太阳能工作性能的主要参数之一。
太阳能电池可认为是“电流限制”型电源,输出电压会随着输出电流的增加而降低,并在负载电流达到短路电流时降为零。 其极端情况为:
- 当输出电压为其最大数值 (Voc) 时,输出电流为零
- 当输出电流达到最大值 (Isc),但输出电压为零
曲线关系为:
则输出功率也是动态变化的,其极值为最大功率点 (MPP)。
实验记录出输出曲线,就能求得最大矩形面积的点 MPP,一般都会在输出特性曲线的下半部分的某个位置,其确切位置会因入射光线和环境温度的不同而不同
太阳能电池的输出电流随光照强度的变化而变化,上下电流波动较大,一般不能直接给用电系统供电,需将能量先存储于电池中,然后通过电池为系统供电。
2.2 电池板
- 多晶太阳能电池板 4V/30mA,65mm x 28mm x 3mm
- 多晶太阳能电池板 5.5V/60mA,60mm x 60mm x 3mm
2.3 CN3083
芯片内部集成有 8 模数转换器,能够根据输入电压源的电流输出能力自动调节充电电流,用户不需要考虑最坏情况。当输入电压过低时,锁存,自动再充电;当输入电压掉电时,CN3083自动进入低功耗的睡眠模式,此时电池的电流消耗小于 3 uA
充电电流通过一个外部电阻设置。
内部固定的恒压充电电压为 4.2V,也可以通过一个外部电阻往高处调节。
热调制电路可以在器件的功耗比较大或者环境温度比较高的时候将芯片温度控制在安全范围内。
其它功能包括电池温度监控以及充电状态/充电结束状态指示等
2.3.1 预充电状态
在充电周期的开始,如果电池电压 Kelvin 检测输入端 (FB) 的电压低于3V,充电器处于预充电状态,充电器以恒流充电模式充电电流的 10% 对电池进行充电。
2.3.2 输入电压源限流模式
当 CN3083 输入电压源的电流输出能力(带负载能力)小于第 2 管脚的电阻 RISET 所设置的充电电流时,器件内部的 8 位 ADC 根据输入电压源的电流输出能力自动控制充电电流,此时实际充电电流可能小于所设置的充电电流,但是在保证 CN3083 第 4 管脚 VIN 的电压不低于最小工作电压的前提下,能够使得充电电流最大化
即当输出电流小于设置电流时,判断为光照不足,自动调节输出电流,优先保证电池板的输出电压。在这种模式下用户只要根据输入电压源的最大电流输出能力设置充电电流即可
2.3.3 电池电压Kelvin检测
CN3083 有一个电池电压 Kelvin检测输入端 (FB),此管脚通过芯片内部的精密电阻分压网络连接到恒压充电的误差放大器。
FB 管脚可以直接连接到电池的正极,这样可有效避免电池正极和 CN3083 的第 5 管脚 BAT 之间的寄生电阻(包括导线电阻,接触电阻等)对充电的影响。这些寄生电阻的存在会使充电器过早的进入恒压充电状态,延长充电时间,甚至使电池充不满,通过使用电池电压 Kelvin 检测可以解决这些问题。
如果将 CN3083 的电池电压 Kelvin 检测输入端 (FB) 悬空,那么CN3083一直处于预充电状态,充电电流为所设置的恒流充电电流的 1/10
2.3.4 充电结束
在恒压充电状态,当施加在 CN3083 的第 4 管脚 VIN 的电压大于 4.45V,并且当充电电流小于所设置的恒流充电电流的 1/10 时,充电周期结束。
在输入电压源限流模式,即使充电电流小于所设置的恒流充电电流的 1/10,充电也将继续,不会结束。这样可以保证即使在输入电压源的电流输出能力很微弱的情况下,也能为电池充电。
2.3.5 参考电路
2.3.6 Datasheet
2.3.7 其他选择
2.4 CN3082
CN3083 + 恒流后的维持电流模式 + 外部电阻设置维持电流
当 FB 管脚的电压上升到 2.445V 时,充电器结束恒流充电状态,进入维持充电状态,此时电池端对应的的恒流充电终止电压为:
VBAT=2.445×(1+R3/R4)
此模式用于支持更多类型电池充电,比如:镍氢电池,磷酸铁锂电池和铅酸电池
3 TODO
-
ADC 获取电池电压(小改硬件电路),电池电压数据上传 -
太阳能充电支持 -
动态开启/关闭 MQTT20181101, http post 返回 {"mqtt":"disable"} - 低功耗优化
- 电池电压过低 (<3V) 时候,以小时为单位延长 deep sleep 时间,给太阳能补电争取时间
4 电池电压监控
VBAT ------ 1M 1% ------ 200K 1% ------ GND | | ADC
int ad = system_adc_read(); float V = (ad / 1024.0) * (1000.0 + 200)/200;
电流消耗:3.7 / (220+100) = 0.0112 mA = 11.2 uA
如果换成: 200K + 1M,则电流消耗会降到 3 uA 左右
char *get_vbat(float *fv) { int uv = mcp342x_get_uv(); float vbat = uv * (99.985 + 219.35) / 99.985 / 1000000.0; dtostrf(vbat, 6, 2, g_vbat); if(fv != NULL) *fv = vbat; unsigned char *p = g_vbat; while(isspace(*p)) p++; return p; }
5 低功耗优化
5.1 Base
-
Transfer to use raw sdkdone -
Disable Pingdone -
Change the mode of mcp342x to One-Shot Conversion with 1 SPSdone
5.2 phy_get_vdd33()
Remove the mcp342x, use the internal phy_get_vdd33()
system_get_vdd33 功能:
测量 VDD3P3 管脚 3 和 4 的电压值,单位:1/1024 V
- system_get_vdd33 必须在 TOUT 管脚悬空的情况下使⽤,否则值不准
- TOUT 管脚悬空的情况下,esp_init_data_default.bin(0~127byte)中的第 107 byte 为 "vdd33_const",必须设为 0xFF,即 255,否则总是返回 65535
5.3 Deep Sleep
http://wiki.jackslab.org/ESP8266_Sleep#Deep_Sleep
#define __SET__DEEP_SLEEP__WAKEUP_NO_RF__ system_deep_sleep_set_option(4) #define __SET__DEEP_SLEEP__WAKEUP_NORMAL__ system_deep_sleep_set_option(1) system_deep_sleep(100000); During deep sleep, only RTC still working, so you can save some user data in RTC memory. Only "user data" area can be used by user #define RTC_RAM_BASE 0x60001000 // Size: 1024 bytes #define RTC_MEM_BASE 0x60001100 0x60001000 0x100 rtcb RTC backup memory, see rtc_mem_backup 0x60001100 0x300 rtcmem RTC semi-persistent memory, see system_rtc_mem_write |-------- system data --------|-------- user data --------| | 256 bytes | 512 bytes | | 256/4 = 64 block | 128 block | rtc time use the first 24 bytes of user data area void system_deep_sleep_instant(uint32 time_in_us);
Notice: Seems like the system timer of WiFi is working when chip is in deep sleep, so you need to disable the all timers ...
5.4 Example
#define SENSOR_DATA_NUM 20 #define SENSOR_DATA_MEM_ADDR 120 #define INIT_MAGIC 0x7e7e55aa typedef struct{ uint32 init_flg; uint16 cnt; uint16 wifi_config; uint16 data[SENSOR_DATA_NUM]; }SENSOR_DATA_RTC_MEM; SENSOR_DATA_RTC_MEM sensor_data; void ICACHE_FLASH_ATTR data_func() { // Read out the sensor data structure from RTC memory system_rtc_mem_read( SENSOR_DATA_MEM_ADDR, &sensor_data, sizeof(SENSOR_DATA_RTC_MEM) ); // When the system powers on for the first time, the data in the rtc memory is random. struct esp_platform_saved_param esp_param_t; user_esp_platform_load_param(&esp_param_t); // Stored in flash // Load user params to check if the device was successfully registered to the server // If it wasn't, it usually returns 255 (from the flash.) if(sensor_data.init_flg!=INIT_MAGIC || sensor_data.cnt>SENSOR_DATA_NUM ) { // This case runs when we first power on or when it time to flush the RTC memory of old data. if(esp_param_t.activeflag!=1) { // If registered & activated user_esp_platform_init(); // Router is not configured. Setup softAP. Wait for config. user_webserver_init(SERVER_PORT); } else { // was connected! So we set init magic to exit the setup loop sensor_data.init_flg = INIT_MAGIC; sensor_data.cnt = 0; system_rtc_mem_write(SENSOR_DATA_MEM_ADDR, &sensor_data, sizeof(SENSOR_DATA_RTC_MEM)); __SET__DEEP_SLEEP__WAKEUP_NO_RF__; system_deep_sleep(100000); } } else { // This is where the measurements are made uint16 vdd_val = 0; if(sensor_data.cnt<0 || sensor_data.cnt>=SENSOR_DATA_NUM) sensor_data.cnt=0; // range check and resets counter if needed /* Reads power supply voltage, byte 107 of init_data.bin should be set to 0xFF. * Replace with your own code.*/ sensor_data.data[sensor_data.cnt++] = (uint16)(phy_get_vdd33()); system_rtc_mem_write( SENSOR_DATA_MEM_ADDR, &sensor_data, sizeof(SENSOR_DATA_RTC_MEM) ); // Setup next sleep cycle if(sensor_data.cnt==SENSOR_DATA_NUM-1) { __SET__DEEP_SLEEP__WAKEUP_NORMAL__; } else { __SET__DEEP_SLEEP__WAKEUP_NO_RF__; } // Uploads or go to sleep if(sensor_data.cnt == SENSOR_DATA_NUM) { user_esp_platform_init(); } else { system_deep_sleep(SENSOR_DEEP_SLEEP_TIME); } } }
5.5 TX Power
函数: void system_phy_set_max_tpw(uint8 max_tpw) 功能: 设置 RF TX Power 最大值,单位:0.25dBm 参数: uint8 max_tpw : RF Tx Power 的最大值,可参考 esp_init_data_default.bin(0 ~ 127byte)的第 34 byte (target_power_qdb_0) 设置,单位:0.25dBm,参数范围 [0, 82]
函数: void system_phy_set_tpw_via_vdd33(uint16 vdd33) 功能: 根据改变的 VDD33 电压值,重新调整 RF TX Power,单位:1/1024 V 注意: 在 TOUT 管脚悬空的情况下,VDD33 电压值可通过 system_get_vdd33 测量获得。 在 TOUT 管脚接外部电路情况下,不可使用 system_get_vdd33 测量 VDD33 电压值。 参数: uint16 vdd33 : 重新测量的 VDD33 值,单位:1/1024V,有效值范围:[1900, 3300]
6 Notes
Fluke 18B 毫安档:
- 冷启动最高 85mA,75 ~ 60mA 常见,持续时间平均 8s 左右,这个时间有点长。。。
- deep sleep 电流 1.7mA,移除 TL431 后,电流降为 65uA
- boot_v1.5.bin: 从 deep sleep 醒来,有时 50/18, 40/17, 33/18, 30/18, 25/18, 21/18 mA,常见 18/18, 18/17 mA,持续 2s 左右
- 周期 push 点:72/69/79/63/43 mA
- boot_v1.5_low_power.bin: 从 deep sleep 醒来,有时 25/18, 23/18, 18/15, 18/16, 12/18, 18/10 mA, 常见 18/18 mA,持续 2s 左右
- 周期 push 点:71/69/74/68/40 mA, 71/98/69/72 mA
2019/05/24:
Fluke 18B 微安档,实测睡眠电流 65uA 左右。。。
2019/05/27 OpenTemp:
- iBee AP2112 as device power switch: deep sleep current 390uA
- 移除 iBee AP2112 (dev pwr switch): deep sleep current 370uA
- 移除另一个 iBee AP2112 (Vbat LDO): deep sleep current 40uA
- 增加两个 AP2112 (Vbat LDO 和 dev pwr switch): deep sleep current 79uA
6.1 NO RF
- 硬件:Falcon v2.4 开发板,ESP-12F
- 固件:examples/noduino/hello
void setup() { serial_begin(115200); wifi_set_opmode(NULL_MODE); } void loop() { serial_printf("Hello World!\r\n"); delay(1500); }
- 90 mA 左右
- 用 disable-rf 脚步处理后,依然是 90mA 左右,这个影响的应该是深睡眠唤醒后的功耗
7 Reference
- http://www.gongkong.com/advanced/ShowPaper.aspx?id=2010042110265100006
- ESP8266 Sleep
- WiFi 低功耗传感器示例: https://github.com/EspressifSystems/low_power_voltage_measurement
- https://github.com/EspressifSystems/low_power_voltage_measurement/wiki
- 红外载波信号PWM生成 https://bbs.espressif.com/viewtopic.php?t=2127