Как включить Vref в расчет температуры термистора?
Это код, который я использую для получения температуры:
#define COEFF_A 0.8662984364E-03
#define COEFF_B 2.780704551E-04
#define COEFF_C -0.9395108479E-07
float VRT, Temp;
float Vref = 2.52;
void setup() {
Serial.begin(9600);
analogReference(EXTERNAL);
}
void loop() {
long Resistance;
VRT = analogRead(A3);
Resistance = 10000 / ((1023.0 / VRT) - 1);
Temp = log(Resistance);
Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
Temp += -273.15;
Serial.println(Temp);
delay(500);
}
Я знаю, что вычисление должно быть следующим: V = Vref × VRT ÷ 1023
, но я не знаю, как внедрить его в этот код, буду признателен за любую помощь.
Обновить
После ответа Эдгара Боне отредактированный код:
#define COEFF_A 0.8662984364E-03
#define COEFF_B 2.780704551E-04
#define COEFF_C -0.9395108479E-07
float VRT, Temp, VR;
void setup() {
Serial.begin(9600);
analogReference(EXTERNAL);
}
void loop() {
long Resistance;
VRT = analogRead(A3);
VR = 2.52 * VRT / 1024;
Resistance = 10000 * VR / (2.52 - VR);
Temp = log(Resistance);
Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
Temp += -273.15;
Serial.println(Temp);
delay(500);
}
Но показания температуры на 2 градуса по Цельсию меньше, чем должны быть, когда я удаляю analogReference(EXTERNAL);
он показывает нормальные/правильные показания температуры.
@ElectronSurf, 👍0
2 ответа
Лучший ответ:
Формула для получения аналогового напряжения из показаний АЦП:
V = Vref × чтение ÷ 1024
(да, это 1024, а не 1023). Формула для определения сопротивления термистора от измеренного напряжения составляет:
R = Rref × V ÷ (Vref – V)
где Rref — подтягивающий резистор 10 кОм. Вы можете комбинировать эти две формулы для того, чтобы получить сопротивление непосредственно из АЦП чтение:
R = Rref × чтение ÷ (1024 – чтение)
Вы можете заметить, что при упрощении Vref отменяет. Это не ошибка. Показания, которые вы получаете с этой настройкой, действительно не зависит от вашего опорного напряжения.
Обновление 1: после редактирования OP у нас теперь есть совершенно другой вопрос. Теперь возникает вопрос: как получилось, что показания зависят от используется опорное напряжение, тогда как теоретически они не должны использоваться.
Скорее всего, ответ заключается в калибровке АЦП. Если высокая точность требование, правильная формула для измеренного напряжения:
V = Vref × (показание + Eвыкл.) ÷ (1024 + Eусиление)
где Eвыкл и Eусиление — ошибка смещения, а ошибка усиления соответственно. Эти ошибки не известны априори, и они обычно пренебрегают, когда требования к точности невелики. таблица данных только дает ограничения на то, насколько большими могут быть эти ошибки. фактические значения зависят от конкретного микроконтроллера и могут несколько зависит от опорного напряжения. Единственное решение, чтобы избавиться от этих ошибки заключается в калибровке собственного АЦП. См. ответ Arduino ADC для примера того, как это можно сделать.
Обновление 2: если бы мне пришлось программировать это в Arduino, я бы предпочел максимально упростить расчеты перед кодированием:
- не не вычислять измеренное аналоговое напряжение или сопротивление, т.к. они не нужны
- вместо этого вычислить отношение R/Rref непосредственно из аналогового чтение
- перепишите калибровочный полином как функцию log(R/Rref) вместо log(R) (что фактически означает log(R/(1 Ω)))
- оптимизировать вычисление полинома с помощью метод Хорнера.
Благодаря этим оптимизациям мы получаем:
// Коэффициенты полиномиальной аппроксимации log(R/Rref) -> 1/Т.
const float c0 = 3.3540165e-3;
const float c1 = 2.5416075e-4;
const float c2 = -2.5959644e-6;
const float c3 = -9.3951087e-8;
// Преобразование показаний АЦП в температуру в градусах. С.
static float temperature(int reading)
{
float R_ratio = reading / (1024.0 - reading); // = R / Rref
float x = log(R_ratio);
float inverse_T = c0 + x*(c1 + x*(c2 + x*c3));
return 1/inverse_T - 273.15;
}
void loop()
{
int reading = analogRead(A3);
Serial.println(temperature(reading));
deay(500);
}
Примечание. Я сформулировал этот ответ на ваш предыдущий удаленный вопрос.
Увеличивается или уменьшается напряжение при повышении температуры, зависит от вашей схемы: если вы используете ntc с R1 в качестве понижающего напряжения, напряжение будет увеличиваться при повышении температуры. Если R1 является подтягивающим, напряжение соответственно упадет.
Что касается вашего расчета: я настоятельно рекомендую вместо этого использовать справочную таблицу. Это сложные расчеты, и при разрешении ардуино вам подойдет LUT с примерно 64 записями. Существуют инструменты, которые генерируют LUT для данной настройки NTC (лично мне нравится этот инструмент ).
эээ, мне так плохо, что я удалил этот вопрос, пока ты отвечал на него! извини..., @ElectronSurf
код, который я разместил в своем вопросе, выполняет все расчеты, мне не нужно его повторять, мне просто нужно добавить Vref в расчет, и я не знаю, как это сделать... между прочим, это выпадающее меню., @ElectronSurf
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Что лучше использовать: #define или const int для констант?
- Функции со строковыми параметрами
- Как работать с аналоговыми контактами в цикле?
- Какие есть другие IDE для Arduino?
- Как использовать переменные и функции в нескольких файлах .ino
- Разница между void setup() и void setup(void)
- Будет ли .ino-скетч ардуино компилироваться непосредственно на GCC-AVR?
поэтому в этом примере должно быть так: «Сопротивление = 2,52 * ВРТ / (1024 - ВРТ);», правильно?, @ElectronSurf
Нет. Ваше эталонное сопротивление составляет 10 кОм, а не 2,52 Ом., @Edgar Bonet
но показания неверны, "Сопротивление = 10000 * ВРТ / (1024 - ВРТ);" я что-то пропустил? вроде на 2С меньше..., @ElectronSurf
Я не понимаю вашего последнего комментария. Пожалуйста, отредактируйте исходный вопрос, если чего-то не хватает., @Edgar Bonet
когда я использую предложенную вами формулу «Сопротивление = 10000 * ВРТ / (1024 - ВРТ); температура на 2 градуса по Цельсию меньше, чем должна быть., @ElectronSurf
если я не удалю
analogReference(EXTERNAL);
, это означает, что он не игнорирует «отмену» Vref!, @ElectronSurfОбновите свой вопрос., @Edgar Bonet
Отредактировал вопрос., @ElectronSurf
Статья, на которую вы ссылаетесь, - это кусок золота, спасибо., @ElectronSurf