Терморезистор
- Войдите на сайт для отправки комментариев
Реализую ПИ регулятор для управления электроконвектором. Столкнулся со следующей проблемой.
Оставляю регулятор на тестирование в течении суток (на даче), уставка 10С. Смотрю через сутки на регуляторе температура 9.8С, вроде держит уставку, а ртутный термометр расположенный рядом с терморезистором показывает 20С. Перезапускаю регулятор, он тоже показывает 19.7С. Грешил на саморазогрев терморезистора, переделал схему, теперь напряжение на терморезистор подается только в момент замера температуры (частота опроса 1сек.), но проблемма не ушла. тестировал дома за два часа, стал занижать на 0,9С , перезагрузил, стал показывать актуальную температуру. Не могу понять в чем проблемма.
Схема включения
U0 посажен на аналоговый DP16(Ain2)- перед опросом сюда подается напряжение (1), после снимаеться (0) (ранее подовалось постоянно с шины +5В (результата не дало).
код замера температуры
float addr[25][2] = { { 0,32.0 } , { 5,25.5 } , { 10,20.0 } , { 15,15.7 } , { 20,12.62 } , { 25,10.0 } , { 30,8.24 } , { 35,6.63 } , { 40,5.41 } , { 45,4.41 } , { 50,3.62 } , { 55,2.99 } , { 60,2.48 } , { 65,2.08 } , { 70,1.75 } , { 75,1.47 } , { 80,1.258 } , { 85,1.063 } , { 90,0.905 } , { 95,0.776 } , { 100,0.669 } , { 105,0.581 } , { 110,0.505 } , { 115,0.442 } , { 120,0.387 } , }; void setup() { // } void loop() { temp=getTemp(t); } //------------------замер температуры---------------------- double getTemp(float V) { float R; R=getR(V); int i=0; while (addr[i][1] >R) { i++; } double result; result=(R-addr[i][1])*(addr[i-1][0]-addr[i][0])/(addr[i-1][1]-addr[i][1])+addr[i][0]; return result; } float getR(float V) { float result; result=-10*V/(V-1024); return result; }
Код привел упращнный, но сути не меняет.
DS18B20 не предлагать, Работаем с тем что есть.
Какие будут соображения? (Прошу отвечать по сути вопроса!)
Забыл добавить, по схеме Ra=10kOm (SMD исполнении), терморезистор 10kOm при 25С. Зависимость сопротивление температура мерил в специальной печке для проверки термодатчиков на производстве.
Проблемма коротко - Показывет 10, отключаю, сразу включаю, показывает правильную температуру.
Показывет 10, отключаю, сразу включаю, показывает правильную температуру.
включай сразу.
Показывет 10, отключаю, сразу включаю, показывает правильную температуру.
включай сразу.
Оценил.
А если серьезно.
А если серьезно.
если серьёзно - странная лингвистически-программно-аппаратная проблема.
не понятно, что значит "сразу включаю" - до того ты не сразу включаешь?
ок. можно отбросить и переформулировать, что работает "не всегда".
...дальше продолжать гадать на кофейной гуще, почему не считываются показания с аналогового входа или не вычисляются нужные переменные не всегда, а только после многократных тыканий в розетку?
>перед опросом сюда подается напряжение
ок. у тебя при первом запустке напряжение не подаётся - при втором запуске ты работаешь на напряжении от первого запуска.
рой в ту сторону
U0 надо бы стабилизировать хороше, или его мерить и учитывать. В приведеном коде не видно криминала с составом преступления.
Перейти на опорное напряжение 1.1 вольт, чтобы диапазон измерений увеличить. Но все равно будет скакать 0.5 гр. И если использовать тарировочную кривую в виде массива, то вроде ничего считать не надо, прямо маром между точками.
Вот видео происходящего с девайсом.
На нем видно что после выклчения и повторного включения температура изменилась на 1С.
Проверяйте условия по коду, похоже, что считывается один раз, а дальше прекращает.
Проверяйте условия по коду, похоже, что считывается один раз, а дальше прекращает.
Если датчик нагреваю, показания меняються, посто через какоето время "уплывают".
Вот схема включения
Чип тактируеться от внутреннего генератора 8МГц. На ADC2 в момент измерения температуры подается напряжение, усредняеться 10 измерений затем напряжение снимаеться (чтобы исключить саморазогрев термистора от протекающего в делителе тока.
Чисто для эксперимента, оставить на аналоговых входах только чтение датчика, питание и реле перенести на цифровые. Может кто еще чего посоветует.
С таким делителем саморазогрев, десятые градуса, не больше.
для начала я применил бы вместо массива и коррекции по отрезкам уравнение , в Вашем случае это
y = -6E-09x5 + 2E-06x4 - 0.0004x3 + 0.0326x2 - 1.485x + 32.019
Чисто для эксперимента, оставить на аналоговых входах только чтение датчика, питание и реле перенести на цифровые. Может кто еще чего посоветует.
С таким делителем саморазогрев, десятые градуса, не больше.
Питание делителя изночально бралось с обшей шины питания, положение реле на показания не влияет.
Если прибор не отключать то температура постепенно (незаметно) вниз уходит.
Для проверки аппаратной части, можете параллельно произвести замеры напряжения тестером, но скорее это программное.
Выходит, что где то при усреднении начинает накапливаться ошибка.
И предложение inspiritus попробуйте.
Для проверки аппаратной части, можете параллельно произвести замеры напряжения тестером, но скорее это программное.
Выходит, что где то при усреднении начинает накапливаться ошибка.
И предложение inspiritus попробуйте.
Тоже к этому склоняюсь. Вот так выглядит код усрезнения, может чето не доглядел.
для начала я применил бы вместо массива и коррекции по отрезкам уравнение , в Вашем случае это
y = -6E-09x5 + 2E-06x4 - 0.0004x3 + 0.0326x2 - 1.485x + 32.019
Спасибо попробую.
как получено y = -6E-09x5 + 2E-06x4 - 0.0004x3 + 0.0326x2 - 1.485x + 32.019
закладываете таблицу в эксель, строите график ТОЧЕЧНЫЙ!, включаете линию тренда и подбираете метод , в Вашем случае подошел полиномиальный 5 степени, ставите галку отображать формулу, это она и есть.
По усреднению вроде все корректно должно работать. Загадка природы)))). Похоже пошагово надо рыть.
И попробуйте int t = 0; Локальные переменные не обязательно нулем инициируются.
Вот так выглядит код усрезнения, может чето не доглядел.
Простите, я не знаю что у Вас за термистор, потому утверждать не могу ничего, но Вы подумайте - нормально ли то, что Вы кидаетесь мерять сразу же по подаче напряжения безо всякой малейшей паузы? Он так работет? Какова у него скорость "устаканивания" по даташиту?
Рание питание на датчик подовалось постоянно, теперь питание подаеться при замере температуры - РАЗНИЦЫ НЕТ. При включение температуру показывает точно (К точности показаний притензий нет, непойму почему через пару часов работы появляеться разница около 1 градуса).
Как я уже выше писал - Поставил уставку 10С, на следующий день приехал, уставка 10С, текущая 9,8С (по девайсу) ,а термометр показывает 19С (ртутный). Выключил девайс снова включил, сразуже показывает текущую 19С. Вопрос в том почему измеренная температура падает современем, а после рестарта актуальную температуру отображает.:(
Вы int t = 0; попробовали в 4 строке?
Я бы между
04
int
t;
05
for
(
int
i=0; i <= 9; i++)
t=0;
вставил.
#14 temp=getTemp(t); при чём t типа int
в исходном коде
double
getTemp(
float
V)
{......}
параметр функции
float
......дайте весь крайний код....
Зависимость сопротивление температура мерил в специальной печке для проверки термодатчиков
практичнее снять сразу зависимость температура -> АЦП ( 0...1023 ) , пересчётов будет меньше
Вы int t = 0; попробовали в 4 строке?
Попробую, но уже не сегодня. Завтра утром попробую отпишу.
Пока видео что происходит.
#14 temp=getTemp(t); при чём t типа int
в исходном коде
double
getTemp(
float
V)
{......}
параметр функции
float
......дайте весь крайний код....
Весь код
строка 141 присваивает float temp значение функции getTemp( t ) в которую передаёте параметр типа int
а в строке 238 эта функция принимает параметр типа float , и возвращает double
строку 241 R=getR(V); переделать в R=-10*V/(V-1024); и убрать строки 251...256 ( зачем одно действие выносить в функцию ? )
Что то я совсем наверное темы не понимаю.. Сделал уже с десяток самопальных датчиков на базе самых разных термисторов.. Честно говоря не знаю их точность в запредельных температурах. Применяю их в диапазоне 17-30 градусов. Остальное меня не интересует..
Подключаю по схеме. Фактически как кнопки аналоговые вешаю. только по 1 штуке на аналоговый вход. Считываю показания и перевожу данные в градусы примерно так, не сильно большая точность в большом диапазоне, но на 15градусов точности вполне хватает.
формула расчета подбирается эмпирическим путем исходя из текущей температуры (23.5), текущего сопротивления(388) и некойдельты температур (9.5) тут можно просто подобрать если не понятно как высчитывать..
Напряжение подается постоянно. И только на датчике влажности грунта подаю его через 13ую ногу только в момент замера. Чтоб грунт не сушил. (сорри за схему. не умею их рисовать :))
Чтоб грунт не сушил.
не осушит :) , а вот окисляться под напругой будет очень хорошо
Что то я совсем наверное темы не понимаю.. Сделал уже с десяток самопальных датчиков на базе самых разных термисторов.. Честно говоря не знаю их точность в запредельных температурах. Применяю их в диапазоне 17-30 градусов. Остальное меня не интересует..
Подключаю по схеме. Фактически как кнопки аналоговые вешаю. только по 1 штуке на аналоговый вход. Считываю показания и перевожу данные в градусы примерно так, не сильно большая точность в большом диапазоне, но на 15градусов точности вполне хватает.
формула расчета подбирается эмпирическим путем исходя из текущей температуры (23.5), текущего сопротивления(388) и некойдельты температур (9.5) тут можно просто подобрать если не понятно как высчитывать..
Напряжение подается постоянно. И только на датчике влажности грунта подаю его через 13ую ногу только в момент замера. Чтоб грунт не сушил. (сорри за схему. не умею их рисовать :))
Приведенную Вами схему рекомендуют использовать при изменении низких температур.
У меня точность хорошая, но со временем врать начинает (отношение температура сопротивление мерил в специальной печи у КИПовцев.)
А схему рисовал тут.
Можете свой код для примера выложить?
У меня точность хорошая, но со временем врать начинает (отношение температура сопротивление мерил в специальной печи у КИПовцев.)
раз есть такая возможность , то собери схему измерения и простой скетч вывода в терминал значений с аналогового пина
и сними прямую зависимость T от значения с аналогового пина , и проверь - плывут ли показания при постоянной температуре в печи
код чего?? остальное все просто.
сравниваем значение Trra с заданными параметрами. Если ниже 17 - включаю обогреватель. Если выше 30 вентиляцию.. две команды digital.Write ;)
Чтоб грунт не сушил.
не осушит :) , а вот окисляться под напругой будет очень хорошо
к стати да! датчик самодельный из гвоздей :)))). пока едет норм из поднебесной. один из гвоздей имеет ярко выраженный окрас окисления. но пока вроде датчик не врет. думаю китаец успеет приехать.
Завтра попробую все предложенные варианты, если не выдет напишу код с 0, есче менюшку добавить надо (ну это на пару минут) для настройки П,И коэффициентов.
как получено y = -6E-09x5 + 2E-06x4 - 0.0004x3 + 0.0326x2 - 1.485x + 32.019
закладываете таблицу в эксель, строите график ТОЧЕЧНЫЙ!, включаете линию тренда и подбираете метод , в Вашем случае подошел полиномиальный 5 степени, ставите галку отображать формулу, это она и есть.
Это (апроксимацию) я давно знаю, но она не очень точна и процессорного времени больше займет. Спасибо за труд!
но она не очень точна и процессорного времени больше займет
тогда составьте массив 100 ( или 200 , через 0.5 градуса ), индекс = температура , элемент массива = код АЦП - точнее способа нет
но она не очень точна и процессорного времени больше займет
тогда составьте массив 100 ( или 200 , через 0.5 градуса ), индекс = температура , элемент массива = код АЦП - точнее способа нет
Можно не больше 10, межу ними маром.
но она не очень точна и процессорного времени больше займет
тогда составьте массив 100 ( или 200 , через 0.5 градуса ), индекс = температура , элемент массива = код АЦП - точнее способа нет
Можно не больше 10, межу ними маром.
не нравятся ТС-у апроксимации... при массиве соответствия 200 никаких расчётов не нужно , только поиск по массиву-таблице
Нормальная апроксимация. График гладкий.
Надо в код вставить вывод значения АЦП (t) после
139
T_Sensor_OFF;
140
t=t/10;
и следить за ним. Если плывёт во времени, то виноват резистор, если нет - искать в коде.
Нормальная апроксимация. График гладкий.
Надо в код вставить вывод значения АЦП (t) после
139
T_Sensor_OFF;
140
t=t/10;
и следить за ним. Если плывёт во времени, то виноват резистор, если нет - искать в коде.
никогда не видел терморезистора ( с любым ТКС , + или - ) изменяющего свою характеристику за мин , час , сутки , год.... за 10 лет может быть и изменится :(
см. #30
И я не видел. Но я много раз встречал плохой контакт, окисление и прочие чудеся приводящие к неправильной работе. Поэтому с #30 согласен. Жду от ТС табличку замера напряжения на резисторе и расчитанной температуры от времени.
расчитанной температуры от времени.
зачем ?
Где то появляется и накапливается ошибка. Контрольных точек две - выход терморезистора и расчитанная в программе температура. Анализ изменения напряжения в этих точках поможет локализовать место ошибки.
В формуле расчёта сопротивления стоит 10. Это значит что верхнее сопротивление 2 кОм?
ТС так и не ответил, пробовал ли он явное обнуление своей локальной переменной. В куске кода который он привел, это наиболее вероятная причина возникновения ошибки с течением времени. Мы не знаем, что происходит с его ОЗУ за время работы программы и возможность, что на очередном проходе t не будет равна 0, весьма высока.
В полном коде есть t=0;
Извиняюсь, не заметил.
Извиняюсь, не заметил.
Это изменение я внес по рекомендации читателей форума уже позже, но проверить неуспел (на работе целый день).
Весь день слежу за предложениями (ответить не мог, мобильный браузер не хотел логиниться на форуме).
Для себя зделал вывод, что ошибка скорее программная.
Буду пробовать следующее:
0. Разберусь с объявлением переменных в функции getTemp().
1. Обнуление t (уже внесено)
2. Введу задержку между подачей питания на терморезистор и снятием показаний.
Буду пробовать поочередно и всё вместе, посмотрю от чего эффект будет.
В железе смогу проверить только послезавтра (работа).
Всем спасибо за предложенные варианты.
По локальным переменным, лучше все инициируйте явно, если дальше не следует прямое присваивание.
2. Введу задержку между подачей питания на терморезистор и снятием показаний.
...трата времени :)
это не какой-то MQxxx с подогревом рабочей зоны , ТР-у всё равно - под напряжением он или нет....
а выкладка сюда крайнего кода желательна :) , чтобы по постам не скакать....
Весь код
У Вас ошибка.
В функции double getTemp(float V) определяется параметр в цикле while (addr[i][1] >R)
и при некотром значении V значение параметра i будет равно 0.
Какое значение даст обращение к массиву addr[-1][0] или addr[-1][1] не скажет никто.