avatar_UriBas

Моргалка на Arduino. Этюды для начинающих.

Автор UriBas, 08 Март 2017 в 16:08

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Necromant

Суточный лог медалиста, начальное НРЦ 12,30В, последняя подзарядка полтора месяца назад
Выставлены параметры очень бережного заряда
Спойлер
Медалист 55Ач предположительно 2005 гв, эксплуатировался до конца 2015 на авто, далее 2 года помирал в ИБП, с января этого года в роли подопытного для испытания алгоритмов заряда. Был долит, немного восстановился, без проблем всегда заводит дизельгенератор и свежезаряженным моего Гольфа

на графике видно, что очень долго держалось волшебное напряжение 12,868, потом начался рост


заряд продолжается...

Necromant

Цитата: UriBas от 25 Окт. 2018 в 19:31
На форумах читал,  в каких случаях людям удавалось устранять КЗ, например:  Прожиганием мостика (КЗ) мощным импульсом тока; промывкой водой и последующим зарядом; переполюсовкой;  удалением шлама с поверхности пластин (пинцетом и чем-то подобным) еще когда с помощью тонкой полоски текстолита проводили между пластинами и удаляли мостик, используя тепловизор.. и т.д.  Иногда само по себе уходило.
Нет никакого желания возиться в замкнутым трупом - этот аккумулятор никакой ценности не представляет, даже если и удастся убрать КЗ, в авто его ставить точно не следует, может снова в самый неподходящий момент коротнуть. В нем кристаллы льда многократно разорвали АМ пластин. На нем было бы интересно посмотреть динамику восстановления после сильной сульфатации. Не вышло

Паяка

Цитата: Necromant от 25 Окт. 2018 в 19:58на графике видно, что очень долго держалось волшебное напряжение 12,868, потом начался рост
И ещё вопрос, хорошо ли, что он начался, и что с этим делать. Не поставить ли на отстой (минуты, часы, дни?), или на разряд (насколько глубокий?), после которого снова на заряд?

На моём опыте, бывает так, что дозаряжать уже нет смысла, но после рабочего разряда или саморазряда в отстое можно продолжить восстановление АКБ до ещё лучших параметров, чем получились в предыдущем цикле.
GT TF1 60V 20Ah Chilwee DZF

Necromant

Цитата: Паяка от 25 Окт. 2018 в 20:30
И ещё вопрос, хорошо ли, что он начался, и что с этим делать. Не поставить ли на отстой (минуты, часы, дни?), или на разряд (насколько глубокий?), после которого снова на заряд?

На моём опыте, бывает так, что дозаряжать уже нет смысла, но после рабочего разряда или саморазряда в отстое можно продолжить восстановление АКБ до ещё лучших параметров, чем получились в предыдущем цикле.
но там итак паузы до 4-5 минут
я связываю это с полным расходованием легкогодоступного сульфата в АМ, а далее или расслоение или начал твердый сульфат потихоньку расходоваться

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

UriBas

#1084
Цитата: Necromant от 25 Окт. 2018 в 19:58
Спойлер

Суточный лог медалиста, начальное НРЦ 12,30В, последняя подзарядка полтора месяца назад
Выставлены параметры очень бережного заряда
Спойлер
Медалист 55Ач предположительно 2005 гв, эксплуатировался до конца 2015 на авто, далее 2 года помирал в ИБП, с января этого года в роли подопытного для испытания алгоритмов заряда. Был долит, немного восстановился, без проблем всегда заводит дизельгенератор и свежезаряженным моего Гольфа

на графике видно, что очень долго держалось волшебное напряжение 12,868, потом начался рост


заряд продолжается...
[user]Necromant  [/user]  Все пытаюсь понять логику подбора длительности пауз и импульсов, и чё-то торможу..   пауза ((U1 - U2) > 0) по первой производной не понятно на какой скорости останавливается.. получается если после 1 секунды разность напряжений больше нуля, то пауза прекращается, но на мой взгляд, там может быть разные ситуации..  то же самое по длительности импульса + применение ограничения ChargePeriod = long(pow(2.72, ((U50 - U1) / 1000)) * Timer)..
Судя по графикам (по НРЦ в паузе), на мой взгляд, идет пережим" (резкий взлет НРЦ)..  с другой стороны, есть участки где наоборот, недожим"..  (резкий спад НРЦ)
Восточная мудрость - "Шакал воет - караван идет"  Эл.вел. 350Вт.   Верую в Иисуса Христа, НЛО.  тема "продвинутой моргалки" https://electrotransport.ru/index.php?msg=1669651

Necromant

Цитата: UriBas от 27 Окт. 2018 в 13:14
[user]Necromant  [/user]  Все пытаюсь понять логику подбора длительности пауз и импульсов, и чё-то торможу..   пауза ((U1 - U2) > 0) по первой производной не понятно на какой скорости останавливается.. получается если после 1 секунды разность напряжений больше нуля, то пауза прекращается, но на мой взгляд, там может быть разные ситуации..  то же самое по длительности импульса + применение ограничения ChargePeriod = long(pow(2.72, ((U50 - U1) / 1000)) * Timer)..
Судя по графикам (по НРЦ в паузе), на мой взгляд, идет пережим" (резкий взлет НРЦ)..  с другой стороны, есть участки где наоборот, недожим"..  (резкий спад НРЦ)
Если после RelaxPeriod = int(pow(2.72, ((U1 - U50) / 1000)) * 3000) разность напряжений ноль и меньше, тогда конец паузы (чем выше напряжение в конце паузы тем длинее период для дифференцирования, соответственно длиннее пауза) Пережима быть не может: из-за шумов и наводок получить 0 производной не всегда удается и алгоритм уходит на следующий круг (недожим, и он может неоднократно повторится), для более жесткого режима я ставлю 5мВ тогда разброс в паузах соседних циклов минимален. Резкий взлет НРЦ норма для этого уставшего от жизни зомби. :-)
Зарядный импульс ограничен или 14,22В или временем ChargePeriod = long(pow(2.72, ((U50 - U1) / 1000)) * Timer), где Timer время предыдушей паузы, у меня источник питания не стабилизированный (2 транса впараллель и 4 диода), при пониженном напряжении он может часами не дать подняться выше 14,22.
Если остались вопросы, готов пояснить, вечером выложу лог за 2,5 суток

Necromant

Графики за последние 2,5 суток, шкала времени в минутах, длительности в секундах, напряжение в милливольтах




UriBas

#1087
Цитата: Necromant от 23 Окт. 2018 в 21:43
скетч
Спойлер

мусор не удалял, если кому надо, подчищу

// Пауза по первой производной, качели, отсечка
#include <stdint.h>
#define maxV 18820 // R1=10.00 kOhm R2=1.52 kOhm
#define U0 780
#define U50 12300.
#define UpLimit 14220  //отсечка сверху
#define LowLimit 12800  //нижний предел качелей
//#define dU 1 // значение первой производной для паузы
#define minChargeTime 200 //условие перехода в качели
#define MeasureCount 4  //размер массива для измерения напряжения
#define VoltmeterPin A0
#define ChargeRelayPin 6 //SSR-10DA
#define InternalLedPin 13

// Переменные
uint16_t RelaxPeriod = 1000;
int16_t U1;
uint8_t minChargeTimeCounter = 0;// счетчик условий перехода в качели
//Функции
uint16_t ReadU (uint8_t Pin)// Вольтметр
{
  uint32_t S = 0,
           SumU = 0;
  uint8_t j = 0;
  struct MeasuredValue
  {
    uint16_t Value;
    int16_t Delta;
  } U[MeasureCount];
  for (uint8_t i = 0; (i + 1) <= MeasureCount; i++) // Считаем среднее арифметическое
  {
    U.Value = analogRead_16bits(Pin); // 8ms
    SumU += U.Value;
  }
  SumU /= MeasureCount;
  for (uint8_t i = 0; (i + 1) <= MeasureCount; i++) // Считаем среднеквадратическую погрешность
  {
    U.Delta = SumU - U.Value;
    U.Delta = abs(U.Delta);
    S += sq(long(U.Delta));
  }
  S /= (MeasureCount - 1);
  S = sqrt( S );
  // S *= 3;
  SumU = 0;

  for (uint8_t i = 0; (i + 1) <= MeasureCount; i++) // Отсеиваем промахи
  {
    //Serial.print (abs(U.Delta));

    // Serial.print(" ");
    // Serial.print ( S);
    if (U.Delta <= S)
    {
      SumU += U.Value;
      j++;
    }
    // Serial.print(" ");
    // Serial.println(j);

  }
  /* if (j == 0)
    {
    for (uint8_t i = 0; (i +1)<= MeasureCount; i++)
    {
    Serial.print (i);
    Serial.print(" ");
    Serial.print (U.Delta);
    Serial.print(" ");
    Serial.println (U.Value);
    }
    Serial.println(S);

    }
  */
  SumU /= j;
  SumU = map(SumU, U0, 65535, 0, maxV);
  //Serial.println (U1);
  //Serial.println (SumU);
  return SumU;
}
//Процедуры
void relax(uint16_t Period)// Пауза по первой производной
{
  int16_t U2;
  do
  {
    U1 = ReadU(VoltmeterPin);
    delay (Period);
    U2 = ReadU(VoltmeterPin);
    // Serial.println (U1-U2);Serial.println ();
  }
  while ((U1 - U2) > 0);
  //Serial.println (U1);Serial.println (U2);

}
/*void relax(uint16_t Period)// Пауза по второй производной
  {
  uint16_t U2;
  int16_t dU1, dU2;
  U1 = ReadU(VoltmeterPin);
  do
  {
    delay (Period);
    U2 = ReadU(VoltmeterPin);
    dU1 = U1 - U2;
    delay (Period);
    U1 = ReadU(VoltmeterPin);
    dU2 = U2 - U1;
    Serial.println (dU1); Serial.println (dU2); Serial.println (dU1 - dU2); Serial.println ();
  }
  while ((dU1 - dU2) >= 0);

  }*/
void relayON()
{
  digitalWrite(ChargeRelayPin, HIGH);
  digitalWrite(InternalLedPin, LOW);
}
void relayOFF()
{
  digitalWrite(ChargeRelayPin, LOW);
  digitalWrite(InternalLedPin, HIGH);
}
//Инициализация
void setup()
{
  analogReference(INTERNAL2V56);
  pinMode(ChargeRelayPin, OUTPUT); //SSR-10DA
  pinMode(InternalLedPin, OUTPUT); //LED
  pinMode(VoltmeterPin, INPUT); //Voltmeter
  do //защита от обратной полярности
  {
    U1 = analogRead_16bits(VoltmeterPin);
    digitalToggle(InternalLedPin);
    delay(250);
  }
  while (U1 == 0);
  do //раскачка до 12В
  {
    delay(2000);
    U1 = ReadU(VoltmeterPin);
    relayON();
    delay(1000);
    relayOFF();
  }
  while (U1 <= 12000);
  delay(500);
  Serial.begin(9600);
}
//Цикл
void loop()
{
  uint32_t Timer, ChargePeriod;
  //uint32_t jj = 0;
  Timer = millis();
  relax(RelaxPeriod);
  Timer = millis() - Timer;
  U1 = ReadU(VoltmeterPin);
  RelaxPeriod = int(pow(2.72, ((U1 - U50) / 1000)) * 3000);
  //Timer = constrain(Timer, 500, 60000);
  ChargePeriod = long(pow(2.72, ((U50 - U1) / 1000)) * Timer); //защита от вечного заряда
  //Serial.println (pow(2.72, ((U50 - U1) / 1000)) * Timer);
  Serial.println (U1);
  Serial.println (Timer); Serial.println (ChargePeriod); Serial.println (RelaxPeriod); Serial.println ();
  Timer = millis();
  relayON();

  while ((U1 <= UpLimit) && ((millis() - Timer) <= ChargePeriod))//отсечка
  {
    U1 = ReadU(VoltmeterPin);
  }
  //jj++;
  // Serial.println (U1);
  relayOFF();
  //качели
  Timer = millis() - Timer;
  Serial.println (Timer); Serial.println ();
  //Serial.println (Timer); Serial.print (" ");//Serial.print (Timer/jj);Serial.print (" "); Serial.println (jj);
  if (Timer <= minChargeTime) //отсеиваем случайные значения из-за нестабильности питания
  {
    minChargeTimeCounter++;
  }
  else
  {
    minChargeTimeCounter = 0;
  }
  if (minChargeTimeCounter >= 5)   //переход в качели
  {
    digitalWrite(InternalLedPin, LOW);
    do
    {
      U1 = ReadU(VoltmeterPin);
      delay(5000);
      for (uint8_t i = 1; i <= 4; i++)  //индикация качелей
      {
        digitalToggle(InternalLedPin);
        delay(500);
      }
    }
    while (U1 >= LowLimit);
    minChargeTimeCounter = 0;
  }
}
По скетчу,
Цикл формирования отсечки импульса заряда
    while ((U1 <= UpLimit) && ((millis() - Timer) <= ChargePeriod)) //отсечка
      {
         U1 = ReadU(VoltmeterPin);
       }
В цикле по отсечке стоит ограничение по 14,22   «И» по разности настоящего времени и времени Паузы..  т.е. стоит оператор «И» (&&)  вместо «ИЛИ» (||)   
Вопрос еще по переменной Timer, с начала цикла она формируется :
  Timer = millis();
  relax(RelaxPeriod);
  Timer = millis() - Timer;
т.е. получается она повторяет значение RelaxPeriod которая изначально = 1 сек,
.. затем принимает значение 
  Timer = millis() - Timer;
затем
       ChargePeriod = long(pow(2.72, ((U50 - U1) / 1000)) * Timer); //защита от вечного заряда
затем
      Timer = millis();   -
и уже участвует в формировании отсечки..   
      while ((U1 <= UpLimit) && ((millis() - Timer) <= ChargePeriod))  //отсечка
..  т.е. не понятны все эти преобразования.. 


Восточная мудрость - "Шакал воет - караван идет"  Эл.вел. 350Вт.   Верую в Иисуса Христа, НЛО.  тема "продвинутой моргалки" https://electrotransport.ru/index.php?msg=1669651

Necromant

#1088
Цитата: UriBas от 27 Окт. 2018 в 22:27стоит оператор «И» (&&)  вместо «ИЛИ» (||)   
((millis() - Timer) <= ChargePeriod)  все верно, именно И, "пока напряжение ниже напряжения отсечки И таймер меньше времени отсечки" в цикле измеряем напряжение и считаем таймер.
Цитата: UriBas от 27 Окт. 2018 в 22:27т.е. получается она повторяет значение RelaxPeriod которая изначально = 1 сек,
нет, измеряет длительность функции relax(RelaxPeriod), которая кратна RelaxPeriod (постоянной дифференцирования для текущего цикла)  по условию нулевой первой производной. В самом первом круге она кратна 1 сек

Цитата: UriBas от 27 Окт. 2018 в 22:27..  т.е. не понятны все эти преобразования.. 
Далее для экономии памяти мы снова используем эту же переменную Timer и для отсечки, и для качелей. Она всего лишь для промежуточного хранения millis.

Dunkel

Пришла пора приделать к нашей моргалке интерфейс.
Тема для начинающих, поэтому упражняться в программировании и городить свой сервер с базой данных мы не будем, воспользуемся готовыми решениями.
Из известных мне решений для моргалки подойдут два:
1. Blynk
Позволяет оперативно (раз в секунду) выводить данные с моргалки на телефон, имеет ограничения в бесплатном режиме.

2.Народный мониторинг.
Есть ограничения на интервал обновления данных - 5мин. Зато позволяет хранить результаты в базе и строить графики.

Эти решения хорошо дополняют друг друга, поэтому я предлагаю их совмещать.
Вот пример реализации:
https://morgalka.wordpress.com/%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80-%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81%D0%B0-%D1%87%D0%B5%D1%80%D0%B5%D0%B7-blynk-%D0%B8-%D0%BD%D0%B0%D1%80%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9-%D0%BC/
Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Alex_N

А на кой хрен, я извиняюсь, далась вам эта БД ? Да и вывод на смартфон ?
Может сразу на ноутбук ? Там есть всё - и графики и БД и протокол и ещё много чего. Чего только в голове родится.
Только это уже не про начинающих. Хотя по сравнению с Касс-ом тут почти все начинающие.

Паяка

[user]Alex_N[/user], есть мнение, что БД, поддерживающая SQL-запросы, (кстати говоря, освоить SQL крайне легко и просто, это самый лёгкий из всех языков), позволит обрабатывать данные оперативнее, и углядеть в результатах электрических измерений те сигнатуры банок и процессов в них, что не замечали раньше.

На самом деле, ещё более информативным может быть лог, записанный прибором с аппаратными триггерами по первой и второй производным. Он будет занимать гораздо меньше места, представляя собой нечто вроде MPEG-сжатия, где сохраняется не поток карт (bitmap) абсолютных значений, а начальные значения кадров и векторы (тензоры), отражающие переходы между участками стандартной формы (отрезками прямых, сегментами парабол).

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

Ещё можно порекомендовать рядом с фрагментами графиков рисовать графики максимально близких простых функций, и смотреть, во-первых, как меняются параметры этих функций (приближений) по ходу заряда, разряда, отстоя, от цикла к циклу. Во-вторых, что представляют собой отклонения реальных графиков от упрощённых. Так постепенно научимся определять дифференциальные и интегральные сигнатуры. И, может быть, научим этому компьютер, а затем и микроконтроллер, которому могут понадобиться в помощь дифференцирующие и интегрирующие цепочки, а могут и не понадобиться, если сумеем настроить подобающим образом цифровой фильтр.
GT TF1 60V 20Ah Chilwee DZF

Dunkel

Цитата: Alex_N от 12 Нояб. 2018 в 07:53А на кой хрен, я извиняюсь, далась вам эта БД ? Да и вывод на смартфон ?
Может сразу на ноутбук ? Там есть всё - и графики и БД и протокол и ещё много чего. Чего только в голове родится.

И чего же в вашей голове нарожалось?
Кроме бессмысленной рекламы этого ноутбука в разных темах, я ничего не заметил...
Может покажите какие-нибудь интересные графики?
А то, что ваша моргалка не может обойтись без ноутбука - так это от неумения программировать МК.

Вернемся к облачному интерфейсу.
В том и прелесть облака, что не нужны никакие локальные компьютеры. Применительно к Народному мониторингу - графики рисуются в реальном времени, автоматически масштабируются. Логи пишутся посуточно в формате csv на яндекс.диск. А все, что требуется от начинающего автора моргалки - добавить два десятка строк в скетч.

Проиллюстрирую.
Дохлая батарея на микроциклировании, графики напряжения в паузе и в импульсе:
Спойлер



Разрыв в графике - это я воду долил и дал отстоятся.

И никаких ноутбуков не нужно!
Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Паяка

[user]Dunkel[/user], у разных людей разные цели и предпочтения. Мне, например, интересно создавать автономные приборы и модули на МК. А кого-то больше порадует, и даст ему больше результатов, прямое управление с ПК, одноплатника или ПЛК. Есть разные методы обработки данных, тоже вопрос предпочтений и умений.

Я, например, работаю во многом по старинке. Рассчитываю цепи с калькулятором на бумаге, иногда применяю электронные таблицы или специальные скрипты, например, для решения матриц. Математическими пакетами давненько не приходилось пользоваться. А коллега прогоняет схемы в симуляторах. Пишет под PIC в ассемблере, я в макроассемблере. Как показала практика, этим мы взаимно обогащаем процесс и плоды работы. Что-то виднее с одной стороны, что-то с другой. Форум и раздел тем очень ценны, что представлены разные подходы и результаты.
GT TF1 60V 20Ah Chilwee DZF

Dunkel

[user]Паяка[/user], все правильно, только в данном случае речь шла об интерфейсе.
У Вас в Бережке - светодиоды разноцветные (на любителя, как мне кажется).
Я в моргалке попытался реализовать идеи Интернета вещей (IoT).
А тот товарищ влез со своим ноутбуком, даже не разобравшись о чем речь...

Кстати, Вы не думали прикрутить к Бережку что-то вроде ESP? Получился бы неплохой конкурент Кулону...

Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Паяка

[user]Dunkel[/user], по ESP есть мысли. После создания 14-амперной версии с предпусковой функцией, можно будет это рассмотреть.
GT TF1 60V 20Ah Chilwee DZF

Alex_N

#1096
Цитата: Dunkel от 12 Нояб. 2018 в 09:58И чего же в вашей голове нарожалось?
Кроме бессмысленной рекламы этого ноутбука в разных темах, я ничего не заметил...
Может покажите какие-нибудь интересные графики?
А то, что ваша моргалка не может обойтись без ноутбука - так это от неумения программировать МК.
От Dunkel только гадости и можно услышать.
Моргалка моя имеет 3 автономных режима. Только я ими практически не пользуюсь. Для обдумывания алгоритмов и сбора информации автономные режимы не годятся. А графики я приводил, но их никто смотреть не хочет.
У меня ненавистный Вами ноутбук рожает их каждый день пачками. С постоянно изменяемыми мною параметрами зарядки. Обычно я разглядываю графики on line на экране монитора и смотрю, что ещё изменить в программе. 
А вообще - главное результат.
А результат  - 3 шт восстановленных АКБ от UPS из 6 штук.
И год работы.

Dunkel

Цитата: Alex_N от 12 Нояб. 2018 в 19:47А результат  - 3 шт восстановленных АКБ от UPS.
И год работы.

Результат впечатляет.  Остальное лучше не буду комментировать.

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

Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/