Мой сайт
Главная | Регистрация | Вход
Среда, 25.06.2025, 18:21
Меню сайта
Мини-чат
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Главная » 2014 » Май » 3 » Ардуино инкубатор. Ethernet термометр на основе Arduino
13:15

Ардуино инкубатор. Ethernet термометр на основе Arduino





23 декабря 2010 в 23:24

Ethernet термометр на основе Arduino

Arduino

О цифровых термометрах на основе Arduino было сказано немало. Все они либо подключались к компьютеру, либо выводили температуры сразу на дисплей.
Но мне был нужен уличный термометр, который автономно и отправляет данные на сайт. Итак, приступим.
1-Wire и каждые 3 секунды самостоятельно отправлять результаты на Web-сервер, на котором они будут храниться.

Алгоритм работы устройства:

  1. присваиваем нашему Ethernet Shield`у MAC адрес и ip-адрес
  2. инициализируем соединение с сервером на 80 порт
  3. получаем данные с цифрового датчика температуры, по 1-Wire шине
  4. формируем GET запрос
  5. отправляем GET запрос
  6. разрываем соединение


Исходный код скетча:

Комментарии по ходу кода должны внести ясность.

include <Ethernet.h>
// Библиотеки ниже нет в стандартной поставке среды разработки Arduino.
// придётся её скопировать.
include <DallasTemperature.h>

// MAC-адрес нашего устройства
byte mac[] = { 0x00, 0x3A, 0xF1, 0x19, 0x69, 0xFC };
// ip-адрес устройства
byte ip[] = { 192, 168, 1, 156 };
// ip-адрес удалённого сервера
byte server[] = { 79, 140, 28, 20 }; // измените на свой
char temp[6];
byte isdata=0;

Client client(server, 80); // 80-порт.
DallasTemperature tempSensor;

void setup()
{
Ethernet.begin(mac, ip); // Инициализируем Ethernet Shield
tempSensor.begin(7); // Датчик температуры на 7-й пин
Serial.begin(9600); // Скорость консольного порта 9600 (пригодится для отладки)
}

void loop()
{
delay(3000); // задержка в 3 сек.
// Соединяемся
if (client.connect()) {
Serial.println("connecting..."); // Serial.println для отладки. Лучше его оставить, на всякий случай, потом будет легче понять, в чём проблема.
// Обработчик ошибок датчика
switch(tempSensor.isValid())
{
case 1:
Serial.println("Invalid CRC"); // ошибка контрольной суммы
tempSensor.reset(); // сбросить девайс
return;
case 2:
Serial.println("Invalid device"); // какой-то "левый" датчик :)
tempSensor.reset(); // сбросить девайс
return;
}

Serial.println("connected");
char buf[80];
float f=tempSensor.getTemperature(); // получаем температуру

Serial.println(tempSensor.getTemperature());

// Ниже извращения с отделением дробной части и целой. Почему-то Arduino не хочет работать с float.
// Вместо числа вставляет вопросик. Наверное, виной тому отсутствие аппаратной поддержки работы с
// числами с плавающей запятой в Arduino. Буду рад увидеть более красивое решение в комментариях.
int temp1 = (f - (int)f) * 100; // выделяем дробную часть
// Составляем GET запрос. Переменная code нужна для того, чтобы вражеский термометр не слал какие попало значения.
// проверяется на стороне Web-сервера.
sprintf(buf, "GET /class/backend/meteo.php?temp=%0d.%d&code=123456 HTTP/1.0", (int)f, abs(temp1));

Serial.println(buf);
client.println(buf); // Отправляем GET запрос
client.println("Host: opck.info"); // Указываем, какой конкретно host на данном ip нас интересует.
client.println();

} else {
Serial.println("connection failed");
}

while (client.available()) {
isdata=1;
char c = client.read(); // Читаем, что нам ответил Web-сервер
Serial.print(c);

}

if (!client.connected()) {
isdata=0;
Serial.println();
Serial.println("disconnecting.");
client.stop(); // Завершаем соединение
}
}


Сборка устройства:

  1. первую «ногу» датчика цепляем на «минус» GND
  2. вторую «ногу» (DQ) на 7-й пин
  3. третью на «плюс»
  4. вторую и третью нужно соединить резистором на ~ 4,7 К. Но я заменил резистор на светодиод и получил индикатор обращения к шине датчика (ВНИМАНИЕ! Без резистора или светодиода работать ничего не будет. Не забудьте!)


По идее, вот и всё. Должно работать.
Работает, но боевые условия показали, что когда падает солнечный свет на датчик, тот может нагреваться и показывать температуру гораздо выше реальной. Всё правильно — он покажет температуру на солнце. А нам нужна температура воздуха.

В первый раз для этого был собран корпус из-под банки от кофе, обёрнутый в фольгу. Но это ничем не помогло.

Изучение фотографий реальных метео-станций помогло найти решение. Корпус для датчика должен быть больше, и к тому же иметь активную вентиляцию для таких случаев.

Делаем корпус для датчика

Подходящей по размеру оказалась банка от водоэмульсионной краски (такие же бывают из-под клея ПВА, объёмом 2-3 литра). В нижней части банки делаем отверстие под вентилятор. И прикрепляем его к банке. В центре банки размещаем площадку под датчики, диаметром немного меньшим самой банки, чтобы воздух мог циркулировать.
Несколько фото:

Банка от водоэмульсионки

Банка от водоэмульсионки
Детали и банка с проделанным отвестием
Детали и банка с проделанным отвестием

Установка датчика в корпус
Установка датчика в корпус

Датчик в корпусе, вид сверху
Датчик в корпусе, вид сверху

Как вы помните, резистор я заменил светодиодом, поэтому делаем и для него отверстие, чтобы всегда было видно работу устройства.

Корпус, вид сбоку
Корпус, вид сбоку

Крышка от банки нам не нужна, вместо неё нужен навес, такой, чтобы и воздух пропускал, и чтобы атмосферные осадки не попадали внутрь (датчик-то будет расположен на улице).

Корпус для Arduino я сделал из пластмассовой коробки от mp3-плеера Explay C360.

Arduino
Arduino

Backend, принимающий данные:

На стороне сервера работает скрипт, к которому обращается термометр. Скрипт проверяет правильность секретного кода, чтобы показания нельзя было подменить.
А затем добавляет новую запись в таблицу MySql. Потом эти данные можно выводить как угодно. При этом каждую минуту данные за прошедшую минуту усредняются и добавляются в другую таблицу.
Нужно это для того, чтобы:
1. проще было делать выборки в базе (не правда ли, удобнее указать конкретную минуту и получить результат)
2. выборки были быстрее (за год ~500 000 записей вместо 10 000 000)

Во время длительной работы датчика обнаружилась проблема, иногда он самопроизвольно (раз в 3-4 часа) выдаёт рандомное значение. Поэтому я добавил проверку на изменение температуры больше чем на 1 градус в течении 15 секунд. Такие значения игнорируются.

Что из этого всего вышло:

На своём сайте я разместил страничку с термометром и добавил график температуры за последние сутки.
Посмотреть можно тут: Ethernet термометр.

Недостатки:

Точность датчика 0.5* С, что для меня недостаточно. Но есть способ улучшить его характеристики. Понадобится ещё один, или более датчиков (желательно из разных партий). Получаем данные со всех датчиков и считаем среднее арифметическое. Так можно добиться точности до сотых градуса.

Планы на будущее:

  • датчик влажности
  • датчик давления
  • датчик скорости ветра
  • датчик освещённости
  • поставить несколько таких в городе и делать свои прогнозы погоды
  • питать Arduino по Power over Ethernet
  • автоматизировать включение и частоту вращения вентилятора в зависимости от освещения
  • удалённое управление
  • сброс данных на случай отсутствия связи (для меня это критично)


Известные мне недостатки:

— высокая цена — 2180 руб. (Freeduino 2009 (800 р.) + Ethernet Shield v2 (1300 р.) + 1 датчик (80 р.))
— если вентилятор включить слишком быстро, то он сам вносит погрешность в температуру, обдувая датчик. Он не должен сдувать, а лишь проталкивать воздух.

Ссылки по теме:

Блог Arduino на Хабре
Онлайн-термометр
DS18B20 Datasheet

PS: статья целиком и полностью принаддежит liderman — все вопросы к нему


Источник: habrahabr.ru
Просмотров: 1544 | Добавил: hapeake | Рейтинг: 0.0/0
Всего комментариев: 0
Форма входа
Поиск
Календарь
«  Май 2014  »
Пн Вт Ср Чт Пт Сб Вс
   1234
567891011
12131415161718
19202122232425
262728293031
Архив записей
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Copyright MyCorp © 2025
    Бесплатный хостинг uCoz