Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Intelligentes Ladegerät für 9V NiMH-Akkus V1

Komponenten und Verbrauchsmaterialien

Arduino UNO
× 1
SparkFun I2C DAC Breakout - MCP4725
× 1
Linearregler mit einstellbarem Ausgang
× 1
Texas Instruments Dual Op-Amp für allgemeine Zwecke
× 1
Widerstand 6,8 ​​kOhm
× 2
Widerstand 3,3 kOhm
× 1
Widerstand 5,1 kOhm
× 1
Widerstand 1k Ohm
× 1
Widerstand 10 Ohm
× 1
Relais (generisch)
× 1
Widerstand 20k Ohm
× 1
SparkFun Breadboard Netzteil 5V/3,3V
× 1
Stromversorgung 17V
× 1
YwRobot I2C SERIELLES LCD 1602 MODUL
× 1

Über dieses Projekt

Ich habe nach einem intelligenten Ladegerät gesucht, das einen 9-V-NiMH-Akku in wenigen Stunden aufladen kann, und habe keinen gefunden. Außerdem waren alle Ladegeräte, die ich fand, wirklich "dumm". Ladestrom unbekannt und keine Funktion zum Beenden des Ladevorgangs nach vollständiger Ladung der Batterie. Problem mit solchen Ladegeräten, dass sie den Akku überladen und die Lebensdauer erheblich verkürzen können. Also beschloss ich, ein "intelligentes" Ladegerät zu entwickeln.

Die erste Version möchte ich einfach halten, sodass grundlegende Dinge wie Laden mit konstantem Strom, automatische Ladebeendigung nach vollständiger Ladung der Batterie, Erhaltungsladung, Messung der auf die Batterie übertragenen Ladung möglich sind.

In der nächsten Version werde ich einige zusätzliche nützliche Funktionen wie Entladen, Kapazitätsmessung und Radfahren hinzufügen.

Warnung:Das Aufladen des Akkus mit hohem Strom kann zu einer Explosion oder einem Brand des Akkus führen. Bitte lassen Sie das Ladegerät nicht unbeaufsichtigt. Versuchen Sie auch nicht, Batterien aufzuladen, die nicht als Alkaline aufgeladen werden sollen. Dieses Ladegerät wurde nur mit NiMH-Akkus getestet (und Sie verwenden es trotzdem auf eigene Gefahr und ich übernehme absolut keine Verantwortung für Schäden, die durch Fehler im Design oder Code verursacht werden). Bei anderen Batterietypen ist eine Codeänderung erforderlich.

Theorie

Einige nützliche Fakten, die Sie sich merken sollten, um die erforderlichen Parameter des Ladegeräts zu verstehen.

C - Strom gleich der Nennkapazität der Batterie

Beim Laden mit der C-Rate kann die Einzelzellenspannung 1,6 V erreichen. Bei alten Batterien kann diese Spannung höher sein.

Die Nennspannung einer einzelnen Zelle beträgt 1,2 V, aber eine vollständig geladene Zelle hat eine Leerlaufspannung von bis zu 1,5 Volt.

Nach vollständiger Aufladung der Batterie wird eine Erhaltungsladerate von weniger als 0,025 C (C/40) empfohlen.

Es gibt im Allgemeinen zwei Möglichkeiten, einen NiMH-Akku aufzuladen:

1. Schnelles Aufladen. Ladestrom 0,5C-1C. Ladezustand muss durch dV/dt (Spannungsänderungsrate) oder dT/dt (Temperaturänderungsrate) überwacht und beendet werden

2. Langsames Aufladen. Ladestrom 0,1C. Ladezeit 14-16 Stunden. Ladebeendigung durch Timer. dT/dt-Ladeterminierung bei niedrigen Strömen nicht möglich. Die dV/dt-Terminierung ist gemäß der Literatur für Ströme unter 0,5 C möglicherweise nicht zuverlässig.

Grundparameter der Ladeschaltung

9-V-Batterien haben normalerweise 7 seriell verbundene Batterien, aber in einigen Fällen kann sie 6 oder 8 Zellen haben. Der Spannungsregler sollte in der Lage sein, eine Ladespannung von mindestens 8 * 1,6 =12,8 V bereitzustellen. Dropout-Spannung des LM317-Reglers bis zu 2 V, daher muss die Versorgungsspannung ~15 V betragen (ohne den Spannungsabfall am Strommesswiderstand zu berücksichtigen).

Für einen maximalen Ladestrom von 200 mA und einen Strommesswiderstand von 10 Ohm beträgt der zusätzliche Abfall am Strommesswiderstand 2 V, sodass eine Versorgungsspannung von 17 V erforderlich ist.

Eine vollständig entladene Zelle kann eine sehr niedrige, sogar negative Spannung haben. Die Mindestspannung des Reglers sollte idealerweise 0 sein, aber mit LM317 kann sie nur 1,2 V betragen.

Schaltung

Schaltungserklärungen

Die Grundidee besteht darin, den Ladestrom zu messen und die Spannung des Reglers anzupassen, bis der gewünschte Strom erreicht ist. Strom gemessen durch Messung des Spannungsabfalls am Strommesswiderstand R5. I=V/R.

SparkFun I2C DAC Breakout - MCP4725 - 12-Bit-Digital-Analog-Wandler zur Spannungsregelung. Die Ausgangsspannung kann über I2C zwischen 0 und 5V konfiguriert werden. Da wir in der Lage sein müssen, die Spannung in einem größeren Bereich einzustellen, wird der Operationsverstärker LM358 von 0 bis 15 V verwendet, um die Ausgangsspannung des DAC zu verstärken. Verstärkung des Operationsverstärkersatzes durch die Widerstände R4 und R3. Gain=1+R4/R3=1+6800/3300=3,06 also Ausgangsspannung des Operationsverstärkers ca. 0 bis 15V.

Der maximale Ausgangsstrom des LM358 beträgt 50 mA, daher wird der einstellbare Spannungsregler LM317 zur Steuerung eines höheren Stroms verwendet. Ausgang des Operationsverstärkers an ADJ-Klemme von LM317 angeschlossen. Der LM317 hält 1,2 V zwischen den ADJ- und OUT-Anschlüssen, sodass die tatsächliche Spannung an der Batterie zwischen 1,2 und 16,2 V konfiguriert werden kann. LM317 benötigt mindestens 3,5 mA Strom, um die Regulierung aufrechtzuerhalten. Der 1kOhm-Widerstand R6 wird also verwendet, um die Regelung zu gewährleisten, wenn die Batterie nicht angeschlossen ist. Kondensator C1 wird verwendet, um die Ausgangsspannung zu filtern und die Stabilität von LM317 zu verbessern.

Spannung an zwei verschiedenen Punkten gemessen.

1. Widerstand R5 an Pin A2 von Arduino angeschlossen. Spannung am Widerstand gemessen und dann Ladestrom berechnet als Icharging=V/R

2. Die Spannung an der Batterie kann bis zu 16,2 V betragen, daher wird der Widerstandsteiler R1, R2 verwendet, um die Spannung unter 5 V zu bringen, was von Arduino erlaubt ist. Ausgang des Teilers, der mit Pin A0 von Arduino verbunden ist. Für R1=5.1k Ohm und R2=20kOhm Vout=Vin/(20000+5100)*5100=0.2 Also Batteriespannung geteilt durch 5.

Relais zum Trennen der Batterie vom Ladestromkreis. Sie können das von mir verwendete Fotorelais sehen, aber im Allgemeinen kann jedes Relais mit 5 V-Steuerung verwendet werden. Es ist sicherer, die Batterie an die normalerweise offenen Kontakte des Relais anzuschließen.

Ich habe YwRobot I2C SERIAL LCD 1602 MODULE verwendet, um den Status des Ladegeräts anzuzeigen, aber jedes andere I2C-gesteuerte LCD-Modul kann verwendet werden. Anscheinend wird das YwRobot-LCD-Modul von der Standardbibliothek LiquidCrystal_I2C nicht unterstützt, daher habe ich die neue LiquidCrystal-Bibliothek verwendet. Wenn Sie ein anderes LCD-Modul verwenden, müssen Sie diese Zeile ändern:

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIV); // setze die LCD-Adresse auf 0x27 für eine 16-stellige und 2-zeilige Anzeige 

Um den Digital-Analog-Wandler und das LCD mit Strom zu versorgen, habe ich das SparkFun-Breadboard-Netzteil 5 V / 3,3 V verwendet. Es ist wahrscheinlich in Ordnung, 5V vom Arduino-Board zu verwenden.

Sie müssen auch 17 V an den Ladestromkreis liefern. Wenn Sie kein Netzteil haben, können Sie einen einstellbaren DC/DC-Wandler wie diesen verwenden

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

Funktionalität

Ich wollte nicht viele Kabel haben, daher gibt es keine Tasten zum Konfigurieren des Ladevorgangs. Ärger aktuell nur im Code konfiguriert. Sie müssen den gewünschten Ladestrom in charge.ino einstellen

//**************************** Ladeparameter ************* **************************** //******************** ************************************************* ****************** float target_current_mA=30; // Ladestrom mAfloat Battery_nominal_capacity_mA =170; //Nennkapazität der Batterie mAfloat max_time_for_trickle_charge=6; //Maximale Erhaltungsladezeit in Minuten //**************************************** ************************************************/ /************************************************ ************************************** 

target_current_mA - konstanter Ladestrom

max_time_for_trickle_charge - maximale Anzahl an Minuten für Erhaltungsladung, einstellbar bis 600 (10h)

battery_nominal_capacity_mA - Batteriekapazität zur Berechnung des Erhaltungsstroms

Generell kann der Ladestrom bis zur Nennkapazität betragen. Für Akkus mit einer Nennkapazität von 170 mAh beträgt der maximale Ladestrom 170 mA. Mindestladestrom normalerweise C/10 - 17mA für 170mAh Akku.

Nach dem Einschalten überprüft das Ladegerät, ob die Batterie angeschlossen ist. Bei angeschlossenem Akku wird der Akku mit konfiguriertem Konstantstrom geladen, bis er vollständig geladen ist. Der Ladevorgang wurde durch Erkennen von negativem dV/dt während 5 Minuten beendet. Nachdem der Ladevorgang abgeschlossen ist, schaltet das Ladegerät auf Erhaltungsladung mit Strom C/40 um. Das Ladegerät trennt sich nach Ablauf der maximalen Erhaltungsladezeit von der Batterie.

1 - dV/dt

2 - Ladezeit in Minuten

1 - Ladezeit

2 - Ladung auf Batterie übertragen

Zusätzliche Informationen zu NiMH-Akkus:

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

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

Code

  • charger.ino
  • main.ino
  • hw.ino
  • lcd.ino
  • calculations.ino
  • Neue LiquidCrystal-Bibliothek für dieses Projekt verwendet
charger.inoArduino
Hauptdatei
//THis zum Laden von 9V NiMH Akkus //Batterie kann 6,7 oder 8 1,25V Zellen haben //Dies ergibt eine Nennspannung zwischen 7,5 und 10V#include #include #include  #include #include LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // setze die LCD-Adresse auf 0x27 für eine 16-stellige und 2-zeilige Anzeige // Hardware-Definitionen#define MCP4725_ADDR 0x60 //DAC-Adresse#define DAC_REF_VOLTAGE 5.0#define CHARGE_RELAY_PIN 2#define DISCONNECT_CHARGE_RELAY HIGH#define CONNECT_CHARGESEN_RELAYCURRENT_define CURRENT_SENSING_SESISTOR 10.2 //OHm#define BATTERY_VOLTAGE_PIN A0#define R1 5090 //Low-Side-Widerstand des Spannungsmessteilers#define R2 19910//High-Side-Widerstand des Spannungsmessteilers#define ADC_REF_VOLTAGE 4.89 //Arduino reale Versorgungsspannung oder AREF-Spannung für richtiges ADC-Spannungsübersetzung#define R3 3300.0#define R4 6800.0#define AMP_GAIN (1+R4/R3)//Verschiedene Definitionen//#define MINIMUM_VOLTAGE 8.1 //Minimale Spannung nach dem Regler#define BATTERY_GOOD_VOLTAGE_THRESHOLD 7.0#define MAXIMIM_ALLOWED_imum Batteriestrom mA (harte Abschaltung)#define MAXIMUM_BATTERY_VOLTAGE 15.0 //Maximal zulässige Batteriespannung V (harte Abschaltung)#define VOLTAGE_STEP 0.001 //Schritt für Spannung Regulation#define POINTS_FOR_AVERAGING 100 //Wie viele Punkte für die Mittelwertbildung verwendet werden#define MEASURE2MEASURE_US 5000 //Zeit zwischen den Messungen in Mikrosekunden (muss mehr als 200 sein wegen zwei analogen Lesevorgängen)#define VOLTAGE_LOG_TIME_MIN 30.0 //Zeit in Minuten zum Speichern der Spannung für dV /dT cutoff#define MINUTES_TO_LOG 5#define TRICKLE_CURRENT_RATIO 40//Ladezustände#define INITIALIZATION 0#define NO_BATTERY 5#define BATTERY_CONNECTED 10#define BATTERY_VOLTAGE_LOW 15#define CURRENT_RAMP_UP 20#_define CHARCUEND_DE_define 32#define CHARCUENDTRICK_define 35 37 # 40 # definieren UNEXPECTED_CURRENT_FALL definieren UNABLE_TO_REACH_CURRENT 60 # 70 # define FULLY_CHARGED definieren CURRENT_TOO_HIGH 80 # 90 # definieren REGULATION_FAILED definieren ÜBERSTROMÜBERSPANNUNGS 100 # 101 # 200 /// End_Zustand unsigned int voltage_readings [POINTS_FOR_AVERAGING], current_sensing_resistor_readings [POINTS_FOR_AVERAGING], averaging_index definieren, definieren; //Für eine Mittelwertbildung ohne Vorzeichen int voltage_sum,current_sum;//Summe der Mittelwertbildungf loat regulator_voltage_code,resistor_voltage,csr_voltage_code,regulator_voltage,current_mA,battery_voltage;//Measurmentsfloat tmp_resistor_voltage,tmp_current_mA,tmp_regulator_volt,tmp_battery_voltage;int i,j,charger_state;;String msg,eoc_line1,eoc_line2;unsigned char sec_index,min_index;//long long intcharging_started;float sec_log[60],min_log[MINUTES_TO_LOG],last_blf;float trickle_current_mA;int total_minutes_average=0;CharlapsedTimeMillis Voltage=0;CharlapsedTimeMillis 0;float last_dac_voltage=0;//Messagesconst char msg_battery_detected[] PROGMEM ="Batterie erkannt";const char msg_no_battery[] PROGMEM ="Keine Batterie";const char msg_battery_ok[] PROGMEM ="Batterie in Ordnung"; PROGMEM ="Batteriespannung zu niedrig";const char msg_voltage_too_low_short[] PROGMEM ="V Batterie schwach";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 ="Erhaltungsladung ";const char msg_no_current[] PROGMEM ="Kein Strom";const char msg_current_unreachable[] PROGMEM ="I nicht erreichbar";const char msg_current_unreachable_long[] PROGMEM ="Der gewünschte Strom kann nicht erreicht werden";const char msg_completed="[] PROGMEM ";const char msg_charge[] PROGMEM ="Charge";const char msg_high_current[] PROGMEM ="Hoher Strom";const char msg_regulation_fault[] PROGMEM ="Regelfehler";const char msg_overcurrent[] PROGMEM ="Strom zu hoch"; const char msg_overvoltage[] PROGMEM ="Spannung zu hoch";const char msg_trickle_completed[] PROGMEM ="Trickle beendet";//************************ **** Ladeparameter **************************************** //* ************************************************* ************************************* Float target_current_mA=30; // Ladestrom mAfloat Battery_nominal_capacity_mA =170; //Nennkapazität der Batterie mAfloat max_time_for_trickle_charge=6; //Maximale Erhaltungsladezeit in Minuten //**************************************** ************************************************/ /************************************************ **************************************struct mytime { unsigned char hours; nicht signierte Zeichenminuten; unsigned int total_minutes;} elapsed_time;void setup () { pinMode (CHARGE_RELAY_PIN, OUTPUT); Disconnect_Charging_Circuit(); // Trennen Sie das Ladegerät von der Batterie Wire.begin (); // I2C dac_write_voltage (0); // Stellen Sie sicher, dass der niedrigere mögliche Strom eingestellt ist Serial.begin (115200); last_second=second(); lcd_last_second=second(); log_last_second=second(); Timer1.initialize(MEASURE2MEASURE_US); // Wird verwendet, um Spannung und Strom der Batterie (Mikrosekunden) zu messen Timer1.attachInterrupt (read_hw); // fügt read_hw () als Timer-Überlauf-Interrupt an averaging_index=0; sec_index=0; min_index=0; charger_state=0;//Anfangszustand der Zustandsmaschine Wanted_dac_Voltage=0;//Stellen Sie den minimalen Spannungsausgang sicher last_blf=1.0; trickle_current_mA=battery_nominal_capacity_mA/TRICKLE_CURRENT_RATIO; //ChargingTimeMillis=0; // LCD lcd.begin (16,2); LCD-Rücklicht(); lcd.clear(); update_lcd(F("Power up..."),empty_string); delay(1000);}float log_battery_voltage(){//Nur einmal pro Sekunde protokollieren if (log_last_second==second()) return last_blf; sonst log_last_second=second(); sec_log[sec_index]=Batteriespannung; if (sec_index<59) { sec_index++; } else {//Wenn eine Minute protokolliert wurde //Berechnen Sie den Durchschnitt pro Minute if (min_index>=MINUTES_TO_LOG) min_index=0; sec_index=0; Schwimmersumme_v=0; für (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();//Stellen Sie das Shure-Relais getrennt dac_write_Voltage(0);//Stellen Sie sicher, dass der niedrigere mögliche Strom gesetzt wird Wanted_dac_Voltage=0;//Stellen Sie sicher, dass die Shure minimale Spannungsausgangsverzögerung eingestellt ist (100); read_status(); if (battery_voltage>0.1) {charger_state=BATTERY_CONNECTED; // Batterie erkannt update_lcd (M2S (msg_battery_detected), empty_string); Serial.println (M2S (msg_battery_detected)); Verzögerung (2000); aufrechtzuerhalten. Sonst {//Keine Batterie Serial.println (M2S (msg_no_battery)); update_lcd(M2S(msg_no_battery),construct_status_string()); Charger_state =NO_BATTERY; // Batterie erkannt Verzögerung (1000); } brechen; case NO_BATTERY://Keine Batterie read_status(); if (battery_voltage>0.1) {charger_state=BATTERY_CONNECTED; // Batterie erkannt Serial.println (M2S (msg_battery_detected)); update_lcd(M2S(msg_battery_detected),construct_status_string()); Verzögerung (1500); } else{//Wenn keine Batterie in diesem Zustand bleibt update_lcd(M2S(msg_no_battery),construct_status_string()); Verzögerung (1100); } brechen; case BATTERY_CONNECTED://Battery connected dac_write_voltage(0);//Stellen Sie sicher, dass der niedrigere mögliche Strom eingestellt ist want_dac_voltage=0; Verzögerung (100); read_status(); if (battery_voltage>BATTERY_GOOD_VOLTAGE_THRESHOLD){charger_state=CURRENT_RAMP_UP; // Ladestromhochlauf starten //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)); Verzögerung (2000); Wanted_dac_Voltage=get_approximated_dac_Voltage (Battery_Voltage); // Benötigte Reglerspannung einstellen //Serial.println (get_approximated_dac_voltage (Battery_Voltage)); connect_charging_circuit(); Verzögerung (200); aufrechtzuerhalten. Sonst {charger_state =BATTERY_VOLTAGE_LOW; // Batteriespannung zu niedrig Serial.println (M2S (msg_voltage_too_low)); update_lcd(M2S(msg_voltage_too_low_short),construct_status_string()); Verzögerung (1000); } brechen; case BATTERY_VOLTAGE_LOW://Batteriespannung zu niedrig update_lcd(M2S(msg_voltage_too_low_short),construct_status_string()); Serial.println (M2S (msg_voltage_too_low)); charge_state=FINAL_STATE; // Pause anhalten; case CURRENT_RAMP_UP:///Current rampup //if (current_mA<1.0) Charger_state=40;//Strom unerwartet gefallen read_status(); update_lcd(M2S(msg_ramp_up),construct_status_string()); Verzögerung (50); if (current_mAMAXIMUM_BATTERY_VOLTAGE ) Charger_state=OVERVOLTAGE;//Überspannung if (abs(current_mA-target_current_mA)>0.2){//If current (deviated) 0.01) Wanted_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; else charge_state=CURRENT_TOO_HIGH;//Strom zu hoch, kann nicht gesenkt werden } } if (abs(current_mA-target_current_mA)>5){//Regulierung fehlgeschlagen, Differenz zu hoch charge_state=REGULATION_FAILED;//Regelfehler, Differenz zu hoch } dac_write_voltage (wollte_dac_Spannung); if (total_minutes_averagetrickle_current_mA) { if (wanted_dac_voltage>VOLTAGE_STEP) { Wanted_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; dac_write_voltage (gesuchte_dac_spannung); } Else Charger_state =CURRENT_TOO_HIGH; // Strom kann nicht auf Erhaltungsrate reduziert werden } Else { Charger_state =TRICKLE; // Aufladen TrickleChargingTimeMillis =0; Serial.println (M2S (msg_trickle_charge)); } brechen; Fall TRICKLE://Ladeverzögerung (200); read_status(); if (current_mA<0.2) charge_state=UNEXPECTED_CURRENT_FALL;//Strom unerwartet gefallen if (battery_voltage>MAXIMUM_BATTERY_VOLTAGE ) Charger_state=OVERVOLTAGE;//Überspannung if (abs(current_mA-trickle_current_mA)>0.2){//If current (deviatedA) 0.01) Wanted_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; else charge_state=CURRENT_TOO_HIGH; // Strom zu hoch, kann nicht gesenkt werden } } if (abs(current_mA-trickle_current_mA)>5){//Regelung fehlgeschlagen, Differenz zu hoch charge_state=REGULATION_FAILED;//Regelfehler, Differenz zu hoch } dac_write_voltage (wollte_dac_Spannung); //if (total_minutes_averagemax_time_for_trickle_charge) {//Maximal zulässige Erhaltungsladung update_lcd(eoc_line1,eoc_line2); charger_state=END_OF_TRICKLE;//Halte Disconnect_charging_circuit(); // Ladegerät vom Akku trennen} Pause; Fall END_OF_TRICKLE:if ((second()%8)<4) update_lcd(M2S(msg_trickle_completed),construct_status_string()); sonst update_lcd(eoc_line1,eoc_line2); brechen; Fall UNEXPECTED_CURRENT_FALL:// Der Strom ist unerwartet gefallen Serial.println (F ("Der Strom ist unerwartet gefallen")); Disconnect_Charging_Circuit(); Wanted_dac_Voltage=0; update_lcd(M2S(msg_no_current),construct_status_string()); charge_state =FINAL_STATE; // Verzögerung anhalten (1000); brechen; Fall UNABLE_TO_REACH_CURRENT:// Kann die gewünschte aktuelle Serial.println (M2S (msg_current_unreachable_long) nicht erreichen); Disconnect_Charging_Circuit(); Wanted_dac_Voltage=0; dac_write_voltage (gesuchte_dac_spannung); Verzögerung (1000); update_lcd(M2S(msg_current_unreachable),construct_status_string()); charge_state=FINAL_STATE; // Pause anhalten; Fall FULLY_CHARGED://Voll aufgeladen 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=Nachricht; eoc_line2=msg1; update_lcd(msg,msg1); Serial.println (msg); //disconnect_charging_circuit (); //gesuchte_dac_spannung=0; //dac_write_voltage (wanted_dac_voltage); Verzögerung (3000); charge_state=CURRENT_RAMP_DOWN; // Pause anhalten; Fall CURRENT_TOO_HIGH:// Strom zu hoch Serial.println (F ("Der Strom kann nicht auf das Ziel gesenkt werden")); Disconnect_Charging_Circuit(); Wanted_dac_Voltage=0; dac_write_volt(0); update_lcd(M2S(msg_high_current),construct_status_string()); Verzögerung (1000); charge_state=FINAL_STATE; // Pause anhalten; Fall REGULATION_FAILED://Regulation fehlgeschlagen Serial.println (M2S (msg_regulation_fault)); Disconnect_Charging_Circuit(); Wanted_dac_Voltage=0; dac_write_volt(0); update_lcd(M2S(msg_regulation_fault),construct_status_string()); Verzögerung (1000); charge_state=FINAL_STATE; // Pause anhalten; Fall ÜBERSTROM:// Überstrom Disconnect_charging_circuit(); Serial.println (M2S (msg_overcurrent)); Wanted_dac_Voltage=0; dac_write_voltage (gesuchte_dac_spannung); update_lcd(M2S(msg_overcurrent),construct_status_string()); Verzögerung (1000); charge_state=FINAL_STATE; // Pause anhalten; Fall OVERVOLTAGE://Overvoltage Disconnect_charging_Circuit(); Serial.println (M2S (msg_overvoltage)); Wanted_dac_Voltage=0; dac_write_voltage (gesuchte_dac_spannung); update_lcd(M2S(msg_overvoltage),construct_status_string()); Verzögerung (1000); charge_state=FINAL_STATE; // Pause anhalten; Fall FINAL_STATE://Halt Verzögerung (10000); brechen; Vorgabe:Wanted_dac_Voltage=0; Ladezustand =0; } //Seriell.println (aktueller_mA); //Serial.print("Aktuell="); //Seriell.print (aktueller_mA); //Seriell.println("mA"); // Serial.print ( "DAC-Spannung"); // Serial.println (dac_voltage); // Serial.print ( "Gesuchte DAC-Spannung"); // Serial.println (wanted_dac_voltage); //Seriell.print (aktueller_mA); //Seriendruck(" "); // Serial.print (dac_voltage); //Seriendruck(" "); read_status(); if (last_second! =second()) {Serial.print (current_mA); Serial.print (","); // Serial.print (Widerstandsspannung); //Seriendruck(","); // Serial.print (dac_voltage); //Seriendruck(","); // Serial.print (Regler_Spannung); //Seriendruck(","); Serial.println (Batteriespannung); last_second=second(); }}
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; if (adc_voltage<0) adc_volt=0; return adc_voltage;}int voltage_to_code (Float-Spannung) {int code =4095,0/DAC_REF_VOLTAGE * voltage; Rückgabecode;}void dac_write (int code) { Wire.beginTransmission (MCP4725_ADDR); Wire.write(64); // cmd zum Aktualisieren des DAC Wire.write (Code>> 4); // die 8 höchstwertigen Bits... Wire.write((code &15) <<4); // die 4 niederwertigsten Bits... Wire.endTransmission();}void read_status(){ voltage_sum=0; aktuelle_summe=0; for (i=0;i=POINTS_FOR_AVERAGING) averaging_index=0; if(tmp_battery_voltage>MAXIMUM_BATTERY_VOLTAGE) {disconnect_charging_circuit(); // Ladegerät vom Batterieladegerät trennen_state=OVERVOLTAGE; aufrechtzuerhalten. Wenn (tmp_current_mA>MAXIMIM_ALLOWED_CURRENT){disconnect_charging_circuit(); // Ladegerät vom Batterieladegerät trennen_state=OVERCURRENT; }}void Disconnect_charging_circuit () { digitalWrite (CHARGE_RELAY_PIN, DISCONNECT_CHARGE_RELAY); // Ladegerät von Batterie trennen}void connect_charging_circuit () { digitalWrite (CHARGE_RELAY_PIN,CONNECT_CHARGE_RELAY); //Ladegerät an Batterie anschließen}//sec_index=0;//min_index=0;
lcd.inoArduino
void update_lcd(String first_line,String second_line){//Serial.print("update_lcd"); //Seriendruck (lcd_last_string2); //Seriendruck(" "); //Seriell.println (zweite_Zeile); if (lcd_last_string1!=first_line){lcd.clear(); lcd.setCursor(0,0); lcd.print (erste_Zeile); lcd_last_string1=erste_Zeile; lcd.setCursor(0,1); lcd.print (zweite_Zeile); lcd_last_string2=zweite_Zeile; } if(lcd_last_second!=second()){ if (lcd_last_string2!=second_line){lcd.setCursor(0,1); lcd.print (zweite_Zeile); lcd_last_string2=zweite_Zeile; } } lcd_last_second=second();}String construct_status_string(void){ String v,i; if (Batteriespannung <10) v =String (Batteriespannung, 2); sonst v =String (Batteriespannung, 1); if (aktueller_mA<10) i=String(aktueller_mA, 2); sonst i=String(current_mA, 1); //Seriell.println(v); meine Zeit ist abgelaufen; Zeichenfolge msg,msg_time; // Serial.print (aufladen_gestartet); //Seriendruck(" "); //Serial.println(String(millis()-charging_started)); switch (charger_state) { case CHARGING:elapsed =Mills2time (ChargingTimeMillis); brechen; Fall TRICKLE:elapsed=mills2time(TrickleChargingTimeMillis); brechen; } 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; brechen; case TRICKLE:msg=v+String(F("V "))+i+String(F("mA"))+" "+msg_time; brechen; 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
Keine Vorschau (nur Download).

Schaltpläne

charger_AgK96zxw2T.zip

Herstellungsprozess

  1. Pflanzenalarm bei Durstalarm
  2. italienische Wordclock
  3. Nur drei Pins für eine 4x3-Tastatur
  4. Sigfox-kWh-Zähler
  5. Bluetooth-Temperaturüberwachung
  6. Gestengesteuerte Sperre
  7. Der Companion-IC
  8. USB-MIDI-Adapter
  9. Ein isolierter Analogeingang für Arduino
  10. Messen Sie Ihre Reaktionszeit