Проблема в том что на Вики была статья об этом, но там использовалась библиотека math к ней и логорифм. Но так как я в 6 классе понять что значит логорифм я не смог. Так вот я написал о своей идее в "сделаю проект", но там мне толком и не сказали в чем ошибка. Вот моя идея(код прилагается). В первых нахожу Vout, затем по нему по формуле нахожу R (R2 у меня 220 Ом), а потом просто при помощи пропорции вычисляю температуру, исходя из того что 10 кОм=25 градусам С. Я могу быть и не прав)) (Код пока без пропорции) Вот чуть чуть исправоленный код Код (Text): #define SENSOR_PIN A5 #define V 5.0 void setup() { Serial.begin(9600); } void loop() { float val = analogRead(SENSOR_PIN); float y = val * V / 1023.0; //y-Vout delay(1000); Serial.println(val); Serial.print("Sensor:"); float x = y / (V - y); //x - R Serial.println(x); Serial.print("R:"); Serial.println(y); Serial.print("Volt Out:"); delay(1000); } Это уже чисто мой код: Код (Text): #define SENSOR_PIN A5 void setup() { Serial.begin(9600); } void loop() { int val = analogRead(SENSOR_PIN); int y = map(val, 0, 1023, 0, 5); delay(1000); Serial.println(val); Serial.print("Sensor:"); int x = -1100/(y-5); Serial.println(x); Serial.print("R:"); Serial.println(y); Serial.print("Volt:"); delay(1000); Serial.flush(); }
Потому что зависимость не линейная, а логарифмическая. Что такое степень числа представляете? Логарифм это, грубо говоря, обратное от степени. То есть линия X-Y не прямая, а изогнутая, каждый следующий миливольт дает прибавку намного больше чем предыдущий. В общем, надо просто позаимствовать формулу, если нет времени изучать математику прямо сейчас.
Ты абсолютно прав! И, по большому счёту, все быстрые программы работающие на основании формул с sin(), cos(), lg(), ln() и прочей чертовщиной так и пишут. Ты просто не сделал еще один маленький шаг в правильно выбранном направлении. Нужно выбрать границы в которых будет работать твой градусник, и определиться с точностью которая тебя устроит. Что за логарифм, какой такой Эйлер - это пусть математики лоб мнут. Нам программистам это не нать. Решение крайне простое, ты не дошёл до него пол-шага. Допустим, что градусник квартирный (16-30˚С), что точность в 1 градус Цельсия нас вполне устраивает. Что нам дают такие ограничения? Они дают нам решение. Готов его изложить?
Проблема в том что у меня и этот код толком не работает я не могу найти Vout, а от него и сопротивление, а значит и температуру
int y = map(val, 0, 1023, 0, 5); "у" будет в результате целое число от 0 до 5, соотв дальнейшие вычисления бессмыслены. Я предлагаю тебе отвязаться от сопротивлений, логарифмов и т.д. У тебя есть некий датчик, который чегойто выдаёт, и есть ардуина, которая в данном случае меряет напряжение от 0 до 5 вольт. Хотя, строго говоря, там будет некий кусочек этого диапазона зависящий от сопротивления терморезистора при минимальной и максимальной температуре. Ну да ладно. Еслиб я был шестиклашкой с ардуиной, я бы поступил так. Сначала я написалбы примерно такую программу setup(){ Serial.begin(9600); } loop(){ int sensor=analogRead(A0); Serial.println( sensor); delay(1000); } Потом, утащил бы у родителей градусник, примотал к нему изолентой датчик, и затолкал бы это хозяйство в морозилку, минут на 10. Потом достал, и пока градусник с датчиком будут согреваться, заполнял табличку, какой температуре на градуснике какя цифирь с ардуины соответствует. В результате получилось бы такое 10˚ = 100 11˚ = 115 12˚ =148 .... 25˚ = 450 Теперь мы свели задачу к тому, что ты умеешь. Если память меня не подводит, это называется кусочно линейная интерполяция. Или как то еще более заумно. Теперь для каждого отрезка данных ардуины ( 100-115, 115-148 ...), ты можешь посчитать коэффициэнт наклона отрезка интерполяции. Это в смысле "k" для формулы: "температура"=k*"показания_ардуины" А программа градусника у тебя примет вид: const float k100_115="сам посчитай"; const float k115_148="сам посчитай"; .... loop(){ int sens=analogRead(A0); if( sens<100) Serial.println( "too cold"); else if( sens<=115) Serial.println( sens*k100_115 ); else if( sens<=148) Serial.println( sens*k115_148 ); ...... else Serial.println( "too hot" ); delay(1000); } И никаких бананов логарифмов. Дополнительный плюс - эта программа будет в разы быстрее работать, в ней нет ни логарифмов ни деления. Табличку эту, можно составить как мы сейчас - воруя градусник. А а по взрослому если, то её считают через ln(), но один раз в начале программы. Если позволяет память железа, то считают для каждого значения analogRead(). Тогда loop() сведется всего к трём строкам float analogRead_to_celsius[1024]={ t0, t1, ..., t1023 }; loop(){ int sens=analogRead( A0 ); Seral.println( analogRead_to_celsius[ sens ] ); delay(1000); } loop
Выражаю сомнение, что будет работать более-менее точно. Разве что в совсем небольшом диапазоне - в несколько градусов плюс минус. Опять же смотря какая стоит задача, если отслеживать несколько четко заданных температур, то вполне можно сделать это вручную заданием эмпирически полученных параметров. Например, при определенном значении включить вентилятор, про другом выключить. Если же нужен именно электронный градусник, то не получится.
Кусочно-линейная аппроксимация (то есть УСРЕДНЕНИЕ). Чтобы это работало нужно чтобы интервалы были или очень малы или различны. Даже в приведенном примере: коэффициенты получаются: 10; 10,46; 12;... 18 соответственно. Не слабо так на 15 градусов в два раза. Получается что интервалы в таблице должны быть порядка 1-2 градусов. Ну хорошо. Допустим что мы меряем от +15 до +30. Таблица в 7-15 значений. Терпимо. Но нужно всегда помнить что жарким летом, без кондея градусник начинает врать безбожно. Или вообще прекращает работу. Сам метод определения коэффициентов. Предложенный метод дает погрешность порядка 3х (это в лучшем случае) градусов. По такому методу не построить таблицу с шагом 1-2 градуса. Это будет устройство уровень точности которого можно можно охарактеризовать как "холодно - тепло - горячо". Если такая точность устраивает, то и таблица не нужна. Просто определяем два порога: холодно-тело и тепло-горячо. И всё. Считываем датчик и определяем к какому из трех интервалов относится значение.
Перепалки не будет. Я вижу вы специалист. Так ради интереса, по данным моей таблички, если analogRead() вернет 107, какая температура будет? А если 133, а если 140? Наверное вы просто не разобрались с тем что я описал.
Проблема в том, формулы лежащие на вики сама вики объяснить толком не может, и как тогда таким шестиклассникам как я разбираться во всем. А идея с градусником не получится у нас в доме только электронные градусники а они меньше 30 градусов пишу букву L (low)
Зачем разбираться во ВСЕМ? Есть формула - используйте. А если нужны значения горячо-холодно, то задайте их в программе жестко, как это выше рекомендовали. Это уменьшит код и сделает его проще. Задача то какая? Или это секрет?
Да я просто заинтересовался этим, затем хотел код написать на processing и в строить в систему умного дома
Уверяю, никто бы не заморачивался с логарифмами, будь зависимость линейной. Ну не получается, например, разделить сопротивление на 20 и получить температуру. Поэтому или хитрая формула или готовые аппаратные решения.
Конечно, про Эйлера и математиков писать не стоило, но парень прав, в реальных проектах math.h не используют, даже при программировании 32х битных контроллеров, не используют и деление, умножение, все выполняется побитовыми операциями. В реальных ситуациях и составляются массивы данных, из которых можно судить о зависимости. Задачи разбираться во всем парень не ставил, а хотел разобраться, потому что особого ума не надо, чтобы воткнуть провода, как это показано на вики и скопировать код с чудо-функцией, и все заработает, и все будут радоваться, но попадется другой датчик температуры с даташитом на английском и собрать проект уже не получится. Можно было бы сказать "зачем разбираться во ВСЕМ?", если бы он хотел разобраться с полупроводниковыми материалами, pn-переходами, барьерной емкостью, .... . Но здесь просили разъяснить минимальные сведения о компоненте, чтобы получить навык работы с подобными датчиками. Доступно объяснить у меня вряд ли получится, но постараюсь. В хобби, которым мы все занимаемся, огромную роль играют полупроводниковые материалы(диоды, транзисторы, светодиоды, сами микроконтроллеры и т.д.). Измерение температуры возможно в силу зависимости сопротивления компонента от температуры. Например, для обычного резистора зависимость сопротивления от температуры линейная, то есть как раз то, о чем Вы говорили, можно пользоваться пропорцией. Я попытался изобразить график зависимости сопротивления проводника от температуры(теоретический), для удобства коэффициент пропорциональности альфа выбран 1 Ом/градус Цельсия. Теперь попытаемся разобраться с формулой из Вики. Зависимость температуры полупроводника от его сопротивления логарифмическая. Если хочется разобраться с логарифмом, экспонентой, то у меня есть для Вас отличная книга, будучи школьником восхищался, разъясняется на пальцах. http://www.mccme.ru/free-books/shen/shen-log.pdf Теперь попытаемся построить график этой чудо-формулы из Вики. Что за число 273? Существуют разные температурные шкалы. Мы часто пользуемся шкалой Цельсия, так как при 0 градусов тает лед, а при 100 градусах кипит вода - удобно. В науке используют шкалу Кельвина - шкала, по которой не бывает отрицательных температур. Чтобы получить температуру по шкале Кельвина, необходимо к температуре по Цельсию прибавить число 273.15, так как в данном проекте такие точности не требуются, 273.15 округляют до 273. Что означает число TERMIST_B? это экспериментально найденный для данного датчика коэффициент, который авторы кода взяли из даташита на данный компонент(http://files.amperka.ru/datasheets/B57164.pdf). Теперь посмотрим на график зависимости температуры от вычисляемого r1 ( float voltage = analogRead(A1) * VIN / 1024.0; float r1 = voltage / (VIN - voltage); float temperature = 1./( 1./(TERMIST_B)*log(r1)+1./(25. + 273.) ) - 273; ) Из графика видно, что при 25 градусах(число, которое присутствует в формуле) r1=1, но что значит, что r1=1? Для этого обратимся к схеме подключения датчика и формуле расчета r1. Если r1=1, то voltage / (VIN - voltage), следовательно, voltage = VIN/2, то есть на нашем датчике и резисторе 10кОм падает одинаковое напряжение, значит их сопротивления равны! По сути r1 является реальным сопротивлением полупроводникового сенсора, деленным на 10кОм. Кстати, если почитать даташит, то там пишут, что 25 градусов - температура его градуировки. при ней его сопротивление равно 10кОм(кстати это число на нем написано ) Удачи в проектах и всегда пытайтесь понять код, который компилируете, конечно, здорово, когда, купив новый совершенно неизвестный датчик, ты скачиваешь библиотеку, и все сразу работает, но попадись что-то другое или реальные контроллеры, а не Arduino-платы, ничего не получится. Успехов! P.S. обращайтесь с вопросами. Уверен, что сделал много косяков в объяснении. Для графиков использовался Matlab.