Andrey_Ch8

Алгоритм Измерения Температуры

40 сообщений в этой теме

COKPOWEHEU    263
Как скажите так и сделаю.
Плохая идея.
он у меня с отрицательным температурным коэффициентом
По формуле так и выходит T=131.7-0.808*x. Разницы в подключении никакой нет, что положительный наклон, что отрицательный.
Точность желательно 0.1 измерения температуры.Если это возможно.
При линейном приближении, по Вашим предыдущим значениям сопротивлений и моим допущениям получается, что изменение младшего разряда АЦП соответствует 0,8 градусов при линейном приближении. Для повышения точности в идеальном случае надо сдвинуть-растянуть выходное напряжение к диапазону АЦП, то есть что бы 100 градусов соответствовало минимальному значению, а 0 - максимальному (все же, 26 градусов - странная точка отсчета, пусть лучше ноль). Вообще говоря, это можно сделать аналоговым вычитанием из напряжения выхода напряжения нуля. Не знаю, что за контроллер хотите использовать, в некоторых можно попробовать аппаратно. Чуть хуже, если границе соответствует только одно значение, например, 26 градусам - 2.56 В. Лобовое решение - подбор резистора Ro - приведет к увеличению нелинейности: с уменьшением сопротивления ток через него будет нарастать. Точнее будет, если соберете стабилизированный источник тока. Ну или хотя бы убедитесь, что во всем диапазоне точность останется удовлетворительной.
Выбрал внутренний ион от мк Uref=2.56В.
Вообще-то внутренний ИОН контроллеров не славится ни точностью, ни термостабильностью.
Вот пока что весь такой мой код, пробую выводить хоть какую нибуть температуру.
Динамическую индикацию лучше делать на таймере: задать массив из 4 элементов (char, как и сами порты), в любом удобном месте их заполнять, а по таймеру выводить в порт их значения по очереди. Это проще, быстрее и надежнее. Вообще, использование delay обычно плохая идея. Для начала можно выводить на индикатор не вычисленную температуру, а просто значение АЦП, как раз для заполнения таблицы.

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

m=((v-500)*30/10); // высчитываем температуру от 30 до 40 градусов
Магические чиселки лучше не использовать. Трудно что ли где-то в начале объявить хотя бы коэффициенты уравнения (например, #define U2T_K 30/10 ; #define U2T_B -500*10/30), тогда формула выглядела бы чуть логичнее m=U2T_K*v+U2T_B. Откуда эти числа взялись тоже непонятно, но, будем считать, они правильные.

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

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Использую Атмегу8.Динамическую индикацию как сделать смотрел в видео уроках, спс за подсказку переделаю.

Могу предложить свой вариант термометра, но он был заточен на платиновый терморезистор с линейной характеристикой с положительным наклоном. К тому же я самонадеянно посчитал, что смогу программно учесть нелинейность при такой же лобовой схеме задания тока. В принципе, для того применения той точности хватило, но вообще хорошо бы переделать, хотя бы с таблицами. Впрочем, ту же динамическую индикацию оттуда выдрать можно.
О класс!!! Если можно выложите свой вариант, я думаю другим пользователя будет тоже интересно.Проделал измерения термистора при 0-градусов =13 кОм.Вообщем теперь есть три точки зависимости сопротивления от температуры: 0оС = 13кОм, 26оС=7кОм, 100оС=2кОм.
T=131.7-0.808*x

Да еще хотел спросить как вы рассчитали эту формулу, как нашли эти числа, очень интересно.

Изменено пользователем Павел Царь

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
COKPOWEHEU    263
есть три точки зависимости сопротивления от температуры
Если построить по ним график - видна сильная нелинейность. Лучше бы побольше точек наснимать, но это когда будет готова схема. Какие граничные температуры планируются, 0 - 100 градусов?
Да еще хотел спросить как вы рассчитали эту формулу, как нашли эти числа, очень интересно.
Тупо нахождение коэффициентов линейного уравнения y=k*x+b (y - температура, х - значение АЦП) вычислить значение АЦП из сопротивления термистора, надеюсь, сможете.
Если можно выложите свой вариант
От самого варианта толку мало: довольно специфичная штука, да и точность градусов 5. Но вот код динамической индикации - пожалуйста

4-разрядный 7-сегментный индикатор висит между PORTD и PORTB. В принципе по коду все понятно. Разве что не указаны настройки таймера (да пофиг, главное его запустить, частота не важна, у меня это тактовая, деленная на 8, но можно медленнее), портов (очевидно де, что все используемые линии на выход) и процедура перевода числа в набор символов у меня другая (используется 3 разряда, вместо последнего - отдельные диоды, для прочей индикации).

//Макросы, определяющие соответствия выводов контроллера и сегментов индикатора
#define SEG_A (1<<PD7)
#define SEG_B (1<<PD5)
#define SEG_C (1<<PD3)
#define SEG_D (1<<PD1)
#define SEG_E (1<<PD0)
#define SEG_F (1<<PD6)
#define SEG_G (1<<PD4)
#define SEG_H (1<<PD2)
//Массив, расположенный во flash-памяти, указывающий, на какие выводы контроллера
//надо подать напряжение, чтобы на индикаторе отобразилась соответствующая цифра
PROGMEM unsigned char SEG[10]={
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, //0
SEG_B | SEG_C, //1
SEG_A | SEG_B | SEG_D | SEG_E | SEG_G, //2
SEG_A | SEG_B | SEG_C | SEG_D | SEG_G, //3
SEG_B | SEG_C | SEG_F | SEG_G, //4
SEG_A | SEG_C | SEG_D | SEG_F | SEG_G, //5
SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G, //6
SEG_A | SEG_B | SEG_C, //7
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G,//8
SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G //9
};

//значения отдельных сегментов, для динамической индикации
volatile unsigned char seg[4];

//Динамическая индикация происходит по прерыванию Timer0 по переполнению
//точная частота здесь абсолютно не важна, главное, чтобы она была больше ~200 Гц
ISR(TIMER0_OVF_vect){
static unsigned char pos=0; //номер индицируемого символа
static unsigned char mask=(1<<0); //маска, определяющая, на какой вывод PORTB надо
//подать напряжение для индикации
unsigned char res=PORTB;
PORTB = PORTB | 0x0F;
res=PORTB ^ mask;
PORTD = seg[pos];
PORTB = res;
if(++pos>3){pos=0; mask=(1<<0);}else mask<<=1;
}

//процедура преобразования числа в последовательность символов для отображения
void outint(unsigned int temp){
seg[3]=pgm_read_byte(&SEG[temp%10]); temp/=10; //младший разряд
seg[2]=pgm_read_byte(&SEG[temp%10]); temp/=10; //средний разряд
seg[1]=pgm_read_byte(&SEG[temp%10]); temp/=10; //старший разряд
if(temp==0)return; //если число больше 999, для индикации не поместившегося старшего разряда
//используются десятичные точки, имеющиеся на индикаторе:
if(temp==1)seg[1]|=SEG_H;else //если число от 1000 до 1999 загорается одна десятичная точка
if(temp==2)seg[2]|=SEG_H;else //если число от 2000 до 2999 - вторая
//если же больше 2999 то загораются все
if(temp==3)seg[3]|=SEG_H;else {seg[1]|=SEG_H; seg[2]|=SEG_H; seg[3]|=SEG_H;}
}

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Подскажите еще вот, как найти с массива ниже 2 значения для подставки в формулу расчета температуры что вы давали:

значение 121. Ближайшие значения - 120 и 130, которым соответствуют температуры 30 и 50 градусов. Тогда линейное приближение даст температуру ((121-120)*50+(130-121)*30)/(130-120) = 32 градусов. Разумеется, для контроллера проще делать шаг по значениям АЦП не 10, а степень двойки: 2, 4, 8, 16... но на суть это не влияет. Преимущество тут в том, что не надо искать наиболее похожее значение в таблице, достаточно одной операции целочисленного деления (лучше - сдвига, он быстрее). В примере, x=121, тогда x1=x/10 a x2=x1+1, то есть x1=12, x2=13, это и есть номера ячеек таблицы. В общем виде формула будет выглядеть как x1=x/N; x2=x1+1; T=((x-x1*N)*T2+(x2*N-x)*T1))/N; где N - шаг по значениям АЦП

/* Таблица суммарного значения АЦП в зависимости от температуры. От большего значения к меньшему
Для построения таблицы использованы следующие парамертры:
 R1(T1): 13кОм(0°С)
 R2(T2): 2кОм(100°С)
 Схема включения: C
 Ra: 4кОм
 Напряжения U0/Uref: 2.5В/5В
*/
unsigned char temperature [52] = {

341, 338, 335, 332, 328, 325, 321, 318,
314, 311, 307, 303, 299, 295, 291, 287,
283, 279, 275, 271, 266, 262, 257, 253,
248, 243, 239, 234, 229, 224, 220, 215,
210, 205, 200, 195=30oC, 190=28oC, 185=26oC, 180=24oC, 175=22oC,
170=20oC, 165=18oC, 160=16oC, 155=14oC, 150=12oC, 145=10oC, 140=8oC, 135=6oC,
130=4oC, 125=2oC, 120=0oC
};

В масиве ""=температура"" это для наглядности , дальше не писал.

Например АЦП преобразовало значение х=183, тогда по вашей формуле получается что нужно найти два значения из массива, ищем:

х1=х/2(шаг 2оС) , х2=х1+1.

х1=183/2=91.5 , х2=91.5+1=92.5. Но 91 и 92 нет таких номеров таблице!!!

Подскажите как в данном примере найти номера ячеек из таблици.

Еще, при подстановке в вашу формулу

T=x^2+sin(x)+5

чет не получается выводить температуру, например: значение АЦП= х=(теже)183, тогда Т=183^2+sin(183)+5 = 33489+(я искал синус числа так sin(183)=183*180/3.14=10490 - походу не верно я ищу)+10490+5=43984!!! а должно както быть примерно 25оС, вообщем я уже не знаю что как делать, запутался. Помогите разобраться. И если этой формулой будет довольно точно высчитывать температуру, то таблица тогда уже и не надо будет, вообще нужно разобраться.

Изменено пользователем Павел Царь

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alex    556
Но 91 и 92 нет таких номеров таблице!!!
Дак а как их найти, если их там вообще нет ? Их даже глазами визуально найти нельзя, не то что программно...

Странный какой то вопрос :huh:

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
COKPOWEHEU    263
х1=х/2(шаг 2оС)
Еще раз говорю, шаг не по температуре, а по АЦП. То есть температура, соответствующая 0, 2, 4, 6, ... 1022. В Вашем случай (шаг 5 по АЦП, почему-то равный 2 по температуре. Если зависимость получилась линейной, может проще формулу написать? T=0.4x-48) таблица будет выглядеть примерно так

unsigned int T [] = { //лень мне постоянно копипастить это название

0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30

};

А, поскольку шаг по АЦП равен 5, а первое значение не 0, а 120, расчет будет вестись как x1=x/5-120/5; Формула для x2 такая же как была - x2=x1+1; Дело в том, что целочисленное деление не учитывает округления и, скажем, 20/11=1. То есть оно будет точно не больше истинного значения (20/9=1.82). А вот значение на 1 больше как раз соответствует округлению в большую сторону (20/11+1=2). Для значения АЦП 183, получаются x1=12; x2=13 (они целочисленные). T[12]=24; T[13]=26; Откуда T=25.2 градуса.

Еще, при подстановке в вашу формулу

T=x^2+sin(x)+5

чет не получается выводить температуру

Ну еще бы, я эту формулу от балды придумал. Да и как напряжение на термисторе может зависеть от температуры циклически (sin)?!

Еще раз: мой метод чуть сложнее в подготовке, чем описанный по той ссылке, зато быстрее для вычислений. Сначала составляется зависимость значений АЦП от температуры. Например, получилось, что x=arctg(T)-273 (это прямое измерение). Тогда зависимость температуры от сопротивления будет T=tg(x+273). Теперь по формуле строим таблицу T(x) через каждые 8 значений АЦП например T[]={-19, -5, -3,...}. Преимущество в том, что эти хитрые преобразования делаются на компьютере, то есть их можно делать с гораздо большей точностью (например, измерить значения в 10 точках и строить по ним полином 9 степени, а уже по нему рассчитывать таблицу для контроллера. Сам полином он считал бы час, а таблицу обработает за сотню тактов)

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
fuckir    6

Может не стоит привязываться так к скорости вычисления МК? У датчика какая энерционность?

Павел Царь а вы чем контролируете температуру? Если вам нужна точность 0.1С, то контролирующее устройство должно быть на порядок точнее.

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
COKPOWEHEU    263

Ну надо же хоть к чему-то стремиться: либо скорость, либо объем кода, либо переносимость, либо простота.

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
fuckir    6

Ну так если человек не в состоянии обеспечить контрольным оборудованием хотя бы с точностью 0,05С, то зачем париться с 0,1С. Тем более, если использовать в программе таблицы АЦП->Град. Раз разговор о коде ..

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
COKPOWEHEU    263

Если у датчика сильная нелинейность - вводить корректировки в любом случае придется. Либо формулой, либо таблицей. В той же таблице может быть любое число элементов, хоть 256, хоть 10, хоть 2, достаточно поймать такое количество, чтобы линейное приближение между точками обеспечивало достаточную точность. Формула может оказаться достаточно сложной, как и ее отладка. А принцип определения температуры один хоть для 0.1 градуса, хоть для 10. А точность определяется не только контрольным оборудованием, но и областью применения: уличному термометру достаточно и 2 градусов, а вот медицинскому 0.1 градус необходим (хотя там вся шкала от 34 до 42).

А чем кроме размера не устраивают таблицы?

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо за розяснение SOKROWEHEU. Буду пробовать по вашему табличному методу, скорость мне ни к чему, главное точность.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
fuckir    6

COKPOWEHEU автор хочет точность 0,1С об этом и речь. Можно хоть 0,01 на дисплее нарисовать, но если ты контролируешь каким-нибудь хорошим Квиком, у которого идет +-0,2С, то достоверность ваших показаний ->0 и колибровка имеет смысл только с d 0,5С.

Изменено пользователем fuckir

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
COKPOWEHEU    263

А вдруг у автора есть доступ к палате мер и весов и он может обеспечить точность хоть 0.001 градуса, мы же не знаем. К тому же, точность наверняка нужна не по всему диапазону, а около ключевых точек (0С, 37С, 100С), а там можно попытаться ее обеспечить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

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

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас