реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Малоресурсный алгоритм измерения температуры
ARV
сообщение Jun 9 2009, 05:03
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



прошу помощи в плане общего алгоритма... лучшей темы для своего вопроса не нашел...

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

что сделано сейчас и что не удовлетворяет (псевдо-Си-код)
t2 = 0;
do{
t1 = t2;
pause_1s();
t2 = get_temperature();
} while (t1 != t2);

это дает отличный результат при измерении температуры воды (большая теплоемкость, контакт с датчиком идеальный, быстро его нагревает) - за 15 секунд получается верный результат. для тела человека как правило цикл завершается за 0,3-0,6°С до реальной температуры, что не устраивает. кроме того, процесс длится не менее 30 секунд...

какие будут советы?


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
SKov
сообщение Jun 9 2009, 05:53
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(ARV @ Jun 9 2009, 09:03) *
прошу помощи в плане общего алгоритма... лучшей темы для своего вопроса не нашел...
....
это дает отличный результат при измерении температуры воды (большая теплоемкость, контакт с датчиком идеальный, быстро его нагревает) - за 15 секунд получается верный результат. для тела человека как правило цикл завершается за 0,3-0,6°С до реальной температуры, что не устраивает. кроме того, процесс длится не менее 30 секунд...

какие будут советы?

Варианта два.
1) Надо подождать, пока температура застабилизируется. Например, пока не получите пять одинаковых показаний датчика.
2) Надо оценить скорость нарастания температуры и по форме этой кривой попробовать экстраполировать эту кривую
на пару минут вперед. Но тут уже могут быть грабли в виде разной теплопроводности кожи людей в зависимости от...
Так что первый пункт надежнее.
Go to the top of the page
 
+Quote Post
fontp
сообщение Jun 9 2009, 07:05
Сообщение #3


Эксперт
*****

Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183



Цитата(ARV @ Jun 9 2009, 09:03) *
что сделано сейчас и что не удовлетворяет (псевдо-Си-код)
t2 = 0;
do{
t1 = t2;
pause_1s();
t2 = get_temperature();
} while (t1 != t2);

это дает отличный результат при измерении температуры воды (большая теплоемкость, контакт с датчиком идеальный, быстро его нагревает) - за 15 секунд получается верный результат. для тела человека как правило цикл завершается за 0,3-0,6°С до реальной температуры, что не устраивает. кроме того, процесс длится не менее 30 секунд...

какие будут советы?



Можно, например, сделать Ваш алгоритм робастным, если t1 и t2 считать не изолироваными измерениями, а результатом фильтрации измеренных величин. Причем, лучше взять не скользящее среднее, а медианную фильтрацию
Go to the top of the page
 
+Quote Post
ARV
сообщение Jun 9 2009, 07:47
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



спасибо.
у меня была фильтрация скользящим средним по 16 точкам - результат был вроде более удовлетворительный, но очень уж долгим... в некоторых случаях и по 3 минуты шел процесс... кроме того, из-за скудности ресурсов от фильтрации пришлось отказаться sad.gif я понимаю, что надо ждать N одинаковых показаний, и чем больше N, тем вернее будет найдено решение задачи... но есть вопрос, например, такого плана: обнаружив, что не все N равны между собой, как поступить лучше? отбросить первое отличающееся значение и продолжать ждать равного остальным? сдвинуть массив предыдущих значений по типу скользящего среднего и продолжать "заталкивать" туда новые значения, добиваясь, чтобы все стали одинаковыми? обнулить все и начать снова? проблема в том, что младщий бит, а то и 2, результата АЦП "дрожит"... как бы не попасть в бесконечный цикл...

у меня есть термометр OMRON. так вот эта штука измеряет либо до стабилизации показаний, либо 2 минуты. в любом случае то, что к концу 120 секунд будет на индикаторе - то и считается реальной температурой. алгоритм вроде нормальный, но долгий... и все равно какой-то негарантированный - чуть расслабился, перестал прижимать термометр подмышкой - получил нормальную температуру во время гриппа sad.gif

я уже близок к тому, что просто 1-2 бита отбросить при анализе на равенство... в принципе, должно хватить...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Tanya
сообщение Jun 9 2009, 08:00
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883



Цитата(ARV @ Jun 9 2009, 09:03) *
прошу помощи в плане общего алгоритма... лучшей темы для своего вопроса не нашел...

требуется измерять температуру тела человека, при этом процесс измерения от наблюдателя скрыт
какие будут советы?

Если теплопроводность в процессе измерения не меняется, а именно: площадь контакта и сила прижима не меняются, тогда можно пользоваться экстраполяцией. Но "малоресурсно" ли получится, зависит от Ваших ресурсов.
Вариант. Если к датчику добавить нагреватель, который предварительно нагревает датчик до... пусть будет 36 градусов, то можно ускорить, если датчик относительно массивный. Нагревателем может служить и сам датчик.
Есть еще вариант - измеряется температура. Пусть она растет. Тогда датчик немного нагревается дозированным током. Опять смотрим за дрейфом (скоростью изменения) температуры при малом токе.... Это вариант для термосопротивления с (полу)мостовой схемой.
Go to the top of the page
 
+Quote Post
il--ya
сообщение Jul 2 2009, 10:41
Сообщение #6





Группа: Новичок
Сообщений: 1
Регистрация: 2-07-09
Пользователь №: 50 842



Цитата(ARV @ Jun 9 2009, 09:03) *
что сделано сейчас и что не удовлетворяет (псевдо-Си-код)
t2 = 0;
do{
t1 = t2;
pause_1s();
t2 = get_temperature();
} while (t1 != t2);


Попробуйте так (код написан исходя из 16-битной разрядности int)
Код
// Допустимые колебания показаний,
// вы говорите, что дрожат младшие 2 бита, накинем еще один, чтобы избежать ложного перезапуска осреднения
#define ERROR 8
#define AVERAGE_SHIFT 4
// Количество показаний для осреднения,
// whatever you like чтобы получить больше точность, в данном случае 16
#define AVERAGE_COUNT (1<<AVERAGE_SHIFT)

#define ABS(a) ((a)>=0 ? (a) : -(a))

int t1;
int t2;
long int average = 0; // если разрядности хватит для суммирования температур из области
                               //допустимых значений, то long может и не нужен
int count = 0

t2 = get_temperature();
do
{
  t1 = t2;
  if (!count)
    pause_long(); // достаточно долго, чтобы датчик успел нагреться/остыть на величину больше ERROR
  else
    pause_1s(); // при осреднении интервалы короче (может, можно и чаще чем раз в секунду?)

  t2 = get_temperature();
  if (ABS(t2-t1)<ERROR)
  {
    // если температура устаканилась, начинаем считать среднее
    average+=t2;
    count++;
  }
  else
  {
    // если температура не устаканилась, или опять начала меняться, сбрасываем среднее и опять ждём
    average=0;
    count=0;
  }
} while (count<AVERAGE_COUNT);

average>>=AVERAGE_SHIFT; // результат

Надеюсь, четыре int в стеке - это не слишком большие ресурсы.

Сообщение отредактировал il--ya - Jul 2 2009, 10:58
Go to the top of the page
 
+Quote Post
barabek
сообщение Jul 3 2009, 12:21
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



Цитата(ARV @ Jun 9 2009, 18:47) *
проблема в том, что младщий бит, а то и 2, результата АЦП "дрожит"... как бы не попасть в бесконечный цикл...

Чтобы этого не было можно закончить тогда, когда измерения перестали быть больше максимального получившегося значения в течении N измерений.
Go to the top of the page
 
+Quote Post
EvgenyNik
сообщение Jul 3 2009, 19:40
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 597
Регистрация: 24-05-06
Из: г. Чебоксары
Пользователь №: 17 402



Если взять за основу электрический эквивалент, то:
1. тело человека - источник эдс постоянного тока.
2. датчик - ёмкость конечной величины (конденсатор)
3. теплопроводность от тела к датчику - резистивная проводимость (величина обратная резистивному сопротивлению)
4. окружающая среда - резистивный ток утечки ёмкости (датчика). Пренебрегаем этой утечкой.
Что мы имеем?
При возникновении контакта ёмкость (датчик) начинает заряжаться с постоянной времени RC и т.д.
В нашем же случае при использовании такой модели, мы получаем график роста показаний термометра:
Тд = Тд.н + (Тт - Тд.н)*(1 - exp (- k * t)), где
Тд - текущая температура датчика,
Тд.н. - начальная температура датчика
k - конструктивная постоянная времени (зависит от физ.свойств поверхности тела и датчика)
t - время в секундах.
Можно было бы сделав 2 замера, вычтя начальное значение датчика, расчитать через натуральный логарифм постоянную k и вычислить величину Тт, к которой стремится значение Тд. Но для этого термометр надо включить так, чтобы нагрев датчика не произошёл. Иначе мы получим смещение Тд.н. из-за инерционности датчика. Как правило, термометр вертят в руках, касаясь датчика, да и в вычислении логарифма, а потом и экспоненты - приятного мало в рамках малоресурсного алгоритма.
Предлагаю сделать 3 замера через равные интервалы времени, но на начальном участке нагрева, например в 5, 15 и 25 секунд и воспользоваться свойством экспоненты сохранять отношение текущего приращения к прошлому.
Иначе говоря, отношение (Tд(25) - Тд(15)) / (Тд(15) - Тд(5)) будет справедливо ко всем последующим приращениям, взятым с таким же интервалом времени.
Ну и вот - запускаете итерацию с накоплением результата до тех пор, пока расчётное приращение не станет ниже допустимой погрешности.
P.S. если дрожит младший бит - делайте подряд 8-16 измерений (сравнительно быстро, конечно) и вычисляйте по ним среднее для текущего времени.


--------------------
Почему разработчики систем повышенной надёжности плохо справляются с простыми проектами? :)
Go to the top of the page
 
+Quote Post
=AK=
сообщение Jul 6 2009, 05:36
Сообщение #9


pontificator
******

Группа: Свой
Сообщений: 3 055
Регистрация: 8-02-05
Из: страны Оз
Пользователь №: 2 483



Цитата(ARV @ Jun 9 2009, 14:33) *
прошу помощи в плане общего алгоритма... лучшей темы для своего вопроса не нашел...

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


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

Номер слева указывает порядковый номер измерения, res - 32-битное целое:

1: res = (meas << 16);
2,3: res = res - (res >> 1) + (meas << 15); // вес очередного измерения meas равен 1/2
4...7: res = res - (res >> 2) + (meas << 14); // вес измерения равен 1/4
8...15: res = res - (res >> 3) + (meas << 13); // вес измерения равен 1/8
... и т.д., однако далее некого предела вес уменьшать нельзя

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

Процедуру можно усовершенствовать, если переход на следующий шаг (с уменьшенным весом) тоже будет происходить в результате проверки, обнаруживающей, что результат стал изменяться сравнительно мало. Конечно, при этом доверительный интервал тоже должен уменьшаться на каждом шаге.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th June 2025 - 15:33
Рейтинг@Mail.ru


Страница сгенерированна за 0.01428 секунд с 7
ELECTRONIX ©2004-2016