Колебания показаний датчика температуры LM35 (+- 5°C) с Arduino UNO
Я пытаюсь прочитать датчик температуры LM35 с помощью Arduino UNO, который мне подарили. Дело в том, что мои показания датчика, по крайней мере, подозрительны - они прыгают с каждым показанием примерно на 5 °C вверх или вниз.
Я использовал несколько сообщений о том, как подключить устройство к плате Arduino и запрограммировать чтение (1, < a href="https://www.timdejong.nl/blog/get-accurate-temperature-lm35-arduino-correctly">2, 3) и создал код, размещенный ниже. Показания датчика действительно сильно колеблются - они подскакивают примерно на 3-7 °C после каждого показания независимо от частоты считывания (тестировалось с показаниями каждые 0,5 с, 1,0 с или 2,5 с). (К сожалению, у меня нет мультиметра для проверки фактических значений.) Чтобы смягчить проблему, я применил усреднитель, но основная проблема осталась. Ожидаемые значения составляют примерно 23 или 24 °C, измеренные цифровой метеостанцией и биметаллическим термометром соответственно.
Вы встречали это раньше? У вас есть идеи, что может быть источником этого? Я новичок в электронике, а также в Arduino, пытаюсь изучить и в основном понять это.
Полный код:
#include <WString.h>
// Сохраняет считанные аналоговые значения
int readLM35;
const int sensorAnalogPin = 0;
const float voltsToTemperature = 1.1 / 1023 * 100; // (питание 1,1 В / разрешение 10 бит) * (10 мВ/°C = 1 В / 100 °C)
//Сохраняет температуру в °C
float temp;
//Усреднение
float temps[8];
byte position = 0;
float averageTemp;
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
//Для установки внутреннего аналогового опорного напряжения на 1,1 В
analogReference(INTERNAL);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(50);
digitalWrite(LED_BUILTIN, LOW);
//Измерение температуры
readLM35 = analogRead(sensorAnalogPin);
temp = readLM35 * voltsToTemperature;
//Сохрани это
temps[position] = temp;
if (position == 7) {
position = 0;
} else {
position++;
}
//Получить среднее
averageTemp = 0;
for (byte i = 0; i < 8; i++) {
averageTemp += temps[i] / 8;
}
//Писать
Serial.println(String(readLM35) + " => " + String(temp, 1) + " deg. C, avg. " + String(averageTemp, 1));
delay(2500);
}
Пример вывода (обратите внимание на первые цифры - фактическое чтение):
211 => 22.7 deg. C, avg. 22.5
186 => 20.0 deg. C, avg. 21.9
234 => 25.2 deg. C, avg. 22.7
173 => 18.6 deg. C, avg. 21.9
237 => 25.5 deg. C, avg. 22.6
185 => 19.9 deg. C, avg. 21.9
231 => 24.8 deg. C, avg. 22.4
193 => 20.8 deg. C, avg. 22.2
223 => 24.0 deg. C, avg. 22.3
206 => 22.2 deg. C, avg. 22.6
197 => 21.2 deg. C, avg. 22.1
225 => 24.2 deg. C, avg. 22.8
183 => 19.7 deg. C, avg. 22.1
240 => 25.8 deg. C, avg. 22.8
@Rao, 👍7
Обсуждение7 ответов
Попробуйте :-
const int temperaturePin = A0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
double getVoltage(int pin)
{
return (analogRead(pin) * 0.004882814);
}
void loop() {
double degree,voltage;
degree = analogRead(temperaturePin)*0.48875855;
voltage = getVoltage(temperaturePin);
Serial.print(voltage);
Serial.print(degree);
delay(1000);
}
компьютеры начинают считать с "0" вместо "1"..., @dandavis
Я это прекрасно знаю, но почему вы один раз считаете с 1023, а другой раз с 1024? (Если бы мои предположения были верны.) Похоже, что вы когда-то использовали «последний элемент № 1023», а в другой раз «у нас есть 1024 элемента»., @Rao
Думаю, когда 0 = 0 и 5 В = 1023, тогда вам следует разделить на 1023. Глядя на вопрос, я замечаю, что вы используете AnalogPin = 0. Лично я бы придерживался AnalogPin = A0. A0 определяется как:
определить PIN_A0 (14)
поэтому он не эквивалентен 0. Вы уверены, что читаете правильный пин? Также попробуйте другой контакт, например A3.
Использование 0, A0 или 14 будет считывать данные с одного и того же аналогового контакта., @gre_gor
это известная проблема для всех датчиков Arduino (колебания и дрейф), у меня также была эта проблема с датчиком влажности и датчиком уровня воды с компаратором LM393, что я пытался сделать, чтобы уменьшить колебания, пытаясь вычислить средние показания вместо одиночного чтения:
for (int i = 0; i < 100; i++)
{
levelSensorValue = levelSensorValue + analogRead(levelSensorPin);
moistureSensorValue = moistureSensorValue + analogRead(moistureSensorPin);
}
levelSensorValue = levelSensorValue / 100;
moistureSensorValue = moistureSensorValue / 100;
вообще говоря, все датчики имеют линейный диапазон, за его пределами надежность быть не может, а также необходима их калибровка.
Почему вы сделали 1.1/1023. Вы говорите, что питание составляет 1,1 В, но вы снабжаете его 5 В. Я использую (readLM35/1024)*500, чтобы получить значение температуры в °C, и оно соответствует значению купленного мною термометра. Если это не сработает, попробуйте другой lm35. Возможно, у вас просто неисправный.
Кроме того, LM35 откалиброван на заводе по напряжению. Поэтому вам нужно откалибровать его в соответствии с используемой вами Arduino. Я бы порекомендовал ds18b20, так как он откалиброван по температуре. Использование библиотеки температур Далласа также упрощает использование
многие ответы, придерживайтесь кода или самого LM35, а не основной части, АЦП. когда вы читаете [примерно] правильную температуру, ну тогда код, vRef и конфиг пинов правильный. У меня были проблемы с АЦП, так как мне нужно было измерить много голосовых сигналов для моей диссертации. вот некоторые проблемы, которые могут возникнуть:
- Перепроверьте, есть ли на самой плате надлежащие развязывающие колпачки AVCC/AREF. многие платы-клоны не обращают внимания на производственные сбои. развязывающие колпачки обычно подключаются между землей (GND) и положительной линией питания (например, VCC) для фильтрации шума.
- Если у вас есть доступ к контакту AVCC/AREF, подключите 2 или 3 параллельных конденсатора 100nf между ними и землей. значения не критичны. все в диапазоне от 10 нФ до 10 мкФ в порядке. вы можете использовать разные значения для каждого предела.
- проверьте шум источника питания. Порт USB компьютера является наиболее надежным источником питания. другие блоки питания (сетевые адаптеры, дешевые блоки питания и т. д.) издают невообразимый шум.
- используйте колпачки (разъединяющие колпачки. колпачки, которые соединяются между контактами + и -) на каждом отдельном компоненте или датчике. например ЖК-дисплеи, сенсор LM35... .
- попробуйте использовать точный код и датчик на других аналоговых контактах и, если они у вас есть, на другом Arduino. если проблема сохраняется, вы можете проверить другой LM35 или код, как сказали другие. но если проблемы не было, то проблема в плате. это может быть вызвано любым неисправным компонентом в линии подачи. от регуляторов к неисправному соединению или плате.
Хотя я согласен с тем, что мощность USB-порта компьютера намного чище, чем у китайского блока питания, она _не_ самая чистая. Существуют различные модули DC-DC, которые обеспечат очень чистый выходной сигнал, и если вам нужна идеально плавная мощность, вам не победить химическую батарею. Я никогда не проектирую для них, но я использую их для устранения неполадок., @Peter Wone
Причина в том, что выходной сигнал LM35 имеет низкую способность опускания. Это делает выход чувствительным к электромагнитным помехам. Да, выходное выходное сопротивление указано как 0,5 Ом, но только для источника тока. Потребляемый ток ограничен 1 мкА, что легко достигается за счет шума окружающей среды.
Вам нужно добавить нагрузку с низким импедансом между выходом LM35 и землей, может быть 200 Ом, как рекомендовано в технических характеристиках для тяжелых емкостных нагрузок, но я бы не стал заходить так далеко, может быть 1 или 2 кОм, чтобы избежать ошибок самонагрева.
Ни одно программное решение не может устранить эту ошибку.
Если проблема с показаниями не устранена, установите RC-цепь для измерения напряжения, так как это похоже на усреднение, выполняемое в программном обеспечении. Еще одна вещь, которую вы можете попробовать, это заменить LM35 на новый, так как иногда он может быть неисправен или вы могли его повредить (это случилось со мной). Однако вы можете легко проверить это, измерив напряжение на чувствительном штифте, соответствует ли оно тому, что вы получаете. Если вы работаете с электроникой, купите мультиметр, так как он поможет вам во всех ваших проектах
- Неверные показания PT100 и MAX31865
- Отправка аналоговых входных данных из последовательного порта в Google Таблицы
- Датчик температуры не выдает правильных значений
- Погрешность измерения датчика температуры LMT 84
- Проблема с условием if
- L293D для изменения направления тока и усиления его - Стабилизатор температуры
- Сопряжение LM35 и MQ2 с Arduino
- Изменение выходного сигнала в зависимости от температуры LM35 с использованием Arduino и LINX LabVIEW
Я не вижу никаких развязывающих конденсаторов (обычно 100 нФ) на LM35. Ознакомьтесь с рекомендациями в таблице данных., @Transistor
+1 еще за то же самое. Очень хороший вопрос. Я бы дал еще +1 за код усреднения, если бы мог. Вы на правильном пути. Я всегда использую конденсаторы 0,1 мкФ на своих аналоговых входах. Не электролитический. Я избегаю керамики, но тантал и слюда в порядке. Это может быть больше по стоимости, но не сильно поможет. Немного поможет. Но, возможно, чуть больше, чем алюминиевая фольга и обертка Saran. ;-) (Кстати, @analogsystemsrf, вы напоминаете мне, как я делал нечто подобное с газетами на журнальном столике. Подача звука на первичную обмотку высоковольтного трансформатора, а затем вторичная обмотка на фольгу делает динамик), @SDsolar
@SDsolar ... можете ли вы объяснить, почему вы избегаете керамики (и неэлектролитической)?, @Michel Keijzers