Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Заряд емкости


Автор: PILOT 22.2.2004, 01:10
Есть ли способ в реальном времени реализовать программную модель заряда емкости через резистор. (иными словами экспоненту с заданной постоянной времени). Причем без операции деления и умножения (на крайняк умножение можно, но не нужно, т.к. его придется выполнять программно. Деление не использовать т.к. программное деление выполняется оооочень долго, особенно многобайтное).
Постоянная времени может быть равна, например, минуте.
Нужно в любой момент реального времени остановив заряд узнать какого напряжение на емкости.

СУВ.

Автор: Chingachguk 22.2.2004, 08:38
Непонятно... Если это делается на P-120, даже, то неужели так долго ? И вообще если есть аналитическая зависимость U(t)=f(R,C,t), то ее можно вычислить и все, зачем что-то моделировать ? Моделируют обычно если нельзя получить "руками" такую зависимость ? Ну и можно использовать таблицы с плотностью вероятности, заранее вычисленную...

Автор: PILOT 22.2.2004, 09:19
Нет, не на P120 конечно. На контроллере, в котором нет ни умножения ни деления.
А моделировать нужно интегратор(RC-цепь в данном случае) причем так, чтобы он не отличался от настоящей RC-цепи.
На вход подаем напряжение от -10 до +10 Вольт, на выходе имеем экспоненциальные кривые в зависимости от того, как на входе изменяется сигнал, т.е. работа в реальном времени.

СУВ.

Автор: podval 22.2.2004, 14:43
Возьми пакет Matlab, там есть Simulink. Установи и наслаждайся smile.gif

Автор: PILOT 22.2.2004, 17:23
smile.gif
Если бы мне нужно было бы воспользоваться МатЛабом я бы это сделал и не морочил бы Вам голову smile.gif
Попробую объяснить точнее:

Итак есть схема RC-цепь (интегратор), на нее с другой схемы подается напряжение (от -10Вольт до +10Вольт) которое изменяется от времени U(t).
После интегратора на RC-цепи стоит другая схема, которая получает проинтегрированное значение. Причем она работает только тогда, когда интегрирование происходит по закону интегрирования на RC-цепи.
Т.е. вот так:

[СХЕМА СИГНАЛА] -> [ИНТЕГРАТОР (RC)] -> [СХЕМА ПОЛУЧАТЕЛЬ]

Элементная база не позволяет использовать именно RC-цепь (огромные размеры и вес конденсаторов или большое сопротивление начинает сильно "чувствовать" внешнюю среду).
Я ставлю контроллер, в который я запрограммирую модель RC-цепи (о которой я спрашиваю).
Так вот вопрос:
Есть ли способ реализовать программную модель заряда емкости через резистор в реальном времени. Т.е. так чтобы получатель не почувствовал разницы.

СУВ.

Автор: shedon 22.2.2004, 17:45
Как это зделать без деления я не знаю, но можно попытаться поставить контроллер по быстрее или поставить DSP.

Автор: Crait 22.2.2004, 18:35
Приближенно так.

dUc = Ur * (1 - exp(-dT / (R*C))) ,

где dUc - изменение напряжения на емкости за такт работы алгоритма,

Ur - среднее напряжение на резисторе за такт работы.
Можно считать (при достаточно малых квантах) равным Uвх - Uc

dT - величина временнОго такта,
R, C - ну понятно что

Если dT, R, C постоянны,
1 - exp(-dT / (R*C)) = const = K
и не требует вычисления каждый раз. Таким образом,

dUc = Ur * K или

Uc(i+1) = Uc(i) + (Uвх - Uc(i)) * K ,

где Uc(i+1) - напряжение на конденсаторе в следующем такте,
Uc(i) - напряжение на конденсаторе в текущем такте.

Автор: Chingachguk 22.2.2004, 19:57
Цитата

(1 - exp(-dT / (R*C))


Ну можна так попробовать. Замечаем, что exp(-t / (R*C) можно рассчитывать таблично.При инициализации грузим заранее расчитанный на PC таблиц подстановки exp(-t/RC) = T(t). Таблицу можно сделать с достаточно небольшим шагом.

Можно в ряд разложить также. Возле нуля это будет хорошо, потом таблица.

Автор: PILOT 22.2.2004, 21:38
Итак, я к примеру воспользуюсь итерационным методом который предложил Крейт. И к примеру буду пользоваться вордом в качестве Uc. Тогда с условием одни итерация 1мс, RC=50сек:
Uc(i+1)=Uc(i)+(Uвх-Uc(i))*T/t = Uc(i)+(Uвх-Uc(i))*0.0002
учитывая например что за ноль взято $8000, то за 50 секунд с указанной разядностью (word) емкость зарядится несколько сотен раз. Данной точности недостаточно.
При увеличении разрядности резко увеличивается время вычислений (умножение на константу).

Можно ли модифицировать алгоритм так чтобы при 2-х байтной разрядности модель выполняла свои функции?

СУВ.


Автор: dm9 22.2.2004, 21:38
Я бы сделал по таблице таким образом (исходисм из того, что постоянная времни = 60 сек): f(t) = 1 - exp (-t/T), T=RC=60сек
1. Время от одной секунды до 400 сек. Здесь надо делать таблицу. Я прикинул по графику, 100-200 точек таблицы дадут неплохую погрешность (ну, хотя если тебе ядерным реактором управлять, то... ну, понятно). Таковой я называю погрешность порядка одного процента (это навскидку). Далее пользуемся разложением по Тейлору. f(t+dt) = f(t) + f'(t)dt, и получаем f(t+dt) = (exp (-t/T))(1/T+dt). Ну... здесь придётся умножить... разок.
2. Первая строка таблицы - точка (0,0). Следовательно, на интервале от нуля до 0,5-1 секунды заменяем экспоненту t на t.

Ну, вроде того. Просто экспонента простыми ф-циями не описывается, кроме как по Тейлору... Ну а считать до высокого порядка времени у тебя не будет.

Автор: dm9 22.2.2004, 21:45
PS Ну, понятно, что после 400 секунд считаем f(t)=1.
PPS Когда отвечал, твоего сообщения ещё не было.
Вопрос. Что такое "за ноль взято $8000"?

Автор: dm9 22.2.2004, 21:52
Про итерационный метод: через сотню-другую итераций не накопится ли слишком большая погрешность? Или я неправильно понимаю суть метода? Ты рассчитываешь первое значение, затем по первому второе, и так далее?

Автор: Crait 22.2.2004, 23:44
Ну во-первых, для приведенных параметров расчета (dT=1mS, RC=50s)
коэффициент K равен 2e-5.
Умножение же на 2e-5 эквивалентно делению на 50000.
Так что при таком подходе от двухбайтового диапазона остаются
рожки да ножки (один значащий разряд).

Выхода два. Либо увеличить шаг по времени,
либо точность представления чисел. Советую второе.

Вот например, для 4-байтного представления 1/50000
можно вычислить так.

1/50000 ~ 1/65536 + 1/262144

Взятие же 1/65536 и 1/262144 долей легко делается с помощью сдвигов
на 16 и потом еще два разряда соответственно.
С сохранением знака, разумеется.

Автор: PILOT 23.2.2004, 00:05
16777216 (это три байта) / 50000 = 335 ну... не знаю даже...
А для 4-х байтной арифметики совсем уж долго все будет... sad.gif

СУВ.

Автор: Crait 23.2.2004, 00:20
PILOTIK, что долго ?
1/65536 - это, к примеру, старшие 2 байта 4-байтового числа smile.gif

Автор: PILOT 23.2.2004, 10:50
Долго будет вычисляться.
Умножение байт на байт около 48 тактов при частоте 6МГц (т.е. 8 мкс) это здорово.
Умножение ворд на ворд это уже где-то 480 тактов это уже 80 мкс - куда не шло.
А умножение дворд на дворд это около 1500 тактов а это уже 0.2 мс, с учетом того что эту операцию придется выполнять в одном рабочем цикле 8 раз а сам рабочий цикл 2 мс то на выполнение остальных задач остается всего 0.4мс sad.gif
эх...

СУВ.

Автор: shedon 23.2.2004, 12:16
Цитата
тактов при частоте 6МГц

PILOTIK, а не проще контроллер по быстрее поставить ?

Автор: Crait 23.2.2004, 13:34
Так умножай старший WORD DWORD'а на WORD и результат сдвигай вправо.
MSP430 юзаешь ?

Автор: PILOT 23.2.2004, 13:52
Цитата(shedon @ 23.2.2004, 09:16)
Цитата
тактов при частоте 6МГц

PILOTIK, а не проще контроллер по быстрее поставить ?

это невоможно, 51-ый единственный в МОП - перечне... так что только он.

СУВ.
ЗЫ. Ладненько будем пробовать smile.gif Спасибо.


Автор: PILOT 6.3.2004, 22:12
Пришлось использовать 3 байта!
Пропорция :
FF FF FF - 10Вольт
80 00 00 - 0Вольт
00 00 01 - -10Вольт

для того чтобы зарядить емкость с постоянной времени 50 секунд до 1.65 Вольта (к примеру) потребовалось прибавлять каждые 2 мс по 2-10 единиц!!! smile.gif
точнгости едва хватило smile.gif

Спасибо, всем отвечавшим smile.gif

СУВ.

Автор: Unregistered 8.3.2004, 18:11
ЗдОрово, что получилось ;)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)