Обычно, мы получаем сенсор в корпусе TO-92 (не перепутайте с транзистором):
На фото - популярный датчик TMP36 от Analog Devices. Как видите, выводов три, и если смотреть в положении "надписью к нам, ножками вниз", то получается (слева направо): питание (Vs), выход (Vout), земля (GND). Главная особенность таких датчиков - значение напряжения на выходе однозначно определяет температуру, независимо от напряжения питания (!). Последнее может варьироваться от 2,7 до 5,5 Вольт.
Это очень удобно, и позволяет нам выполнить проверку датчика вне схемы, если под рукой есть элемент питания 3В, хотя бы даже и батарейка CR2032. В активном состоянии датчик потребляет не более 50 мкА, для проверки в течение двух-трех минут вполне хватает. Собираем схему:
Теперь, подключая мультиметр к выходу датчика (разумеется, в режиме измерения напряжения), мы будем наблюдать напряжение около 0,78 В, что соответствует 28 °С.
Чтобы убедиться в работоспособности датчика, его надо слегка нагреть, отлично подойдут:
- пальцы рук (температура вашего тела - 36,6 °С)
- дующий горячим возухом фен (можно довести и до 50 °C)
- кошка (температура 38-39 °C)
Показания мультиметра должны расти при нагревании и уменьшаться при охлаждении.
Конечно, даже простого пальца будет достаточно, чтобы увидеть результат:
Теперь подключим датчик к Arduino. Пусть выход будет подключаться к analog0, а питание - к стабилизированному питанию +5В Arduinio:
Для чтения придется использовать АЦП, а ему, как известно, требуется опорное напряжение, надо выбрать один из трех вариантов: питание, внешнее на AREF или внутреннее.
Напряжение на выходе датчика TMP36 меняется от 100 мВ до 2В, так что использовать внутренний источник опорного напряжения 1,1В не получится. Хотя, такое значение у источника МК ATmega168/328, а вот в ATmega8 это будет уже 2,56 В. Гораздо проще ориентироваться на стабилизированные +5 В, которые поступают от USB.
Чтобы правильно перевести показания датчика в температуру, надо сначала понять, какое напряжение мы прочитали. АЦП возвращает число от 0 до 1023, при этом 0 = 0В, 1023 = 5В для нашего случая. Поэтому:
voltage = 5 В / 1024 * sensor
Заглянем в документацию на датчик: там оговаривается, что изменение на один градус цельсия соответствует изменению на 10 мВ, при этом 500 мВ будет соответствовать температуре 0°C. Получаем формулу:
tempC = (voltage - 0.5) * 100
void setup() {
Serial.begin(38400);
}
void loop() {
float voltage = 5.0 / 1024.0 * analogRead(0);
Serial.print(voltage);
Serial.println(" B");
float tempC = ( voltage - 0.5 ) * 100;
Serial.print(tempC);
Serial.println(" C");
delay(1000);
}
Одно маленькое замечание к тексту скетча: значение опорного напряжения надо писать именно "5.0", чтобы компилятор случаем не решил разделить 5 на 1024 целочисленным делением и не получил пожизненный ноль в итоге.
Вернемся к вопросу о точности. Наш АЦП имеет шаг измерения 4,9 мВ, в то время как сам датчик имеет погрешность ±1°C, или ±10 мВ. Таким образом, даже если мы понизим опорное напряжение, например, до 3,3 В и получив таким образом шаг преобразования 3,3 / 1024 = 3,2 мВ, это повышение точности не спасет нас от ошибки самого сенсора. С другой стороны, напряжение питания +5 В тоже может запросто "гулять" ±5%, но в итоге это порождает ту же самую ошибку ±10 мВ. Таким образом, как ни крути, для данной схемы погрешность измерения будет не менее ±2°C. Из этого следует, кстати, забавный метрологический вывод: дробную часть можно отбрасывать ;)
вот здорово,красота!! :)
ОтветитьУдалитьвозможно будет интересно-датчик давления за пять рублей:одноразовый шприц,таблетка активированного угля,пружинка и два провода.
да, забавная, наверное, конструкция.
ОтветитьУдалитьнельзя ли немного поподробнее? ;)
с двух сторон сторон таблетки проводники(у меня кружки из фольгированного тестолита с припаянными проводами,между ними таблетка),выводятся в носик шприца,сверху пружинка,чтоб поршень возвращать,еще выше поршень шприца,давилка обрезана,давление сверху поршня,всё.таблетка изменяет сопротивление,при 0.8 кг/квсм китайский мультиметр показывает 74,0 ом при 1кг/квсм 72.7 ом в этих пределах,при моем поршне и таблетке почти прямая,я его планирую как отключатель,точность приемлема.беда только-при включении насоса цифры вылезают дикие,а потом вообще зависает,помехи наверно.пальцем давишь-всё в порядке,и прибор китайский исправно показывает.
ОтветитьУдалитьА, теперь понятно, спасибо ;)
ОтветитьУдалитьА кто зависает-то? Какое-то устройство на МК?
выдает какую нибудь цифру левую и перестает реагировать на все изменения,я тогда нажимал кнопку "загрузить скетч" со стрелочкой такая.так вроде,давно не трогал я его
ОтветитьУдалитьПосле нажатия на кнопку загрузки обычно происходит сброс, если речь про Arduino, и если Arduino с автосбросом, конечно.
ОтветитьУдалитьЧтобы понять, почему зависает, надо смотреть скетч, а затем схему...
а,разберусь.вдохновение вот найдет только :)
ОтветитьУдалитьСкажите пожалуйста,а почему у меня не отражаются десятые доли,скопировал-вставил ваш пример,проверить-не работает :(
ОтветитьУдалитьесли написать так:
void setup() {
Serial.begin(38400);
}
void loop() {
float voltage = 5.0 / 1024.0;
Serial.print(voltage);
delay(1000);
}
,то скетч не грузится,пишет ошибку(на скриншоте видно),а если так:
void setup() {
Serial.begin(38400);
}
void loop() {
float voltage = 5.0 / 1024.0;
Serial.print(voltage ,DEC);
delay(1000);
}
то получается ноль
http://s52.radikal.ru/i136/0908/04/17bbddcf2b64.jpg
Это где же вы такой древний раритет откопали?!
ОтветитьУдалитьВозьмите последнюю ArduinoIDE, тот же 0017 - всё должно заработать.
В последнем случае пишется 0 из-за неявного приведения типов, видимо результат меньше нуля, после приведения к целому дробная часть отбрасывается. Остается ровно ноль ;)
почему то всё равно не выходит :(
ОтветитьУдалитьhttp://i038.radikal.ru/0908/ef/ba951517efe0.png
а с реальным датчиком всё работает!спасибо,никогда бы не подумал,что дело может быть в софте
ОтветитьУдалитьВы хотите распечатать 0,0048828125? Видимо, Serial.print() для типа float предлагает только две цифры после запятой, отсюда и 0,00.
ОтветитьУдалитьЗдравствуте!
ОтветитьУдалитьИнтересная статья!Я сам новичёк и ещё толком не разобрался с программированием Arduin,пока что получается играться со светодиодами и мерить температуру.У меня такой вот вопрос.Можно ли Arduino Duemilanove настроить так ,что при показании температурного датчика(LM 35)скажем +35 С электромагнит получит свои 9v , ну а если электричество и вовсе отключенно то питание берётся с батарейки "кроны" 9v ??
Ничего не понял :( Надо электромагнитом управлять, что ли?
ОтветитьУдалитьУстройство такое.Есть аналоговый температурный датчик LM-35,трансформатор на 9v,Arduino Duemilanove,электромагнитный замок потребляющий 8-12v и батарейка на 9v.Задача в том чтоб электромагнитный замок открыл дверцу если температура в комнате превысила +35 С ну и автономное питание-это на случай сбоев в электрической сети чтоб автоматом на батарейку перешёл.Понятно что электромагниту нужно всего 2 секунды задержки чтоб наверняка окрыть дверь.
ОтветитьУдалитьВозможно ли всё это сделать при помощи Arduino Duemilanove без реле и прочей конителей?
Спасибо!
Возможно, если исполнительный механизм замка будет совместим с сигналами TTL. А без этого, увы, "конителей" не избежать...
ОтветитьУдалитьСовместим.Что мне в скетче написать чтоб при температуре +35С Arduino послал сигнал на эл.замок ? Спасибо.
ОтветитьУдалитьif (temperature >= 35) digitalWrite(controlPin, HIGH);
ОтветитьУдалитьЕстественно, температуру надо сначала вычислить (по шкале Цельсия) и поместить в переменную temperature.К пину controlPin, сконфигурированному как выход, подключен исполнительный вход реле.
Где-то так.
спасибочки!Будем пробовать.
ОтветитьУдалитьКаким образом можно сделать весь процесс в скетче одноразовым?То есть для повторного запуска нужно нажать на кнопку reset.Спасибо.
ОтветитьУдалитьПоместите весь код внутри setup. А loop оставьте пустым.
ОтветитьУдалитьа как же вычисление температуры?
ОтветитьУдалитьvoid loop()
{
double val = analogRead(tempPin);
Serial.print(" Analog 0: ");
Serial.print(int(val));
double voltage = val * 5.0/1024;
double temp = voltage * 100;
Serial.print(" Temperature: ");
Serial.println(temp);
delay(1000);
{
Поместите его в setup - и оно будет именно "одноразовым", исполняться только по reset.
ОтветитьУдалитьа как сделать чтоб температура выводилась на дисплэй постоянно т.е. в лупе а светодиод при превышении 25 С включился один раз?
ОтветитьУдалитьСпасибо.
А что плохого будет, если его включать каждый раз?...
ОтветитьУдалитьМожно пойти и сложным путем:
float current_temp;
int temp_over_25 = 0;
void setup() {
...
}
void measure_indicate() {
...
/* текущая температура записывается в current_temp */
}
void loop() {
indicate();
if (!temp_over_25 && current_temp > 25.0) {
action();
temp_over_25 = 1;
}
}
а куда светодиод вписывать,что-то не могу разобраться?
ОтветитьУдалитьдействие, производимое однократно, можно поместить в процедуру action().
ОтветитьУдалитьчто то не получается у меня ничего.
ОтветитьУдалитьА нельзя ли этот скетч поправить?
float temp;
int tempPin=0;
int controlPin=8;
int powerPin=13;
void setup()
{
Serial.begin(9600);
pinMode(powerPin, OUTPUT);
digitalWrite(powerPin, HIGH);
}
void loop()
{
temp = analogRead(tempPin) * 5.0/1024 * 100;
Serial.print(" Temperature: ");
Serial.println(temp);
delay(1000);
if (temp > 25)
{
digitalWrite(controlPin, HIGH);
delay(5000);
digitalWrite(controlPin, LOW);
delay(1000);
}
}
температура должна постоянно вычисляться,но как только превышает +25С - должен загореться светодиод(5 секунд) и на этом вся программа заканчивается, а для того чтоб возобновить работу скетча нужно нажать на сброс.И ещё вопрос.
Как можно вывести кнопку сброса самой ардуины отдельно?Спасибо.
заменить последний блок на:
ОтветитьУдалитьif (temp > 25.0) {
digitalWrite(controlPin, HIGH);
delay(5000);
digitalWrite(controlPin, LOW);
while(1) {};
}
Внешняя кнопка сброса включается между пинами с надписью "RESET" и "GND", в нормальном состоянии должна быть разомкнута.
огроменное тебе спасибо!!!
ОтветитьУдалитьподскажите пож-та а почему так прыгают показания?
ОтветитьУдалить22.75 C
0.74 B
24.22 C
0.75 B
25.20 C
0.76 B
26.17 C
0.77 B
26.66 C
0.84 B
33.98 C
0.73 B
23.24 C
0.83 B
33.50 C
0.75 B
25.20 C
0.74 B
23.73 C
0.70 B
20.31 C
0.76 B
26.17 C
Не знаю.
ОтветитьУдалитьНо вообще-то не должны - проверьте схему подключения, попробуйте поменять датчик.
Рекомендую DS18B20 - там, по крайней мере, цифровой интерфейс, меньше влияние побочных факторов типа проводов.