Библиотека для терморезистора
- Войдите на сайт для отправки комментариев
Пнд, 25/04/2016 - 09:07
В своих поделках часто использую терморезистор NTC 10kOm.
Есть код которым пользуюсь. Но для удобности хочу оформить его в библиотеку.
Код замера температуры.
float temp=0.0;//текущее значение температуры 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 loop(){ temp=getTemp(); } //------------------замер температуры---------------------- double getTemp() { T_Sensor_ON; delay(10);//задержка при подаче питания терморезистора int t; t=0; for (int i=0; i <= 15; i++){ t = t + analogRead(1); } t=t/4; float R; R=getR(t); 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-4096); //result=-10*V/(V-1024); T_Sensor_OFF; return result; }Подскажите с чего начать
/* TermoRes10k */ #ifndef TermoRes_h #define TermoRes_h #include "WProgram.h" class TermoRes { public: TermoRes(byte pin);//экземпляр класса double getTemp();//вычисление температуры private: float getR(float V);// byte _pin; }; #endifа температура правильно измеряется? второй резистор на 10к?
Подскажите с чего начать
С яндекса, вот например http://robocraft.ru/blog/arduino/102.html
только имейте в виду, что не все термисторы на 10к одинаковы
Подскажите с чего начать
С чтения вот этой инструкции.
А формула вместо таблиц не подойдёт?
http://playground.arduino.cc/ComponentLib/Thermistor2
А формула вместо таблиц не подойдёт?
http://playground.arduino.cc/ComponentLib/Thermistor2
если ресурсы не важны то можно и формулу. С таблицами можно все свести к целочисленным вычеслениям (я не про код автора), а это значит, что они преимущественно будут делаться за одну или несколько машинных команд. В отличии от плавающей точки которая реализуется сотнями команд
Я этот код уже применял, например тут. Разбирался с ним тут.
Всё устраивает.
Получилось следующее
Фаил TermoRes.h
/* TermoRes.h */ #ifndef TermoRes_h #define TermoRes_h //#include "WProgram.h" class TermoRes { public: TermoRes(int pin); double getTemp(); private: float getR(float V); int _pin; }; #endifФаил TermoRes.cpp
/* TermoRes.cpp */ #include "WProgram.h" #include "TermoRes.h" TermoRes::TermoRes(byte pin) { _pin = pin; } void TermoRes::getTemp(byte _pin) { int t; t=0; for (int i=0; i <= 15; i++){ t = t + analogRead(_pin); } t=t/4; float R; R=getR(t); 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; }При компиляции выдает
termostat_PI_proba:2: error: 'TermpRes' does not name a type
termostat_PI_proba.ino: In function 'void loop()':
termostat_PI_proba:63: error: 'termo' was not declared in this scope
Смотрю пример, походу cpp и h перепутал
папка с библиотекой должна называться так же как класс и после добавления библиотеки надо или перезапустить IDE или пересканировать библиотеки
Ну, конечно, будет ругаться, если в классе написано TermoRes, а в скетче TermpRes.
Что за addr в строке 24? Он нигде не описан. Если описан в другом файле, то это не считается.
Всё так, папка TermoRes в ней TermoRes.h и TermoRes.cpp. Всё подключилось. Нашел некоторые ошибки
/* TermoRes.cpp */ //#include "WProgram.h" #include "TermoRes.h" 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 } , }; TermoRes::TermoRes(int pin) { _pin = pin; } double TermoRes::getTemp(int _pin) { int t; t=0; for (int i=0; i <= 15; i++){ t = t + analogRead(_pin); } t=t/4; float R; R=getR(t); 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 TermoRes::getR(float V) { float result; result=-10*V/(V-4096); //result=-10*V/(V-1024); return result; }/* TermoRes.h */ #ifndef TermoRes_h #define TermoRes_h class TermoRes { public: TermoRes(int pin); double getTemp(int pin); //private: float getR(float V); int _pin; }; #endifСейчас выдает
G:\Documents and Settings\Андрей\Мои документы\Загрузки\arduino-1.0.4-windows\arduino-1.0.4\libraries\TermoRes\TermoRes.cpp: In member function 'double TermoRes::getTemp(int)':
G:\Documents and Settings\Андрей\Мои документы\Загрузки\arduino-1.0.4-windows\arduino-1.0.4\libraries\TermoRes\TermoRes.cpp:120: error: 'analogRead' was not declared in this scope
G:\Documents и Settings\Андрей\Мои документы\Загрузки\с Arduino-1.0.4-окна для Arduino-1.0.4\\библиотек\TermoRes\TermoRes.ЧГК:120: ошибка: 'analogRead' не был объявлен в этой области видимости
Пытаюсь внедрит в проект
Так напишите
#include <arduino.h>
вот и будет у Вас analogRead описан
cpp
/* TermoRes.cpp */ #include <arduino.h> #include "TermoRes.h" 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 } , }; TermoRes::TermoRes(int pin) { _pin = pin; } TermoRes::double getTemp(_pin) { int t; t=0; for (int i=0; i <= 15; i++){ t = t + analogRead(_pin); } t=t/4; float R; R=getR(t); 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; } TermoRes::float getR(float V) { float result; result=-10*V/(V-4096); //result=-10*V/(V-1024); return result; }h
/* TermoRes.h */ #ifndef TermoRes_h #define TermoRes_h class TermoRes { public: TermoRes(int pin); int _pin; double getTemp(int _pin); //private: float getR(float V); }; #endifВыдает
G:\Documents and Settings\Андрей\Мои документы\Загрузки\arduino-1.0.4-windows\arduino-1.0.4\libraries\TermoRes\TermoRes.cpp:115: error: expected unqualified-id before 'double'
ошибка: ожидается безусловный-ID и перед "двойным"
Вы каждую ошибку компиляции будете сюда выкладывать? Может иногда стоит и в ситаксис языка самому глянуть?
Всё собралось и работает. Благодарю за помощь! Отдельная благодарность Google и Яндекс переводчику )
h
/* TermoRes.h */ #ifndef TermoRes_h #define TermoRes_h class TermoRes { public: TermoRes(int pin); int _pin; double getTemp(); //private: static float getR(float V); }; #endifcpp
/* TermoRes.cpp */ #include <arduino.h> #include "TermoRes.h" static 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 } , }; TermoRes::TermoRes(int pin) { _pin = pin; } double TermoRes::getTemp() { int t; t=0; for (int i=0; i <= 15; i++){ t = t + analogRead(_pin); } t=t/4; float R; R=getR(t); 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 TermoRes::getR(float V) { float result; result=-10*V/(V-4096); //result=-10*V/(V-1024); return result; }Вы каждую ошибку компиляции будете сюда выкладывать? Может иногда стоит и в ситаксис языка самому глянуть?
Да это агония от безысходности и непонимания была)
Ну, ставьте через строчку Serial.println, печатайте свои переменные, смотрите на них, найдите в каком месте начались проблемы. локализуйте ошибку и исправьте её. Никто за Вас этого делать не будет.
Поторопился написать о неработоспособности. В железе проблеммы были. Всё устранил Всё работает.
Терморезистор такой NTC 3950 1% 10kOm
Схема включения
Ra-10кОм U0-5V
Библиотека TermoRes3950
Библиотека с примером
Вроде как можно просто по формуле считать, но у меня ни excel ни calc не воспринимают таблицу значений.
Может у кого получится если интересно. Надо по этим точка в excel построить график и вытащить формулу.
Источник https://radiomart.org/datchiki-temperatury/153-datchik-temperatury-termistor-ntc-mf52-103-3435.html
Апроксимация
Читал, просто excel не воспринимал те значения. сейчас получил это https://otvet.mail.ru/question/189916153, жду ответов))
Почему Вас таблица не устраивает?
Заменяете своими данными
/* TermoRes.cpp */ #include <arduino.h> #include "TermoRes.h" static float addr[Кол-во строк][2] = { { ...Сюда Ваши зависимости температура сопротивление } , }; TermoRes::TermoRes(int pin) { _pin = pin; } double TermoRes::getTemp() { int t; t=0; for (int i=0; i <= 15; i++){ t = t + analogRead(_pin); } t=t/4; float R; R=getR(t); 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 TermoRes::getR(float V) { float result; result=-(Сопротивление резистора в делителе)*V/(V-4096); return result; }Почему Вас таблица не устраивает?
Заменяете своими данными
А я формулу хочу)) причём простую))
Всё сделал)) Точность немного хромает, но в целом норм.
У = -25,6ln(Х) + 344,8. Х сопротивление термистора, У температура в градусах цельсия
Доработал библиотеку. Расширил диапазон в отрицательные температуры до -45С.
Библиотека
Пример
#include <TermoRes3950.h>//библиотека терморезистора TermoRes3950 termometr(0);//инициализация терморезистора на АЦП 0 float temp=0.0;//переменная для хранения температуры void setup(){ Serial.begin(9600); } void loop(){ temp=termometr.getTemp();//получаем температуру Serial.println(temp);//выводим температуру в монитор порта delay(1000);//задержка }Доброго времени суток!
Прошу простить великодушно, а как добавить второй термистор в скетч?
Вы каждую ошибку компиляции будете сюда выкладывать? Может иногда стоит и в ситаксис языка самому глянуть?
Да это агония от безысходности и непонимания была)
Не стоит с таким уровнем знаний языка библиотеки писать и в инет выкладывать. Потом в итоге выходит. что две трети либ для ардуино - быдлокод сплошной.
Доброго времени суток!
Прошу простить великодушно, а как добавить второй термистор в скетч?
#include <TermoRes3950.h>//библиотека терморезистора TermoRes3950 termo_0(0);//терморезистор первый на АЦП 0 TermoRes3950 termo_1(1);//терморезистор второй на АЦП 1 float temp0=0.0;//переменная для хранения температуры первого терморезистора float temp1=0.0;//переменная для хранения температуры второго терморезистора void setup(){ Serial.begin(9600); } void loop(){ temp0=termo_0.getTemp();//получаем температуру с первого temp1=termo_1.getTemp();//получаем температуру со второго Serial.println(temp0);//выводим температуру с первого терморезистора Serial.println(temp1);//выводим температуру со второго терморезистора delay(1000); }Вы каждую ошибку компиляции будете сюда выкладывать? Может иногда стоит и в ситаксис языка самому глянуть?
Да это агония от безысходности и непонимания была)
Не стоит с таким уровнем знаний языка библиотеки писать и в инет выкладывать. Потом в итоге выходит. что две трети либ для ардуино - быдлокод сплошной.
ТРОЛЬ.
А библиотека со своей задачей справляеться отлично. (Не уверен, Не пользуйся!)
Если можеш лучше предложить, то давай, я не против.
а чем плоха эта библилтека? все параметры можно выставить "thermistor.h"
а чем плоха эта библилтека? все параметры можно выставить "thermistor.h"
Не встречал. Ссылу скинте для ознакомления.
https://github.com/panStamp/thermistor
Если можеш лучше предложить, то давай, я не против.
Код сырой. Даже если отбросим корявый синтаксис - логика тоже хромает.
Файл TermoRes.cpp
1. В цикле for в строке 23 считывается и суммируется 16 значений сопротивления резистора. Для усреднения? - хорошо. Но почему тогда итоговая сумма в строке 26 делится на 4, а не на 16? Из-за этого в процедуру getR передается значение, вчетверо больше реального и там приходится применять странный квалификатор 4096 вместо стандартного 1024.
2. В той же формуле в процедуре getR - откуда знак "минус"? Все параметры положительные и результат - сопротивление - тоже положительное. А потому что накосячили и вместо (4096 -V) написали почему-то (V - 4096) Если написать правильно - не понадобиться минус перед формулой.
В общем, такое впечатление, что код откуда-то списан без понимания. И потом это выкладывается для сообщества.
Доброго времени суток!
Прошу простить великодушно, а как добавить второй термистор в скетч?
#include <TermoRes3950.h>//библиотека терморезистора TermoRes3950 termo_0(0);//терморезистор первый на АЦП 0 TermoRes3950 termo_1(1);//терморезистор второй на АЦП 1 float temp0=0.0;//переменная для хранения температуры первого терморезистора float temp1=0.0;//переменная для хранения температуры второго терморезистора void setup(){ Serial.begin(9600); } void loop(){ temp0=termo_0.getTemp();//получаем температуру с первого temp1=termo_1.getTemp();//получаем температуру со второго Serial.println(temp0);//выводим температуру с первого терморезистора Serial.println(temp1);//выводим температуру со второго терморезистора delay(1000); }пробовали? Работает? на каком МК?
на Уно и Нано работать не будет
пробовали? Работает? на каком МК?
на Уно и Нано работать не будет
У меня других и нет. На них работает и в Proteus`e работает. Проверь.
Код сырой. Даже если отбросим корявый синтаксис - логика тоже хромает.
Файл TermoRes.cpp
1. В цикле for в строке 23 считывается и суммируется 16 значений сопротивления резистора. Для усреднения? - хорошо. Но почему тогда итоговая сумма в строке 26 делится на 4, а не на 16? Из-за этого в процедуру getR передается значение, вчетверо больше реального и там приходится применять странный квалификатор 4096 вместо стандартного 1024.
Про оверсемплинг слышал чтонибудь?
2. В той же формуле в процедуре getR - откуда знак "минус"? Все параметры положительные и результат - сопротивление - тоже положительное. А потому что накосячили и вместо (4096 -V) написали почему-то (V - 4096) Если написать правильно - не понадобиться минус перед формулой.
В общем, такое впечатление, что код откуда-то списан без понимания.
Да формула не моя, слизал гдето, непомню уже.
Если тебя так коробит от этой библиотеки напиши свою.
Я ей пользуюсь и проблемм небыло еще.
вот здесь есть отличная страничка в которой можно задать параметры любого термистора включенного по одной из нескольких разных схем, задать точность и диапазон вычислений (влияет на размер кода во флэш) и на выходе получить готовый код для вставки в скетч
http://aterlux.ru/article/ntcresistor
более того в коде делается апроксимация по множеству (до 64) замеров что дает некоторое улучшение точности замера
на Уно и Нано работать не будет
У меня других и нет. На них работает и в Proteus`e работает. Проверь.
О том, что Serial сидит на тех же пинах 0 и 1 - не забыл?
Про оверсемплинг слышал чтонибудь?
Да-да. конечно, это оверсамплинг, и потому ты потом вынужден в формуле еще и на 4 делить:)
Да формула не моя, слизал гдето, непомню уже.
Весь этот код где-то слизан. И потом отлажен по методу "воткнем сюда t=0 и посмотрим, что выйдет". Нет ничего плохого, если ты его для себя написал. Но выкладывать для других, как библиотеку - не умея программировать и вообще не понимая, что в коде происходит - зачем?
О том, что Serial сидит на тех же пинах 0 и 1 - не забыл?
Ты че скоробленый такой?
Пины 0 и 1 АНАЛОГОВЫЕ имеется в виду.
double TermoRes3950::getTemp() { int t; t=0; for (int i=0; i <= 15; i++){ t = t + analogRead(_pin); } t=t/4; float R; R=getR(t); 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; }В строке 6 чтение с аналогового входа.
Пины 0 и 1 АНАЛОГОВЫЕ имеется в виду.
А программа об этом знает? :)
аналоговые пины обозначаются A0 и А1
Пины 0 и 1 АНАЛОГОВЫЕ имеется в виду.
А программа об этом знает? :)
аналоговые пины обозначаются A0 и А1
Я выше предлагал проверить работоспособность библиотеки, к чему не обоснованные притензии.
Буковка не обязательна.
yul-i-an, еще одно важное замечание.
Номинал второго резистора в делителе в формуле getR обозначьте именованой константой и задавайте его в заголовочном файле, снабдив подробными комментариями, чтобы облегчить жизнь тем, кто соберет вашу схему с другими номиналами.
А программа об этом знает? :)
аналоговые пины обозначаются A0 и А1
Знает. analogRead понимает, что ему дали именно аналоговые пины, а не какие-то другие.
Спасибо, что отозвались на мой призыв о помощи! Все работает.
Еще раз, благодарю!
Доброго времени суток!
Подскажите пожалуйста, как при выводе температуры с датчиков увидить целые значения? Сотые мне совсем без надобности :) десятые ещё куда ни шло, но только если округлять до 0,5 :)
Возможно ли выводить значения, округлённые до 0,5 градусов? Если нет, то как убрать знаки после запятой?
А как Вы их сейчас выводите?
Возможно ли выводить значения, округлённые до 0,5 градусов? Если нет, то как убрать знаки после запятой?
Нет ничего невозможного.
В Вашем случае:
- умножаете на 2,
- прибавляете 0.5,
- округляете до целых,
- делите на 2.
+0.5 и округление до целого. о.45+0.5=0.95=> 0 ; 0.55+0.5 =1.05 => 1 ;
А как Вы их сейчас выводите?
tft.setTextSize(3); tft.setTextColor(WHITE); tft.setCursor(1, 16); tft.print(" "); tft.setCursor(1, 16); tft.print(Temp);+0.5 и округление до целого. о.45+0.5=0.95=> 0 ; 0.55+0.5 =1.05 => 1 ;
Наверно это глупый вопрос :) но где это прописывать?
Я использую библиотеку из этой темы. Округление должно быть прописано в библиотеке или в скетче?
Возможно ли выводить значения, округлённые до 0,5 градусов? Если нет, то как убрать знаки после запятой?
Нет ничего невозможного.
В Вашем случае:
- умножаете на 2,
- прибавляете 0.5,
- округляете до целых,
- делите на 2.
А здесь я вообще ничего не понял :(