Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Интеллектуальное зарядное устройство для аккумуляторов NiMH 9 В V1

Компоненты и расходные материалы

Arduino UNO
× 1
SparkFun I2C DAC Breakout - MCP4725
× 1
Линейный регулятор с регулируемым выходом
× 1
Двойной операционный усилитель общего назначения Texas Instruments
× 1
Резистор 6,8 кОм
× 2
Резистор 3,3 кОм
× 1
Резистор 5,1 кОм
× 1
Резистор 1 кОм
× 1
Резистор 10 Ом
× 1
Реле (универсальное)
× 1
Резистор 20 кОм
× 1
Источник питания макетной платы SparkFun 5 В / 3,3 В
× 1
Источник питания 17 В
× 1
МОДУЛЬ ПОСЛЕДОВАТЕЛЬНОГО ЖК-дисплея 1602 YwRobot I2C
× 1

Об этом проекте

Я искал смарт-зарядное устройство, способное зарядить 9-вольтовый никель-металлгидридный аккумулятор за пару часов, и не нашел. Более того, все зарядные устройства, которые я нашел, были действительно "тупыми". Зарядный ток неизвестен, функция прекращения зарядки после полной зарядки аккумулятора отсутствует. Проблема с такими зарядными устройствами в том, что они могут перезарядить аккумулятор и значительно сократить срок службы. Поэтому я решил создать «умное» зарядное устройство.

Первую версию, которую я намерен сохранить простой, позволяет выполнять такие базовые операции, как зарядка постоянным током, автоматическое прекращение зарядки после полной зарядки аккумулятора, непрерывный заряд, измерение заряда, передаваемого аккумулятору.

В следующей версии я добавлю несколько дополнительных полезных функций, таких как разрядка, измерение емкости и цикличность.

Предупреждение:зарядка аккумулятора большим током может привести к взрыву аккумулятора или возгоранию. Пожалуйста, не оставляйте зарядное устройство без присмотра. Также не пытайтесь заряжать аккумулятор, который не предназначен для зарядки как щелочной. Это зарядное устройство протестировано только с NiMH батареями (и тем не менее вы используете его на свой страх и риск, и я не несу никакой ответственности за любой ущерб, вызванный ошибками в конструкции или коде). Недовольство другими типами батарей потребует изменения кода.

Теория

Несколько полезных фактов, которые нужно запомнить, которые помогут понять необходимые параметры зарядного устройства.

C - ток, равный номинальной емкости аккумулятора

При зарядке со скоростью C напряжение на одной ячейке может достигать 1,6 В. Это напряжение может быть выше для старых батарей.

Номинальное напряжение одиночного элемента составляет 1,2 В, но полностью заряженный элемент имеет напряжение холостого хода до 1,5 В.

После полной зарядки аккумулятора рекомендуется скорость капельного заряда менее 0,025 C (C / 40).

Обычно есть два варианта зарядки никель-металлгидридного аккумулятора:

1. Быстрая зарядка. Зарядный ток 0.5C-1C. Состояние заряда должно контролироваться и прекращаться с помощью dV / dt (скорость изменения напряжения) или dT / dt (скорость изменения температуры)

2. Медленная зарядка. Ток зарядки 0,1С. Время зарядки 14-16 часов. Прекращение заряда по таймеру. Прекращение заряда dT / dt невозможно при малых токах. Согласно литературе, согласование dV / dt может быть ненадежным для токов ниже 0,5 ° C.

Основные параметры цепи зарядки

Батарея 9V обычно имеет 7 последовательно соединенных ячеек, но в некоторых случаях она может быть 6- или 8-элементной. Регулятор напряжения должен обеспечивать зарядное напряжение минимум до 8 * 1,6 =12,8В. Падение напряжения регулятора LM317 до 2 В, поэтому напряжение питания должно быть ~ 15 В (без учета падения напряжения на токоизмерительном резисторе).

При максимальном токе зарядки 200 мА и резисторе измерения тока 10 Ом дополнительное падение на резисторе измерения тока составляет 2 В, поэтому требуется напряжение питания 17 В.

Полностью разряженный элемент может иметь очень низкое, даже отрицательное напряжение. Минимальное напряжение регулятора в идеале должно быть 0, но при использовании LM317 оно может быть ниже 1,2 В.

Схема

Пояснения к схемам

Основная идея состоит в том, чтобы измерить зарядный ток и отрегулировать напряжение регулятора до достижения желаемого значения тока. Ток измеряется путем измерения падения напряжения на токоизмерительном резисторе R5. I =V / R.

SparkFun I2C DAC Breakout - MCP4725 - 12-битный цифро-аналоговый преобразователь, используемый для управления напряжением. Выходное напряжение кулачка настраивается через I2C в диапазоне от 0 до 5 В. Поскольку нам нужно иметь возможность регулировать напряжение в более широком диапазоне, операционный усилитель LM358 от 0 до 15 В используется для усиления выходного напряжения ЦАП. Усиление операционного усилителя установлено резисторами R4 и R3. Коэффициент усиления =1 + R4 / R3 =1 + 6800/3300 =3,06, поэтому выходное напряжение операционного усилителя примерно от 0 до 15 В.

Максимальный выходной ток LM358 составляет 50 мА, поэтому регулируемый регулятор напряжения LM317 используется для управления более высоким током. Выход операционного усилителя, подключенного к выводу ADJ на LM317. LM317 будет поддерживать 1,2 В между клеммами ADJ и OUT, поэтому фактическое напряжение на батарее можно настроить в пределах от 1,2 до 16,2 В. LM317 требуется минимальный ток 3,5 мА для поддержания регулирования. Таким образом, резистор R6 на 1 кОм используется для обеспечения стабилизации, если батарея не подключена. Конденсатор C1 используется для фильтрации выходного напряжения и повышения стабильности LM317.

Напряжение измеряется в двух разных точках.

1. Резистор R5 подключен к выводу A2 Arduino. Напряжение на резисторе измерено, а ток зарядки рассчитан как Icharging =V / R

2. Напряжение на батарее может достигать 16,2 В, поэтому резистивный делитель R1, R2 используется для понижения напряжения ниже 5 В, разрешенного Arduino. Выход делителя подключен к выводу A0 Arduino. Для R1 =5,1 кОм и R2 =20 кОм Vout =Vin / (20000 + 5100) * 5100 =0,2 Таким образом, напряжение батареи делится на 5.

Реле используется для отключения аккумулятора от цепи зарядки. Вы можете видеть на фото реле, которое я использовал, но обычно можно использовать любое реле с управлением 5В. К нормально разомкнутым контактам реле безопаснее подключать аккумулятор.

Я использовал YwRobot I2C SERIAL LCD 1602 MODULE для отображения состояния зарядного устройства, но можно использовать любой другой ЖК-модуль, управляемый I2C. Похоже, что ЖК-модуль YwRobot не поддерживается стандартной библиотекой LiquidCrystal_I2C, поэтому я использовал новую библиотеку LiquidCrystal. Если вы используете другой ЖК-модуль, вам нужно будет изменить эту строку:

  ЖК-дисплей LiquidCrystal_I2C (0x27, 2, 1, 0, 4, 5, 6, 7, 3, ПОЛОЖИТЕЛЬНЫЙ); // устанавливаем адрес ЖК-дисплея на 0x27 для 16-символьного и 2-строчного отображения  

Для питания цифро-аналогового преобразователя и ЖК-дисплея я использовал источник питания SparkFun Breadboard 5V / 3.3V. Вероятно, можно будет использовать 5 В от платы Arduino.

Вам также необходимо будет подать 17V в цепь зарядки. Если у вас нет источника питания, вы можете использовать регулируемый преобразователь постоянного / постоянного тока, подобный этому

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

Функциональность

Много проводов не хотелось, поэтому кнопок для настройки зарядки нет. Течение огорчения настраивается только в коде. Вам необходимо установить желаемый ток зарядки в charger.ino

  // *************************** Параметры зарядки ************* *************************** // ******************** ************************************************* ******************* float target_current_mA =30; // Ток зарядки mAfloat battery_nominal_capacity_mA =170; // Номинальная емкость аккумулятора mAfloat max_time_for_trickle_charge =6; // Максимальное время непрерывной зарядки в минутах // *************************************** ************************************************ / / ************************************************ ***************************************  

target_current_mA - постоянный ток зарядки

max_time_for_trickle_charge - максимальное количество минут для капельной зарядки, можно установить до 600 (10ч)

battery_nominal_capacity_mA - емкость батареи, используемая для расчета постоянного тока

Обычно зарядный ток может достигать номинальной емкости. Для аккумулятора номинальной емкостью 170 мАч максимальный ток зарядки составляет 170 мА. Минимальный зарядный ток обычно C / 10 - 17 мА для аккумулятора 170 мАч.

После включения зарядное устройство проверит, подключен ли аккумулятор. Если аккумулятор подключен, аккумулятор будет заряжаться заданным постоянным током до полной зарядки. Заряд прекращен при обнаружении отрицательного значения dV / dt в течение 5 минут. После завершения зарядки зарядное устройство перейдет в режим непрерывной зарядки с током C / 40. Зарядное устройство отключится от аккумулятора по истечении максимального времени непрерывной зарядки.

1 - dV / dt

2 - время зарядки в минутах

1 - Время зарядки

2 - Заряд перенесен на аккумулятор

Дополнительная информация о NiMH батареях:

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

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

Код

  • charger.ino
  • main.ino
  • hw.ino
  • lcd.ino
  • calculate.ino
  • В этом проекте использовалась новая библиотека LiquidCrystal.
charger.ino Arduino
Главный файл
 // Это для зарядки 9-вольтовой NiMH батареи // Батарея может иметь 6,7 или 8 ячеек 1,25 В // Это делает номинальное напряжение от 7,5 до 10 В # include  #include  #include  #include  #include  LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7, 3, ПОЛОЖИТЕЛЬНО); // установить адрес ЖК-дисплея на 0x27 для 16-символьного и 2-строчного отображения // Аппаратные функции # определить MCP4725_ADDR 0x60 // Адрес ЦАП # определить DAC_REF_VOLTAGE 5.0 # определить CHARGE_RELAY_PIN 2 # определить DISCONNECT_CHARGE_RELAY HIGH # определить CONNECT_CHARGE_RELAY LOWS # определить CONNECT_CHARGE_ORELAY_LAY_RELAY_SIN_RELAY_RELAY_SIN_RELAY_SIN_RELAY_SIN_RELAY_SIN_RELAY_SIN_RELAY_RELAY_SIN_RELURS_IN_RELAYS CURRENT_SENSING_SESISTOR 10.2 // OHm # define BATTERY_VOLTAGE_PIN A0 #define R1 5090 // Резистор нижней стороны чувствительного к напряжению делителя # define R2 19910 // Верхний резистор чувствительного делителя напряжения # define ADC_REF_VOLTAGE 4.89 // Реальное напряжение питания Arduino или напряжение AREF для правильного Преобразование АЦП в напряжение # определить R3 3300.0 # определить R4 6800.0 # определить AMP_GAIN (1 + R4 / R3) // Различные определения // # определить MINIMUM_VOLTAGE 8.1 // Минимальное напряжение после регулятора # определить BATTERY_GOOD_VOLTAGE_THRESHOLD 7.0 # определить MAXIMIM_ALLOWED_CURRENT 200 // ток батареи мА (жесткое отключение) #define MAXIMUM_BATTERY_VOLTAGE 15.0 // Максимально допустимое напряжение батареи В (жесткое отключение) #define VOLTAGE_STEP 0,001 // Шаг для напряжения регуляция #define POINTS_FOR_AVERAGING 100 // Сколько точек взято для усреднения # define MEASURE2MEASURE_US 5000 // Время между измерениями в микросекундах (должно быть больше 200 из-за двух аналоговых считываний) #define VOLTAGE_LOG_TIME_MIN 30.0 // Время в минутах для сохранения напряжения для dV / dT cutoff #define MINUTES_TO_LOG 5 #define TRICKLE_CURRENT_RATIO 40 // Состояния зарядного устройства # 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 CURRENT_RAMP_UP 20 #define CURRENT_RAMP_UP 20 #define CURRENT_RAMP_UP 20 #define 37 # определяют UNEXPECTED_CURRENT_FALL 40 # определить UNABLE_TO_REACH_CURRENT 60 # определяет FULLY_CHARGED 70 # определяют CURRENT_TOO_HIGH 80 # определяет REGULATION_FAILED 90 # 100 определяют перегрузки по току # определить OverVoltage 101 # определить FINAL_STATE 200 /// беззнакового целочисленного значения voltage_readings [POINTS_FOR_AVERAGING], current_sensing_resistor_readings [POINTS_FOR_AVERAGING], averaging_index; // Для длинного усреднения без знака int Voltage_sum, current_sum; // Сумма усреднения f 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, короткие неподписанных INT last_second, lcd_last_second, log_last_second; Строка lcd_last_string1, lcd_last_string2; Строка 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_minutesCharging_average_current_mA; 0; float last_dac_voltage =0; // Сообщенияconst char msg_battery_detected [] PROGMEM ="Батарея обнаружена"; const char msg_no_battery [] PROGMEM ="Нет батареи"; const char msg_battery_ok [] PROGMEM ="Battery ok"; const char msg_voltage_too_too PROGMEM ="Напряжение батареи слишком низкое"; const char msg_voltage_too_low_short [] PROGMEM ="V Battery low"; const char msg_ramp_up [] PROGM EM ="Наращивание"; const char msg_charging [] PROGMEM ="Зарядка"; const char msg_space [] PROGMEM =""; const char msg_ramp_down [] PROGMEM ="Замедление"; const char msg_trickle_charge [] PROGMEM ="Капельный заряд "; const char msg_no_current [] PROGMEM =" Нет тока "; const char msg_current_unreachable [] PROGMEM =" Я недоступен "; const char msg_current_unreachable_long [] PROGMEM =" Невозможно достичь желаемого тока "; const char msg_completed [] PROG "; const char msg_charge [] PROGMEM =" Заряд "; const char msg_high_current [] PROGMEM =" Высокий ток "; const char msg_regulation_fault [] PROGMEM =" Ошибка регулирования "; const char msg_overcurrent [] PROGMEM =" Слишком высокий ток "; const char msg_overvoltage [] PROGMEM =«Слишком высокое напряжение»; const char msg_trickle_completed [] PROGMEM =«Подвод напряжения завершен»; // *********************** **** Параметры зарядки **************************************** // * ************************************************* ************************************* float target_current_mA =30; // Ток зарядки mAfloat battery_nominal_capacity_mA =170; // Номинальная емкость аккумулятора mAfloat max_time_for_trickle_charge =6; // Максимальное время непрерывной зарядки в минутах // *************************************** ************************************************ / / ************************************************ ************************************** struct mytime {unsigned char hours; минуты без знака; беззнаковый int total_minutes;} прошедшее_время; недействительная настройка () {pinMode (CHARGE_RELAY_PIN, OUTPUT); disconnect_charging_circuit (); // Отключение зарядного устройства от аккумулятора Wire.begin (); // I2C dac_write_voltage (0); // Убедитесь, что установлен более низкий возможный ток Serial.begin (115200); last_second =второй (); lcd_last_second =второй (); log_last_second =второй (); Timer1.initialize (MEASURE2MEASURE_US); // Будет использовать для измерения напряжения и тока батареи (микросекунды) Timer1.attachInterrupt (read_hw); // подключает read_hw () как прерывание переполнения таймера averaging_index =0; sec_index =0; min_index =0; Charger_state =0; // Начальное состояние конечного автомата desire_dac_voltage =0; // Сделать минимальное выходное напряжение shure last_blf =1.0; trickle_current_mA =номинальная_батарея_мощности_mA / TRICKLE_CURRENT_RATIO; // ChargingTimeMillis =0; // ЖК-дисплей lcd.begin (16,2); lcd.backlight (); lcd.clear (); update_lcd (F ("Включите ..."), empty_string); delay (1000);} float log_battery_voltage () {// Журнал только один раз в секунду if (log_last_second ==second ()) return last_blf; иначе log_last_second =second (); sec_log [sec_index] =напряжение батареи; если (сек_индекс <59) {сек_индекс ++; } else {// Если записана одна минута // Вычислить среднее значение за минуту if (min_index> =MINUTES_TO_LOG) min_index =0; sec_index =0; с плавающей точкой sum_v =0; для (я =0; я <60; я ++) {sum_v + =sec_log [я]; } float min_average =sum_v / 60.0; для (i =1; i  
main.ino Arduino
 void loop () {String msg1; switch (charger_state) {case INITIALIZATION:// Начальное состояние disconnect_charging_circuit (); // Отключить реле shure dac_write_voltage (0); // Убедиться, что установлен более низкий возможный ток, желаемый_dac_voltage =0; // Задержка отключения минимального напряжения (100); read_status (); if (battery_voltage> 0.1) {charger_state =BATTERY_CONNECTED; // Батарея обнаружена update_lcd (M2S (msg_battery_detected), empty_string); Serial.println (M2S (msg_battery_detected)); задержка (2000); } else {// Нет батареи Serial.println (M2S (msg_no_battery)); update_lcd (M2S (msg_no_battery), construct_status_string ()); Charger_state =NO_BATTERY; // Задержка обнаружения батареи (1000); } ломать; case NO_BATTERY:// Нет батареи read_status (); if (battery_voltage> 0.1) {charger_state =BATTERY_CONNECTED; // Батарея обнаружена Serial.println (M2S (msg_battery_detected)); update_lcd (M2S (msg_battery_detected), construct_status_string ()); задержка (1500); } else {// Если батарея не остается в этом состоянии update_lcd (M2S (msg_no_battery), construct_status_string ()); задержка (1100); } ломать; case BATTERY_CONNECTED:// Батарея подключена dac_write_voltage (0); // Удостоверьтесь, что установлен более низкий возможный ток Wish_dac_voltage =0; задержка (100); read_status (); if (battery_voltage> BATTERY_GOOD_VOLTAGE_THRESHOLD) {charger_state =CURRENT_RAMP_UP; // Начинаем нарастание тока зарядки // snprintf (welcome, sizeof (welcome), "Прошивка:V% d.% d% d", ver, ver2, ver3); update_lcd (M2S (msg_battery_ok), construct_status_string ()); Serial.println (M2S (msg_battery_ok)); задержка (2000); Wish_dac_voltage =get_approximated_dac_voltage (battery_voltage); // Устанавливаем необходимое напряжение регулятора //Serial.println(get_approximated_dac_voltage(battery_voltage)); connect_charging_circuit (); задержка (200); } else {charger_state =BATTERY_VOLTAGE_LOW; // Напряжение аккумулятора слишком низкое Serial.println (M2S (msg_voltage_too_low)); update_lcd (M2S (msg_voltage_too_low_short), construct_status_string ()); задержка (1000); } ломать; case BATTERY_VOLTAGE_LOW:// Напряжение батареи слишком низкое update_lcd (M2S (msg_voltage_too_low_short), construct_status_string ()); Serial.println (M2S (msg_voltage_too_low)); Charger_state =FINAL_STATE; // Остановить перерыв; case CURRENT_RAMP_UP:/// Наращивание тока // if (current_mA <1.0) charger_state =40; // Ток неожиданно упал read_status (); update_lcd (M2S (msg_ramp_up), construct_status_string ()); задержка (50); if (current_mA  MAXIMUM_BATTERY_VOLTAGE) charger_state =OVERVOLTAGE; // Перенапряжение if (abs (current_mA-target_current_mA)> 0,2) {// Если ток отклонился от целевого значения  0,01) Wish_dac_voltage =Wish_dac_voltage-VOLTAGE_STEP; else charger_state =CURRENT_TOO_HIGH; // Слишком высокий ток, его невозможно снизить}} if (abs (current_mA-target_current_mA)> 5) {// Регулирование не выполнено, разница слишком велика charger_state =REGULATION_FAILED; // Ошибка регулирования, слишком большая разница} dac_write_voltage (хотел_дак_вольт); if (total_minutes_average  trickle_current_mA) {if (Wish_dac_voltage> VOLTAGE_STEP) {хотел_dac_voltage =хотел_dac_voltage-VOLTAGE_STEP; dac_write_voltage (хочет_dac_voltage); } else charger_state =CURRENT_TOO_HIGH; // Невозможно уменьшить ток до скорости утечки} else {charger_state =TRICKLE; // Зарядка TrickleChargingTimeMillis =0; Serial.println (M2S (msg_trickle_charge)); } ломать; case TRICKLE:// Задержка зарядки (200); read_status (); if (current_mA <0.2) charger_state =UNEXPECTED_CURRENT_FALL; // Ток неожиданно упал, если (battery_voltage> MAXIMUM_BATTERY_VOLTAGE) charger_state =OVERVOLTAGE; // Перенапряжение if (abs (current_mA-trickle_current_mA)> 0.2) {// Если ток  0,01) Wish_dac_voltage =Wish_dac_voltage-VOLTAGE_STEP; else charger_state =CURRENT_TOO_HIGH; // Слишком высокий ток, его невозможно снизить}} if (abs (current_mA-trickle_current_mA)> 5) {// Регулирование не выполнено, разница слишком велика charger_state =REGULATION_FAILED; // Ошибка регулирования, слишком большая разница} dac_write_voltage (хотел_дак_вольт); // if (total_minutes_average  max_time_for_trickle_charge) {// Максимально допустимый капельный заряд update_lcd (eoc_line1, eoc_line2); Charger_state =END_OF_TRICKLE; // Остановить disconnect_charging_circuit (); // Отключаем зарядное устройство от аккумулятора} break; case END_OF_TRICKLE:if ((second ()% 8) <4) update_lcd (M2S (msg_trickle_completed), construct_status_string ()); иначе update_lcd (eoc_line1, eoc_line2); ломать; case UNEXPECTED_CURRENT_FALL:// Ток неожиданно упал Serial.println (F ("Текущий неожиданно упал")); disconnect_charging_circuit (); Wish_dac_voltage =0; update_lcd (M2S (msg_no_current), construct_status_string ()); Charger_state =FINAL_STATE; // Задержка остановки (1000); ломать; case UNABLE_TO_REACH_CURRENT:// Невозможно достичь желаемого текущего Serial.println (M2S (msg_current_unreachable_long)); disconnect_charging_circuit (); Wish_dac_voltage =0; dac_write_voltage (хочет_dac_voltage); задержка (1000); update_lcd (M2S (msg_current_unreachable), construct_status_string ()); Charger_state =FINAL_STATE; // Остановить перерыв; case FULLY_CHARGED:// Полностью заряжено elapsed_time =mills2time (ChargingTimeMillis); int charge_mAh; charge_mAh =calculate_charge (ChargingTimeMillis); msg =Строка (M2S (msg_completed) + M2S (msg_space) + construct_time_string (elapsed_time)); msg1 =Строка (M2S (msg_charge) + M2S (msg_space) + String (charge_mAh) + String («mAh»)); eoc_line1 =сообщение; eoc_line2 =msg1; update_lcd (сообщение, сообщение1); Serial.println (сообщение); // disconnect_charging_circuit (); // Wish_dac_voltage =0; // dac_write_voltage (хотела_dac_voltage); задержка (3000); Charger_state =CURRENT_RAMP_DOWN; // Остановить перерыв; case CURRENT_TOO_HIGH:// Слишком большой ток Serial.println (F («Невозможно снизить ток до цели»)); disconnect_charging_circuit (); Wish_dac_voltage =0; dac_write_voltage (0); update_lcd (M2S (msg_high_current), construct_status_string ()); задержка (1000); Charger_state =FINAL_STATE; // Остановить перерыв; case REGULATION_FAILED:// Ошибка регулирования Serial.println (M2S (msg_regulation_fault)); disconnect_charging_circuit (); Wish_dac_voltage =0; dac_write_voltage (0); update_lcd (M2S (msg_regulation_fault), construct_status_string ()); задержка (1000); Charger_state =FINAL_STATE; // Остановить перерыв; case OVERCURRENT:// Перегрузка по току disconnect_charging_circuit (); Serial.println (M2S (msg_overcurrent)); Wish_dac_voltage =0; dac_write_voltage (хочет_dac_voltage); update_lcd (M2S (msg_overcurrent), construct_status_string ()); задержка (1000); Charger_state =FINAL_STATE; // Остановить перерыв; case OVERVOLTAGE:// Перенапряжение disconnect_charging_circuit (); Serial.println (M2S (msg_overvoltage)); Wish_dac_voltage =0; dac_write_voltage (хочет_dac_voltage); update_lcd (M2S (msg_overvoltage), construct_status_string ()); задержка (1000); Charger_state =FINAL_STATE; // Остановить перерыв; case FINAL_STATE:// Задержка остановки (10000); ломать; по умолчанию:wish_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( "Требуемое напряжение ЦАП"); //Serial.println(wanted_dac_voltage); //Serial.print(current_mA); //Serial.print (""); //Serial.print(dac_voltage); //Serial.print (""); read_status (); if (last_second! =second ()) {Serial.print (текущий_мА); Serial.print (","); //Serial.print(resistor_voltage); //Serial.print (","); //Serial.print(dac_voltage); //Serial.print (","); //Serial.print(regulator_voltage); //Serial.print (","); Serial.println (напряжение батареи); last_second =второй (); }} 
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; если (adc_voltage <0) adc_voltage =0; return adc_voltage;} int Voltage_to_code (напряжение с плавающей запятой) {int code =4095.0 / DAC_REF_VOLTAGE * Voltage; код возврата;} void dac_write (int code) {Wire.beginTransmission (MCP4725_ADDR); Wire.write (64); // команда для обновления ЦАП Wire.write (код>> 4); // 8 старших разрядов ... Wire.write ((code &15) <<4); // 4 младших бита ... Wire.endTransmission ();} void read_status () {Voltage_sum =0; текущая_сумма =0; for (i =0; i  =POINTS_FOR_AVERAGING) averaging_index =0; если (tmp_battery_voltage> MAXIMUM_BATTERY_VOLTAGE) {disconnect_charging_circuit (); // Отключаем зарядное устройство от аккумулятора charger_state =OVERVOLTAGE; } если (tmp_current_mA> MAXIMIM_ALLOWED_CURRENT) {disconnect_charging_circuit (); // Отключаем зарядное устройство от аккумулятора charger_state =OVERCURRENT; }} void disconnect_charging_circuit () {digitalWrite (CHARGE_RELAY_PIN, DISCONNECT_CHARGE_RELAY); // Отсоединение зарядного устройства от аккумулятора} void connect_charging_circuit () {digitalWrite (CHARGE_RELAY_PIN, CONNECT_CHARGE_RELAY); // Подключаем зарядное устройство к аккумулятору} // 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); если (lcd_last_string1! =первая_строка) {lcd.clear (); lcd.setCursor (0,0); lcd.print (первая_ строка); lcd_last_string1 =первая_ строка; lcd.setCursor (0,1); lcd.print (вторая_ строка); lcd_last_string2 =вторая_ строка; } если (lcd_last_second! =second ()) {if (lcd_last_string2! =second_line) {lcd.setCursor (0,1); lcd.print (вторая_ строка); lcd_last_string2 =вторая_ строка; }} lcd_last_second =second ();} String construct_status_string (void) {String v, i; if (battery_voltage <10) v =String (battery_voltage, 2); иначе v =Строка (напряжение_батареи, 1); if (current_mA <10) i =Строка (current_mA, 2); иначе я =Строка (current_mA, 1); //Serial.println(v); мое время истекло; Строка msg, msg_time; //Serial.print(charging_started); //Serial.print (""); //Serial.println(String(millis()-charging_started)); переключатель (состояние_зарядки) {case ЗАРЯДКА:истекло =mills2time (ChargingTimeMillis); ломать; case TRICKLE:elapsed =mills2time (TrickleChargingTimeMillis); ломать; } 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; ломать; case TRICKLE:msg=v+String(F("V "))+i+String(F("mA"))+" "+msg_time; ломать; 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
 Нет предварительного просмотра (только загрузка). 

Схема

charger_AgK96zxw2T.zip

Производственный процесс

  1. Сигнал тревоги для растений, предупреждающий о жажде
  2. Итальянские часы со словами
  3. Только три контакта для клавиатуры 4x3
  4. Счетчик кВтч Sigfox
  5. Монитор температуры Bluetooth
  6. Блокировка, управляемая жестами
  7. Компаньон IC
  8. USB-MIDI-адаптер
  9. Изолированный аналоговый вход для Arduino
  10. Измерьте время реакции