亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

9V NiMH 充电电池智能充电器 V1

组件和用品

Arduino UNO
× 1
SparkFun I2C DAC 突破 - MCP4725
× 1
输出可调的线性稳压器
× 1
德州仪器通用双运放
× 1
电阻 6.8k ohm
× 2
电阻 3.3k ohm
× 1
电阻 5.1k ohm
× 1
电阻 1k ohm
× 1
电阻 10 ohm
× 1
中继(通用)
× 1
电阻 20k ohm
× 1
SparkFun 面包板电源 5V/3.3V
× 1
电源 17V
× 1
YwRobot I2C 串行 LCD 1602 模块
× 1

关于这个项目

我寻找智能充电器聊天可以在几个小时内为 9V 镍氢电池充电,但没有找到。此外,我发现的所有充电器都非常“愚蠢”。充电电流未知,电池充满后无终止充电功能。此类充电器的问题是它们会使电池过度充电并显着缩短使用寿命。所以我决定创造“智能”充电器。

第一个版本我打算保持简单,因此它允许进行基本的操作,例如恒流充电、电池充满电后自动终止充电、涓流充电、测量转移到电池的电量。

在下一个版本中,我将添加一些额外的有用功能,例如放电、容量测量和循环。

警告:用大电流给电池充电可能会导致电池爆炸或起火。请不要让充电器无人看管。此外,请不要尝试为不打算作为碱性电池充电的电池充电。该充电器仅使用镍氢电池进行了测试(并且您仍然需要自行承担风险使用它,如果由于设计或代码中的错误造成的任何损坏,我绝对不承担任何责任)。其他类型电池的懊恼需要修改代码。

理论

需要记住的一些有用事实将有助于了解充电器所需的参数。

C——电流等于电池标称容量

以C倍率充电时单体电池电压可能达到1.6V。对于旧电池,此电压可能更高。

单体电池标称电压为1.2V,但充满电的电池开路电压高达1.5V。

电池充满电后,建议涓流充电率小于0.025 C (C/40)。

给镍氢电池充电一般有两种选择:

1.快速充电。充电电流0.5C-1C。充电状态必须通过 dV/dt(电压变化率)或 dT/dt(温度变化率)监测和终止

2.充电慢。充电电流0.1C。充电时间14-16小时。通过定时器终止充电。 dT/dt 充电终止不可能用于低电流。根据文献,dV/dt 终止对于低于 0.5C 的电流可能不可靠。

充电电路基本参数

9V 电池通常有 7 节串联电池,但在某些情况下可能有 6 节或 8 节电池。稳压器应该能够提供至少高达 8*1.6=12.8V 的充电电压。 LM317稳压器的压降高达2V,因此电源电压需要~15V(这不考虑电流感应电阻上的压降)。

对于 200mA 的最大充电电流和 10 欧姆的电流感应电阻器,电流感应电阻器上的附加压降为 2V,因此需要 17V 的电源电压。

完全放电的电池可能具有非常低的甚至负电压。理想情况下稳压器的最低电压应为0,但使用LM317可能低至1.2V。

电路

电路说明

基本思想是测量充电电流并调整稳压器的电压,直到达到所需的电流。通过测量电流感测电阻器 R5 上的电压降来测量电流。 I=V/R。

SparkFun I2C DAC Breakout - MCP4725 - 用于控制电压的 12 位数模转换器。输出电压可以通过 I2C 配置在 0 到 5V 之间。因为我们需要能够在更宽的范围内调节电压,所以使用0到15V的运算放大器LM358来放大DAC的输出电压。由电阻 R4 和 R3 设置的运算放大器的放大。 Gain=1+R4/R3=1+6800/3300=3.06 所以运算放大器的输出电压大约为0到15V。

LM358 的最大输出电流为 50mA,因此 LM317 使用可调稳压器来控制更高的电流。运放输出接LM317的ADJ端。 LM317 将在 ADJ 和 OUT 端子之间保持 1.2V,因此电池上的实际电压可以配置在 1.2 和 16.2V 之间。 LM317 需要最小 3.5mA 电流来维持调节。因此,如果电池未连接,则使用 1kOhm 电阻器 R6 来确保调节。电容C1用于过滤输出电压,提高LM317的稳定性。

在两个不同点测得的电压。

1. 电阻 R5 连接到 Arduino 的引脚 A2。测量电阻上的电压,然后按 Icharge=V/R 计算充电电流

2. 电池电压最高可达16.2V,因此使用电阻分压器R1、R2将电压降至5V以下,Arduino允许。连接到 Arduino 引脚 A0 的分频器输出。对于 R1=5.1k Ohm 和 R2=20kOhm Vout=Vin/(20000+5100)*5100=0.2 所以电池电压除以 5。

继电器用于断开电池与充电电路的连接。您可以在我使用的照片继电器上看到,但通常可以使用任何具有 5V 控制的继电器。将电池连接到继电器的常开触点更安全。

我使用 YwRobot I2C SERIAL LCD 1602 MODULE 来显示充电器的状态,但可以使用任何其他 I2C 控制的 LCD 模块。似乎标准 LiquidCrystal_I2C 库不支持 YwRobot LCD 模块,所以我使用了新的 LiquidCrystal 库如果您使用不同的 LCD 模块,则需要更改此行:

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // 将 LCD 地址设置为 0x27 以实现 16 个字符和 2 行显示 

为数模转换器和 LCD 供电,我使用了 SparkFun 面包板电源 5V/3.3V。使用 Arduino 板的 5V 可能就可以了。

您还需要为充电电路提供 17V 电压。如果你没有电源,你可以使用这样的可调 DC/DC 转换器

http://www.ebay.com/itm/DC-DC-Adjustable-Step-up-boost-Power-Converter-Module-XL6009-Replace-LM2577-/310717070508

功能

我不想要很多电线,所以没有用于配置充电的按钮。懊恼电流仅在代码中配置。您需要在charger.ino 中设置所需的充电电流

//**************************** 充电参数************ ****************************//******************** ****************************************************** *******************浮动target_current_mA=30; //充电电流mAfloat Battery_nominal_capacity_mA=170; //标称电池容量mAfloat max_time_for_trickle_charge=6; //以分钟为单位的最大涓流充电时间//**************************************** ****************************************************/ /***************************************************** ******************************************** 

target_current_mA - 恒定充电电流

max_time_for_trickle_charge - 涓流充电的最大分钟数,可设置为600(10h)

Battery_nominal_capacity_mA - 用于计算涓流电流的电池容量

一般充电电流可达标称容量。对于标称容量为 170mAh 的电池,最大充电电流为 170mA。 170mAh电池的最小充电电流通常为C/10 - 17mA。

通电后充电器会检查电池是否连接。如果连接了电池,电池将以配置的恒定电流充电,直到充满电。通过在 5 分钟内检测到负 dV/dt 来终止充电。充电完成后,充电器将切换到电流 C/40 的涓流充电。最大涓流充电时间过后,充电器将自动断开与电池的连接。

1 - dV/dt

2 - 以分钟为单位的充电时间

1 - 充电时间

2 - 电荷转移到电池

关于镍氢电池的其他信息:

1. http://data.energizer.com/PDFs/nickelmetalhydride_appman.pdf

2. http://batteryuniversity.com/learn/article/charging_nickel_metal_hydride

代码

  • charger.ino
  • main.ino
  • hw.ino
  • lcd.ino
  • calculations.ino
  • 用于此项目的新 LiquidCrystal 库
charger.inoArduino
主文件
//用于为 9V NiMH 电池充电 //电池可以有 6,7 或 8 个 1.25V 电池//这使得标称电压在 7.5 和 10V 之间#include #include #include  #include #include LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // 将 LCD 地址设置为 0x27,用于 16 字符和 2 行显示//硬件定义#define MCP4725_ADDR 0x60 //DAC 地址#define DAC_REF_VOLTAGE 5.0#define CHARGE_RELAY_PIN 2#define DISCONNECT_CHARGE_RELAY_PIN 2#define DISCONNECT_CHARGE_RELAY_RELAY HIGHCHARGE_PIN_define CONNECT HIGHCHARGE_PINSERING_PIN_define CONNECT CURRENT_SENSING_SESISTOR 10.2 //OHm#define BATTERY_VOLTAGE_PIN A0#define R1 5090 //电压检测分压器的低边电阻#define R2 19910//电压检测分压器的高边电阻#define ADC_REF_VOLTAGE 4.89 //Arduino 实际电源电压或AREF电压ADC 到电压转换#define R3 3300.0#define R4 6800.0#define AMP_GAIN (1+R4/R3)//各种定义//#define MINIMUM_VOLTAGE 8.1 //调节后的最小电压#define BATTERY_GOOD_VOLTAGE_THRESHOLD 7.0#define AL EDim 0 MAX EDim 0 MAX EDim 0 MAX 0 IM 0电池电流mA(硬截止)#define MAXIMUM_BATTERY_VOLTAGE 15.0 //最大允许电池电压V(硬截止)#define VOLTAGE_STEP 0.001 //电压步进规则#define POINTS_FOR_AVERAGING 100 //平均需要多少点#define MEASURE2MEASURE_US 5000 //测量之间的时间以微秒为单位(由于两次模拟读取需要超过200)#define VOLTAGE_LOG_TIME_MIN 30.0 //以分钟为单位的电压保存时间/dT cutoff#define MINUTES_TO_LOG 5#define TRICKLE_CURRENT_RATIO 40//充电器状态#define INITIALIZATION 0#define NO_BATTERY 5#define BATTERY_CONNECTED 10#define BATTERY_VOLTAGE_LOW 15#define CURRENT_RAMP_30GdefineP CONNECTED CURRENT_RAMP_30GdefineP 3G END CURRENT_RAMP_UP3G定义20000000000000000000C 37#限定UNEXPECTED_CURRENT_FALL 40#限定UNABLE_TO_REACH_CURRENT 60#定义FULLY_CHARGED 70#限定CURRENT_TOO_HIGH 80#限定REGULATION_FAILED 90#定义过流100#限定过电压101#限定FINAL_STATE 200个///无符号整型voltage_readings [POINTS_FOR_AVERAGING],current_sensing_resistor_readings [POINTS_FOR_AVERAGING],averaging_index; //for averaginglong unsigned int voltage_sum,current_sum;//求平均值f的总和loatregulator_voltage_code,resistor_voltage,csr_voltage_code,regulator_voltage,current_mA,battery_voltage;//Measurmentsfloat tmp_resistor_voltage,tmp_current_mA,tmp_regulator_voltage,tmp_battery_voltage;int i,j,charger_state;short log unsigned int_last_string_second,String_Lcd=”;String msg,eoc_line1,eoc_line2;unsigned char sec_index,min_index;//long long int Charge_started;float sec_l​​og[60],min_log[MINUTES_TO_LOG],last_blf;float trickle_current_mA;int total_minutes_average=0;elapsedMillis,TrickleVoltageChargingTimeMillisfloat WantedMillis 0;float last_dac_voltage=0;//Messagesconst char msg_battery_detected[] PROGMEM ="检测到电池";const char msg_no_battery[] PROGMEM ="无电池";const char msg_battery_ok[] PROGMEM ="电池正常";const char msg_low voltage]_to PROGMEM ="电池电压过低";const char msg_voltage_too_low_short[] PROGMEM ="V Battery low";const char msg_ramp_up[] PROGM EM ="Ramp up";const char msg_charging[] PROGMEM ="Charging";const char msg_space[] PROGMEM =" ";const char msg_ramp_down[] PROGMEM ="Ramp down";const char msg_trickle_charge[] PROGMEM ="涓流充电";const char msg_no_current[] PROGMEM ="无电流";const char msg_current_unreachable[] PROGMEM ="我无法访问";const char msg_current_unreachable_long[] PROGMEM ="无法达到所需的电流";const char msg_completed[] PROGMEM ="已完成";const char msg_charge[] PROGMEM ="充电";const char msg_high_current[] PROGMEM ="高电流";const char msg_regulation_fault[] PROGMEM ="调节故障";const char msg_overcurrent[] PROGMEM ="电流过高"; const char msg_overvoltage[] PROGMEM ="电压太高";const char msg_trickle_completed[] PROGMEM ="涓流完成";//*********************** **** 充电参数 ************************************************/* ****************************************************** ******************************************浮动 target_current_mA=30; //充电电流mAfloat Battery_nominal_capacity_mA=170; //标称电池容量mAfloat max_time_for_trickle_charge=6; //以分钟为单位的最大涓流充电时间//**************************************** ****************************************************/ /***************************************************** ********************************************struct mytime { unsigned char hours;无符号字符分钟; unsigned int total_minutes;} elapsed_time;void setup() { pinMode(CHARGE_RELAY_PIN, OUTPUT);断开充电电路(); //断开充电器与电池的连接 Wire.begin();//I2C dac_write_voltage(0);//确保设置较低的电流 Serial.begin(115200); last_second=second(); lcd_last_second=second(); log_last_second=second(); Timer1.initialize(MEASURE2MEASURE_US); //将用于测量电池的电压和电流(微秒) Timer1.attachInterrupt(read_hw); // 附加 read_hw() 作为定时器溢出中断 averaging_index=0; sec_index=0; min_index=0; Charger_state=0;//状态机初始状态 want_dac_voltage=0;//使舒尔输出最小电压 last_blf=1.0;涓流电流_mA=battery_nominal_capacity_mA/TRICKLE_CURRENT_RATIO; //充电时间Millis=0; //LCD lcd.begin(16,2);液晶背光();液晶显示器(); update_lcd(F("加电..."),empty_string); delay(1000);}float log_battery_voltage(){ //每秒只记录一次 if (log_last_second==second()) return last_blf;否则 log_last_second=second(); sec_l​​og[sec_index]=battery_电压;如果(sec_index<59){sec_index++; } else {//如果记录了一分钟 //计算每分钟平均数 if (min_index>=MINUTES_TO_LOG) min_index=0; sec_index=0;浮动 sum_v=0; for (i=0;i<60;i++){ sum_v+=sec_l​​og[i]; } float min_average=sum_v/60.0; for(i=1;i 
main.inoArduino
void loop() { String msg1; switch(charger_state){ case INITIALIZATION://Initial state disconnect_charging_circuit();//使舒尔继电器断开dac_write_voltage(0);//确保设置尽可能低的电流wanted_dac_voltage=0;//使舒尔最小电压输出延迟(100);读取状态(); if (battery_voltage>0.1) { Charger_state=BATTERY_CONNECTED;//电池检测到update_lcd(M2S(msg_battery_detected),empty_string); Serial.println(M2S(msg_battery_detected));延迟(2000); } else {//无电池Serial.println(M2S(msg_no_battery)); update_lcd(M2S(msg_no_battery),construct_status_string()); Charger_state=NO_BATTERY;//电池检测延迟(1000); } 休息; case NO_BATTERY://无电池 read_status(); if (battery_voltage>0.1) { Charger_state=BATTERY_CONNECTED;//电池检测到Serial.println(M2S(msg_battery_detected)); update_lcd(M2S(msg_battery_detected),construct_status_string());延迟(1500); } else{ //如果没有电池保持此状态 update_lcd(M2S(msg_no_battery),construct_status_string());延迟(1100); } 休息; case BATTERY_CONNECTED://Battery connected dac_write_voltage(0);//确保设置较低的可能电流wanted_dac_voltage=0;延迟(100);读取状态(); if (battery_voltage>BATTERY_GOOD_VOLTAGE_THRESHOLD){ Charger_state=CURRENT_RAMP_UP;//开始充电电流上升 //snprintf(welcome, sizeof(welcome),"Firmware:V%d.%d%d",ver,ver2,ver3); update_lcd(M2S(msg_battery_ok),construct_status_string()); Serial.println(M2S(msg_battery_ok));延迟(2000); Want_dac_voltage=get_approximated_dac_voltage(battery_voltage);//设置需要的稳压器电压 //Serial.println(get_approximated_dac_voltage(battery_voltage));连接充电电路();延迟(200); } else { Charger_state=BATTERY_VOLTAGE_LOW;//电池电压过低Serial.println(M2S(msg_voltage_too_low)); update_lcd(M2S(msg_voltage_too_low_short),construct_status_string());延迟(1000); } 休息; case BATTERY_VOLTAGE_LOW://电池电压过低 update_lcd(M2S(msg_voltage_too_low_short),construct_status_string()); Serial.println(M2S(msg_voltage_too_low)); Charger_state=FINAL_STATE;//暂停中断; case CURRENT_RAMP_UP:///电流上升//if (current_mA<1.0) Charger_state=40;//电流意外下降 read_status(); update_lcd(M2S(msg_ramp_up),construct_status_string());延迟(50); if (current_mAMAXIMUM_BATTERY_VOLTAGE ) Charger_state=OVERVOLTAGE;//过压 if (abs(current_mA-target_current_mA)>0.2){//如果电流偏离目标 if (current_mA) 0.01) Wanted_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; else Charger_state=CURRENT_TOO_HIGH;//电流太高,无法降低} } if (abs(current_mA-target_current_mA)>5){//调节失败,差值太高charger_state=REGULATION_FAILED;//调节错误,差值太高} dac_write_voltage (wanted_dac_电压); if (total_minutes_averagetrickle_current_mA) { if (wanted_dac_voltage>VOLTAGE_STEP) { Wanted_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; dac_write_电压(wanted_dac_电压); } else Charger_state=CURRENT_TOO_HIGH;//无法将电流降低到涓流率} else { Charger_state=TRICKLE;//充电TrickleChargingTimeMillis=0; Serial.println(M2S(msg_trickle_charge)); } 休息; case TRICKLE://充电延迟(200);读取状态(); if (current_mA<0.2) Charger_state=UNEXPECTED_CURRENT_FALL;//电流意外下降 if (battery_voltage>MAXIMUM_BATTERY_VOLTAGE ) Charger_state=OVERVOLTAGE;//过压 if (abs(current_mA-trickle_current_mA)>0.2){//如果电流偏离目标 if (current_mA) 0.01) Wanted_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; else Charger_state=CURRENT_TOO_HIGH;//电流太高,无法降低} } if (abs(current_mA-trickle_current_mA)>5){//调节失败,差值太高charger_state=REGULATION_FAILED;//调节错误,差值太高} dac_write_voltage (wanted_dac_电压); //if (total_minutes_averagemax_time_for_trickle_charge) {//最大允许涓流充电 update_lcd(eoc_line1,eoc_line2); Charger_state=END_OF_TRICKLE;//停止disconnect_charging_circuit(); //断开充电器与电池的连接 } break; case END_OF_TRICKLE:if ((second()%8)<4) update_lcd(M2S(msg_trickle_completed),construct_status_string());否则 update_lcd(eoc_line1,eoc_line2);休息; case UNEXPECTED_CURRENT_FALL://电流意外下降Serial.println(F("电流意外下降"));断开充电电路(); Wanted_dac_电压=0; update_lcd(M2S(msg_no_current),construct_status_string()); Charger_state=FINAL_STATE;//暂停延迟(1000);休息; case UNABLE_TO_REACH_CURRENT://无法达到所需的当前Serial.println(M2S(msg_current_unreachable_long));断开充电电路(); Wanted_dac_电压=0; dac_write_电压(wanted_dac_电压);延迟(1000); update_lcd(M2S(msg_current_unreachable),construct_status_string()); Charger_state=FINAL_STATE;//暂停中断; case FULLY_CHARGED://完全充电 elapsed_time=mills2time(ChargingTimeMillis); int charge_mAh; Charge_mAh=calculate_charge(ChargingTimeMillis); msg =String(M2S(msg_completed)+M2S(msg_space)+construct_time_string(elapsed_time)); msg1=String(M2S(msg_charge)+M2S(msg_space)+String(charge_mAh)+String("mAh")); eoc_line1=msg; eoc_line2=msg1;更新液晶(味精,味精1); Serial.println(msg); //disconnect_charge_circuit(); //wanted_dac_电压=0; //dac_write_电压(wanted_dac_电压);延迟(3000); Charger_state=CURRENT_RAMP_DOWN;//暂停中断; case CURRENT_TOO_HIGH://电流太高 Serial.println(F("Unable to lower current to target"));断开充电电路(); Wanted_dac_电压=0; dac_write_电压(0); update_lcd(M2S(msg_high_current),construct_status_string());延迟(1000); Charger_state=FINAL_STATE;//暂停中断; case REGULATION_FAILED://Regulation failed Serial.println(M2S(msg_regulation_fault));断开充电电路(); Wanted_dac_电压=0; dac_write_电压(0); update_lcd(M2S(msg_regulation_fault),construct_status_string());延迟(1000); Charger_state=FINAL_STATE;//暂停中断; case OVERCURRENT://过流disconnect_charge_circuit(); Serial.println(M2S(msg_overcurrent)); Wanted_dac_电压=0; dac_write_电压(wanted_dac_电压); update_lcd(M2S(msg_overcurrent),construct_status_string());延迟(1000); Charger_state=FINAL_STATE;//暂停中断; case OVERVOLTAGE://过压disconnect_charge_circuit(); Serial.println(M2S(msg_overvoltage)); Wanted_dac_电压=0; dac_write_电压(wanted_dac_电压); update_lcd(M2S(msg_overvoltage),construct_status_string());延迟(1000); Charger_state=FINAL_STATE;//暂停中断; case FINAL_STATE://暂停延迟(10000);休息;默认值:wanted_dac_voltage=0;充电器状态=0; } //Serial.println(current_mA); //Serial.print("Current="); //Serial.print(current_mA); //Serial.println("mA"); //Serial.print("DAC电压"); //Serial.println(dac_电压); //Serial.print("需要的DAC电压"); //Serial.println(wanted_dac_电压); //Serial.print(current_mA); //Serial.print(" "); //串行打印(dac_电压); //Serial.print(" ");读取状态(); if (last_second!=second()){ Serial.print(current_mA); Serial.print(","); //Serial.print(resistor_voltage); //Serial.print(","); //串行打印(dac_电压); //Serial.print(","); //Serial.print(regulator_voltage); //Serial.print(","); Serial.println(电池电压); last_second=second(); }}
hw.inoArduino
float get_approximated_dac_voltage(float vbat){ //float offset_voltage=1.2/R3*(R3+R4);浮动偏移_电压=1.2;浮动adc_电压=(vbat-offset_电压)/AMP_GAIN-0.5;如果(adc_电压<0)adc_电压=0; return adc_voltage;}int voltage_to_code(float voltage){ int code=4095.0/DAC_REF_VOLTAGE*电压;返回代码;}void dac_write(int 代码){ Wire.beginTransmission(MCP4725_ADDR); Wire.write(64); // cmd 更新 DAC Wire.write(code>> 4); // 8 个最高有效位... Wire.write((code &15) <<4); // 4 个最低有效位... Wire.endTransmission();}void read_status(){ voltage_sum=0; current_sum=0; for (i=0;i=POINTS_FOR_AVERAGING) averaging_index=0;如果(tmp_battery_voltage>MAXIMUM_BATTERY_VOLTAGE){disconnect_charge_circuit(); //断开充电器与电池的连接charger_state=OVERVOLTAGE; } if (tmp_current_mA>MAXIMIM_ALLOWED_CURRENT ){ disconnect_charging_circuit(); //断开充电器与电池充电器_state=OVERCURRENT; }}void disconnect_charging_circuit(){ digitalWrite(CHARGE_RELAY_PIN,DISCONNECT_CHARGE_RELAY); //断开充电器与电池的连接}void connect_charge_circuit(){ digitalWrite(CHARGE_RELAY_PIN,CONNECT_CHARGE_RELAY); //将充电器连接到电池}//sec_index=0;//min_index=0;
lcd.inoArduino
void update_lcd(String first_line,String second_line){ //Serial.print("update_lcd "); //Serial.print(lcd_last_string2); //Serial.print(" "); //Serial.println(second_line); if (lcd_last_string1!=first_line){ lcd.clear(); lcd.setCursor(0,0);液晶显示(第一行); lcd_last_string1=first_line; lcd.setCursor(0,1); lcd.print(second_line); lcd_last_string2=second_line; } if(lcd_last_second!=second()){ if (lcd_last_string2!=second_line){ lcd.setCursor(0,1); lcd.print(second_line); lcd_last_string2=second_line; } } lcd_last_second=second();}Stringconstruct_status_string(void){String v,i;如果(电池电压<10)v=字符串(电池电压,2);否则 v=String(battery_voltage, 1); if (current_mA<10) i=String(current_mA, 2);否则 i=String(current_mA, 1); //Serial.println(v);我的时间过去了; String msg,msg_time; //Serial.print(charging_started); //Serial.print(" "); //Serial.println(String(millis()-charging_started)); switch(charger_state){ case CHARGING:elapsed=mills2time(ChargingTimeMillis);休息; case TRICKLE:elapsed=mills2time(TrickleChargingTimeMillis);休息; } if (charger_state==CHARGING || charger_state==TRICKLE){ if (elapsed.total_minutes<10) msg_time=String(elapsed.total_minutes)+" "; else if (elapsed.total_minutes<100) msg_time=String(elapsed.total_minutes)+" "; else msg_time=String(elapsed.total_minutes); } switch(charger_state){ case CHARGING:msg=v+String(F("V "))+i+String(F("mA"))+" "+msg_time;休息; case TRICKLE:msg=v+String(F("V "))+i+String(F("mA"))+" "+msg_time;休息; default:msg=v+String(F("V "))+i+String(F("mA")); } msg.replace("-","");//Remove minus sign return msg;}String construct_time_string(mytime timeinfo){ String mystring=String(timeinfo.hours,DEC)+String(F(":"))+String(timeinfo.minutes,DEC); //return String(timeinfo.hours,DEC)+String(F(":"))+String(timeinfo.minutes,DEC); return mystring;}
calculations.inoArduino
float best_linear_fit(float y[MINUTES_TO_LOG]){ float sx =0.0, sy =0.0, sxx =0.0, sxy =0.0; //int n =y.size(); for (i =0; i  
New LiquidCrystal library used for this projectArduino
无预览(仅限下载)。

示意图

charger_AgK96zxw2T.zip

制造工艺

  1. 干渴警报植物警报
  2. 意大利字时钟
  3. 4x3 键盘只有三个引脚
  4. Sigfox kWh Meter
  5. 蓝牙温度监视器
  6. 手势控制锁
  7. 伴侣 IC
  8. USB MIDI 适配器
  9. Arduino 的隔离模拟输入
  10. RGB 32-Band Audio Spectrum Visualizer
  11. Arduino TV 输出电缆
  12. 测量你的反应时间