Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Intelligente oplader voor 9V NiMH oplaadbare batterijen V1

Componenten en benodigdheden

Arduino UNO
× 1
SparkFun I2C DAC Breakout - MCP4725
× 1
Lineaire regelaar met instelbare uitgang
× 1
Texas Instruments Dual Op-Amp voor algemeen gebruik
× 1
Weerstand 6,8k ohm
× 2
Weerstand 3,3k ohm
× 1
Weerstand 5,1k ohm
× 1
Weerstand 1k ohm
× 1
Weerstand 10 ohm
× 1
Relais (algemeen)
× 1
Weerstand 20k ohm
× 1
SparkFun Breadboard-voeding 5V/3,3V
× 1
Voeding 17V
× 1
YwRobot I2C SERILE LCD 1602 MODULE
× 1

Over dit project

Ik heb gezocht naar een slimme oplader die de 9V NiMH-batterij in een paar uur kan opladen en heb er geen gevonden. Bovendien waren alle opladers die ik vond echt "dom". Laadstroom onbekend en geen functie om het opladen te beëindigen nadat de batterij volledig is opgeladen. Het probleem met dergelijke opladers is dat ze de batterij kunnen overladen en de levensduur aanzienlijk kunnen verkorten. Dus besloot ik om een ​​"slimme" oplader te maken.

De eerste versie wil ik eenvoudig houden, zodat basisdingen mogelijk zijn, zoals opladen met constante stroom, automatische beëindiging van het opladen nadat de batterij volledig is opgeladen, druppellading, meting van de lading die naar de batterij wordt overgebracht.

In de volgende versie zal ik een aantal extra handige functies toevoegen, zoals ontlading, capaciteitsmeting en fietsen.

Waarschuwing:Het opladen van de batterij met een hoge stroomsterkte kan een batterijexplosie of brand veroorzaken. Laat de oplader niet onbeheerd achter. Probeer ook niet de batterij op te laden die niet bedoeld is om als Alkaline te worden opgeladen. Deze oplader is alleen getest met NiMH-batterijen (en u gebruikt hem nog steeds op eigen risico en ik ben absoluut niet verantwoordelijk voor eventuele schade veroorzaakt door fouten in het ontwerp of de code). Bij ergernis over andere typen batterijen moet de code worden gewijzigd.

Theorie

Enkele nuttige feiten om te onthouden die u zullen helpen de benodigde parameters van de oplader te begrijpen.

C - stroom gelijk aan nominale capaciteit van batterij

Wanneer opgeladen met de C-snelheid, kan de spanning van een enkele cel 1,6 V bereiken. Deze spanning kan hoger zijn voor oude batterijen.

De nominale spanning van een enkele cel is 1,2 V, maar een volledig opgeladen cel heeft een nullastspanning tot 1,5 volt.

Een druppellaadsnelheid van minder dan 0,025 C (C/40) wordt aanbevolen nadat de batterij volledig is opgeladen.

Er zijn over het algemeen twee opties om de NiMH-batterij op te laden:

1. Snel opladen. Laadstroom 0.5C-1C. De laadstatus moet worden bewaakt en beëindigd door dV/dt (spanningsveranderingssnelheid) of dT/dt (temperatuurveranderingssnelheid)

2. Langzaam opladen. Laadstroom 0.1C. Oplaadtijd 14-16 uur. Laadbeëindiging door timer. dT/dt ladingsbeëindiging onmogelijk voor lage stromen. dV/dt-afsluiting is volgens de literatuur mogelijk niet betrouwbaar voor stromen onder 0,5C.

Basisparameters van laadcircuit

Een 9V-batterij heeft meestal 7 serieel aangesloten verkopen, maar in sommige gevallen kan deze 6 of 8 cellen hebben. De spanningsregelaar moet een laadspanning van minimaal 8*1.6=12.8V kunnen leveren. Uitvalspanning van de LM317-regelaar tot 2V, dus de voedingsspanning moet ~15V zijn (zonder rekening te houden met de spanningsval op de stroomdetectieweerstand).

Voor een maximale laadstroom van 200mA en een stroomdetectieweerstand van 10 Ohm is een extra daling van de stroomdetectieweerstand 2V, dus 17V voedingsspanning nodig.

Een volledig ontladen cel kan een zeer lage, zelfs negatieve spanning hebben. De minimale spanning van de regelaar zou idealiter 0 moeten zijn, maar bij gebruik van LM317 kan deze zo laag zijn als 1,2 V.

Circuit

Circuit uitleg

Het basisidee is om de laadstroom te meten en de spanning van de regelaar aan te passen totdat de gewenste stroom is bereikt. Stroom gemeten door spanningsval te meten op stroomdetectieweerstand R5. I=V/R.

SparkFun I2C DAC Breakout - MCP4725 - 12 bit digitaal naar analoog converter gebruikt om de spanning te regelen. Uitgangsspanning kan via I2C worden geconfigureerd tussen 0 en 5V. Omdat we de spanning in een groter bereik moeten kunnen aanpassen, werd de operationele versterker LM358 van 0 tot 15V gebruikt om de uitgangsspanning van DAC te versterken. Versterking van operationele versterker ingesteld door weerstanden R4 en R3. Gain=1+R4/R3=1+6800/3300=3.06 dus uitgangsspanning van operationele versterker ongeveer 0 tot 15V.

De maximale uitgangsstroom van de LM358 is 50mA, dus de instelbare spanningsregelaar van de LM317 wordt gebruikt om een ​​hogere stroom te regelen. Uitgang van operationele versterker aangesloten op ADJ-aansluiting van LM317. De LM317 behoudt 1,2 V tussen de ADJ- en OUT-aansluitingen, dus de werkelijke spanning op de batterij kan worden geconfigureerd tussen 1,2 en 16,2 V. LM317 heeft minimaal 3,5 mA stroom nodig om de regelgeving te handhaven. Dus 1kOhm weerstand R6 gebruikt om te zorgen voor regeling als de batterij niet is aangesloten. Condensator C1 gebruikt om de uitgangsspanning te filteren en de stabiliteit van LM317 te verbeteren.

Spanning gemeten op twee verschillende punten.

1. Weerstand R5 aangesloten op pin A2 van Arduino. Spanning op weerstand gemeten en dan laadstroom berekend als Icharging=V/R

2. De spanning op de batterij kan oplopen tot 16,2 V, dus resistieve verdeler R1, R2 wordt gebruikt om de spanning onder de 5 V te brengen, toegestaan ​​door Arduino. Uitgang van verdeler aangesloten op pin A0 van Arduino. Voor R1=5.1k Ohm en R2=20kOhm Vout=Vin/(20000+5100)*5100=0,2 Dus accuspanning gedeeld door 5.

Relais dat wordt gebruikt om de accu los te koppelen van het laadcircuit. Je kunt het zien op het fotorelais dat ik heb gebruikt, maar over het algemeen kan elk relais met 5V-besturing worden gebruikt. Het is veiliger om de batterij aan te sluiten op normaal open contacten van het relais.

Ik heb YwRobot I2C SERIAL LCD 1602 MODULE gebruikt om de status van de oplader weer te geven, maar elke andere I2C-gestuurde LCD-module kan worden gebruikt. Het lijkt erop dat de YwRobot LCD-module niet wordt ondersteund door de standaard LiquidCrystal_I2C-bibliotheek, dus ik heb de nieuwe LiquidCrystal-bibliotheek gebruikt. Als u een andere LCD-module gebruikt, moet u deze regel wijzigen:

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIEF); // stel het LCD-adres in op 0x27 voor een display van 16 tekens en 2 regels 

Om de digitaal-naar-analoog-omzetter en het LCD-scherm van stroom te voorzien, heb ik SparkFun Breadboard-voeding 5V / 3,3V gebruikt. Het is waarschijnlijk oké om 5V van het Arduino-bord te gebruiken.

U moet ook 17 V leveren aan het laadcircuit. Als je geen voeding hebt, kun je een instelbare DC/DC-converter zoals deze gebruiken

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

Functionaliteit

Ik wilde niet veel kabels, dus er zijn geen knoppen om het opladen te configureren. Chagrin huidige alleen geconfigureerd in code. U moet de gewenste laadstroom instellen in charger.ino

//************************** Oplaadparameters *********** **************************//******************** ********************************************** ****************float target_current_mA=30; // Oplaadstroom mAfloat battery_nominal_capacity_mA=170; //Nominale capaciteit van batterij mAfloat max_time_for_trickle_charge=6; //Maximale druppellaadtijd in minuten//**************************************** **********************************************/ /************************************************** ************************************ 

target_current_mA - constante laadstroom

max_time_for_trickle_charge - maximaal aantal minuten voor druppelladen, instelbaar tot 600 (10 uur)

battery_nominal_capacity_mA - batterijcapaciteit gebruikt om druppelstroom te berekenen

Over het algemeen kan de laadstroom oplopen tot de nominale capaciteit. Voor batterijen met een nominale capaciteit van 170mAh is de maximale laadstroom 170mA. Minimale laadstroom meestal C/10 - 17mA voor 170mAh batterij.

Nadat de stroom is ingeschakeld, controleert de lader of de batterij is aangesloten. Als de batterij is aangesloten, wordt de batterij opgeladen met een geconfigureerde constante stroom totdat deze volledig is opgeladen. Het opladen is beëindigd door gedurende 5 minuten een negatieve dV/dt te detecteren. Nadat het opladen is voltooid, schakelt de lader over op druppelladen met stroom C/40. De oplader zal zichzelf loskoppelen van de batterij nadat de maximale druppellaadtijd is verstreken.

1 - dV/dt

2 - oplaadtijd in minuten

1 - Oplaadtijd

2 - Opladen overgebracht naar batterij

Aanvullende informatie over NiMH-batterijen:

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
  • Nieuwe LiquidCrystal-bibliotheek gebruikt voor dit project
charger.inoArduino
Hoofdbestand
//Dit voor het opladen van 9V NiMH-batterijen //Batterij kan 6,7 of 8 cellen van 1,25V hebben//Dit maakt een nominale spanning tussen 7,5 en 10V#include #include #include  #include #include LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIEF); // stel het LCD-adres in op 0x27 voor een display van 16 tekens en 2 regels//Hardware-definities#define MCP4725_ADDR 0x60 //DAC-adres#define DAC_REF_VOLTAGE 5.0#define CHARGE_RELAY_PIN 2#define DISCONNECT_CHARGE_RELAY HIGH#CHARGE#defineRELAY CURRENT_SENSING_SESISTOR 10.2 //OHm#define BATTERY_VOLTAGE_PIN A0#define R1 5090 //Lage zijweerstand van spanningsdeler#define R2 19910//Hoge zijweerstand van spanningsdetectiedeler#define ADC_REF_VOLTAGE 4.89 //Arduino ADC naar spanningsvertaling#define R3 3300.0#define R4 6800.0#define AMP_GAIN (1+R4/R3)//Diverse definities//#define MINIMUM_VOLTAGE 8.1 //Minimum voltage after regulator#define BATTERY_GOOD_VOLTAGE_THRESHOLD 7.0#define MAXIMRRIMENT_ALLOWED_MaximCUMIMENT_ALLOWED_MaximumCURIMENT_ALLOWED_ batterijstroom mA (harde uitschakeling)#define MAXIMUM_BATTERY_VOLTAGE 15.0 //Maximum toegestane batterijspanning V (harde uitschakeling)#define VOLTAGE_STEP 0,001 //Stap voor spanning regelgeving#define POINTS_FOR_AVERAGING 100 //Hoeveel punten genomen voor middeling#define MEASURE2MEASURE_US 5000 //Tijd tussen metingen in microseconden (moet meer dan 200 zijn vanwege twee analoge uitlezingen)#define VOLTAGE_LOG_TIME_MIN 30.0 //Tijd in minuten om spanning op te slaan voor dV /dT cutoff#define MINUTES_TO_LOG 5#define TRICKLE_CURRENT_RATIO 40//Lader toestanden#define INITIALIZATION 0#define NO_BATTERY 5#define BATTERY_CONNECTED 10#define BATTERY_VOLTAGE_LOW 15#define_CURRENT_RAMP_UP 20#define CURRENT_RAMP_UP 20#define CURRENT_RAMP_UP 20#define 37 # 40 # UNEXPECTED_CURRENT_FALL definiëren definiëren UNABLE_TO_REACH_CURRENT 60 # 70 # bepalen FULLY_CHARGED definiëren CURRENT_TOO_HIGH 80 # 90 # REGULATION_FAILED definiëren definiëren OVERCURRENT 100 # 101 # OVERVOLTAGE definiëren definiëren FINAL_STATE 200 /// unsigned int voltage_readings [POINTS_FOR_AVERAGING] current_sensing_resistor_readings [POINTS_FOR_AVERAGING] averaging_index; // Voor middeling van lange niet-ondertekende int voltage_sum,current_sum;// Som van middelingf 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;short unsigned intdstring last_korte unsigned intdstring last_korte unsigned intdstring;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=0;elapsedMillis 0;float last_dac_voltage=0;//Messagesconst char msg_battery_detected[] PROGMEM ="Batterij gedetecteerd";const char msg_no_battery[] PROGMEM ="Geen batterij";const char msg_battery_ok[] PROGMEM ="Battery msg_lowvoltage ok";const char PROGMEM ="Batterijspanning te laag";const char msg_voltage_too_low_short[] PROGMEM ="V Batterij bijna leeg";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 ="Trickle charge ";const char msg_no_current[] PROGMEM ="Geen stroom";const char msg_current_unreachable[] PROGMEM ="Ik onbereikbaar";const char msg_current_unreachable_long[] PROGMEM ="Kan gewenste stroom niet bereiken";const char msg_completed[] PROGMEM =" ";const char msg_charge[] PROGMEM ="Laden";const char msg_high_current[] PROGMEM ="Hoge stroom";const char msg_regulation_fault[] PROGMEM ="Regelfout";const char msg_overcurrent[] PROGMEM ="Stroom te hoog"; const char msg_overvoltage[] PROGMEM ="Spanning te hoog";const char msg_trickle_completed[] PROGMEM ="Trickle voltooid";//************************* **** Laadparameters ****************************************//* ********************************************** ************************************float target_current_mA=30; // Oplaadstroom mAfloat battery_nominal_capacity_mA=170; //Nominale capaciteit van batterij mAfloat max_time_for_trickle_charge=6; //Maximale druppellaadtijd in minuten//**************************************** **********************************************/ /************************************************** **************************************** struct mytime { unsigned char hours; ongetekende char minuten; unsigned int total_minutes;} elapsed_time; void setup () { pinMode (CHARGE_RELAY_PIN, OUTPUT); disconnect_charging_circuit(); //Koppel de oplader los van de batterij Wire.begin();//I2C dac_write_voltage(0);//Zorg ervoor dat de mogelijke stroom lager is ingesteld Serial.begin(115200); last_second=second(); lcd_last_second=seconde(); log_last_second=second(); Timer1.initialize(MEASURE2MEASURE_US); // Zal gebruiken om de spanning en stroom van de batterij te meten (microseconden) Timer1.attachInterrupt (read_hw); // voegt read_hw() toe als een timer overflow interrupt averaging_index=0; sec_index=0; min_index=0; charger_state=0;//Initial state of state machine wanted_dac_voltage=0;//Maak shure minimale spanning outout last_blf=1,0; trickle_current_mA=battery_nominal_capacity_mA/TRICKLE_CURRENT_RATIO; //ChargingTimeMillis=0; //LCD lcd.begin (16,2); lcd.achtergrondverlichting(); lcd.wissen(); update_lcd(F("Opstarten..."),empty_string); delay(1000);}float log_battery_voltage(){ //Log slechts één keer per seconde if (log_last_second==second()) return last_blf; else log_last_second=second(); sec_log[sec_index]=batterijspanning; if (sec_index<59) { sec_index++; } else {//If één minuut gelogd // Bereken het gemiddelde per minuut if (min_index>=MINUTES_TO_LOG) min_index=0; sec_index=0; float sum_v=0; voor (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();//Maak shure relais ontkoppeld dac_write_voltage(0);//Zorg ervoor dat de mogelijke stroom lager is ingesteld wanted_dac_voltage=0;//Make shure minimum voltage outout delay(100); lees_status(); if (battery_voltage>0.1) {charger_state=BATTERY_CONNECTED;//Batterij gedetecteerd update_lcd(M2S(msg_battery_detected),empty_string); Serial.println(M2S(msg_battery_detected)); vertraging (2000); } else {//Geen batterij Serial.println (M2S (msg_no_battery)); update_lcd(M2S(msg_no_battery),construct_status_string()); charger_state=NO_BATTERY;//Batterij gedetecteerde vertraging (1000); } pauze; case NO_BATTERY://Geen batterij read_status(); if (battery_voltage>0.1) {charger_state=BATTERY_CONNECTED;//Batterij gedetecteerd Serial.println (M2S (msg_battery_detected)); update_lcd(M2S(msg_battery_detected),construct_status_string()); vertraging (1500); } else{ //Als er geen batterij in deze staat blijft update_lcd(M2S(msg_no_battery),construct_status_string()); vertraging (1100); } pauze; case BATTERY_CONNECTED://Batterij aangesloten dac_write_voltage (0);//Zorg ervoor dat de mogelijke stroom lager is ingesteld wanted_dac_voltage=0; vertraging (100); lees_status(); if (battery_voltage>BATTERY_GOOD_VOLTAGE_THRESHOLD){ charger_state=CURRENT_RAMP_UP;//Start laadstroom opvoeren //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)); vertraging (2000); wanted_dac_voltage=get_ approximated_dac_voltage (battery_voltage);//Stel de benodigde spanning van de regelaar in //Serial.println (get_ approximated_dac_voltage (battery_voltage)); connect_charging_circuit(); vertraging (200); } else { charger_state=BATTERY_VOLTAGE_LOW;//Batterijspanning te laag Serial.println (M2S (msg_voltage_too_low)); update_lcd(M2S(msg_voltage_too_low_short),construct_status_string()); vertraging (1000); } pauze; case BATTERY_VOLTAGE_LOW://Batterijspanning te laag update_lcd(M2S(msg_voltage_too_low_short),construct_status_string()); Serial.println(M2S(msg_voltage_too_low)); charger_state=FINAL_STATE;//Halt pauze; case CURRENT_RAMP_UP:///Current rampup //if (current_mA<1.0) charger_state=40;//Current viel onverwachts read_status(); update_lcd(M2S(msg_ramp_up),construct_status_string()); vertraging (50); if (current_mAMAXIMUM_BATTERY_VOLTAGE) charger_state=OVERVOLTAGE;//Overvoltage if (abs(current_mA-target_current_mA)>0.2){//If stroom wijkt af van 0.01) wanted_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; anders charger_state=CURRENT_TOO_HIGH;//Stroom te hoog, niet in staat om te verlagen} } if (abs(current_mA-target_current_mA)>5){//Regeling mislukt, verschil te hoog charger_state=REGULATION_FAILED;//Regulatiefout, verschil te hoog} dac_write_voltage (wanted_dac_voltage); if (total_minutes_averagetrickle_current_mA) {if (wanted_dac_voltage>VOLTAGE_STEP) { wanted_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; dac_write_voltage (wanted_dac_voltage); } else charger_state=CURRENT_TOO_HIGH;//Kan stroom niet verlagen tot druppelsnelheid } else { charger_state=TRICKLE;//Charging TrickleChargingTimeMillis=0; Serial.println(M2S(msg_trickle_charge)); } pauze; geval TRICKLE://Laadvertraging (200); lees_status(); if (current_mA<0.2) charger_state=UNEXPECTED_CURRENT_FALL;//Current viel onverwachts als (battery_voltage>MAXIMUM_BATTERY_VOLTAGE) charger_state=OVERVOLTAGE;//Overvoltage if (abs(current_mA-trickle_current_mA)>0.2)_If huidige deviated van doel 0.01) wanted_dac_voltage=wanted_dac_voltage-VOLTAGE_STEP; anders charger_state=CURRENT_TOO_HIGH;//Stroom te hoog, niet in staat om te verlagen} } if (abs(current_mA-trickle_current_mA)>5){//Regeling mislukt, verschil te hoog charger_state=REGULATION_FAILED;//Regulatiefout, verschil te hoog } dac_write_voltage (wanted_dac_voltage); //if (total_minutes_averagemax_time_for_trickle_charge) {//Maximaal toegestane druppellading update_lcd(eoc_line1,eoc_line2); charger_state=END_OF_TRICKLE;//Halt disconnect_charging_circuit(); // Koppel de oplader los van de batterij } pauze; case END_OF_TRICKLE:if ((second()%8)<4) update_lcd(M2S(msg_trickle_completed),construct_status_string()); anders update_lcd(eoc_line1,eoc_line2); pauze; case UNEXPECTED_CURRENT_FALL://Current viel onverwachts Serial.println(F("Current viel onverwachts")); disconnect_charging_circuit(); wanted_dac_voltage=0; update_lcd(M2S(msg_no_current),construct_status_string()); charger_state=FINAL_STATE;//Halt vertraging (1000); pauze; case UNABLE_TO_REACH_CURRENT://Kan de gewenste huidige Serial.println (M2S (msg_current_unreachable_long)) niet bereiken; disconnect_charging_circuit(); wanted_dac_voltage=0; dac_write_voltage (wanted_dac_voltage); vertraging (1000); update_lcd(M2S(msg_current_unreachable),construct_status_string()); charger_state=FINAL_STATE;//Halt pauze; case FULLY_CHARGED://Volledig opgeladen elapsed_time=mills2time(ChargingTimeMillis); int lading_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=bericht; eoc_line2=bericht1; update_lcd(msg,msg1); Serial.println(msg); //disconnect_charging_circuit (); //wanted_dac_voltage=0; //dac_write_voltage (wanted_dac_voltage); vertraging (3000); charger_state=CURRENT_RAMP_DOWN;//Haltpauze; case CURRENT_TOO_HIGH://Stroom te hoog Serial.println(F("Kan stroom niet verlagen naar doel")); disconnect_charging_circuit(); wanted_dac_voltage=0; dac_write_voltage (0); update_lcd(M2S(msg_high_current),construct_status_string()); vertraging (1000); charger_state=FINAL_STATE;//Halt pauze; case REGULATION_FAILED://Regulation failed Serial.println(M2S(msg_regulation_fault)); disconnect_charging_circuit(); wanted_dac_voltage=0; dac_write_voltage (0); update_lcd(M2S(msg_regulation_fault),construct_status_string()); vertraging (1000); charger_state=FINAL_STATE;//Halt pauze; geval OVERSTROOM://Overstroom disconnect_charging_circuit(); Serial.println(M2S(msg_overcurrent)); wanted_dac_voltage=0; dac_write_voltage (wanted_dac_voltage); update_lcd(M2S(msg_overcurrent),construct_status_string()); vertraging (1000); charger_state=FINAL_STATE;//Halt pauze; geval OVERVOLTAGE://Overvoltage disconnect_charging_circuit(); Serial.println (M2S (msg_overvoltage)); wanted_dac_voltage=0; dac_write_voltage (wanted_dac_voltage); update_lcd(M2S(msg_overvoltage),construct_status_string()); vertraging (1000); charger_state=FINAL_STATE;//Halt pauze; geval FINAL_STATE://Halt vertraging (10000); pauze; standaard:wanted_dac_voltage=0; charger_state=0; } //Serial.println(current_mA); //Serial.print("Huidige="); //Serial.print (huidige_mA); //Serial.println("mA"); //Serial.print ("DAC-spanning"); //Serial.println(dac_voltage); //Serial.print ("Gewilde DAC-spanning"); //Serial.println (wanted_dac_voltage); //Serial.print (huidige_mA); //Serial.print(" "); //Serial.print (dac_voltage); //Serial.print(" "); lees_status(); if (last_second!=second()){ Serial.print(current_mA); Serieel.print(","); //Serial.print (weerstandsspanning); //Serial.print(","); //Serial.print (dac_voltage); //Serial.print(","); //Serial.print (regulator_voltage); //Serial.print(","); Serial.println (batterijspanning); 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; als (adc_voltage<0) adc_voltage=0; retourneer adc_voltage;}int voltage_to_code (float voltage) {int code=4095.0/DAC_REF_VOLTAGE*voltage; retourcode;} ongeldig dac_write (int-code) { Wire.beginTransmission (MCP4725_ADDR); Draad.schrijven(64); // cmd om de DAC Wire.write (code>> 4) bij te werken; // de 8 meest significante bits... Wire.write((code &15) <<4); // de 4 minst significante bits... Wire.endTransmission();}void read_status(){ voltage_sum=0; huidige_som=0; voor (i=0;i=POINTS_FOR_AVERAGING) averaging_index=0; if (tmp_battery_voltage>MAXIMUM_BATTERY_VOLTAGE) { disconnect_charging_circuit (); // Koppel de oplader los van de batterij charger_state =OVERVOLTAGE; } if (tmp_current_mA>MAXIMIM_ALLOWED_CURRENT){ disconnect_charging_circuit(); // Koppel de oplader los van de batterij charger_state =OVERSTROOM; }}void disconnect_charging_circuit(){ digitalWrite(CHARGE_RELAY_PIN,DISCONNECT_CHARGE_RELAY); // Koppel de oplader los van de batterij} ongeldig connect_charging_circuit () {digitalWrite (CHARGE_RELAY_PIN, CONNECT_CHARGE_RELAY); // Sluit de oplader aan op de batterij}//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 (tweede regel); if (lcd_last_string1!=first_line){ lcd.clear(); lcd.setCursor(0,0); lcd.print(eerste_regel); lcd_last_string1=eerste_regel; lcd.setCursor(0,1); lcd.print(second_line); lcd_last_string2=tweede_lijn; } if(lcd_last_second!=second()){ if (lcd_last_string2!=second_line){ lcd.setCursor(0,1); lcd.print(second_line); lcd_last_string2=tweede_lijn; } } lcd_last_second=second();}String construct_status_string(void){ String v,i; if (battery_voltage<10) v=String(battery_voltage, 2); anders v =String (batterijspanning, 1); if (current_mA<10) i=String(current_mA, 2); anders i=String(current_mA, 1); //Serial.println(v); mijn tijd verstreken; Tekenreeks msg,msg_time; //Serial.print (opladen_gestart); //Serial.print(" "); //Serial.println(String(millis()-opladen_started)); switch (charger_state) {geval OPLADEN:verstreken =mills2time (ChargingTimeMillis); pauze; geval TRICKLE:verstreken =mills2time (TrickleChargingTimeMillis); pauze; } if (charger_state==OPLADEN || 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; pauze; case TRICKLE:msg=v+String(F("V "))+i+String(F("mA"))+" "+msg_time; pauze; 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
Geen voorbeeld (alleen downloaden).

Schema's

charger_AgK96zxw2T.zip

Productieproces

  1. Dorstalarm plantalarm
  2. Italiaanse Word Clock
  3. Slechts drie pinnen voor een 4x3-toetsenbord
  4. Sigfox kWh-meter
  5. Bluetooth-temperatuurmeter
  6. Gebarengestuurd slot
  7. The Companion IC
  8. USB MIDI-adapter
  9. Een geïsoleerde analoge ingang voor Arduino
  10. RGB 32-bands audiospectrumvisualizer
  11. Meet je reactietijd