ฉันใช้ YwRobot I2C SERIAL LCD 1602 MODULE เพื่อแสดงสถานะของอุปกรณ์ชาร์จ แต่สามารถใช้โมดูล LCD I2C แบบควบคุมอื่น ๆ ได้ ดูเหมือนว่าโมดูล YwRobot LCD ไม่ได้รับการสนับสนุนจากไลบรารี LiquidCrystal_I2C มาตรฐานดังนั้นฉันจึงใช้ไลบรารี LiquidCrystal ใหม่หากคุณใช้โมดูล LCD ที่แตกต่างกันคุณจะต้องเปลี่ยนบรรทัดนี้:
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
ในการแปลงดิจิตอลเป็นอนาล็อกและแอลซีดีฉันใช้ SparkFun Breadboard Power Supply 5V / 3.3V อาจเป็นไปได้ที่จะใช้ 5V จากบอร์ด Arduino
นอกจากนี้คุณยังต้องจ่ายไฟ 17 โวลต์ หากคุณไม่มีแหล่งจ่ายไฟคุณสามารถใช้ตัวแปลง DC / DC แบบปรับได้เช่นนี้
target_current_mA - กระแสประจุไฟฟ้าคงที่
max_time_for_trickle_charge - จำนวนนาทีสูงสุดสำหรับการชาร์จไฟแบบหยดสามารถตั้งค่าได้สูงสุด 600 (10 ชั่วโมง)
battery_nominal_capacity_mA - ความจุแบตเตอรี่ที่ใช้คำนวณกระแสหยด
โดยทั่วไปการชาร charging จไฟจะขึ้นอยู่กับความจุที่ระบุ สำหรับแบตเตอรี่ที่มีกำลังการผลิตน้อยที่สุดคือกระแสไฟฟ้าสูงสุด 170mAh คือ 170mA กระแสประจุกระแสไฟต่ำสุดคือ C / 10 - 17mA สำหรับแบตเตอรี่ 170mAh
หลังจากชาร์จไฟแล้วเครื่องชาร์จจะตรวจสอบว่าต่อแบตเตอรี่หรือไม่ หากแบตเตอรี่ที่ต่ออยู่กับแบตเตอรี่จะถูกชาร์จด้วยกระแสไฟฟ้าที่กำหนดไว้จนกว่าจะชาร์จจนเต็ม การชาร์จไฟสิ้นสุดลงโดยตรวจจับค่า dV / dt เป็นลบในช่วง 5 นาที หลังจากชาร์จเครื่องชาร์จเสร็จแล้วจะเปลี่ยนไปใช้การชาร์จด้วยกระแส C / 40 เครื่องชาร์จจะตัดการเชื่อมต่อตัวเองจากแบตเตอรี่หลังจากหมดเวลาการชาร์จไฟสูงสุด
1 - dV / dt
2 - ชาร์จไฟเป็นนาที
1 - เวลาในการชาร์จ
2 - ชาร์จแบตเตอรี่
ข้อมูลเพิ่มเติมเกี่ยวกับแบตเตอรี่ NiMH:
สำหรับการชาร์จแบตเตอรี่ NiMH 9V
// แบตเตอรี่สามารถมีได้ 6,7 หรือ 8 เซลล์
1.25 โวลต์// ทำให้แรงดันไฟฟ้าระหว่าง 7.5 ถึง 10V
# รวม<Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <TimerOne.h>
#include <elapsedMillis.h>
LiquidCrystal_I2C lcd ( 0x27 , 2 , 1 , 0 , 4 , 5 , 6 , 7 , 3 , เป็นบวก); // ตั้งค่าที่อยู่ LCD เป็น 0x27 สำหรับตัวอักษร 16 ตัวและการแสดงผล 2 บรรทัด
// ฮาร์ดแวร์ defenitions # ระบุ MCP4725_ADDR 0x60 // ที่อยู่ DAC # กำหนด DAC_REF_VOLTAGE 5.0 # define CHARGE_RELAY_PIN 2 # กำหนด DISCONNECT_CHARGE_RELAY HIGH # define CONNECT_CHARGE_RELAY LOW # กำหนด CURRENT_SENSIST_SESISTOR_PIN A2 #define CURRENT_SENSING_SESISTOR 10.2 // OHm
#define BATTERY_VOLTAGE_PIN A0
# กำหนด R1 5090 // รีซิสเตอร์ด้านแรงดันไฟฟ้าต่ำตรวจจับ
# กำหนด R2 19910 // รีซิสเตอร์ด้านสูงของเครื่องตรวจจับแรงดันไฟฟ้า
# กำหนด ADC_REF_VOLTAGE 4.89 // แรงดันไฟฟ้า Arduino จริงหรือแรงดันไฟฟ้า AREF สำหรับ ADC ที่เหมาะสมสำหรับการแปลแรงดันไฟฟ้า
# กำหนด R3 3300.0
#
กำหนดR4 6800.0 # กำหนด AMP_GAIN (1 + R4 / R3)
// คำจำกัดความต่าง ๆ// # define MINIMUM_VOLTAGE 8.1 / แรงดันต่ำสุดหลังจากควบคุม# กำหนด BATTERY_GOOD_VOLTAGE_THRESHOLD 7.0 # ระบุ MAXIMIM_ALLOWED_CURRENT 200 // กระแสไฟแบตเตอรี่สูงสุดที่สามารถใช้งานได้ mA (ยาก cut-off) #define MAXIMUM_BATTERY_VOLTAGE 15.0 // แรงดันไฟฟ้าแบตเตอรี่สูงสุดที่อนุญาต V (ตัดยาก)
#define VOLTAGE_STEP 0.001 // ขั้นตอนสำหรับการควบคุมแรงดันไฟฟ้า
#
กำหนดPOINTS_FOR_AVERAGING 100 // จำนวนจุดที่ใช้สำหรับการเฉลี่ย# กำหนด MEASURE2MEASURE_US 5000 // เวลาระหว่างการวัดเป็นหน่วยเป็นมิลลิวินาที (ต้องมากกว่า 200 ครั้งเนื่องจากมีการอ่านแบบอนาล็อกสองอัน)
#define VOLTAGE_LOG_TIME_MIN 30.0 / / เวลาเป็นนาทีเพื่อประหยัดแรงดันไฟฟ้าสำหรับ dV / dT cutoff
# กำหนด MINUTES_TO_LOG 5
# กำหนด TRICKLE_CURRENT_RATIO 40
// สถานะเครื่องชาร์จ# กำหนดการเริ่มต้น 0 # ระบุ NO_BATTERY 5 # กำหนด BATTERY_CONNECTED 10 # กำหนด BATTERY_VOLTAGE_LOW 15 # กำหนด CURRENT_RAMP_UP 20 #define CHARGING 30 #define CURRENT_RAMP_DOWN 32 # กำหนด TRICKLE 35
#define END_OF_TRICKLE 37
#define UNEXPECTED_CURRENT_FALL 40
#define UNABLE_TO_REACH_CURRENT 60
#define FULLY_CHARGED 70
#define CURRENT_TOO_HIGH 80
#define REGULATION_FAILED 90
#define กระแสเกิน 100
overvoltage #define 101
#define FINAL_STATE 200
/// unsigned int voltage_readings [ POINTS_FOR_AVERAGING ] current_sensing_resistor_readings [ POINTS_FOR_AVERAGING ] , averaging_index ; // สำหรับค่าเฉลี่ยระยะยาวที่ไม่มีการลงชื่อint voltage_sum , current_sum ; // ผลรวมของลอยโดยเฉลี่ย
regulator_voltage_code , resistor_voltage , csr_voltage_code , regulator_voltage , current_mA , แบตเตอรี่แรงดันไฟฟ้า; // หน่วยวัด
ลอย tmp_resistor_voltage , tmp_current_mA , tmp_regulator_voltage , tmp_battery_voltage ;
int i , j , charger_state ;
สั้น unsigned int last_second , lcd_last_second , log_last_second ;
สายอักขระ lcd_last_string1 ,lcd_last_string2 ;
สายอักขระ empty_string = "" ;
ข้อความสตริง , eoc_line1 , eoc_line2 ;
unsigned char sec_index , min_index ;
// long ยาว int charging_started;
float sec_log [ 60 ], min_log [ MINUTES_TO_LOG ], last_blf ;
ลอย trickle_current_mA ;
int total_minutes_average = 0 ;
elapsedMillis ChargingTimeMillis ,
TrickleChargingTimeMillis ;
float wanted_dac_voltage = 0 ; float last_dac_voltage = 0 ; // ข้อความconst char msg_battery_detected [] PROGMEM = "ตรวจพบแบตเตอรี่" ; const char msg_no_battery [] PROGMEM = "ไม่มีแบตเตอรี่" ; const char msg_battery_ok [] PROGMEM = "แบตเตอรี่ตกลง" ; const char msg_voltage_too_low [] PROGMEM =
"แรงดันแบตเตอรี่ต่ำเกินไป" ;
const char msg_voltage_too_low_short [] PROGMEM = "V แบตเตอรี่ต่ำ" ;
const char msg_ramp_up [] PROGMEM = "ตั้งขึ้น" ;
const char msg_charging [] PROGMEM = "กำลังชาร์จ" ;
const char msg_space [] PROGMEM = "" ;
const char msg_ramp_down [] PROGMEM = "ลาดลง" ;
[] 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_regulating_fault [] PROGMEM = "ข้อบังคับ" ;
const char msg_overcurrent [] PROGMEM = "ปัจจุบันสูงเกินไป" ;
const char msg_overvoltage [] PROGMEM = "แรงดันสูงเกินไป" ;
const char msg_trickle_completed [] PROGMEM = "Trickle เสร็จสิ้น" ;
// *************************** พารามิเตอร์การชาร์จ ******************* **********************
// ************************** ************************************************** *************
float target_current_mA = 30 ; // การชาร์จกระแส mA แบบ mA
float battery_nominal_capacity_mA = 170 ; / ความจุที่กำหนดของแบตเตอรี่ mA
float max_time_for_trickle_charge = 6 ; // เวลาการหยดน้ำสูงสุดในนาที
// **************************************** *************************************************
/ / ************************************************* ****************************************
struct
ทุกวัน {
unsigned char hours ; นาทีถ่านที่ไม่ได้ลงชื่อ; unsigned int total_minutes ; } elapsed_time ; การตั้งค่าเป็นโมฆะ() { pinMode ( CHARGE_RELAY_PIN , OUTPUT ); disconnect_charging_circuit (); // ชาร์จแบตเตอรี่ ftom ยกเลิกการเชื่อมต่อสายไฟ เริ่มต้น(); // I2C dac_write_voltage ( 0 ); // ตรวจสอบว่าเป็นไปได้ที่ต่ำกว่าชุดปัจจุบันอนุกรม เริ่มต้น(
115200 );
last_second = second (); lcd_last_second = วินาที(); log_last_second = วินาที(); Timer1 . เริ่มต้น( MEASURE2MEASURE_US ); // จะใช้ในการวัดแรงดันและกระแสของแบตเตอรี่ (ไมโคร) Timer1 attachInterrupt ( read_hw ); / / ยึด read_hw () เป็นตัวจับเวลาล้น interrupt averaging_index = 0 ; sec_index = 0 ; min_index = 0 ; charger_state
= 0 ; / / สถานะเริ่มต้นของเครื่องรัฐ
wanted_dac_voltage = 0 ; // ทำให้แรงดันต่ำสุดของ shure last_blf = 1.0 ; trickle_current_mA = battery_nominal_capacity_mA / TRICKLE_CURRENT_RATIO ; // ChargingTimeMillis = 0; // จอแอลซีดีแอลซีดี เริ่มต้น( 16 , 2 ); จอแอลซีดี backlight (); จอแอลซีดี clear (); update_lcd ( F ( "เปิดเครื่อง ... " ), empty_string
);
ความล่าช้า( 1000 ); } float log_battery_voltage () ( / / เข้าสู่ระบบเพียงครั้งเดียวต่อวินาทีถ้า( log_last_second == วินาที()) return last_blf ; อื่นlog_last_second = วินาที(); sec_log [ sec_index ] = battery_voltage ; if ( sec_index < 59 ) { sec_index ++ ; } else { // ถ้ามีการบันทึกหนึ่งนาที
// คำนวณจำนวนนาทีต่อหนึ่งนาที
หาก( min_index > = MINUTES_TO_LOG ) min_index = 0 ; sec_index = 0 ; float sum_v = 0 ; สำหรับ( i = 0 ; i < 60 ; i ++ ) { sum_v + = sec_log [ i ]; } float min_average = sum_v / 60.0 ; สำหรับ( i = 1 ;
i < MINUTES_TO_LOG ; i ++ ) min_log [ i - 1 ] = min_log [ i ];
min_log [ MINUTES_TO_LOG - 1 ] = min_average ; // บันทึกนาทีเฉลี่ย//Serial.print(min_index); //Serial.print (""); //Serial.print(min_average); //Serial.print ("arr:"); //Serial.print(min_log[0]); //Serial.print (""); //Serial.print(min_log[1]); //Serial.print (""); //Serial.print(min_log[2]); //Serial.print ("");
//Serial.print(min_log[3]);
//Serial.print (""); //Serial.print(min_log[4]); last_blf = best_linear_fit ( min_log ); //Serial.print("Slope "); //Serial.println(last_blf); min_index ++ ; total_minutes_average ++ ; } return last_blf ; }