Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Pengisi Daya Cerdas untuk Baterai Isi Ulang 9V NiMH V1

Komponen dan persediaan

Arduino UNO
× 1
SparkFun I2C DAC Breakout - MCP4725
× 1
Regulator Linier dengan Output yang Dapat Disesuaikan
× 1
Texas Instruments Tujuan Umum Dual Op-Amp
× 1
Resistor 6.8k ohm
× 2
Resistor 3.3k ohm
× 1
Resistor 5.1k ohm
× 1
Resistor 1k ohm
× 1
Resistor 10 ohm
× 1
Relai (umum)
× 1
Resistor 20k ohm
× 1
SparkFun Breadboard Power Supply 5V/3.3V
× 1
Suplai daya 17V
× 1
MODUL LCD SERIAL YwRobot I2C 1602
× 1

Tentang proyek ini

Saya mencari obrolan pengisi daya pintar yang dapat mengisi baterai 9V NiMH dalam beberapa jam dan tidak menemukannya. Apalagi semua charger yang saya temukan benar-benar "bodoh". Pengisian saat ini tidak diketahui dan tidak ada fungsi untuk menghentikan pengisian setelah baterai terisi penuh. Masalah dengan pengisi daya sedemikian rupa sehingga mereka dapat mengisi daya baterai secara berlebihan dan secara signifikan mengurangi masa pakai. Jadi saya memutuskan untuk membuat pengisi daya "pintar".

Versi pertama yang ingin saya buat tetap sederhana, sehingga memungkinkan hal-hal dasar seperti pengisian daya dengan arus konstan, penghentian pengisian otomatis setelah baterai terisi penuh, pengisian daya tetesan, pengukuran pengisian daya yang ditransfer ke baterai.

Di versi berikutnya saya akan menambahkan beberapa fitur tambahan yang berguna seperti pengosongan, pengukuran kapasitas, dan siklus.

Peringatan:Mengisi baterai dengan arus tinggi dapat menyebabkan ledakan atau kebakaran baterai. Tolong jangan tinggalkan pengisi daya tanpa pengawasan. Juga tolong jangan mencoba mengisi baterai yang tidak dimaksudkan untuk diisi sebagai Alkaline. Pengisi daya ini hanya diuji dengan baterai NiMH (dan Anda tetap menggunakannya dengan risiko Anda sendiri dan saya sama sekali tidak bertanggung jawab jika ada kerusakan yang disebabkan karena bug dalam desain atau kode). Kekecewaan baterai jenis lain akan memerlukan modifikasi kode.

Teori

Beberapa fakta berguna yang perlu diingat yang akan membantu memahami parameter pengisi daya yang diperlukan.

C - arus sama dengan kapasitas nominal baterai

Ketika diisi pada tingkat C tegangan sel tunggal dapat mencapai 1.6V. Tegangan ini mungkin lebih tinggi untuk baterai lama.

Tegangan nominal sel tunggal adalah 1,2V, tetapi sel yang terisi penuh memiliki tegangan rangkaian terbuka hingga 1,5 volt.

Tingkat pengisian daya tetesan kurang dari 0,025 C (C/40) disarankan setelah baterai terisi penuh.

Biasanya ada dua opsi untuk mengisi baterai NiMH:

1. Pengisian cepat. Pengisian arus 0.5C-1C. Status pengisian harus dipantau dan diakhiri dengan dV/dt (laju perubahan tegangan) atau dT/dt (laju perubahan suhu)

2. Pengisian lambat. Pengisian saat ini 0.1C. Waktu pengisian 14-16 jam. Penghentian pengisian daya oleh pengatur waktu. pemutusan muatan dT/dt tidak mungkin untuk arus rendah. pemutusan dV/dt mungkin tidak dapat diandalkan untuk arus di bawah 0,5C menurut literatur.

Parameter Dasar Rangkaian Pengisian

Baterai 9V biasanya memiliki 7 penjualan yang terhubung secara serial, tetapi dalam beberapa kasus mungkin memiliki 6 atau 8 sel. Pengatur tegangan harus dapat memberikan tegangan pengisian setidaknya hingga 8*1.6=12.8V. Tegangan putus regulator LM317 hingga 2V, sehingga tegangan suplai harus ~15V (ini tidak memperhitungkan penurunan tegangan pada resistor penginderaan arus).

Untuk arus pengisian maksimum 200mA dan resistor penginderaan arus 10 Ohm penurunan tambahan pada resistor penginderaan arus adalah 2V, sehingga diperlukan tegangan suplai 17V.

Sel yang benar-benar kosong mungkin memiliki tegangan yang sangat rendah, bahkan negatif. Tegangan minimum regulator idealnya adalah 0, tetapi menggunakan LM317 mungkin serendah 1.2V.

Sirkuit

Penjelasan Sirkuit

Ide dasarnya adalah mengukur arus pengisian dan menyesuaikan tegangan regulator hingga arus yang diinginkan tercapai. Arus diukur dengan mengukur penurunan tegangan pada resistor penginderaan arus R5. I=V/R.

SparkFun I2C DAC Breakout - MCP4725 - konverter digital ke analog 12 bit yang digunakan untuk mengontrol tegangan. Cam tegangan keluaran dikonfigurasi melalui I2C antara 0 dan 5V. Karena kita harus bisa mengatur tegangan dalam rentang yang lebih luas, dari 0 sampai 15V penguat operasional LM358 digunakan untuk memperkuat tegangan keluaran DAC. Amplifikasi penguat operasional diatur oleh resistor R4 dan R3. Gain=1+R4/R3=1+6800/3300=3,06 sehingga tegangan keluaran penguat operasional kira-kira 0 sampai 15V.

Arus keluaran maksimum LM358 adalah 50mA, jadi regulator tegangan LM317 digunakan untuk mengontrol arus yang lebih tinggi. Keluaran penguat operasional dihubungkan ke terminal ADJ LM317. LM317 akan mempertahankan 1.2V antara terminal ADJ dan OUT, sehingga tegangan aktual pada baterai dapat dikonfigurasi antara 1.2 dan 16.2V. LM317 membutuhkan arus minimum 3.5mA untuk menjaga regulasi. Jadi resistor 1kOhm R6 digunakan untuk memastikan regulasi jika baterai tidak terhubung. Kapasitor C1 digunakan untuk menyaring tegangan keluaran dan meningkatkan stabilitas LM317.

Tegangan diukur pada dua titik yang berbeda.

1. Resistor R5 terhubung ke pin A2 Arduino. Tegangan pada resistor diukur dan dari arus pengisian dihitung sebagai Icharging=V/R

2. Tegangan pada baterai bisa sampai 16.2V, jadi pembagi resistif R1, R2 digunakan untuk membawa tegangan di bawah 5V, diizinkan oleh Arduino. Output pembagi terhubung ke pin A0 Arduino. Untuk R1=5.1k Ohm dan R2=20kOhm Vout=Vin/(20000+5100)*5100=0.2 Jadi tegangan baterai dibagi 5.

Relay digunakan untuk memutuskan baterai dari rangkaian pengisian. Anda dapat melihat pada relai foto yang saya gunakan, tetapi umumnya relai apa pun dengan kontrol 5V dapat digunakan. Lebih aman untuk menghubungkan baterai ke kontak relai yang biasanya terbuka.

Saya menggunakan YwRobot I2C SERIAL LCD 1602 MODULE untuk menampilkan status pengisi daya, tetapi modul LCD terkontrol I2C lainnya dapat digunakan. Sepertinya modul LCD YwRobot tidak didukung oleh pustaka LiquidCrystal_I2C standar, jadi saya menggunakan pustaka LiquidCrystal Baru Jika Anda menggunakan modul LCD yang berbeda, Anda perlu mengubah baris ini:

LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIF); // setel alamat LCD ke 0x27 untuk 16 karakter dan tampilan 2 baris 

Untuk menyalakan konverter Digital ke analog dan LCD saya menggunakan SparkFun Breadboard Power Supply 5V/3.3V. Mungkin tidak masalah menggunakan 5V dari papan Arduino.

Anda juga perlu menyuplai 17V ke sirkuit pengisian daya. Jika tidak memiliki catu daya, Anda dapat menggunakan konverter DC/DC yang dapat disesuaikan seperti ini

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

Fungsionalitas

Saya tidak ingin banyak kabel, jadi tidak ada tombol untuk mengonfigurasi pengisian daya. Chagrin saat ini dikonfigurasi hanya dalam kode. Anda perlu mengatur arus pengisian yang diinginkan di charger.ino

//*************************** Parameter pengisian daya ************* ***************************//********************* ************************************************** *******************float target_current_mA=30; //Mengisi daya mAfloat battery_nominal_capacity_mA=170 saat ini; //Kapasitas nominal baterai mAfloat max_time_for_trickle_charge=6; //Waktu pengisian tetesan maksimum dalam hitungan menit//**************************************** *************************************************/ /************************************************ **************************************** 

target_current_mA - arus pengisian konstan

max_time_for_trickle_charge - jumlah menit maksimum untuk pengisian daya tetesan, dapat diatur hingga 600 (10 jam)

battery_nominal_capacity_mA - kapasitas baterai yang digunakan untuk menghitung arus tetesan

Umumnya arus pengisian bisa sampai kapasitas nominal. Untuk baterai dengan kapasitas nominal 170mAh arus pengisian maksimum adalah 170mA. Arus pengisian minimum biasanya C/10 - 17mA untuk baterai 170mAh.

Setelah daya menyala, pengisi daya akan memeriksa apakah baterai terhubung. Jika baterai terhubung, baterai akan diisi dengan arus konstan yang dikonfigurasi hingga terisi penuh. Pengisian diakhiri dengan mendeteksi dV/dt negatif selama 5 menit. Setelah pengisian selesai, pengisi daya akan beralih ke pengisian daya menetes dengan C/40 saat ini. Pengisi daya akan memutuskan sambungannya sendiri dari baterai setelah waktu pengisian tetesan maksimum berlalu.

1 - dV/dt

2 - waktu pengisian dalam hitungan menit

1 - Waktu pengisian daya

2 - Pengisian daya ditransfer ke baterai

Informasi tambahan tentang baterai NiMH:

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

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

Kode

  • charger.ino
  • main.ino
  • hw.ino
  • lcd.ino
  • kalkulasi.ino
  • Library LiquidCrystal baru digunakan untuk proyek ini
charger.inoArduino
File utama
//Ini untuk mengisi baterai NiMH 9V //Baterai dapat memiliki 6,7 atau 8 sel 1,25V//Ini membuat tegangan nominal antara 7,5 dan 10V#include #include #include  #include #include LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIF); // tentukan alamat LCD ke 0x27 untuk 16 karakter dan tampilan 2 baris//Definisi perangkat keras#definisikan MCP4725_ADDR 0x60 //alamat DAC#tentukan DAC_REF_VOLTAGE 5.0#tentukan CHARGE_RELAY_PIN 2#tentukan DISCONNECT_CHARGE_RELAY HIGH#DEFINE CURRENT_SENSING_SESISTOR 10.2 //OHm#define BATTERY_VOLTAGE_PIN A0#define R1 5090 //Resistor sisi rendah dari pembagi pendeteksi tegangan#menentukan R2 19910//Resistor sisi tinggi dari pembagi pendeteksi tegangan#menentukan ADC_REF_VOLTAGE 4.89 //Arduino tegangan suplai nyata atau tegangan AREF untuk tegangan suplai yang tepat atau tegangan AREF ADC ke terjemahan tegangan#define R3 3300.0#define R4 6800.0#define AMP_GAIN (1+R4/R3)//Berbagai definisi//#define MINIMUM_VOLTAGE 8.1 //Tegangan minimum setelah regulator#define BATTERY_GOOD_VOLTAGE_THRESHOLD 7.0#define MAXIMRRENTALLOW arus baterai mA (hard cut-off)#menentukan MAXIMUM_BATTERY_VOLTAGE 15.0 //Tegangan baterai maksimum yang diizinkan V (hard cut-off)#menentukan VOLTAGE_STEP 0,001 //Langkah untuk tegangan regulasi#define POINTS_FOR_AVERAGING 100 //Berapa banyak poin yang diambil untuk rata-rata#define MEASURE2MEASURE_US 5000 //Waktu antar pengukuran dalam mikrodetik (perlu lebih dari 200 karena dua pembacaan analog)#define VOLTAGE_LOG_TIME_MIN 30.0 //Waktu dalam menit untuk menghemat tegangan dV / dT cutoff # mendefinisikan MINUTES_TO_LOG 5 # mendefinisikan TRICKLE_CURRENT_RATIO 40 // Charger menyatakan # mendefinisikan INITIALIZATION 0 # mendefinisikan NO_BATTERY 5 # mendefinisikan BATTERY_CONNECTED 10 # mendefinisikan BATTERY_VOLTAGE_LOW 15 # mendefinisikan CURRENT_RAMP_UP 20 # mendefinisikan PENGISIAN 30 # mendefinisikan CURRENT_RAMP_DOWN 32 # mendefinisikan tetesan 35 # mendefinisikan END_OF_TRICKLE 37 # mendefinisikan UNEXPECTED_CURRENT_FALL 40 # mendefinisikan UNABLE_TO_REACH_CURRENT 60 # mendefinisikan FULLY_CHARGED 70 # mendefinisikan CURRENT_TOO_HIGH 80 # mendefinisikan REGULATION_FAILED 90 # mendefinisikan arus lebih 100 # mendefinisikan tegangan 101 # mendefinisikan FINAL_STATE 200 /// unsigned int voltage_readings [POINTS_FOR_AVERAGING], current_sensing_resistor_readings [POINTS_FOR_AVERAGING], averaging_index; //Untuk rata-rata panjang unsigned int voltage_sum,current_sum;//Jumlah rata-rataf loat regulator_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; pendek unsigned int last_second, lcd_last_second, log_last_second; String lcd_last_string1, lcd_last_string2; String empty_string ="";String msg,eoc_line1,eoc_line2;unsigned char sec_index,min_index;//long long int charging_started;float sec_log[60],min_log[MINUTES_TO_LOG],last_blf;float trickle_current_mA;int total_minutes_average_average=0_FlolapsedTimeMillis;elapsed 0;float last_dac_voltage=0;//Messagesconst char msg_battery_detected[] PROGMEM ="Baterai terdeteksi";const char msg_no_battery[] PROGMEM ="Tidak ada baterai";const char msg_battery_ok[] PROGMEM ="Batchar ok";const char msg_battery_ok[] PROGMEM ="Baterai ok"; PROGMEM ="Tegangan baterai terlalu rendah";const char msg_voltage_too_low_short[] PROGMEM ="V Baterai lemah";const char msg_ramp_up[] PROGM EM ="Meningkatkan";const char msg_charging[] PROGMEM ="Mengisi daya";const char msg_space[] PROGMEM =" ";const char msg_ramp_down[] PROGMEM ="Menurunkan";const char msg_trickle_charge[] PROGMEM ="Trickle charge ";const char msg_no_current[] PROGMEM ="Tidak ada arus";const char msg_current_unreachable[] PROGMEM ="Saya tidak dapat dijangkau";const char msg_current_unreachable_long[] PROGMEM ="Tidak dapat mencapai arus yang diinginkan";const char msg_completed[] PROGMEM ="Selesai ";const char msg_charge[] PROGMEM ="Charge";const char msg_high_current[] PROGMEM ="Arus tinggi";const char msg_regulation_fault[] PROGMEM ="Kesalahan regulasi";const char msg_overcurrent[] PROGMEM ="Arus terlalu tinggi"; const char msg_overvoltage[] PROGMEM ="Tegangan terlalu tinggi";const char msg_trickle_completed[] PROGMEM ="Tetesan selesai";//************************ **** Parameter pengisian *****************************************//* ************************************************** **************************************float target_current_mA=30; //Mengisi daya mAfloat battery_nominal_capacity_mA=170 saat ini; //Kapasitas nominal baterai mAfloat max_time_for_trickle_charge=6; //Waktu pengisian tetesan maksimum dalam hitungan menit//**************************************** *************************************************/ /************************************************ **************************************** struct mytime { jam karakter yang tidak ditandatangani; menit char yang tidak ditandatangani; unsigned int total_minutes;} elapsed_time;void setup() { pinMode(CHARGE_RELAY_PIN, OUTPUT); putuskan_pengisian_sirkuit(); //Putuskan sambungan pengisi daya dari baterai Wire.begin();//I2C dac_write_voltage(0);//Pastikan set arus lebih rendah Serial.begin(115200); last_second=kedua(); lcd_last_second=kedua(); log_last_second=kedua(); Timer1.initialize(MEASURE2MEASURE_US); //Akan digunakan untuk mengukur tegangan dan arus baterai (mikrodetik) Timer1.attachInterrupt(read_hw); // melampirkan read_hw() sebagai timer overflow interrupt averaging_index=0; detik_indeks=0; indeks_min=0; charger_state=0;//Status awal keadaan mesin want_dac_voltage=0;//Buat shure tegangan minimum outout last_blf=1.0; trickle_current_mA=baterai_nominal_kapasitas_mA/TRICKLE_CURRENT_RATIO; //ChargingTimeMillis=0; //LCD lcd.begin(16,2); lcd.lampu latar(); lcd.clear(); update_lcd(F("Hidupkan..."),empty_string); delay(1000);}float log_battery_voltage(){ //Log hanya sekali per detik jika (log_last_second==second()) mengembalikan last_blf; lain log_last_second=kedua(); sec_log[sec_index]=tegangan_baterai; if (indeks_detik<59) { indeks_detik++; } else {//Jika satu menit masuk //Hitung rata-rata per menit if (min_index>=MINUTES_TO_LOG) min_index=0; detik_indeks=0; float sum_v=0; untuk (i=0;i<60;i++){ sum_v+=sec_log[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();//Make shure relay disconnected dac_write_voltage(0);//Pastikan set arus yang lebih rendah yang diinginkan want_dac_voltage=0;//Make shure tunda keluaran tegangan minimum(100); baca_status(); if (baterai_voltage>0.1) { charger_state=BATTERY_CONNECTED;//Baterai terdeteksi update_lcd(M2S(msg_battery_detected),empty_string); Serial.println(M2S(msg_battery_detected)); penundaan(2000); } else {//Tidak ada baterai Serial.println(M2S(msg_no_battery)); update_lcd(M2S(msg_no_battery),construct_status_string()); charger_state=NO_BATTERY;//Battery terdeteksi delay(1000); } merusak; case NO_BATTERY://Tidak ada baterai read_status(); if (battery_voltage>0.1) { charger_state=BATTERY_CONNECTED;//Baterai terdeteksi Serial.println(M2S(msg_battery_detected)); update_lcd(M2S(msg_battery_detected),konstruksi_status_string()); penundaan (1500); } else{ //Jika tidak ada baterai yang tetap dalam keadaan ini update_lcd(M2S(msg_no_battery),construct_status_string()); penundaan (1100); } merusak; case BATTERY_CONNECTED://Baterai terhubung dac_write_voltage(0);//Pastikan set arus lebih rendah yang diinginkan want_dac_voltage=0; penundaan(100); baca_status(); if (baterai_voltage>BATTERY_GOOD_VOLTAGE_THRESHOLD){ charger_state=CURRENT_RAMP_UP;//Mulai pengisian rampup saat ini //snprintf(selamat datang, sizeof(selamat datang),"Firmware:V%d.%d%d",ver,ver2,ver3); update_lcd(M2S(msg_battery_ok),construct_status_string()); Serial.println(M2S(msg_battery_ok)); penundaan(2000); want_dac_voltage=get_approximated_dac_voltage(voltage_baterai);//Set tegangan regulator yang dibutuhkan //Serial.println(get_approximated_dac_voltage(voltage_baterai)); connect_charging_circuit(); penundaan (200); } else { charger_state=BATTERY_VOLTAGE_LOW;//Tegangan baterai terlalu rendah Serial.println(M2S(msg_voltage_too_low)); update_lcd(M2S(msg_voltage_too_low_short),construct_status_string()); penundaan (1000); } merusak; case BATTERY_VOLTAGE_LOW://Tegangan baterai terlalu rendah update_lcd(M2S(msg_voltage_too_low_short),construct_status_string()); Serial.println(M2S(msg_voltage_too_low)); charger_state=FINAL_STATE;//Hentikan istirahat; case CURRENT_RAMP_UP:///Ramp up saat ini //if (current_mA<1.0) charger_state=40;//Arus tiba-tiba turun read_status(); update_lcd(M2S(msg_ramp_up),construct_status_string()); penundaan (50); if (current_mAMAXIMUM_BATTERY_VOLTAGE ) charger_state=OVERVOLTAGE;//Overvoltage if (abs(current_mA-target_current_mA)>0.2){//Jika arus menyimpang dari (arus_mA<1.0) 0,01) want_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; else charger_state=CURRENT_TOO_HIGH;//Arus terlalu tinggi, tidak dapat diturunkan } } if (abs(current_mA-target_current_mA)>5){//Peraturan gagal, perbedaan terlalu tinggi charger_state=REGULATION_FAILED;//Kesalahan regulasi, perbedaan terlalu tinggi } dac_write_voltage (wanted_dac_voltage); if (total_minutes_averagetrickle_current_mA) { if (wanted_dac_voltage>VOLTAGE_STEP) { want_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; dac_write_voltage(diinginkan_dac_voltage); } else charger_state=CURRENT_TOO_HIGH;//Tidak dapat mengurangi arus ke laju tetesan } else { charger_state=TRICKLE;//Charging TrickleChargingTimeMillis=0; Serial.println(M2S(msg_trickle_charge)); } merusak; kasus TRICKLE://Penundaan pengisian daya (200); baca_status(); if (current_mA<0.2) charger_state=UNEXPECTED_CURRENT_FALL;//Arus tiba-tiba turun if (battery_voltage>MAXIMUM_BATTERY_VOLTAGE ) charger_state=OVERVOLTAGE;//Overvoltage if (abs(current_mA-trickle_current_mA)>0.2){//mA 0,01) want_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; else charger_state=CURRENT_TOO_HIGH;//Arus terlalu tinggi, tidak dapat diturunkan } } if (abs(current_mA-trickle_current_mA)>5){//Peraturan gagal, perbedaan terlalu tinggi charger_state=REGULATION_FAILED;//Kesalahan regulasi, perbedaan terlalu tinggi } dac_write_voltage (wanted_dac_voltage); //if (total_minutes_averagemax_time_for_trickle_charge) {//Biaya tetesan maksimum yang diizinkan update_lcd(eoc_line1,eoc_line2); charger_state=END_OF_TRICKLE;//Hentikan disconnect_charging_circuit(); //Putuskan pengisi daya dari baterai } putus; kasus END_OF_TRICKLE:if ((second()%8)<4) update_lcd(M2S(msg_trickle_completed),construct_status_string()); lain update_lcd(eoc_line1,eoc_line2); merusak; case UNEXPECTED_CURRENT_FALL://Arus tiba-tiba turun Serial.println(F("Arus tiba-tiba turun")); putuskan_pengisian_sirkuit(); want_dac_voltage=0; update_lcd(M2S(msg_no_current),construct_status_string()); charger_state=FINAL_STATE;//Hentikan penundaan(1000); merusak; case UNABLE_TO_REACH_CURRENT://Tidak dapat mencapai Serial.println(M2S(msg_current_unreachable_long) yang diinginkan saat ini); putuskan_pengisian_sirkuit(); want_dac_voltage=0; dac_write_voltage(diinginkan_dac_voltage); penundaan (1000); update_lcd(M2S(msg_current_unreachable),construct_status_string()); charger_state=FINAL_STATE;//Hentikan istirahat; case FULLY_CHARGED://Terisi penuh elapsed_time=mills2time(ChargingTimeMillis); int biaya_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=pesan; eoc_line2=msg1; update_lcd(pesan,pesan1); Serial.println(pesan); //putus_pengisian_sirkuit(); //wanted_dac_voltage=0; //dac_write_voltage(diinginkan_dac_voltage); penundaan(3000); charger_state=CURRENT_RAMP_DOWN;//Hentikan istirahat; case CURRENT_TOO_HIGH://Arus terlalu tinggi Serial.println(F("Tidak dapat menurunkan arus ke target")); putuskan_pengisian_sirkuit(); want_dac_voltage=0; dac_write_voltage(0); update_lcd(M2S(msg_high_current),construct_status_string()); penundaan (1000); charger_state=FINAL_STATE;//Hentikan istirahat; kasus REGULATION_FAILED://Peraturan gagal Serial.println(M2S(msg_regulation_fault)); putuskan_pengisian_sirkuit(); want_dac_voltage=0; dac_write_voltage(0); update_lcd(M2S(msg_regulation_fault),construct_status_string()); penundaan (1000); charger_state=FINAL_STATE;//Hentikan istirahat; case OVERCURRENT://Arus lebih disconnect_charging_circuit(); Serial.println(M2S(msg_overcurrent)); want_dac_voltage=0; dac_write_voltage(diinginkan_dac_voltage); update_lcd(M2S(msg_overcurrent),construct_status_string()); penundaan (1000); charger_state=FINAL_STATE;//Hentikan istirahat; kasus OVERVOLTAGE:// Tegangan lebih disconnect_charging_circuit(); Serial.println(M2S(msg_overvoltage)); want_dac_voltage=0; dac_write_voltage(diinginkan_dac_voltage); update_lcd(M2S(msg_overvoltage),construct_status_string()); penundaan (1000); charger_state=FINAL_STATE;//Hentikan istirahat; kasus FINAL_STATE://Menghentikan penundaan (10000); merusak; default:want_dac_voltage=0; pengisi daya_status=0; } //Serial.println(current_mA); //Serial.print("Saat ini="); //Serial.print(current_mA); //Serial.println("mA"); //Serial.print("tegangan DAC"); //Serial.println(dac_voltage); //Serial.print("Tegangan DAC yang diinginkan"); //Serial.println(wanted_dac_voltage); //Serial.print(current_mA); //Serial.print(" "); //Serial.print(dac_voltage); //Serial.print(" "); baca_status(); if (last_second!=second()){ Serial.print(current_mA); Serial.print(","); //Serial.print(resistor_voltage); //Serial.print(","); //Serial.print(dac_voltage); //Serial.print(","); //Serial.print(regulator_voltage); //Serial.print(","); Serial.println(tegangan_baterai); last_second=kedua(); }}
hw.inoArduino
float get_approximated_dac_voltage(float vbat){ //float offset_voltage=1.2/R3*(R3+R4); float offset_voltage=1.2; float adc_voltage=(vbat-offset_voltage)/AMP_GAIN-0.5; jika (adc_voltage<0) adc_voltage=0; kembali adc_voltage;}int voltage_to_code(voltase mengambang){ int code=4095.0/DAC_REF_VOLTAGE*voltage; kode kembali;}void dac_write(int code){ Wire.beginTransmission(MCP4725_ADDR); Kawat.tulis(64); // cmd untuk memperbarui DAC Wire.write(code>> 4); // 8 bit paling signifikan... Wire.write((code &15) <<4); // 4 bit paling tidak signifikan... Wire.endTransmission();}void read_status(){ voltage_sum=0; jumlah_saat ini=0; untuk (i=0;i=POINTS_FOR_AVERAGING) indeks_rata-rata=0; if(tmp_battery_voltage>MAXIMUM_BATTERY_VOLTAGE) { disconnect_charging_circuit(); // Putuskan sambungan pengisi daya dari pengisi daya baterai_status =TEGANGAN BERLEBIHAN; } if (tmp_current_mA>MAXIMIM_ALLOWED_CURRENT ){ disconnect_charging_circuit(); // Putuskan sambungan pengisi daya dari pengisi daya baterai_status=SULIT; }}void disconnect_charging_circuit(){ digitalWrite(CHARGE_RELAY_PIN,DISCONNECT_CHARGE_RELAY); //Putuskan sambungan pengisi daya dari baterai}void connect_charging_circuit(){ digitalWrite(CHARGE_RELAY_PIN,CONNECT_CHARGE_RELAY); //Hubungkan pengisi daya ke baterai}//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(baris_kedua); if (lcd_last_string1!=baris_pertama){ lcd.clear(); lcd.setCursor(0,0); lcd.print(baris_pertama); lcd_last_string1=baris_pertama; lcd.setCursor(0,1); lcd.print(baris_kedua); lcd_last_string2=baris_kedua; } if(lcd_last_second!=second()){ if (lcd_last_string2!=second_line){ lcd.setCursor(0,1); lcd.print(baris_kedua); lcd_last_string2=baris_kedua; } } lcd_last_second=second();}String construct_status_string(void){ String v,i; if (tegangan_baterai<10) v=String(tegangan_baterai, 2); lain v=String(tegangan_baterai, 1); if (current_mA<10) i=String(current_mA, 2); else i=String(current_mA, 1); //Serial.println(v); waktu saya telah berlalu; String pesan,msg_time; //Serial.print(pengisian_mulai); //Serial.print(" "); //Serial.println(String(millis()-charging_started)); switch(charger_state){ case CHARGING:elapsed=mills2time(ChargingTimeMillis); merusak; case TRICKLE:elapsed=mills2time(TrickleChargingTimeMillis); merusak; } 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; merusak; case TRICKLE:msg=v+String(F("V "))+i+String(F("mA"))+" "+msg_time; merusak; 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
Tidak ada pratinjau (hanya unduhan).

Skema

charger_AgK96zxw2T.zip

Proses manufaktur

  1. Alarm Tanaman Peringatan Haus
  2. Jam Kata Italia
  3. Hanya Tiga Pin untuk Keypad 4x3
  4. Sigfox kWh Meter
  5. Pemantau Suhu Bluetooth
  6. Kunci yang Dikendalikan Gerakan
  7. IC Pendamping
  8. Adaptor MIDI USB
  9. Input Analog Terisolasi untuk Arduino
  10. Ukur waktu reaksi Anda