Расчет Ампер часов солнечной панели

Меня интересует вычисление мощности солнечной панели в амперах в час с помощью Arduino. Я уверен, что смогу получить напряжение (с помощью делителя напряжения) и силу тока (с помощью ACS712). Мой вопрос касается математики расчета Ампер * часа.

Вот мой план:

  1. Мой план состоит в том, чтобы каждую секунду увеличивать напряжение и силу тока.
  2. Затем я бы добавил это значение amp * second к переменной. Я бы также увеличивал другую переменную за каждую секунду.
  3. Тогда я смог бы получить среднее или общее количествосекунд усилителя из этих 2 переменных. Я мог бы также разделить ампер-секунду на 3600, если бы хотел ампер-час.

Не слишком ли сложно опрашивать силу тока каждую секунду и называть ее ампер / секунда? Как я могу сделать это более точным?

, 👍2

Обсуждение

а зачем вы измеряете напряжение?, @Juraj

Всего один незначительный комментарий: Это ампер-часы (Ач) и ампер-секунды, а не ампер-часы. В противном случае ваш метод расчета кажется правильным. Однако я бы не стал ожидать очень точных результатов. Вы могли бы использовать напряжение таким же образом для расчета ватт-часов., @StarCat

Я был в процессе редактирования вашего ответа, а затем решил отказаться от него. Вместо этого я просто скажу это здесь: нет такого понятия, как ** ампер / час **, как полезное измерение. То, что вы имеете в виду, это ** ампер * часов **, или Ах (https://en.wikipedia.org/wiki/Ampere_hour ). Кроме того, измените слово "тянуть" на **опрос **. Это два совершенно разных английских слова, и вы имеете в виду ** опрос **, или "спрашивать неоднократно", а не "тянуть", или "прилагать силу к чему-либо", или "тянуть или тянуть к себе"., @Gabriel Staples

@Juraj Я упомянул, что у меня есть напряжение, если случайно это было необходимо., @RonSper


3 ответа


Лучший ответ:

6

Как сделать собственный кулоновый счетчик (ампер-час [Ahr] или ватт*час [Whr] счетчик энергии) с помощью Arduino

Краткий обзор:

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

Подробнее

Здесь много недоразумений, но вот суть.

То, что вы хотите сделать, это идеальное приложение для Arduino. Нет необходимости покупать счетчик кулонов, вместо этого вы должны сделать его с помощью Arduino.

Затем я добавляю это значение в ампер/секунду к переменной.

Первое исправление, это ампер*секунда, НЕ ампер/секунда. Вы умножаете ампер на количество секунд, в течение которых существовало текущее значение.

ампер*секунды / 3600 = ампер*часы. Прочитайте об этом здесь: https://en.wikipedia.org/wiki/Ampere_hour. Умножьте это на напряжение за тот же период времени, и вы получите амперы*часы*вольты = (амперы*вольты)*часы = ватты*часы = единицы энергии. ! Помните, что электроэнергия для вашего дома приобретается в киловатт-часах, то есть киловаттах*часах или кВтч. А в инженерных единицах джоуль является стандартной единицей энергии, и это просто Ватты* секунды. Таким образом, вы можете конвертировать кВтч в джоули следующим образом, где единицы измерения указаны в квадратных скобках [].

Joules = kWhr * 1000 [Whr/kWhr] * 3600 [sec/hr] = [Watts*sec] = [Joules]

Итак, 1 кВтч x 1000 x 3600 = 3600000 Дж = 3600 кДж

Я бы также увеличивал еще одну переменную каждую секунду.

Это не имеет никакого смысла. Не делай этого. Вы уже зафиксировали секунды, добавив новый бит ампер*секунд к старой сумме.

НЕОБХОДИМО учитывать и напряжение! На самом деле вам нужна энергия, которую можно выразить в джоулях или кВтч, как уже описано выше.

Не слишком ли сложно опрашивать силу тока каждую секунду и называть ее amp*second?

(мои исправления выделены жирным шрифтом)

Нет, абсолютно нет! Это точно что такое ампер*секунда! Это ток, ампер, умноженный на количество секунд, в течение которых существовал ток. Это кулоновый счетчик!

А. Как можно лучше сделать счетчик кулонов

Как сделать это более точным?

Это та часть, где инженер и программист (вы) определяете качество результата.

  1. Не думайте, что прошла 1 секунда, потому что вы сказали об этом. Измеряйте каждое измерение!
  2. Чем меньше временной интервал, тем точнее, поскольку он позволяет фиксировать небольшие колебания тока, поэтому используйте меньший временной интервал, чем 1 секунда. Я бы начал с 10 мс.
  3. Измерьте напряжение, ток и фактическое время, прошедшее в этом контуре, как можно ближе к одному и тому же времени.
  4. НЕ используйте методы блокировки, такие как delay() или delayMicroseconds().
  5. То, что вы делаете, когда умножаете показания нового усилителя на x секунд и прибавляете его к предыдущей сумме, называется < em>численное интегрирование. Вы просто численно интегрируете или суммируете площадь под кривой Ампер (ось Y)-время (ось X), или, если вы делаете то, что я говорю вместо этого: Ватт (Y- ось) - временная (ось x) кривая, где площадь под кривой представляет собой общую собранную энергию. Не выполняйте прямоугольное интегрирование, выполняйте трапециевидное интегрирование, следуя правилу трапеций! Это точнее!
  6. Откалибруйте часы! Часы Arduino могут отставать на пару процентов. Выясните, насколько он отличается, сравнив выходные данные часов, скажем, за 10 минут, и сравнив их с лучшим источником часов, скажем... сервером времени в Интернете, отображающим атомные часы в Колорадо или где бы то ни было. Затем умножьте каждое измерение на масштабный коэффициент, чтобы зафиксировать его!
  7. Так же, как и выше, в идеале вы также должны компенсировать температуру в режиме реального времени, поскольку тактовая частота дрейфует в зависимости от температуры.
  8. Выполните калибровку измерения напряжения.
  9. Выполните калибровку текущего измерения.

Б. Дополнительно: когда трапециевидная интеграция наиболее выгодна?

Вы можете назвать следующий список моими "5 гипотезами о преимуществах трапециевидной интеграции".< /p>

Преимущества трапециевидной интеграции можно оспорить, и, возможно, она не так важна, как я изначально представил, но ее супер просто реализовать, так почему бы и нет!? Кроме того, наиболее важно, когда:

  1. Частота дискретизации по времени очень низкая.
  2. Скорость изменения показаний (то есть их производной или наклона) очень высокая.
  3. Показания постоянно имеют возрастающий наклон (прямоугольное интегрирование _занижает_оценку площади в этом случае) ИЛИ постоянно падающий наклон (прямоугольное интегрирование _переоценивает в этом случае).
  4. Если вас интересуют данные в режиме реального времени сейчас, а не только общие тенденции или средние значения. Это связано с тем, что трапециевидное интегрирование мгновенно устраняет ошибки переоценки и недооценки, которые могут накапливаться в течение коротких периодов времени, но затем "деаккумулируются" или сбрасываются в течение длительных периодов времени, когда в данных наблюдается противоположный наклон.
  5. [Это может применяться только при наличии джиттера в частоте дискретизации — см. комментарий @Edgar Bonet здесь]. показания постоянно растут с разной скоростью, чем падают, так как это приводит к асимметричному накоплению ошибки. Это означает, что прямоугольная ошибка интегрирования, накопленная путем увеличения расстояния delta_y, НЕ будет полностью сведена на нет ошибкой в противоположном направлении, когда значения уменьшаются на расстоянии delta_y. Таким образом, даже в течение длительных периодов времени ошибка будет не сбрасываться, а накапливаться со временем все больше и больше. [Примечание: мне нужно некоторое время аналитически/численно поиграть с этой гипотезой, чтобы окончательно доказать ее самому себе, но я почти уверен, что она верна].

Пример полного кулоновского счетчика в коде:

Этот код теперь находится в моем репозитории eRCaGuy_hello_world: coulomb_counter_with_cooperative_multitasking_macro.ino.

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

Я заимствую часть этого кода, основанную на метках времени, для совместной многозадачности из мой ответ о совместной многозадачности здесь, поэтому ознакомьтесь с дополнительной информацией по этому вопросу.

Как написано, этот код компилируется, но я ничего не подключал и не тестировал. Вот результат компиляции:

Sketch использует 3750 байт (12%) места для хранения программ. Максимальный размер – 30 720 байт.
Глобальные переменные используют 262 байта (12%) динамической памяти, оставляя 1786 байтов для локальных переменных. Максимальный размер – 2048 байт.

coulomb_counter_with_cooperative_multitasking_macro.ino:

Перейдите вниз, чтобы узнать о функциях setup() и loop(). Они оба очень короткие.

/// Пример счетчика Кулона
/// Габриэль Стейплс
/// См.: https://arduino.stackexchange.com/questions/75932/calculating-amp-hrs-of-a-solar-panel/75937#75937

/// @brief Макрос, похожий на функцию, для запуска определенного набора событий в желаемое фиксированное время.
/// интервал период или частота.
/// @details Это метод опроса времени на основе временных меток, часто используемый на «голом железе».
/// программирование как основное средство достижения совместной многозадачности. Примечание
/// что получение правильных деталей синхронизации затруднено, поэтому одна из причин, по которой этот макрос
/// очень полезно. Другая причина в том, что этот маро значительно уменьшает количество
/// строки кода, которые вам нужно написать, чтобы представить новый кооператив на основе временных меток
/// задача. Используемый здесь метод обеспечивает идеальный желаемый период (или частоту)
/// в среднем, так как дрожание, присущее любому методу опроса, сосредоточено вокруг
/// желаемая уставка временной дельты, а не всегда отстающая, как многие другие
/// подходы делают.
///
/// ПРИМЕР ИСПОЛЬЗОВАНИЯ:
/// ```
/// // Создать таймер задачи для работы с частотой 500 Гц (каждые 2000 мкс или 2 мс; 1/0,002 с = 500 Гц)
/// const uint32_t PERIOD_US = 2000; // 2000 мкс pd --> частота 500 Гц
/// bool time_to_run;
/// uint32_t fact_period_us;
/// CREATE_TASK_TIMER(PERIOD_US, time_to_run, fact_period_us);
/// если (time_to_run)
/// {
/// run_task_2();
///
/// // ИЛИ, если `run_task_2()` нужен фактический период, который только что произошел, для
/// // какой бы ни была причина, вы можете передать ее вашей функции `run_task_2()`:
/// run_task_2(actual_period_us);
///
/// // ИЛИ, просто сделайте весь свой код прямо здесь, а не в `run_task_2()`
/// }
/// ```
///
/// Источник: Габриэль Стейплс
///
/// @param[in] period_desired_us (uint32_t) Желаемый период дельта-времени в микросекундах;
/// примечание: pd = 1/freq; тип должен быть `uint32_t`.
/// @param[out] time_to_run (bool) `bool`, область видимости которого будет входить *в* блок области видимости на основе фигурных скобок
/// ниже; используется как *выходной* флаг для вызывающего: эта переменная будет
/// быть установлено в true, если пришло время запустить ваш код, в соответствии с
/// временные метки, в противном случае будет установлено значение false.
/// @param[out] fact_period_us (uint32_t) Фактический период в нас с момента последнего
/// время запуска -- то есть: с момента, когда `time_to_run` в последний раз было установлено значение true.
/// @return NA -- это не настоящая функция
#define CREATE_TASK_TIMER(period_desired_us, time_to_run, actual_period_us)                                            \
{ /* Use scoping braces to allow multiple calls of this macro all in one outer scope while */                          \
  /* allowing each variable created below to be treated as unique to its own scope */                                  \
    time_to_run = false;                                                                                               \
                                                                                                                       \
    /* set the desired run pd / freq */                                                                                \
    const uint32_t PERIOD_DESIRED_US = period_desired_us;                                                              \
    static uint32_t t_start_us = micros();                                                                             \
    uint32_t t_now_us = micros();                                                                                      \
    uint32_t period_us = t_now_us - t_start_us;                                                                        \
    actual_period_us = period_us;                                                                                      \
                                                                                                                       \
    /* See if it's time to run this Task */                                                                            \
    if (period_us >= PERIOD_DESIRED_US)                                                                                \
    {                                                                                                                  \
        /* 1. Add PERIOD_DESIRED_US to t_start_us rather than setting t_start_us to t_now_us (which many */            \
        /* people do) in order to ***avoid introducing artificial jitter into the timing!*** */                        \
        t_start_us += PERIOD_DESIRED_US;                                                                               \
        /* 2. Handle edge case where it's already time to run again because just completing one of the main */         \
        /* "scheduler" loops in the main() function takes longer than PERIOD_DESIRED_US; in other words, here */       \
        /* we are seeing that t_start_us is lagging too far behind (more than one PERIOD_DESIRED_US time width */      \
        /* from t_now_us), so we are "fast-forwarding" t_start_us up to the point where it is exactly */               \
        /* 1 PERIOD_DESIRED_US time width back now, thereby causing this task to instantly run again the */            \
        /* next time it is called (trying as hard as we can to run at the specified frequency) while */                \
        /* at the same time protecting t_start_us from lagging farther and farther behind, as that would */            \
        /* eventually cause buggy and incorrect behavior when the (unsigned) timestamps start to roll over */          \
        /* back to zero. */                                                                                            \
        period_us = t_now_us - t_start_us; /* calculate new time delta with newly-updated t_start_us */                \
        if (period_us >= PERIOD_DESIRED_US)                                                                            \
        {                                                                                                              \
            t_start_us = t_now_us - PERIOD_DESIRED_US;                                                                 \
        }                                                                                                              \
                                                                                                                       \
        time_to_run = true;                                                                                            \
    }                                                                                                                  \
}

// Преобразование микросекунд в секунды
#define US_TO_SEC(us) ((us)/1000000UL)
// Преобразование джоулей в кВтч (киловатт*часы)
#define JOULES_TO_KWHRS(joules) ((joules)/3600/1000)

/// @brief Получить скорректированное измерение времени из необработанного измерения времени.
/// @details Предполагая, что вы провели эксперименты по определению вашего микроконтроллера (mcu)
/// ошибка часов, вы можете исправить ее с помощью этой функции. Пройти за время
/// измерение, которое микроконтроллер замерил напрямую, и получить скорректированное значение.
/// @param[in] raw_sec Необработанное измерение времени в секундах
/// @return Скорректированное измерение времени в секундах
float do_time_correction(float raw_sec)
{
    // Вы определяете правильную константу калибровки. Возможно, это 0,9813, или, возможно, это
    // 1.19.... Вам нужно будет определить это для каждого отдельного микроконтроллера.
    constexpr float TIME_CORRECTION_CONST = 1.0; // по умолчанию: 1.0
    float corrected_sec = raw_sec*TIME_CORRECTION_CONST;
    return corrected_sec;
}

/// @brief Получить новое мгновенное (на данный момент) значение тока в амперах
/// @параметр Нет
/// @return Ток, в амперах
float get_current()
{
    // вы реализуете это
}

/// @brief Получить новое мгновенное (на данный момент) значение напряжения в вольтах
/// @параметр Нет
/// @возвратное напряжение, в вольтах
float get_voltage()
{
    // вы реализуете это
}

/// @brief Запустите задачу счетчика кулонов, чтобы просуммировать общую энергию, полученную от солнечных панелей
/// @param[out] total_energy_joules_p (необязательно) Указатель на число с плавающей запятой для получения суммы
/// значение полученной энергии, в джоулях (Ватт*сек). Передайте `nullptr`, чтобы не
/// получить обратно это значение. Обратите внимание, что ранее кэшированное значение
/// отключается, если не время вычислять новое значение.
/// Возвращаемое значение этой функции будет указывать, будет ли новое значение
/// или здесь передается кэшированное значение.
/// @param[in] reset_sum (необязательно) передайте значение true, чтобы сбросить хранящуюся внутри "общую энергию"
/// приобрел" значение во время этого вызова (до выполнения последней
/// вычисление power_watts_avg, если пришло время для этого).
/// @return true, если новое значение total_energy_joules было только что рассчитано и передано обратно через
/// указатель выше или false, если вместо него было передано старое кэшированное значение, поскольку оно
/// не было времени получить и вычислить новое значение.
bool run_coulomb_counter(float* total_energy_joules_p = nullptr, bool reset_sum = false)
{
    // Установите эту задачу для работы на частоте 100 Гц
    constexpr uint32_t PERIOD_DESIRED_US = 10000; // 10000 мкс = 10 мс или рабочая частота 100 Гц

    static float total_energy_joules = 0;

    if (reset_sum)
    {
        total_energy_joules = 0;
    }
    
    bool time_to_run = false;
    uint32_t actual_period_us;
    CREATE_TASK_TIMER(PERIOD_DESIRED_US, time_to_run, actual_period_us);
    if (time_to_run)
    {
        // Пришло время получить новые выборки и выполнить численное интегрирование для получения общего
        // энергия получена.

        // предыдущий расчет мощности в ваттах; требуется для трапециевидной интеграции
        static float power_watts_old = 0; 

        // взять новые образцы, & рассчитать мощность по этим образцам
        float current_amps = get_current(); 
        float voltage = get_voltage(); 
        float power_watts = current_amps*voltage;

        float actual_period_sec = US_TO_SEC((float)actual_period_us);
        actual_period_sec = do_time_correction(actual_period_sec);

        // Выполняем трапециевидное интегрирование, чтобы получить «площадь под кривой», которая равна
        // энергия в джоулях. Представьте себе график, где ось Y — мощность, а ось X — время. Если
        // вы разбиваете ось X на сегменты шириной PERIOD_DESIRED_US, затем трапециевидный
        // площадь под кривой в каждом из этих временных сегментов равна time_delta x
        // (power_old + мощность)/2. Это энергия (Джоули), полученная за этот период времени.
        float power_watts_avg = (power_watts + power_watts_old)/2;
        power_watts_old = power_watts; // подготовка к следующей итерации
        float energy_joules = actual_period_sec*power_watts_avg; 

        total_energy_joules += energy_joules;
    }

    if (total_energy_joules_p != nullptr)
    {
        // выводим это значение обратно пользователю
        *total_energy_joules_p = total_energy_joules;
    }

    return time_to_run;
}

void setup()
{
    // делаем здесь все, что вам нужно
    Serial.begin(115200);
}

void loop()
{
    // Энергия в джоулях или ваттах*секундах. Чтобы перевести в ватт*часы, просто разделите на 3600 [сек/ч]
    float total_energy_joules;
    bool new_measurements_made = run_coulomb_counter(&total_energy_joules);
    
    // Давайте выполним печать на основе событий, где мы печатаем последнее значение total_energy_joules со скоростью
    // 2 Гц, что характерно для цифровых дисплеев, отображающих информацию, которую предполагается прочитать
    // мы медленные люди. Поскольку задача run_coulomb_counter() выполняется с частотой 100 Гц, это означает, что мы
    // нужно печатать последнее значение каждые 50 запусков.
    if (new_measurements_made)
    {
        static uint16_t run_count = 0;
        run_count++;
        if (run_count % 50 == 0)
        {
            float total_energy_kwh = JOULES_TO_KWHRS(total_energy_joules);
            Serial.print("total energy received (J) = ");
            Serial.print(total_energy_joules);
            Serial.print("; (kWh) = ");
            Serial.println(total_energy_kwh);
        }
    }
}

Ссылки:

  1. Мой собственный ответ об универсальной совместной многозадачности на основе меток времени: Переполнение стека: как сделать -блокировка, однопоточная совместная многозадачность

См. также:

  1. [мой ответ] Числовой вывод и интеграция в код для физики, робототехники, игр и элементов управления
,

Итак, как OP будет измерять ток? Резистор с высоким током и низким значением, соответствующий потоку тока, и использование Arduino для измерения напряжения на резисторе?, @Duncan C

Это сработает, но он упомянул, что вместо этого у него есть это: ACS712., @Gabriel Staples

Позже я опубликую пример кода для всего счетчика кулонов., @Gabriel Staples

Кроме того, измерение этих типов низких напряжений на резисторе требует либо [передискретизации] (https://www.electricrcaircraftguy.com/2014/05/using-arduino-unos-built-in-16-bit-adc.html), либо ОУ, так что ACS712 легче точно., @Gabriel Staples

Трапециевидный или прямоугольный не имеет большого значения: это всего лишь коэффициент 1/2 для первой и последней точек данных. Было бы уместно, если бы интервал интегрирования был известен с гораздо большей точностью, чем период выборки (распространенный случай в некоторых инженерных контекстах), но это _не_ относится к отображению в реальном времени, особенно если выборка с интервалом 10 мс и мониторинг результат с использованием человеческих глаз., @Edgar Bonet

Достоинства трапециевидной интеграции можно оспорить, и, вероятно, это не так важно, как я изначально это звучал, но это *супер просто* реализовать, так почему бы и нет!? Кроме того, это _наиболее важно_, когда: 1) частота выборки по времени *очень низкая*, 2) скорость изменения показаний *очень высокая*, 3) показания постоянно имеют возрастающий наклон (прямоугольное интегрирование здесь недооценивает) ИЛИ последовательный падающий наклон (здесь прямоугольные переоценки) и 4) когда вас интересуют показания в реальном времени *в данный момент*, а не только общие тенденции или средние значения., @Gabriel Staples

Кроме того, я не думал, что эти данные будут просто просматриваться человеческим глазом: я планировал, что они также будут регистрироваться, так что вы можете сделать это правильно, когда сделать это правильно так просто (трапециевидная интеграция очень проста) ., @Gabriel Staples

Код выложен. Я только что сделал полный счетчик кулонов., @Gabriel Staples

При постоянной частоте дискретизации ваша гипотеза 5 неверна, так как прямоугольная и трапециевидная формы отличаются только весами первой и последней выборки. **Однако**, если частота дискретизации нестабильна и коррелирует с производной сигнала (например, более быстрая дискретизация при нарастании сигнала), то прямоугольное интегрирование действительно будет накапливать ошибки. В отсутствие этой корреляции ошибка, вносимая дрожанием дискретизации в прямоугольный интегратор, будет «блуждать» (т. е. случайным блужданием) как √t. Трапециевидный определенно лучше справляется с выборкой с очень высоким джиттером., @Edgar Bonet

Интересно, почему минус только сейчас. Если вы минусуете, я хотел бы знать, насколько ответ неадекватен и где он идет не так., @Gabriel Staples

Я только что проголосовал за этот ответ. Не знаю, почему кто-то проголосовал бы за это. Очень тщательно и легко понять. Мне пришлось бы изучить это намного усерднее, чем у меня сейчас есть время, чтобы понять ваш № 5 о трапециевидной интеграции по сравнению с прямоугольной. Как вы говорите, это легко, так почему бы и нет?, @Duncan C


2

Вам нужно устройство под названием "кулоновский счетчик". Такое устройство измеряет общий ток, который протекает через него.

Я видел некоторые для Arduino. Я полагаю, что SparkFun продает один из них. Однако при быстром поиске кажется, что у них может быть слишком низкое напряжение для большой солнечной панели.

,

Смогу ли я увеличить силу тока быстрее, чтобы получить эквивалентную мощность, или это глупая затея? Спасибо за подсказку кулоновского счетчика. LTC4150 кажется дешевым и простым в использовании., @RonSper

Кулоновский счетчик измеряет ток в амперах/часах напрямую. Каково максимальное напряжение вашей солнечной панели? Предполагая, что он может обрабатывать напряжение и величину тока, которые вам нужно измерить, он должен идеально соответствовать вашим потребностям., @Duncan C

Мне не нравится этот ответ, потому что он игнорирует тот факт, что Arduino * ЯВЛЯЕТСЯ кулоновским счетчиком, если используется правильно, но я не буду его понижать, потому что этот ответ сам по себе не является неправильным. @RonSper, Arduino прекрасно может выступать в качестве кулоновского счетчика. Это не дурацкая затея, это именно то, что я бы сделал., @Gabriel Staples

В случае, если вам интересно, поскольку я думаю, что это довольно классный вариант использования для Arduino, я только что выполнил полную реализацию алгоритма кулоновского счетчика с нуля, в коде, в моем ответе., @Gabriel Staples


1

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

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

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

Просто полагаясь на Amp-hours_out = constant * Amp-Hours_in, необходимо установить константу на максимальное значение, чтобы избежать попыток подачи тока с высокой скоростью в полностью заряженные ячейки. Это зарядное устройство полагается на длительную фазу завершения зарядки и балансировки с низкой скоростью, чтобы избежать постепенного перехода от состояния заряда к частичному заряду с максимальной приемлемостью. Доступные часы солнечного света, как правило, ограничивают время, доступное для балансировки заряда, а доступная емкость аккумулятора определяется ячейкой с самым низким уровнем заряда, поэтому идея состоит в том, чтобы максимально приблизиться к 100% на ячейке с самым высоким уровнем заряда до того, как скорость заряда снизится. отбросить, чтобы избежать повреждения клеток.

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

,