Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Carregador inteligente para baterias recarregáveis ​​de 9V NiMH V1

Componentes e suprimentos

Arduino UNO
× 1
SparkFun I2C DAC Breakout - MCP4725
× 1
Regulador linear com saída ajustável
× 1
Texas Instruments, de uso geral, Dual Op-Amp
× 1
Resistor 6,8 k ohm
× 2
Resistor 3,3 k ohm
× 1
Resistor 5,1 k ohm
× 1
Resistor 1k ohm
× 1
Resistor 10 ohm
× 1
Relé (genérico)
× 1
Resistor 20k ohm
× 1
Fonte de alimentação SparkFun breadboard 5V / 3,3V
× 1
Fonte de alimentação 17V
× 1
MÓDULO YwRobot I2C SERIAL LCD 1602
× 1

Sobre este projeto


Procurei um carregador inteligente que pode carregar uma bateria 9V NiMH em algumas horas e não encontrei um. Além disso, todos os carregadores que encontrei eram realmente "burros". Corrente de carregamento desconhecida e nenhuma função para encerrar o carregamento após a bateria estar totalmente carregada. Problema com tais carregadores que podem sobrecarregar a bateria e reduzir significativamente sua vida útil. Então decidi criar um carregador "inteligente".

Pretendo manter a primeira versão simples, de modo que permite coisas básicas como carregar com corrente constante, término automático do carregamento após a bateria totalmente carregada, carga lenta, medição da carga transferida para a bateria.

Na próxima versão, acrescentarei alguns recursos úteis adicionais, como descarga, medição de capacidade e ciclagem.

Aviso:Carregar a bateria com alta corrente pode causar explosão ou incêndio. Por favor, não deixe o carregador sem supervisão. Além disso, não tente carregar uma bateria que não seja alcalina. Este carregador foi testado apenas com baterias NiMH (e ainda assim você o está usando por sua própria conta e risco e eu não tenho nenhuma responsabilidade se houver algum dano causado por erros no design ou código). O desgosto de outros tipos de baterias exigirá a modificação do código.





Teoria


Alguns fatos úteis para lembrar que ajudarão a entender os parâmetros necessários do carregador.

C - corrente igual à capacidade nominal da bateria

Quando carregada na taxa C, a voltagem de célula única pode chegar a 1,6V. Esta tensão pode ser maior para baterias velhas.

A voltagem nominal de uma única célula é de 1,2 V, mas a célula totalmente carregada tem uma voltagem de circuito aberto de até 1,5 volt.

Recomenda-se uma taxa de carga lenta inferior a 0,025 C (C / 40) após a bateria estar totalmente carregada.

Geralmente, há duas opções para carregar a bateria NiMH:

1. Carregamento rápido. Corrente de carregamento 0,5C-1C. O estado de carga deve ser monitorado e encerrado por dV / dt (taxa de mudança de tensão) ou dT / dt (taxa de mudança de temperatura)

2. Carregamento lento. Corrente de carregamento 0.1C. Tempo de carregamento 14-16 horas. Encerramento de carga por cronômetro. Terminação de carga dT / dt impossível para correntes baixas. A terminação dV / dt pode não ser confiável para correntes abaixo de 0,5C, de acordo com a literatura.





Parâmetros básicos do circuito de carregamento


A bateria de 9 V geralmente tem 7 pontos de venda conectados em série, mas em alguns casos pode ter 6 ou 8 células. O regulador de tensão deve ser capaz de fornecer tensão de carga de pelo menos 8 * 1,6 =12,8V. Tensão de queda do regulador LM317 de até 2 V, então a tensão de alimentação precisa ser ~ 15 V (isso não leva em consideração a queda de tensão no resistor de detecção de corrente).

Para corrente de carga máxima de 200mA e resistor de detecção de corrente de 10 Ohm, a queda adicional no resistor de detecção de corrente é de 2 V, portanto, é necessária uma tensão de alimentação de 17 V.

A célula totalmente descarregada pode ter tensão muito baixa, mesmo negativa. A tensão mínima do regulador idealmente deve ser 0, mas usando o LM317, pode ser tão baixa quanto 1,2V.





Circuito





Explicações do circuito


A ideia básica é medir a corrente de carga e ajustar a tensão do regulador até que a corrente desejada seja alcançada. Corrente medida medindo a queda de tensão no resistor de detecção de corrente R5. I =V / R.

SparkFun I2C DAC Breakout - MCP4725 - conversor digital para analógico de 12 bits usado para controlar a tensão. A tensão de saída pode ser configurada via I2C entre 0 e 5V. Porque precisamos ser capazes de ajustar a tensão em uma faixa mais ampla, de 0 a 15 V amplificador operacional LM358 usado para amplificar a tensão de saída do DAC. Amplificação do amplificador operacional definido pelos resistores R4 e R3. Ganho =1 + R4 / R3 =1 + 6800/3300 =3,06 então a tensão de saída do amplificador operacional é de aproximadamente 0 a 15V.

A corrente de saída máxima do LM358 é 50mA, então o regulador de tensão ajustável LM317 é usado para controlar a corrente mais alta. Saída do amplificador operacional conectado ao terminal ADJ do LM317. O LM317 manterá 1,2 V entre os terminais ADJ e OUT, de modo que a tensão real da bateria pode ser configurada entre 1,2 e 16,2 V. O LM317 precisa de corrente mínima de 3,5 mA para manter a regulação. Portanto, o resistor R6 de 1kOhm é usado para garantir a regulagem se a bateria não estiver conectada. Capacitor C1 usado para filtrar a tensão de saída e melhorar a estabilidade do LM317.

Tensão medida em dois pontos diferentes.

1. Resistor R5 conectado ao pino A2 do Arduino. Tensão no resistor medida e então a corrente de carga calculada como Icharging =V / R

2. A tensão na bateria pode ser de até 16,2 V, então o divisor resistivo R1, R2 costumava trazer a tensão abaixo de 5 V, permitido pelo Arduino. Saída do divisor conectado ao pino A0 do Arduino. Para R1 =5,1k Ohm e R2 =20kOhm Vout =Vin / (20000 + 5100) * 5100 =0,2 Portanto, a tensão da bateria dividida por 5.

Relé usado para desconectar a bateria do circuito de carga. Você pode ver no foto-relé que usei, mas geralmente qualquer relé com controle de 5V pode ser usado. É mais seguro conectar a bateria aos contatos normalmente abertos do relé.

Usei YwRobot I2C SERIAL LCD MÓDULO 1602 para exibir o status do carregador, mas qualquer outro módulo LCD controlado por I2C pode ser usado. Parece que o módulo YwRobot LCD não é compatível com a biblioteca LiquidCrystal_I2C padrão, então usei a nova biblioteca LiquidCrystal. Se você estiver usando um módulo LCD diferente, será necessário alterar esta linha:
  LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVO); // define o endereço LCD para 0x27 para um display de 16 caracteres e 2 linhas  

Para alimentar o conversor digital para analógico e o LCD, usei a fonte de alimentação SparkFun Breadboard 5V / 3,3V. Provavelmente não haverá problema em usar 5V da placa Arduino.

Você também precisará fornecer 17 V ao circuito de carregamento. Se você não tem fonte de alimentação, você pode usar um conversor DC / DC ajustável como este

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





Funcionalidade


Eu não queria muitos fios, então não há botões para configurar o carregamento. Chagrin atual configurado apenas em código. Você precisa definir a corrente de carga desejada no charger.ino
  // *************************** Parâmetros de carregamento ************* ***************************** // ******************** *************************************************** ******************* float target_current_mA =30; // Corrente de carregamento mAfloat battery_nominal_capacity_mA =170; // Capacidade nominal da bateria mAfloat max_time_for_trickle_charge =6; // Tempo máximo de carga lenta em minutos // *************************************** *************************************************** / / ************************************************** *****************************************  

target_current_mA - corrente de carga constante

max_time_for_trickle_charge - número máximo de minutos para carregamento lento, pode ser configurado até 600 (10h)

battery_nominal_capacity_mA - capacidade da bateria usada para calcular a corrente de gotejamento

Geralmente, a corrente de carga pode atingir a capacidade nominal. Para bateria com capacidade nominal de 170mAh, a corrente máxima de carga é 170mA. Corrente de carga mínima geralmente C / 10 - 17mA para bateria de 170mAh.

Depois de ligar o carregador, verificará se a bateria está conectada. Se a bateria estiver conectada, a bateria será carregada com a corrente constante configurada até que esteja totalmente carregada. O carregamento foi encerrado detectando dV / dt negativo durante 5 minutos. Após o carregamento concluído, o carregador mudará para carregamento lento com C / 40 atual. O carregador se desconectará da bateria depois de decorrido o tempo máximo de carregamento lento.

1 - dV / dt

2 - tempo de carregamento em minutos

1 - Tempo de carregamento

2 - Carga transferida para a bateria

Informações adicionais sobre baterias NiMH:

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

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

Código

  • charger.ino
  • main.ino
  • hw.ino
  • lcd.ino
  • cálculos.ino
  • Nova biblioteca LiquidCrystal usada para este projeto
charger.ino Arduino
Arquivo principal
 // ISTO para carregar bateria NiMH de 9 V // A bateria pode ter 6,7 ou 8 células de 1,25 V // Isso torna a tensão nominal entre 7,5 e 10 V # include  #include  #include  #include  #include  LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVO); // definir o endereço LCD para 0x27 para um display de 16 caracteres e 2 linhas // Definições de hardware # definir MCP4725_ADDR 0x60 // endereço DAC # definir DAC_REF_VOLTAGE 5.0 # definir CHARGE_RELAY_PIN 2 # definir DISCONNECT_CHARGE_RELAY HIGH # definir CONNECT_CHARGE_RELAY_VOLTAGE 5.0 # definir CHARGE_RELAY_PIN 2 # definir DISCONNECT_CHARGE_RELAY HIGH # definir CONNECT_CHARGE_RELAY_VOLTAGE 5.0 # definir CURSO_RELAY_PIN 2 # definir DISCONNECT_CHARGE_RELAY HIGH # definir CONNECT_CHARGE_RELAY_RELAY_SORRENT # definir CURSO_REG_RELAY__RELAYW # definir CURSO_IN_RELAY__RELAYW # definir. CURRENT_SENSING_SESISTOR 10.2 // OHm # define BATTERY_VOLTAGE_PIN A0 # define R1 5090 // Resistor do lado inferior do divisor de detecção de tensão # define R2 19910 // Resistor do lado alto do divisor de detecção de tensão # define ADC_REF_VOLTAGE 4.89 // Arduino real tensão de alimentação ou tensão AREF para adequada ADC para conversão de tensão # define R3 3300.0 # define R4 6800.0 # define AMP_GAIN (1 + R4 / R3) // Várias definições // # define MINIMUM_VOLTAGE 8.1 // Tensão mínima após regulador # define BATTERY_GOOD_VOLTAGE_THRESHOLD 7.0 # define MAXIMIM_ALLOWED_CURRENT 200 // Máximo permitido corrente da bateria mA (corte forçado) #define MAXIMUM_BATTERY_VOLTAGE 15.0 // Tensão máxima permitida da bateria V (corte forçado) #define VOLTAGE_STEP 0,001 // Etapa para tensão regulamento # define POINTS_FOR_AVERAGING 100 // Quantos pontos tomados para calcular a média # define MEASURE2MEASURE_US 5000 // Tempo entre medições em microssegundos (precisa ser mais de 200 por causa de duas leituras analógicas) #define VOLTAGE_LOG_TIME_MIN 30,0 // Tempo em minutos para economizar tensão para dV / dT corte # definir MINUTES_TO_LOG 5 # definir TRICKLE_CURRENT_RATIO 40 // Carregador afirma # definir inicialização 0 # definir NO_BATTERY 5 # definir BATTERY_CONNECTED 10 # definir BATTERY_VOLTAGE_LOW 15 # definir CURRENT_RAMP_UP 20 # definem CARREGAMENTO 30 # 32 # definir CURRENT_RAMP_DOWN definir GOTEJAMENTO 35 # definir 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 OVERCURRENT 100 # define OVERVOLTAGE 101 # define FULLY_CHARGED 70 # define CURRENT_TOO_HIGH 80 # define REGULATION_FAILED 90 # define OVERCURRENT 100 # define OVERVOLTAGE 101 # define FINAL_STATE_FONTE_INDES_reading_FORAGENS_Tensão 200_FORAGING_FORTS_readings_interpretado_interno_portagens_tensão_interna_portando_tensão_interna_portagens_portagens_padrão_pontagem // Para averaginglong unsigned int voltage_sum, current_sum; // Soma de averagingf 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; unsigned short int last_second, lcd_last_second, log_last_second; Cadeia lcd_last_string1, lcd_last_string2; Cadeia EMPTY_STRING =""; String msg, eoc_line1, eoc_line2; unsigned char sec_index, min_index; // long long int charge_started; float sec_log [60], min_log [MINUTES_TO_LOG], last_blf; float trickle_current_mA; int total_harutes Charutes_averageMillis =0; 0; float last_dac_voltage =0; // Mensagensconst char msg_battery_detected [] PROGMEM ="Bateria detectada"; const char msg_no_battery [] PROGMEM ="Sem bateria"; const char msg_battery_ok [] PROGMEM ="Bateria ok"; const char msg_no_battery [] PROGMEM ="Sem bateria"; const char msg_battery_ok [] PROGMEM ="Bateria ok"; const char msg_voltage_too_ PROGMEM ="Bateria com tensão muito baixa"; const char msg_voltage_too_low_short [] PROGMEM ="V Bateria fraca"; const char msg_ramp_up [] PROGM EM ="Aumentar"; const char msg_charging [] PROGMEM ="Carregando"; const char msg_space [] PROGMEM =""; const char msg_ramp_down [] PROGMEM ="Diminuir"; const char msg_trickle_charge [] PROGMEM ="Carga lenta "; const char msg_no_current [] PROGMEM =" Sem corrente "; const char msg_current_unreachable [] PROGMEM =" I inacessível "; const char msg_current_unreachable_long [] PROGMEM =" Não foi possível atingir a corrente desejada "; const char msg_completed [] "; const char msg_charge [] PROGMEM =" Carga "; const char msg_high_current [] PROGMEM =" Corrente alta "; const char msg_regulation_fault [] PROGMEM =" Falha de regulação "; const char msg_overcurrent [] PROGMEM =" Corrente muito alta "; const char msg_overvoltage [] PROGMEM ="Voltagem muito alta"; const char msg_trickle_completed [] PROGMEM ="Trickle finalizado"; // ************************ **** Parâmetros de carregamento ***************************************** // * *************************************************** *************************************** float target_current_mA =30; // Corrente de carregamento mAfloat battery_nominal_capacity_mA =170; // Capacidade nominal da bateria mAfloat max_time_for_trickle_charge =6; // Tempo máximo de carga lenta em minutos // *************************************** *************************************************** / / ************************************************** ***************************************** struct mytime {unsigned char hours; minutos de char unsigned; unsigned int total_minutes;} tempo decorrido; configuração void () {pinMode (CHARGE_RELAY_PIN, OUTPUT); desconectar_charging_circuit (); // Desconecte o carregador da bateria Wire.begin (); // I2C dac_write_voltage (0); // Certifique-se de menor conjunto de corrente possível Serial.begin (115200); último_segundo =segundo (); lcd_último_segundo =segundo (); log_último_segundo =segundo (); Timer1.initialize (MEASURE2MEASURE_US); // Usará para medir a tensão e a corrente da bateria (microssegundos) Timer1.attachInterrupt (read_hw); // anexa read_hw () como uma interrupção de estouro do temporizador averaging_index =0; sec_index =0; min_index =0; charger_state =0; // Estado inicial da máquina de estado want_dac_voltage =0; // Verifique a saída de tensão mínima last_blf =1.0; trickle_current_mA =battery_nominal_capacity_mA / TRICKLE_CURRENT_RATIO; // ChargingTimeMillis =0; // LCD lcd.begin (16,2); lcd.backlight (); lcd.clear (); update_lcd (F ("Ligar ..."), string_vazia); delay (1000);} float log_battery_voltage () {// Registra apenas uma vez por segundo if (log_last_second ==second ()) return last_blf; senão log_último_segundo =segundo (); sec_log [sec_index] =bateria_voltagem; if (sec_index <59) {sec_index ++; } else {// Se um minuto registrado // Calcula a média por minuto if (min_index> =MINUTES_TO_LOG) min_index =0; sec_index =0; float sum_v =0; para (i =0; i <60; i ++) {sum_v + =sec_log [i]; } float min_average =sum_v / 60.0; para (i =1; i  
main.ino Arduino
 void loop () {String msg1; switch (charger_state) {case INITIALIZATION:// Estado inicial disconnect_charging_circuit (); // Faça o relé shure desconectado dac_write_voltage (0); // Certifique-se de menor conjunto de corrente possível Want_dac_voltage =0; // Verifique o retardo de saída de tensão mínima (100); read_status (); if (battery_voltage> 0.1) {charger_state =BATTERY_CONNECTED; // Bateria detectada update_lcd (M2S (msg_battery_detected), empty_string); Serial.println (M2S (msg_battery_detected)); atraso (2000); } else {// Sem bateria Serial.println (M2S (msg_no_battery)); update_lcd (M2S (msg_no_battery), construct_status_string ()); charger_state =NO_BATTERY; // Atraso detectado da bateria (1000); } pausa; case NO_BATTERY:// Sem bateria read_status (); if (battery_voltage> 0.1) {charger_state =BATTERY_CONNECTED; // Bateria detectada Serial.println (M2S (msg_battery_detected)); update_lcd (M2S (msg_battery_detected), construct_status_string ()); atraso (1500); } else {// Se nenhuma bateria permanecer neste estado update_lcd (M2S (msg_no_battery), construct_status_string ()); atraso (1100); } pausa; case BATTERY_CONNECTED:// Bateria conectada dac_write_voltage (0); // Certifique-se de definir a corrente mais baixa possível Want_dac_voltage =0; atraso (100); read_status (); if (battery_voltage> BATTERY_GOOD_VOLTAGE_THRESHOLD) {charger_state =CURRENT_RAMP_UP; // Comece a carregar o aumento atual // 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)); atraso (2000); Want_dac_voltage =get_approximated_dac_voltage (battery_voltage); // Definir a tensão necessária do regulador //Serial.println(get_approximated_dac_voltage(battery_voltage)); connect_charging_circuit (); atraso (200); } else {charger_state =BATTERY_VOLTAGE_LOW; // Tensão da bateria muito baixa Serial.println (M2S (msg_voltage_too_low)); update_lcd (M2S (msg_voltage_too_low_short), construct_status_string ()); atraso (1000); } pausa; case BATTERY_VOLTAGE_LOW:// Voltagem da bateria muito baixa update_lcd (M2S (msg_voltage_too_low_short), construct_status_string ()); Serial.println (M2S (msg_voltage_too_low)); charger_state =FINAL_STATE; // Interromper pausa; case CURRENT_RAMP_UP:/// Rampup atual // if (current_mA <1.0) charger_state =40; // Atual caiu inesperadamente read_status (); update_lcd (M2S (msg_ramp_up), construct_status_string ()); atraso (50); if (current_mA  MAXIMUM_BATTERY_VOLTAGE) charger_state =OVERVOLTAGE; // Sobretensão if (abs (current_mA-target_current_mA)  0,01) want_dac_voltage =wanted_dac_voltage-VOLTAGE_STEP; else charger_state =CURRENT_TOO_HIGH; // Corrente muito alta, incapaz de diminuir}} if (abs (current_mA-target_current_mA)> 5) {// Falha de regulação, diferença muito alta charger_state =REGULATION_FAILED; // Erro de regulação, diferença muito alta} dac_write_voltage (want_dac_voltage); if (total_minutes_average  trickle_current_mA) {if (want_dac_voltage> VOLTAGE_STEP) {want_dac_voltage =want_dac_voltage-VOLTAGE_STEP; dac_write_voltage (want_dac_voltage); } else charger_state =CURRENT_TOO_HIGH; // Incapaz de reduzir a corrente para a taxa de gotejamento} else {charger_state =TRICKLE; // Carregamento TrickleChargingTimeMillis =0; Serial.println (M2S (msg_trickle_charge)); } pausa; case TRICKLE:// Atraso de carregamento (200); read_status (); if (current_mA <0.2) charger_state =UNEXPECTED_CURRENT_FALL; // A corrente caiu inesperadamente if (battery_voltage> MAXIMUM_BATTERY_VOLTAGE) charger_state =OVERVOLTAGE; // Sobretensão if (abs (current_mA-trickle_current_mA)  0,01) want_dac_voltage =wanted_dac_voltage-VOLTAGE_STEP; else charger_state =CURRENT_TOO_HIGH; // Corrente muito alta, incapaz de diminuir}} if (abs (current_mA-trickle_current_mA)> 5) {// Falha na regulação, diferença muito alta charger_state =REGULATION_FAILED; // Erro de regulação, diferença muito alta} dac_write_voltage (want_dac_voltage); // if (total_minutes_average  max_time_for_trickle_charge) {// Carga residual máxima permitida update_lcd (eoc_line1, eoc_line2); charger_state =END_OF_TRICKLE; // Pare a desconexão_charging_circuit (); // Desconecte o carregador da bateria} break; case END_OF_TRICKLE:if ((second ()% 8) <4) update_lcd (M2S (msg_trickle_completed), construct_status_string ()); senão update_lcd (eoc_line1, eoc_line2); pausa; case UNEXPECTED_CURRENT_FALL:// Atual caiu inesperadamente Serial.println (F ("Atual caiu inesperadamente")); desconectar_charging_circuit (); want_dac_voltage =0; update_lcd (M2S (msg_no_current), construct_status_string ()); charger_state =FINAL_STATE; // Interromper atraso (1000); pausa; case UNABLE_TO_REACH_CURRENT:// Incapaz de alcançar o Serial.println atual desejado (M2S (msg_current_unreachable_long)); desconectar_charging_circuit (); want_dac_voltage =0; dac_write_voltage (want_dac_voltage); atraso (1000); update_lcd (M2S (msg_current_unreachable), construct_status_string ()); charger_state =FINAL_STATE; // Interromper pausa; case FULLY_CHARGED:// Elapsed_time =mills2time (ChargingTimeMillis); int charge_mAh; charge_mAh =calcule_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; update_lcd (msg, msg1); Serial.println (msg); // desconectar_charging_circuit (); // want_dac_voltage =0; // dac_write_voltage (wanted_dac_voltage); atraso (3000); charger_state =CURRENT_RAMP_DOWN; // Parar pausa; case CURRENT_TOO_HIGH:// Corrente muito alta Serial.println (F ("Incapaz de diminuir a corrente para o alvo")); desconectar_charging_circuit (); want_dac_voltage =0; dac_write_voltage (0); update_lcd (M2S (msg_high_current), construct_status_string ()); atraso (1000); charger_state =FINAL_STATE; // Interromper pausa; case REGULATION_FAILED:// O regulamento falhou Serial.println (M2S (msg_regulation_fault)); desconectar_charging_circuit (); want_dac_voltage =0; dac_write_voltage (0); update_lcd (M2S (msg_regulation_fault), construct_status_string ()); atraso (1000); charger_state =FINAL_STATE; // Interromper pausa; case OVERCURRENT:// Overcurrent disconnect_charging_circuit (); Serial.println (M2S (msg_overcurrent)); want_dac_voltage =0; dac_write_voltage (want_dac_voltage); update_lcd (M2S (msg_overcurrent), construct_status_string ()); atraso (1000); charger_state =FINAL_STATE; // Interromper pausa; case OVERVOLTAGE:// Overvoltage disconnect_charging_circuit (); Serial.println (M2S (msg_overvoltage)); want_dac_voltage =0; dac_write_voltage (want_dac_voltage); update_lcd (M2S (msg_overvoltage), construct_status_string ()); atraso (1000); charger_state =FINAL_STATE; // Interromper pausa; case FINAL_STATE:// Halt delay (10000); pausa; padrão:want_dac_voltage =0; charger_state =0; } //Serial.println(current_mA); //Serial.print("Current="); //Serial.print(current_mA); //Serial.println("mA "); //Serial.print("DAC voltage "); //Serial.println(dac_voltage); //Serial.print("Wanted DAC voltage "); //Serial.println(wanted_dac_voltage); //Serial.print(current_mA); //Serial.print (""); //Serial.print(dac_voltage); //Serial.print (""); read_status (); if (último_segundo! =segundo ()) {Serial.print (corrente_mA); Serial.print (","); //Serial.print(resistor_voltage); //Serial.print (","); //Serial.print(dac_voltage); //Serial.print (","); //Serial.print(regulator_voltage); //Serial.print (","); Serial.println (bateria_voltagem); último_segundo =segundo (); }} 
hw.ino Arduino
 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_voltage =0; retorno adc_voltage;} int voltagem_para_código (voltagem flutuante) {código interno =4095.0 / DAC_REF_VOLTAGE * voltagem; código de retorno;} void dac_write (código interno) {Wire.beginTransmission (MCP4725_ADDR); Wire.write (64); // cmd para atualizar o DAC Wire.write (código>> 4); // os 8 bits mais significativos ... Wire.write ((code &15) <<4); // os 4 bits menos significativos ... Wire.endTransmission ();} void read_status () {voltage_sum =0; current_sum =0; para (i =0; i  =POINTS_FOR_AVERAGING) averaging_index =0; if (tmp_battery_voltage> MAXIMUM_BATTERY_VOLTAGE) {disconnect_charging_circuit (); // Desconecte o carregador da bateria charger_state =OVERVOLTAGE; } if (tmp_current_mA> MAXIMIM_ALLOWED_CURRENT) {disconnect_charging_circuit (); // Desconecte o carregador da bateria charger_state =OVERCURRENT; }} void disconnect_charging_circuit () {digitalWrite (CHARGE_RELAY_PIN, DISCONNECT_CHARGE_RELAY); // Desconecte o carregador da bateria} void connect_charging_circuit () {digitalWrite (CHARGE_RELAY_PIN, CONNECT_CHARGE_RELAY); // Conecte o carregador à bateria} // sec_index =0; // min_index =0; 
lcd.ino Arduino
 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.print (primeira linha); lcd_last_string1 =first_line; lcd.setCursor (0,1); lcd.print (segunda linha); lcd_last_string2 =second_line; } if (lcd_último_egundo! =segundo ()) {if (lcd_último_string2! =segunda_linha) {lcd.setCursor (0,1); lcd.print (segunda linha); lcd_last_string2 =second_line; }} lcd_last_second =second ();} String construct_status_string (void) {String v, i; if (battery_voltage <10) v =String (battery_voltage, 2); else v =String (bateria_voltagem, 1); if (current_mA <10) i =String (current_mA, 2); else i =String (current_mA, 1); //Serial.println(v); meu tempo decorrido; String msg, msg_time; //Serial.print(charging_started); //Serial.print(" "); //Serial.println(String(millis()-charging_started)); switch(charger_state){ case CHARGING:elapsed=mills2time(ChargingTimeMillis); pausa; case TRICKLE:elapsed=mills2time(TrickleChargingTimeMillis); pausa; } 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; pausa; case TRICKLE:msg=v+String(F("V "))+i+String(F("mA"))+" "+msg_time; pausa; 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
 Sem visualização (somente download). 

Esquemas

charger_AgK96zxw2T.zip

Processo de manufatura

  1. Alarme de planta de alerta de sede
  2. Word Clock italiano
  3. Apenas três pinos para um teclado 4x3
  4. Medidor Sigfox kWh
  5. Monitor de temperatura Bluetooth
  6. Bloqueio controlado por gestos
  7. O Companion IC
  8. Adaptador USB MIDI
  9. Uma entrada analógica isolada para Arduino
  10. Meça seu tempo de reação