Неверные показания аналогового термистора
Есть некоторые расхождения между тем, что считывается по аналоговому каналу для термистора, значениями в омах, полученными непосредственно на термисторе с помощью омметра, и другим цифровым датчиком температуры.
Рисунок 1: левый столбец (ось Y) — градусы Цельсия; ось х - время (минуты). Оранжевый — то, что считывал аналоговый канал (термистор); желтым цветом показаны коммерческие цифровые датчики; зеленым цветом показаны показания термистора с помощью омметра.
Подробнее о контексте: мы создаем простую систему для считывания температуры с термистора по аналоговому каналу. Алгоритм кода очень похож на тот, что можно найти здесь, а электронная схема основана на здесь. Когда мы столкнулись с проблемами, мы просто вернулись к основам работы, как указано в этих двух вышеупомянутых ссылках.
Падовый резистор составляет 7 кОм при +/-1%, измеренное сопротивление составило 6690 Ом. Термистор 2252 Ом при 25 градусах Цельсия. Коэффициенты следующие, коэффициенты были решены после калибровки в термальной ванне:
- COEFF_A = 0,0014644
- COEFF_B = 0,00023888
- COEFF_C = 9,8996E-08
Спецификации от поставщика приведены здесь (PDF), заводские коэффициенты примерно одинаковы. Я пытался рассчитать как с заводской, так и с внутренней калибровкой, и между ними есть разница в несколько тысячных долей градуса - этого недостаточно, чтобы объяснить текущую проблему
Во время исследования я увидел несколько скетчей с одинаковым сопротивлением резистора и термистора, но видел и другие, отличающиеся, поэтому предположил, что это не проблема.
Для устранения неполадок и выявления причин расхождений оранжевой линии и других показаний мы использовали
- другие термисторы (каждый из них ведет себя аналогично оранжевой линии на рисунке 1)
- другие цифровые датчики температуры (каждый из них ведет себя аналогично желтой линии на рисунке 1)
- мы пытаемся поставить 2 аналоговых термистора и 2 цифровых датчика температуры на одну и ту же ардуино - аналоговые были согласованы между собой (расхождения), а цифровой вел себя так, как ожидалось (правильно)
- мы переключили колодочный резистор, безрезультатно
- другие ардуины (ничего не менялось, каждая из них неоднократно демонстрировала одно и то же поведение)
- использовали систему в помещении с контролируемой температурой, и несоответствие по-прежнему присутствовало для аналогового канала и отсутствовало для цифрового датчика.
Для ясности, зеленый и желтый — это то, что мы считаем «настоящей» температурой; а оранжевый – это несоответствие. Разница примерно в 1–2 градуса
Мы использовали необработанное аналоговое значение, считанное Arduino, в качестве входных данных для ручной подачи и решения уравнения Стейнхарта-Харта (например, с помощью IPYTHON и вручную), и выходной результат такой же, как оранжевая линия. То же самое проделал с термистором, полученным омметром (Зеленые точки на рисунке).
Что следует исследовать дальше, чтобы устранить несоответствие между тем, что считывается аналоговым каналом, подключенным к термистору, и тем, что тот же термистор передает на омметр?
Набросок следует
#define THERMISTORPIN_0 0 // аналоговый контакт 0 на плате
#define SERIESRESISTOR_0 6990 // значение балансировочного/нагрузочного резистора (Ом)
#define THERMISTORNOMINAL 2252 // сопротивление при 25 градусах C
#define ZEROABS -273.15 // ноль Кельвина (Цельсия)
#define COEFF_A 1.4644E-03 // Коэффициент A для уравнения Стейнхарта-Харта.
#define COEFF_B 2.3888E-04 // Коэффициент B для уравнения Стейнхарта-Харта.
#define COEFF_C 9.8996E-08 // Коэффициент C для уравнения Стейнхарта-Харта.
void setup()
{
Serial.begin(9600);
}
void loop()
{
float temp1;
temp1 = Thermistor(analogRead(THERMISTORPIN_0),SERIESRESISTOR_0);
Serial.println(temp1);
}
float Thermistor(int RawADC, long padResistance) {
long Resistance;
float Temp;
Resistance = padResistance / ((1023.0 / RawADC) - 1);
Temp = log(Resistance);
Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp,3)));
Temp += ZEROABS;
return Temp;
}
@marsisalie, 👍2
Обсуждение3 ответа
Лучший ответ:
Еще не упомянутая возможность: проблема может быть калибровка вашего преобразователя АЦП. Ваш код несет неявный предположение, что измеряемое напряжение
V = Vref × RawADC ÷ 1023
Правильная формула
V = Vref × (RawADC + offset) ÷ scale
где offset
в идеале равен 0, а scale
в идеале равен 1024 (а не 1023,
как вы предполагаете). Поскольку вы смотрите на относительно небольшие
расхождений, предположение об «идеальном АЦП» может быть недостаточно хорошим. Я
откалибровали 3 АЦП Arduino и обнаружили смещения между 2,2 и
2.4 и коэффициенты масштабирования от 1026,1 до 1026,3. Таким образом, если у вас есть
проблемы с точностью, я рекомендую вам откалибровать собственный АЦП.
Кроме того, вы могли бы ожидать большей точности, если бы термистор и резистор ближе по сопротивлению. Прямо сейчас у вас есть фактор 3, что не так уж плохо, но вы могли бы использовать 2,2 кОм резистор, что является очень стандартным значением.
Мне удалось найти функцию для расчета смещения, поскольку существует приемлемое соотношение между измеренным и ожидаемым, какие бы термисторы, платы Arduino, кабели/провода или макеты мы не использовали. Ваши предложения по диапазону смещения помогли откалибровать наши кривые., @marsisalie
Пока я не вижу ничего плохого.
Все дело в точности и точности. Вот как справиться с этой проблемой. Это не быстрое решение.
Например, значение резистора было: 10k, 7k, 6690 и 6990. Это слишком небрежно.
Я думаю, что вы не сказали нам, что термистор находится на GND (я предпочитаю, чтобы он был на GND, это хорошо).
Тест: при 25 °C термистор и резистор дают значение АЦП, равное 249,5, и при этом на скетче результат равен 25 °C. Очень хорошо. При температуре около 25 °C скетч точен.
Вместо коротких минималистичных расчетов можно было рассчитать все. Например, сопротивление термистора и напряжение на аналоговом выводе. Это упростит проверку этих значений с помощью мультиметра.
Я предпочитаю, чтобы расчеты выполнял Arduino, а не пытался умничать и что-то оптимизировать. Пусть компилятор занимается оптимизацией.
Мы должны заглянуть дальше, чем термистор, Arduino и скетч.
- Какой длины длинный провод? Что за кабель? Экранированный кабель? Один провод подключен к GND? а в конце только термистор? GND не используется для чего-то еще? Соприкасаются ли провода термистора или кабеля с металлическим предметом или водой? Мультиметр ни к чему не подключен, но Arduino подключен через usb к компьютеру и, возможно, к заземлению. С блоком питания имеется небольшая емкостная связь с сетью. Что произойдет, если Arduino питается от батареи и ни к чему не подключен?
- Насколько хорошо провод подключен к Arduino. Попробуйте припаять, если есть возможность. Если он уже припаян, то был ли это хороший сварной шов?
- Что еще происходит с платой Arduino? Это может быть смещение GND, вызванное чем-то, что пропускает ток через GND. Это может быть вызвано ЖК-дисплеем с неправильным подключением фоновой подсветки. Подключен ли термистор через макетную плату, и на этой макетной плате есть что-то еще? Тогда у вас почти наверняка есть смещение постоянного тока.
- Не могли бы вы попробовать другую плату Arduino и другой компьютер? Только плата Arduino, термистор + резистор и кабель USB к компьютеру. Без длинных проводов. Попробуйте настольный компьютер, а не ноутбук (USB 5V ноутбука может быть менее надежным). Теперь вы попали в какую-то ловушку, и вы выбираетесь, делая вторую тестовую установку с новым набором компонентов и даже не используя ни одного провода из первой установки.
- NTC может охлаждаться через металлические ножки.
- Возможно, поможет усреднение нескольких выборок. Когда окончательный расчет среднего выполняется с плавающей запятой, вы можете даже увеличить разрешение АЦП более чем на 10 бит.
На данный момент я думаю, что проблема между термистором и микроконтроллером на плате Arduino. Не могли бы вы попытаться устранить любое смещение постоянного тока GND и обязательно изолировать термистор (от металлических предметов и воды)
Кажется, есть две проблемы:
1) калибровка: цифровой датчик/аналоговый датчик могут быть откалиброваны неправильно — это может объяснить разрыв между двумя кривыми.
2) время отклика: кажется, что цифровой датчик реагирует намного быстрее, чем аналоговый датчик. это может быть связано с размещением, физическими свойствами (например, меньшей тепловой массой), ...
- Использование аналогового входа для чтения кнопки
- Как работать с аналоговыми контактами в цикле?
- Двоичный в десятичный с использованием побитовых операторов
- Отправка аналоговых входных данных из последовательного порта в Google Таблицы
- Декодирование порта VGA с помощью Arduino
- Что касается обхода PGA в ADS1262
- Использование оператора case с приемником ИК-излучателя
- Помогите совместить цифровой и аналоговый код в программировании ардуино
попробуйте построить график VREF на том же временном интервале, что и при считывании с помощью цифрового мультиметра, вы видите искажение?, @dandavis
@dandavis Хорошо, я попробую это, спасибо за предложение, опубликую обновление, когда закончу, @marsisalie
Каково точное значение резистора 7k? Знаете ли вы тип резистора, чтобы иметь возможность найти значения A, B, C и β в таблице данных. Этот онлайн-расчет может быть полезен: http://www.thinksrs.com/downloads/programs/Therm%20Calc/NTCCalibrator/NTCcalculator.htm Пожалуйста, покажите свой эскиз., @Jot
@Jot да, у меня есть точные значения для этого, я обновлю свой пост соответствующей информацией. Этот сайт потрясающий, не так ли (думает). Схему тоже проверю, @marsisalie
1. В ваших расчетах предполагается, что VREF составляет 5 В, или вы знаете *реальное* опорное напряжение (VCC по умолчанию)? 2. Ваш термистор находится на конце длинного провода?, @Majenko
@Majenko (1) Предполагая 5 В, измерено 4,91; но в моем скетче (работающем над ним) я, похоже, вообще не ссылаюсь на VREF, например, на скетчи-примеры - может быть, мне следует проверить это более подробно; (2) Хорошо, да, термистор находится на конце длинного провода. Но все же, если я измеряю с помощью омметра непосредственно на кабеле (рис. 1, результат зеленый), термистор все еще находится на конце того же длинного провода, как и при чтении Arduino (рис. 1 оранжевым), @marsisalie
Вы должны где-то ссылаться на VREF, чтобы рассчитать сопротивление. В конце концов, сопротивление измеряется падением напряжения на нем, и чтобы преобразовать необработанное значение АЦП 0-1023 в напряжение, вам нужно вычислить его относительно VREF. Если вы используете неправильное значение, вы получите неправильный результат. 5В это не 4.91В., @Majenko
@Majenko спасибо за подтверждение этого возможного пути решения; Я подозревал это какое-то время, но, поскольку это не было определено в примерах, я попытался найти другие проблемы, которые я думаю. Это было рассмотрено в примерах, потому что расчет отменяется; например значение АЦП = R / (R + 10K) * Vcc * 1023 / Vcc становиться Значение АЦП = R / (R + 10K) * 1023, @marsisalie
Верно, то есть... Не забывайте, что 10К должно быть 6690, конечно..., @Majenko
@Majenko, если вы хотите резюмировать свое выступление как ответ, я бы выбрал ваш ответ, чтобы закрыть вопрос., @marsisalie
@Majenko, для термистора плюс резистор VCC выпадает из расчета. Это относительно VCC. В расчете можно использовать 5.0, а фактическое напряжение может отличаться, оно может быть 4.0 или 5.5В, это не имеет значения. В этом прелесть термистора. Однако малейшее отклонение в расчете и кривая изменится. Этьен Годен, где эскиз? (это 1024 шага АЦП, а не 1023)., @Jot
Добавлен @Jot Sketch, @marsisalie
@Majenko - комментарии под вопросами предназначены для уточнения вопроса. Если вы считаете, что у вас есть ответ, предпочтительнее опубликовать его, чтобы его можно было принять и/или прокомментировать., @Nick Gammon
@NickGammon на данный момент это чистое предположение. Похоже, что пока это не правильный ответ, поэтому он не заслуживает быть ответом., @Majenko
@Majenko - ОП попросил вас опубликовать ваше * предположение * в качестве ответа. Это не может быть намного яснее, чем это. :), @Nick Gammon
@NickGammon даже после того, как он опроверг (правильно) мое предположение. То, что касается VCC, неверно и не может быть ответом. Упоминание неправильного номинала резистора в расчете я воспринимаю как копию и вставку из первоисточника, а не его измененного источника. Без разъяснения того, действительно ли это неверно в его коде, у меня нет действительного ответа для публикации., @Majenko
@NickGammon Глядя на отредактированный вопрос с включенным кодом, становится ясно, что резистор тоже не проблема, поэтому в моих комментариях нет ничего, что можно было бы преобразовать в правильный ответ, и я не буду публиковать ответ, который я знаю быть откровенно неверным., @Majenko
Глядя на диаграмму, на которую вы ссылаетесь, вы подключаете AREF к 3,3 В, но в вашем коде нет
analogReference(EXTERNAL)
. https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/ говорит не делать этого, поскольку он замыкает внешние и внутренние ссылки вместе во времяanalogueRead()
. Может быть, это может быть причиной некоторых странных переходных процессов во время переключения АЦП?, @Dave X