Алгоритм для чёрного ящика

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Есть некое устройство, управляется ардуиной по 16 битному ШИМу (pin9), точная настройка устройства соответствует максимальному потребляемому току, измерительная цепь MAX471 (0-3А), само устройство потребляет в настроенном режиме от 0,8 до 1,1А, флуктуации по потребляемому току в пределах 10-15 ма.
Ну и как усмирить это устройство? Простым усреднением показаний 30 измерений АЦП проблема не решается. ШИМ использует весь диапазон значений, чтобы загнать устройство в режим, то-есть от 0 до 65535

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Что Вы понимаете под словом "усмирить"?

Просто выдернуть из розетки недостаточно?

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

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

Шим перевёл в 10 битный режим, не вижу необходимости, если входной ток цифруется в 10 битном режиме, опорное 1,1 вольта даёт значение на максимальном токе "во второй половине шкалы"

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

 Ну все измерения имеют значение и погрешность. И если новое значение болтается в районе погрешности, то считать что значение не поменялось, регулировать ничего не надо. А вот если вышло за пределы погрешности, то это новое значение  и надо изменить регулировку. Конечно вы не говорили про инерционость системы. Ее надо компенсировать частотой измерений и мат анализом.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

qwone пишет:

 Ну все измерения имеют значение и погрешность. И если новое значение болтается в районе погрешности, то считать что значение не поменялось, регулировать ничего не надо. А вот если вышло за пределы погрешности, то это новое значение  и надо изменить регулировку. Конечно вы не говорили про инерционость системы. Ее надо компенсировать частотой измерений и мат анализом.

Измеряемый ток и значение для ШИМ зависят динамически, то-есть "ящику" для максимального тока может потребоваться значение ШИМ и 0 и максимум, я принял за максимум 1020, на выходе ШИМ при максимуме после интегрирующей цепи порядка 4,5 вольт, разработчик ящика озвучил, что диапазон регулировки 0 - 2,7 вольта но допустимо до 7 вольт

Ящик работает с динамической нагрузкой, то-есть требуемый максимальный ток в конкретное время всё время разный, здесь как бы две задачи: 1. нахождение требуемого тока 2. его поддержание
В идеале и первое и второе надо вести с частотой 8 герц ))) но это в идеале...тут уж как получится, хотя бы в секунду уложиться

Тут без матанализа видимо никак, как и у меня... )))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну что я могу сказать. У вас та же проблема , что и у новичков на форуме. Они не правильно составляют ТЗ, а у меня хрустальный шар ничего не показывает. Скорее и ваш тоже.

Logik
Offline
Зарегистрирован: 05.08.2014

ua6em пишет:

 две задачи: 1. нахождение требуемого тока 2. его поддержание

В идеале и первое и второе надо вести с частотой 8 герц ))) но это в идеале...тут уж как получится, хотя бы в секунду уложиться

Тут без матанализа видимо никак, как и у меня... )))

Дак тут и с матаном никак))

Требования 2-х задач протеворечивы. Поддерживать максимум величины (кстати только локальный максимум) можна используя вариации управляющего воздействия в обе стороны, т.е. небольшое колебание вокруг текущей точки. А поддержание тока должно эти колебания устранять. Выход только в компромисе, частично удовлетворяющем оба требования.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну да, закон Гука и коэффициент упругости. Чем больше отклонение от заданой (или первоначально измереной) величины, тем больше ШИМ компенсация. Вот только большой коэффициент упругости оформлен программой. Но это для медленно-меняющих нагрузок.Такой же принцип у операционного усилителя. А вот если нагрузка действует по какому-то закону, то сначало вычиляется этот закон, а потом включается противокомпенсация по вычисленному закону.

Logik
Offline
Зарегистрирован: 05.08.2014

//А вот если нагрузка действует по какому-то закону, то сначало вычиляется этот закон

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

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Может просто выбор датчика тока неудачен?

Пытаюсь усмирить входящую последовательность таким простым кодом нарисованным в лоб, не усмиряется )))
 

void loop() {

  for ( int k=1; k<=16;k++){
   for (int j=1; j <= 16; j++) {
   Data_max471=analogRead(Pin_max471);
   Data_max471 = Data_max471/10;
   Data_max471 = Data_max471*10;
   s = s +  Data_max471;
     }
   s = s/16;
   s = s/10;
   s = s*10;
   Serial.print(s);
   Serial.print("-");  
  }
   Serial.println("-*-");
   delay(300);
}

В сериале

620-620-620-620-620-620-620-620-620-610-620-610-620-610-620-620--*-
620-620-620-620-620-620-620-620-620-620-620-620-620-620-610-620--*-
620-620-610-620-620-620-620-620-620-620-620-620-620-620-620-610--*-
620-610-620-610-620-620-620-620-620-620-620-620-620-620-620-620--*-
610-620-610-620-610-620-620-620-610-620-620-620-620-620-620-620--*-
620-610-620-610-620-610-620-610-620-620-620-620-620-620-620-620--*-
620-620-610-620-620-620-610-620-610-620-610-620-610-620-620-620--*-
620-620-620-620-620-620-620-620-620-610-620-610-620-610-620-610--*-
620-620-620-620-620-620-620-620-620-620-620-620-610-620-610-620--*-
620-620-620-620-620-620-620-620-620-620-620-620-620-620-620-620--*-
620-610-620-620-620-610-620-620-620-620-620-620-620-620-610-620--*-
610-620-610-620-620-620-610-620-620-620-610-620-620-620-620-620--*-
620-620-620-610-620-610-620-610-620-610-620-610-620-620-620-620--*-
620-620-620-620-620-620-620-620-610-620-610-620-620-620-620-620--*-
610-620-620-620-620-620-620-620-620-610-620-610-620-610-620-610--*-

Да, напряжение питания ящика - обычный китайский выпрямитель 9 вольт 3 ампера

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Везде есть закон. Тут и разложение по Фурье , и много других подходов. Та же квантовая мехпника. Но городить огород на ровном месте не стоит. Тут надо ТС разобраться в том что он видит, но не замечает. Правильно разобраться с ТЗ. 

ПС: Вот еще индуктивность (L)очень сопротивляется изменению тока.

Logik
Offline
Зарегистрирован: 05.08.2014

qwone пишет:

Везде есть закон. 

Изложите пожалуста закон, определяющий среднесуточную температуру на улице на ближайшие пару месяцев, тогда продолжим дискусию ;)) Можете  разлагать в ряды Фурье, Лагранжа, делать свертки, дифисчесление, матричный анлиз и пр. и др. не стесняйтесь в методах)))

qwone пишет:

Вот еще индуктивность (L)очень сопротивляется изменению тока.

Я верю, Вы чегото знаете, только причем здесь это?

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Нагрузка чёрного ящика - индуктивность, точнее колебательный контур )))
Поставил в качестве датчика INA219
Ток действительно скачет, но по китайскому цифровому прибору прибору (Вольтметр+амперметр) показания на уровне десятков миллиампер - стабильны )))
Дамп с INA219

800 - 800 - 800 - 800 - 800 - 800 - 800 - 800 - 785 - 795 - 800 - 800 - 800 - 800 - 800 - 
800 - 800 - 800 - 796 - 799 - 796 - 800 - 800 - 800 - 800 - 796 - 800 - 800 - 792 - 800 - 
797 - 797 - 800 - 800 - 800 - 800 - 800 - 800 - 800 - 787 - 800 - 800 - 797 - 800 - 800 - 
800 - 800 - 800 - 800 - 790 - 794 - 800 - 796 - 800 - 800 - 800 - 800 - 800 - 800 - 800 - 
800 - 798 - 800 - 800 - 800 - 800 - 797 - 800 - 800 - 800 - 799 - 799 - 797 - 800 - 800 - 
800 - 800 - 798 - 800 - 800 - 796 - 800 - 792 - 800 - 800 - 800 - 800 - 800 - 800 - 800 - 
800 - 791 - 800 - 799 - 800 - 800 - 800 - 800 - 800 - 800 - 800 - 792 - 797 - 800 - 800 - 
800 - 800 - 800 - 790 - 800 - 800 - 800 - 800 - 785 - 800 - 800 - 800 - 800 - 798 - 800 - 
800 - 796 - 800 - 796 - 798 - 800 - 800 - 800 - 800 - 800 - 800 - 800 - 791 - 800 - 800 - 
800 - 800 - 800 - 795 - 800 - 800 - 800 - 796 - 800 - 800 - 798 - 800 - 800 - 800 - 800 - 
800 - 800 - 794 - 800 - 786 - 800 - 800 - 800 - 800 - 786 - 800 - 800 - 791 - 799 - 796 - 
796 - 800 - 800 - 800 - 789 - 800 - 800 - 800 - 795 - 789 - 800 - 800 - 800 - 800 - 791 - 
800 - 800 - 799 - 800 - 787 - 800 - 800 - 800 - 800 - 798 - 800 - 800 - 794 - 795 - 800 - 
798 - 800 - 800 - 800 - 800 - 800 - 800 - 796 - 794 - 800 - 800 - 800 - 800 - 800 - 795 - 
800 - 800 - 800 - 800 - 800 - 798 - 800 - 800 - 800 - 800 - 800 - 800 - 800 - 796 - 800

 

Logik
Offline
Зарегистрирован: 05.08.2014

ua6em пишет:

Может просто выбор датчика тока неудачен?

Пытаюсь усмирить входящую последовательность таким простым кодом нарисованным в лоб, не усмиряется )))

Ну код вобщем ниочем, типа надо шото делать - делаем шо попало )))

Пробуйте так (не компилирую, пишу с мысли). После стр.5

static unsigned long G+=Data_max471-(G>>8);

Data_max471=G>>8;

Это в цикле гоняйте раз 500, пока устаканится. Ну и выводите каждый раз в порт значение Data_max471.

И показуйте что выйдет.

Logik
Offline
Зарегистрирован: 05.08.2014

ua6em пишет:
Дамп с INA219
 

Я б сказал что на наводку от 50Гц похоже.
Там между датчиком и входом ардуины нет длинных линий или цепи с высоким сопротивлением? И до датчика тока в этом плане норма?

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

50 герц поблизости точно нет, питается постоянным током, выпрямитель на розетке, провода для съема тока конечно длинноваты несколько, на ардуину приходит по I2C
А вот поле катушки вполне может воздействовать, корпус металл, но крышка снята
 

Попробовать можно, MAX471 только вернуть назад надо

Logik
Offline
Зарегистрирован: 05.08.2014

I2c вне подозрений. Можна проверить, время между провалами показаний с 800 до <797 близко к 10 или 20мсек. Если да - факт наводок доказан.

Впрочем провалы небольшие, если быстродействие системы не очень большое (по сравнению с 20мксек), можна искать максимальное значение за 20мсек и его применять, или гистограмку собирать и брать наиболее часто встречающееся. А эти значения еще подфильтровать, как выше писал, и будет оч. гладенько.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Скомпилировалось так:

void loop() {

   for (int j=1; j <= 16; j++) {
   Data_max471=analogRead(Pin_max471);

   static unsigned long G;
   G+=Data_max471-(G>>8);
   Data_max471=G>>8;

   Serial.print(Data_max471);
   Serial.print("-");  
  }
   Serial.println("-*-");
   delay(300);
}

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

Начало:

3-7-11-15-19-23-27-31-35-39-43-46-50-54-58-62--*-
65-69-73-77-80-84-88-91-95-99-102-106-109-113-116-120--*-
124-127-131-134-137-141-144-148-151-155-158-161-165-168-171-175--*-
178-181-185-188-191-194-198-201-204-207-211-214-217-220-223-226--*-
229-233-236-239-242-245-248-251-254-257-260-263-266-269-272-275--*-
278-280-283-286-289-292-295-298-301-303-306-309-312-315-317-320--*-
323-326-328-331-334-336-339-342-344-347-350-352-355-358-360-363--*-
365-368-370-373-376-378-381-383-386-388-391-393-395-398-400-403--*-
405-408-410-412-415-417-420-422-424-427-429-431-434-436-438-440--*-
443-445-447-450-452-454-456-458-461-463-465-467-469-472-474-476--*-
478-480-482-484-486-489-491-493-495-497-499-501-503-505-507-509--*-
511-513-515-517-519-521-523-525-527-529-531-533-535-536-538-540--*

Конец:
1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023--*-
1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023--*-
1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023--*-
1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023--*-
1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023--*-
1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023--*-
1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023-1023--*-

У меня хоть понятно было, что делаю а тут )))

Logik
Offline
Зарегистрирован: 05.08.2014

)).

А вводит с analogRead(Pin_max471);чего? Оно должно выходить на него.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Logik пишет:

I2c вне подозрений. Можна проверить, время между провалами показаний с 800 до <797 близко к 10 или 20мсек. Если да - факт наводок доказан.

Однозначно не близко, тау между измерениями 300 мсек, кусок кода у DIMAX позаимствовал

Logik
Offline
Зарегистрирован: 05.08.2014

ua6em пишет:

Logik пишет:

I2c вне подозрений. Можна проверить, время между провалами показаний с 800 до <797 близко к 10 или 20мсек. Если да - факт наводок доказан.

Однозначно не близко, тау между измерениями 300 мсек, кусок кода у DIMAX позаимствовал

delay(300) я видел, оно ж между строками, а в пределах строки - как повезет с сириалом, но явно быстрей 300

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Logik пишет:

)).

А вводит с analogRead(Pin_max471);чего? Оно должно выходить на него.

Это о ШИМ? я шим вообще отрубил, устанавливаю потенциометром ток по китайскому прибору и меряю, на китайском приборе показания не скачут, на обоих измерителях тока, что MAX471, что INA219 - скачут

Logik
Offline
Зарегистрирован: 05.08.2014

Не совсем понял вопрос. Я ШИМ вобще не трогал. 

Просто код должен прийти к среднему значению с с analogRead(Pin_max471).  По факту он пришел к 1023, соответственно подозрение что с  входа идет 1023, т.е. переполнение.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Переполнение? Не должно жеж:

int Pin_max471 = A1;
unsigned int Data_max471 = 0;

void loop() {

  for ( int k=1; k<=16;k++){  
   for (int j=1; j <= 16; j++) {
   Data_max471=analogRead(Pin_max471);
   Data_max471 = Data_max471/10; // округляем до десятков
   Data_max471 = Data_max471*10; // восстанавливаем
   s = s +  Data_max471; // в s накапливаем 16 значений вх.тока округлённых до десятков ма
     }
   s = s/16; // вычисляем среднее
   s = s/10;  // округляем до десятков
   s = s*10; // восстанавливаем
   Serial.print(s);
   Serial.print("-");  
  }
   Serial.println("-*-");
   delay(300);
}

 

Logik
Offline
Зарегистрирован: 05.08.2014

//Переполнение? Не должно жеж:

Ага. Но других причин чего пришло к 1023 нет. Надо просто проверить что идет с входа.

Ну или можна в коде из #17 вместо Data_max471=analogRead(Pin_max471); написать типа Data_max471=777;. Для проверки что прийдет в конце именно к 777.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Да, накосячил с ацп, висел в воздухе ))) перетрудился )))
на 777 вышло стабильно а вот на реальном сигнале есть пробои


333-333-333-332-332-332-332-332-333-333-333-333-333-333-333-333--*-
333-333-333-333-333-333-333-333-333-333-333-333-333-333-333-333--*-
332-332-333-333-333-333-333-333-333-333-333-333-333-333-332-332--*-
333-333-333-333-333-333-333-333-333-333-333-333-332-333-333-333--*-
333-333-333-333-333-332-332-332-332-332-332-332-333-333-333-333--*-
333-333-332-332-332-332-332-332-332-333-333-333-333-333-333-333--*-
333-333-332-332-332-333-333-333-333-333-333-333-333-333-333-333--*-
333-333-333-333-333-333-333-333-333-333-333-333-333-333-333-333--*-
333-333-333-333-333-333-333-333-333-333-333-333-333-333-333-333--*-
333-333-333-333-332-332-332-332-332-332-332-332-332-332-332-333--*-

Получается две единицы разница, хватит ли быстродействия, считывание с этого датчика нормируется в 100 микросекунд

Logik
Offline
Зарегистрирован: 05.08.2014

ОК! так и должно. Что делать если среднее должно выйти 332.75? Вот и выводит 75% значение 333 а 25% значение 332.

Теперь обратите внимание на цыфру 8 в тех двух строках, что вам непонятны)) Это степень сглаживания. Меньше значение  - меньше сгладит, больше (в разумных пределах) - будет сильней сглаживать и медленей выходить на установившуюся цифру. Поиграйте её как нравится. Но менять одновременно в 2-х местах!!

ПС. Поздравляю, у Вас заработал цифровой фильтр первого порядка с конечной импульсной характеристикой))) Если обошлось без обморока ;) - это аналог интегрирующей RC цепи в электронике (а та 8-ка - аналог постоянной времени). Её как бы "впаяли" в прохождение сигнала )))

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Без обморока )))
И это только первого порядка? А что же о более высоких )))
Изначально допустимым порогом задавались для этого ящика в 10ма

Теперь подумать, постоянную интегрирующей на ШИМ какой делать, там чистый аналог - работает на КП-103

Logik
Offline
Зарегистрирован: 05.08.2014

Более высоких - сложно. Надо коэффициенты расчитывать. Там серезная математика. Даже гуглить не советую матимпотенцию иожна получить;) Если сильно надо - можна два фильтра друг за другом включать. Или даже много.  Кстати по странной мат. иронии этот фильтр абсолютно совпадает с простейшим фильтром Кальмана, на котором еще шатлы летали. Так что с Кальманом Вас тоже поздравляю))) 

//работает на КП-103

где вы их только берете?! Я вобще в восторге от своего склероза, что еще вспомнил шо оно такое ))))

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Logik пишет:

Более высоких - сложно. Надо коэффициенты расчитывать. Там серезная математика. Даже гуглить не советую матимпотенцию иожна получить;) Если сильно надо - можна два фильтра друг за другом включать. Или даже много.  Кстати по странной мат. иронии этот фильтр абсолютно совпадает с простейшим фильтром Кальмана, на котором еще шатлы летали. Так что с Кальманом Вас тоже поздравляю))) 

//работает на КП-103

где вы их только берете?! Я вобще в восторге от своего склероза, что еще вспомнил шо оно такое ))))

у нас серьёзные запасы )))

 

Logik
Offline
Зарегистрирован: 05.08.2014

а нафига? Щас такие МОСФЕТы что иногда не верится шо такое бывает в природе. 0,037Ом открытый канал. Он шо, в золото превращается? ;)

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Этож покупать надо где-то, в нашем ауле нету, а это вон в коробочке лежит )))
Первую часть кажись одолели, теперь попробую в виде функции оформить, чтобы пользоваться было удобно.
Область видимости переменной G всё тело программы?

Следующий этап, чтобы всё красиво было, поиск максимального значения тока для текущего отрезка времени.
Вирта я последний раз читал лет 20-25 назад, да и книжки этой нету, но сдаётся мне, что используя приведенные им методы сортировки поиск максимума можно реализовать красиво, у меня из книжки не заработал только один пример (пробовал на интерпретаторе Тихонова Ю.В.)
Сдаётся мне что метод шейкерной сортировки или половинного деления тут будет самый раз, но могу попробовать и все, раз пошла такая пьянка, только подскажите или ссылку дайте где книжку скачать...

PS я тоже усреднял, но в рамках курса 4-го класса ))) чтоб не налететь на переполнение, как вы сказали - надо жеж что-то делать )))

И что, ни у кого нет электронной версии Вирта...?

 

Logik
Offline
Зарегистрирован: 05.08.2014

//Область видимости переменной G всё тело программы?

Да. Значение должно сохранятся все время пока вводятся и обрабатываются данные.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Вирта нашёл )))
Вопрос второй, как этот блок выделить в отдельную подпрограмму и подцепить на прерывание, чтобы раз в миллисекунду (это 10% процессорного времени) просчитывала данные с датчика тока?

void inmax471() {

   for (int j=1; j <= 16; j++) {
   Data_max471=analogRead(Pin_max471);

   static unsigned long G;
   G+=Data_max471-(G>>8);
   Data_max471=G>>8;

   }
   }

Это читал - тунже цу воды

Сможет кто помочь на второй таймер это прицепить?
Так, уже не актуально, оказывается есть библиотека для второго таймера #include <MsTimer2.h> )))

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Прежде чем углубиться в чтение Вирта, снял график зависимости тока от ШИМ, получилось так:

У кого какие мысли по поиску (привязке) значения ШИМ к максимальному току? Пояснение:
Эти переменные могут быть сдвинуты, одна откосительно доугой на цикл всего разворота )))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em, если Вы хотите каких-то комментариев по поводу графика, следует, как минимум, хотя бы подписать оси.

ua6em пишет:

Пояснение:
Эти переменные могут быть сдвинуты, одна откосительно доугой на цикл всего разворота )))
 

Вы сами поняли, что написали?

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Синяя - переменная напряжения ШИМ, красная - ток потребляемый устройством, правильная настройка ящика по максимальному потребляемому току но находиться надо  - на левой ветви на подходе к максимуму, особенности - максимум может быть и при значении ШИМ = 1 и при значении ШИМ =1023, то-есть эти два графика могут смещаться один относительно другого

Горизонтальная ось естественно значение переменной ШИМ, вертикальная - Ток

Оси не обозначаю, так как всё относительно )))

 

А "что-то нам так и не удалось заслушать начальника транспортного цеха"...

Logik
Offline
Зарегистрирован: 05.08.2014

Я бы делал так.

1. Грубый поиск. Разбиваем диапазон ШИМ на части, допустим 4, частей и устанавливаем по очереди ШИМ 0, 256,512,768,1023, измеряем для каждой ток, определяем на каком из значений он максимальный. Это максимум грубо.

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

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

разбирался с конструктором ящика, выяснилось, что полевой транзистор в регуляторе работает наоборот, изначально транзистор максимально открыт, подавая ШИМ мы его закрываем ))), тогда ВАЖНОЕ, попадать надо не на левую ветвь, а на правую, та что более пологая...
У Вирта, этот метод назывался метод половинного деления (делить массив можно на любое число, я тоже реализовывал когда-то четырмя массивами)
Первичный поиск максимума реализован вызовом соответствующей функции в setup, метод обычный пузырёк, фиксируем в двух переменных значение максимума тока и соответствующего ему значения ШИМ, на выходе процедуры устанавливаем найденные значения...
В раздумьях о математике поддержания этого максимума, точнее нужен правый порог максимума...
нужна какая-то математическая модель вот этого: (с арифметикой знаком то, что 2+2*2=6 знаю)

Рабочая точка отмечена вертикальной линией

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

А если делаем так:

1. выставляем ШИМ в минус от текущего значения (20-50 единиц, подобрать опытным путём)
2. измеряем ток
3. Разница между током измеренным и током текущим - направление движение касательной (вправо или влево)
4. Определяем куда двигаться в поиске максимума
5. Ищем текущий максимум
??? понимаю, что в лоб, но по временным укладываемся
 

 

Logik
Offline
Зарегистрирован: 05.08.2014

///А если делаем так:

///3. Разница между током измеренным и током текущим - направление движение касательной (вправо или влево)

Она вобщето может быть и нулевой. Если максимум между точками. Или близкой к нулю. И в таком случае метод касательной "пульнет" точку очень далеко.

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

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

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

Logik
Offline
Зарегистрирован: 05.08.2014

/// нельза прыгать далеко от него, прибор в рабочем режиме

Так я о том и пишу что предлогаемое Вами в п.3 неприемлемо, т.к. при некоторых обстоятельствах отпрыгнет далеко. Касатедьная негодится.

Кстати, а "пузырек" причем? Вы что, сортировку делаете?

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

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

Logik
Offline
Зарегистрирован: 05.08.2014

Так какой, нафиг "пузырек"?! Это обычный поиск максимума. Так все всегда делают. И это верно, но в Вашем случае медлено, т.к. прийдется пробегать ШИМ-ом весь диапазон. И в данном случае не требуется его точное нахождение, т.к. возможную ошибку должен компенсировать алгоритм точной подстройки.

ПС Графики без сортировки значений класа с 5 в школе строили ... В чем проблема... ну да ладно, не по теме.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

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

Мне пробегать весь диапазон совсем нельзя... ПОЛЕЗУТ ГАРМОНИКИ, ЧРЕВАТО...

Реализовал по касательной, как-то так, явно не айс
стрелка показывает куда корректируем, надо вводить диапазон нечувствительности

Correct FREQ --->
Correct FREQ <---
Correct FREQ <---
Correct FREQ <---
Correct FREQ <---
Correct FREQ --->
Correct FREQ <---
Correct FREQ --->
Correct FREQ <---
Correct FREQ <---
Correct FREQ --->
Correct FREQ <---
Correct FREQ <---
Correct FREQ <---
Correct FREQ <---
Correct FREQ --->

 

Logik
Offline
Зарегистрирован: 05.08.2014

ua6em пишет:

Мне пробегать весь диапазон совсем нельзя... ПОЛЕЗУТ ГАРМОНИКИ, ЧРЕВАТО...

Какие гармоники, чё за бред?! Ни один метод не найдет глобального максимума без просмотра всего интервала.
ua6em пишет:

Реализовал по касательной, как-то так, явно не айс
стрелка показывает куда корректируем, надо вводить диапазон нечувствительности

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

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Ду уж, кую железом по железу...

По порядку: устройство - генератор, работает на последовательный колебательный контур, при частоте генератора ниже частоты резонанса начинают лезть гармоники, на осциллографе просматриваются вплоть до 20-й, уровень точно не скажу, но процентов 5-7 думаю есть, на частоте резонанса их уровень минимальный, идентифицируется как максимальный ток потребляемый устройством.
Контур он не абстрактен, работает с реальными "объектами", в зависимости от характеристик объектов (отсос энергии) изменяется и его добротность и его резонансная частота, с некоторыми возрастает (ток растёт) с некоторыми падает (ток падает) и надо быть всегда на пике тока выставляя нужное значение ШИМ. Допустимый интервал удержания +- 5-10  миллиампер. Задача на грани возможного )))
А ручками это регулируется легко ручка вправо ручка влево )))

В Setup скетча вызывается процедура определяющая эту точку и выставляющая нужное значение шим при включении прибора, датчик тока на прерываниях, ШИМ на таймерах 10- битный как и датчик тока, постоянная интегрирующей цепи ШИМ 3-тау частоты шим (думаю % под 95 от расчётного значения напряжения на выходе есть, постоянная интегрирующей по входу, цфпп G>>8

ДА, выше постом, стрелками это вектор направленности ШИМ, сама стрелка - одно деление шим, то есть 4 стрелки подряд в одном направлении - изменение переменной ШИМ на 4 единицы

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

Очень похоже, что кривая соответствует кривой регулирующего частоту элемента - транзистор КП-103Г

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Спасибо всем, кто помогал!!!
Задача решена!
)))

 

ZIA
ZIA аватар
Offline
Зарегистрирован: 04.02.2017

ua6em пишет:

Вирта нашёл )))
Вопрос второй, как этот блок выделить в отдельную подпрограмму и подцепить на прерывание, чтобы раз в миллисекунду (это 10% процессорного времени) просчитывала данные с датчика тока?

void inmax471() {

   for (int j=1; j <= 16; j++) {
   Data_max471=analogRead(Pin_max471);

   static unsigned long G;
   G+=Data_max471-(G>>8);
   Data_max471=G>>8;

   }
   }

Это читал - тунже цу воды

Сможет кто помочь на второй таймер это прицепить?
Так, уже не актуально, оказывается есть библиотека для второго таймера #include <MsTimer2.h> )))

 

я правильно понял обоих, чтобы использовать с прерыванием нужно сделать так:

#include <MsTimer2.h>

int Pin_max471 = A0;
int Data_max471 = 0;

static unsigned long G;


/*   функция чтения данных из аналогового порта и усреднения
 *   значения, аналог интегрирующей цепи или как сказал LOGIK 
 *   цифровой фильтр первого порядка описан здесь:
 *   http://arduino.ru/forum/programmirovanie/algoritm-dlya-chernogo-yashchika
 *   переменную static unsigned long G я вынес в объявления переменных
 *   пост #33 от ua6em
 *   есть вопросы к обоим
 */
void inmax471() {
   for (int j=1; j <= 16; j++) {
   Data_max471=analogRead(Pin_max471);
   G+=Data_max471-(G>>8);
   Data_max471=G>>8; }
   }                         // END INPUT FILTER
   
   

void setup() {
 Serial.begin(115200);
 
 MsTimer2::set(5, inmax471); // вызывать через каждые 5 миллисекунд
 MsTimer2::start();
}

void loop() {
 Serial.print(Data_max471);
 delay(100);
}                            // конец программы

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

А самим попробовать религия не позволяет??? )))
Это только исправьте, а то сливать в консоли будет

 Serial.println(Data_max471);

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

Взял скетч ZIA, чуть допилил, работает мой чёрный ящик, да, для управления MCP4725 использую

Фото ящика