Терморезистор

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Реализую ПИ регулятор для управления электроконвектором. Столкнулся со следующей проблемой.

Оставляю регулятор на тестирование в течении суток (на даче), уставка 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 не предлагать, Работаем с тем что есть.

Какие будут соображения? (Прошу отвечать по сути вопроса!)

 

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Забыл добавить, по схеме Ra=10kOm (SMD исполнении), терморезистор 10kOm при 25С. Зависимость сопротивление температура мерил в специальной печке для проверки термодатчиков на производстве.

Проблемма коротко - Показывет 10, отключаю, сразу включаю, показывает правильную температуру.

Клапауций 666
Offline
Зарегистрирован: 10.11.2015

yul-i-an пишет:

Показывет 10, отключаю, сразу включаю, показывает правильную температуру.

включай сразу.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Клапауций 666 пишет:

yul-i-an пишет:

Показывет 10, отключаю, сразу включаю, показывает правильную температуру.

включай сразу.

Оценил.

А если серьезно.

Клапауций 666
Offline
Зарегистрирован: 10.11.2015

yul-i-an пишет:

А если серьезно.

если серьёзно - странная лингвистически-программно-аппаратная проблема.

не понятно, что значит "сразу включаю" - до того ты не сразу включаешь?

ок. можно отбросить и переформулировать, что работает "не всегда".

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

>перед опросом сюда подается напряжение

ок. у тебя при первом запустке напряжение не подаётся - при втором запуске ты работаешь на напряжении от первого запуска.

рой в ту сторону

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

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

uragan
Offline
Зарегистрирован: 23.02.2015

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

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Вот видео происходящего с девайсом.

На нем видно что после выклчения и повторного включения температура изменилась на 1С.

bwn
Offline
Зарегистрирован: 25.08.2014

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

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

bwn пишет:

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

Если датчик нагреваю, показания меняються, посто через какоето время "уплывают".

Вот схема включения

Чип тактируеться от внутреннего генератора 8МГц. На ADC2 в момент измерения температуры подается напряжение, усредняеться 10 измерений затем напряжение снимаеться (чтобы исключить саморазогрев термистора от протекающего в делителе тока.

bwn
Offline
Зарегистрирован: 25.08.2014

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

inspiritus
Offline
Зарегистрирован: 17.12.2012

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

y = -6E-09x5 + 2E-06x4 - 0.0004x3 + 0.0326x2 - 1.485x + 32.019

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

bwn пишет:

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

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

Если прибор не отключать то температура постепенно (незаметно) вниз уходит.

bwn
Offline
Зарегистрирован: 25.08.2014

Для проверки аппаратной части, можете параллельно произвести замеры напряжения тестером, но скорее это программное.
Выходит, что где то при усреднении начинает накапливаться ошибка.
И предложение inspiritus попробуйте.
 

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

bwn пишет:

Для проверки аппаратной части, можете параллельно произвести замеры напряжения тестером, но скорее это программное.
Выходит, что где то при усреднении начинает накапливаться ошибка.
И предложение inspiritus попробуйте.
 

Тоже к этому склоняюсь. Вот так выглядит код усрезнения, может чето не доглядел.

 if ((millis()-time)>=1000){//чтение температуры
    time=millis();
    T_Sensor_ON;//подаю питание на термосопротивление
    int t;
    for (int i=0; i <= 9; i++){
      t = t + analogRead(1);
    }
    T_Sensor_OFF;//снимаю питание с термосопротивления
    t=t/10;
    temp=getTemp(t);
  }

 

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

inspiritus пишет:

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

y = -6E-09x5 + 2E-06x4 - 0.0004x3 + 0.0326x2 - 1.485x + 32.019

Спасибо попробую.

inspiritus
Offline
Зарегистрирован: 17.12.2012

как получено y = -6E-09x5 + 2E-06x4 - 0.0004x3 + 0.0326x2 - 1.485x + 32.019

закладываете таблицу в эксель, строите график ТОЧЕЧНЫЙ!, включаете линию тренда и подбираете метод , в Вашем случае подошел полиномиальный 5 степени, ставите галку отображать формулу, это она и есть.

bwn
Offline
Зарегистрирован: 25.08.2014

По усреднению вроде все корректно должно работать. Загадка природы)))). Похоже пошагово надо рыть.
И попробуйте int t = 0; Локальные переменные не обязательно нулем инициируются.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

yul-i-an пишет:

Вот так выглядит код усрезнения, может чето не доглядел.

 if ((millis()-time)>=1000){//чтение температуры
    time=millis();
    T_Sensor_ON;//подаю питание на термосопротивление
    int t;
    for (int i=0; i <= 9; i++){
      t = t + analogRead(1);
    }
    T_Sensor_OFF;//снимаю питание с термосопротивления
    t=t/10;
    temp=getTemp(t);
  }

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

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Рание питание на датчик подовалось постоянно, теперь питание подаеться при замере температуры - РАЗНИЦЫ НЕТ. При включение температуру показывает точно (К точности показаний притензий нет, непойму почему через пару часов работы появляеться разница около 1 градуса).

Как я уже выше писал - Поставил уставку 10С, на следующий день приехал, уставка 10С, текущая 9,8С (по девайсу) ,а термометр показывает 19С (ртутный). Выключил девайс снова включил, сразуже показывает текущую 19С. Вопрос в том почему измеренная температура падает современем, а после рестарта актуальную температуру отображает.:(

bwn
Offline
Зарегистрирован: 25.08.2014

Вы int t = 0; попробовали в 4 строке?

nik182
Offline
Зарегистрирован: 04.05.2015

Я бы между 

 
04    int t;
05

   for (int i=0; i <= 9; i++)

t=0;

вставил.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

#14  temp=getTemp(t); при чём t типа int
в исходном коде  

double getTemp(float V)
{......}

 параметр функции float  ......

дайте весь крайний код....

Зависимость сопротивление температура мерил в специальной печке для проверки термодатчиков
практичнее снять сразу зависимость температура -> АЦП ( 0...1023 ) , пересчётов будет меньше

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

bwn пишет:

Вы int t = 0; попробовали в 4 строке?

Попробую, но уже не сегодня. Завтра утром попробую отпишу.

Пока видео что происходит.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

SU-27-16 пишет:

#14  temp=getTemp(t); при чём t типа int
в исходном коде  

double getTemp(float V)
{......}

 параметр функции float  ......

дайте весь крайний код....

Весь код

//кнопки А0, реле 13, подсветка 10
#include <LiquidCrystal.h>
#define key_in analogRead(0)
#define T_Sensor_OFF digitalWrite(16,LOW);//отключить термистор
#define T_Sensor_ON digitalWrite(16,HIGH);//включить термистор  
//для ПИ регулятора
float p,i;
LiquidCrystal lcd(7,6,5,4,3,2);
long time;//интервал замера температуры
long lcd_time;//интервал отрисовки экрана
long on_time;
int zad=0;
int k_b[]={
  512,683,768};//аналоговые кнопки SET + -
float temp=0.0;
float ust=10.0;//termostate
int c=99;//пройденые циклы мощности
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                                                        }
  ,
};

byte cel[] =
{
  0b01000,
  0b10100,
  0b01000,
  0b00111,
  0b01000,
  0b01000,
  0b00111
};

void setup(){
  // Serial.begin(9600);
  pinMode(13,OUTPUT);//реле HI
  pinMode(12,OUTPUT);//реле LO
  pinMode(16,OUTPUT);//питание термистора
  T_Sensor_OFF;
  digitalWrite(13,LOW);//отключить реле
  digitalWrite(12,LOW);//отключить реле
  //digitalWrite(10,LOW);
  lcd.begin(16, 2);
  analogWrite(10,250);//подсветка
  time = millis();
  lcd_time = time;
  on_time = time;
  lcd.createChar(1, cel);
}

void loop(){
  key();
  if (time>millis()){//защита от переполнения
    time=millis();
    lcd_time=time;
    on_time=time;
  }
  if ((millis()-time)>=1000){//чтение температуры
    time=millis();
    T_Sensor_ON;
    int t;
    t=0;
    for (int i=0; i <= 9; i++){
      t = t + analogRead(1);
    }
    T_Sensor_OFF;
    t=t/10;
    temp=getTemp(t);
  }
  //-------------------вывод на экран----------------
  if ((millis()-lcd_time)>=100){//вывод на экран
    lcd_time=millis();
    Screen_print();
  }

  //---------------------управление мощностью--------------------------
  //выдаем мощность
  if((millis()-on_time)>=500){//период ШИМ
    on_time=millis();

    if(c<zad){
      ten(13,1);
    }
    else{
      if (zad != 100){
        ten(13,0);
      }
    }
    c=c+1; 
    if(c==100){
      c=0;
      PIctl();
    }
  }
}


//управление тенами
void ten (int x,boolean s){
  digitalWrite(x,s);
}

void PIctl()
{
  float e;
  e=(ust-temp);
  // расчет выходной мощности:
  p=130.0*e;
  if (p<0.0)
  {
    p=0.0;//ограничение P
  }
  i=(i+(e*1.4));
  zad=p+i;

  //ограничение управляющего сигнала
  if (zad<4){
    zad=0;
  }
  if (zad>96){
    zad=100;
  }

  if (temp<(ust-2.0))
  {
    zad=100;
    i=0;
  }
  if (temp>(ust+2.0))
  {
    zad=0;
    i=0;
  }
  if(temp>(ust-0.5)&&temp<(ust+0.5))//зона нечувствительности +-0,5
  {
    zad=zad;
  }

}

//----------------опрос клавиш-------------------------------
void key(){
  int x;
  x = key_in;
  if (x>k_b[0]-5 && x<k_b[0]+5){//МЕНЮ
    UP_butt(); 
    key_m(0);
  }
  if (x>k_b[1]-5 && x<k_b[1]+5){// +
    UP_butt();
    key_m(1);
  } 
  if (x>k_b[2]-5 && x<k_b[2]+5){// -
    UP_butt();
    key_m(2);
  }  
}
//---------------проверка отпускания кнопки-----------------
void UP_butt(){
  while (key_in<1010){//ждем отпускания кнопки
  } 
}

//------------------замер температуры----------------------
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;
}

//-----------------обработка кнопок-------------------------
void key_m(int x){
  //  lcd.clear();
  switch (x){
  case 0://menu
  ust=10;
    break;
  case 1://кнопка +
    ust++;
    if (ust>35){
      ust=35;
    }
    break;
  case 2://кнопка -
    ust--;
    if (ust<5){
      ust=5;
    }
    break;
  }
}

void Screen_print()
{
  byte a=0;
  byte b=0;
  tempPrint(temp,0,0);
  tempPrint(ust,0,1);
  lcd.setCursor(6, 0);
  lcd.print(zad); 
  lcd.print("%  "); 

  lcd.setCursor(6, 1);
  lcd.print(i); 
  lcd.print("I "); 


  lcd.setCursor(12, 0);
  lcd.print(c); 
  lcd.print("  "); 
  a=digitalRead(13);
  b=digitalRead(12);
  if (a==1 && b==0){
    lcd.setCursor(12, 1);
    lcd.print("HI ");
  }
  if (a==0 && b==1){
    lcd.setCursor(12, 1);
    lcd.print("LO ");
  }
  if (a==0 && b==0){
    lcd.setCursor(12, 1);
    lcd.print("OFF");
  } 
}
  //-------------вывод температуры----------------------------
void tempPrint(double t, int x, int y){
  lcd.setCursor(x, y);
  lcd.print(t);
  lcd.setCursor(x+4, y);
  lcd.print(char(1));//вывод градусов
}

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

строка 141 присваивает float temp значение функции getTemp( t ) в которую передаёте параметр типа int
а в строке 238 эта функция принимает параметр типа float , и возвращает double

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

строку 241 R=getR(V); переделать в R=-10*V/(V-1024); и убрать строки 251...256 ( зачем одно действие выносить в функцию ? ) 

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Что то я совсем наверное темы не понимаю.. Сделал уже с десяток самопальных датчиков на базе самых разных термисторов.. Честно говоря не знаю их точность в запредельных температурах. Применяю их в диапазоне 17-30 градусов. Остальное меня не интересует..

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

int Trra = (analogRead(A1)-388)/9.5+23

формула расчета подбирается эмпирическим путем исходя из текущей температуры (23.5), текущего сопротивления(388)  и некойдельты температур (9.5) тут можно просто подобрать если не понятно как высчитывать..

Напряжение подается постоянно. И только на датчике влажности грунта подаю его через 13ую ногу только в момент замера. Чтоб грунт не сушил. (сорри за схему. не умею их рисовать :))

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Чтоб грунт не сушил.
не осушит :) , а вот окисляться под напругой будет очень хорошо

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

exez пишет:

Что то я совсем наверное темы не понимаю.. Сделал уже с десяток самопальных датчиков на базе самых разных термисторов.. Честно говоря не знаю их точность в запредельных температурах. Применяю их в диапазоне 17-30 градусов. Остальное меня не интересует..

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

int Trra = (analogRead(A1)-388)/9.5+23

формула расчета подбирается эмпирическим путем исходя из текущей температуры (23.5), текущего сопротивления(388)  и некойдельты температур (9.5) тут можно просто подобрать если не понятно как высчитывать..

Напряжение подается постоянно. И только на датчике влажности грунта подаю его через 13ую ногу только в момент замера. Чтоб грунт не сушил. (сорри за схему. не умею их рисовать :))

Приведенную Вами схему рекомендуют использовать при изменении низких температур.

У меня точность хорошая, но со временем врать начинает (отношение температура сопротивление мерил в специальной печи у КИПовцев.)

А схему рисовал тут.

Можете свой код для примера выложить?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

У меня точность хорошая, но со временем врать начинает (отношение температура сопротивление мерил в специальной печи у КИПовцев.)

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

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

код чего?? остальное все просто.

сравниваем значение Trra с заданными параметрами. Если ниже 17 - включаю обогреватель. Если выше 30 вентиляцию.. две команды digital.Write ;)

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

SU-27-16 пишет:

Чтоб грунт не сушил.
не осушит :) , а вот окисляться под напругой будет очень хорошо

к стати да! датчик самодельный из гвоздей :)))). пока едет норм из поднебесной. один из гвоздей имеет ярко выраженный окрас окисления. но пока вроде датчик не врет. думаю китаец успеет приехать.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Завтра попробую все предложенные варианты, если не выдет напишу код с 0, есче менюшку добавить надо (ну это на пару минут)  для настройки П,И коэффициентов.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

inspiritus пишет:

как получено y = -6E-09x5 + 2E-06x4 - 0.0004x3 + 0.0326x2 - 1.485x + 32.019

закладываете таблицу в эксель, строите график ТОЧЕЧНЫЙ!, включаете линию тренда и подбираете метод , в Вашем случае подошел полиномиальный 5 степени, ставите галку отображать формулу, это она и есть.

Это (апроксимацию) я давно знаю, но она не очень точна и процессорного времени больше займет. Спасибо за труд!

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

но она не очень точна и процессорного времени больше займет
тогда составьте массив 100 ( или 200 , через 0.5 градуса ), индекс = температура , элемент массива = код АЦП - точнее способа нет

uragan
Offline
Зарегистрирован: 23.02.2015

SU-27-16 пишет:

но она не очень точна и процессорного времени больше займет
тогда составьте массив 100 ( или 200 , через 0.5 градуса ), индекс = температура , элемент массива = код АЦП - точнее способа нет

Можно не больше 10, межу ними маром.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

uragan пишет:

SU-27-16 пишет:

но она не очень точна и процессорного времени больше займет
тогда составьте массив 100 ( или 200 , через 0.5 градуса ), индекс = температура , элемент массива = код АЦП - точнее способа нет

Можно не больше 10, межу ними маром.

не нравятся ТС-у апроксимации... при массиве соответствия 200 никаких расчётов не нужно , только поиск по массиву-таблице

nik182
Offline
Зарегистрирован: 04.05.2015

Нормальная апроксимация. График гладкий.

Надо в код вставить вывод значения АЦП (t) после

139     T_Sensor_OFF;
140

    t=t/10;

и следить за ним. Если плывёт во времени, то виноват резистор, если нет - искать в коде.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

nik182 пишет:

Нормальная апроксимация. График гладкий.

Надо в код вставить вывод значения АЦП (t) после

139     T_Sensor_OFF;
140

    t=t/10;

и следить за ним. Если плывёт во времени, то виноват резистор, если нет - искать в коде.

никогда не видел терморезистора ( с любым ТКС , + или - ) изменяющего свою характеристику за мин , час , сутки , год.... за 10 лет может быть и изменится :(

см. #30

nik182
Offline
Зарегистрирован: 04.05.2015

И я не видел. Но я много раз встречал плохой контакт, окисление и прочие чудеся приводящие к неправильной работе. Поэтому с #30 согласен. Жду от ТС табличку замера напряжения на резисторе и расчитанной температуры от времени. 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

расчитанной температуры от времени.
зачем ?

nik182
Offline
Зарегистрирован: 04.05.2015

Где то появляется и накапливается ошибка. Контрольных точек две - выход терморезистора и расчитанная в программе температура. Анализ изменения напряжения в этих точках поможет  локализовать место ошибки.

В формуле расчёта сопротивления стоит 10. Это значит что верхнее сопротивление 2 кОм?  

bwn
Offline
Зарегистрирован: 25.08.2014

ТС так и не ответил, пробовал ли он явное обнуление своей локальной переменной. В куске кода который он привел, это наиболее вероятная причина возникновения ошибки с течением времени. Мы не знаем, что происходит с его ОЗУ за время работы программы и возможность, что на очередном проходе t не будет равна 0, весьма высока.

nik182
Offline
Зарегистрирован: 04.05.2015

В полном коде есть t=0;

bwn
Offline
Зарегистрирован: 25.08.2014

Извиняюсь, не заметил.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

bwn пишет:

Извиняюсь, не заметил.

Это изменение я внес по рекомендации читателей форума уже позже, но проверить неуспел (на работе целый день).

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Весь день слежу за предложениями (ответить не мог, мобильный браузер не хотел логиниться на форуме).

Для себя зделал вывод, что ошибка скорее программная.

Буду пробовать следующее:

0. Разберусь с объявлением переменных в функции getTemp().

1. Обнуление t (уже внесено)

2. Введу задержку между подачей питания на терморезистор и снятием показаний.

Буду пробовать поочередно и всё вместе, посмотрю от чего эффект будет.

В железе смогу проверить только послезавтра (работа).

Всем спасибо за предложенные варианты.

bwn
Offline
Зарегистрирован: 25.08.2014

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

2. Введу задержку между подачей питания на терморезистор и снятием показаний.
...трата времени :)
это не какой-то MQxxx с подогревом рабочей зоны , ТР-у всё равно - под напряжением он или нет....

а выкладка сюда крайнего кода желательна :) , чтобы по постам не скакать....

Piskunov
Offline
Зарегистрирован: 13.02.2014

yul-i-an пишет:

Весь код

У Вас ошибка.

В функции double getTemp(float V) определяется параметр в цикле while (addr[i][1] >R)

и при некотром значении V значение параметра i будет равно 0.

Какое значение даст обращение к массиву addr[-1][0] или addr[-1][1] не скажет никто.