BMP085 Barometric Pressure Sensor Module for arduino (или как сделать метеостанцию своими руками)
- Цена: $6,99
- Перейти в магазин
Метеостанция своими руками.
Дело было вечером, делать былонечего после нового года. Как обычно, во время зимних новогодних каникул хочется занять голову да и руки тоже чем-нибудь полезным, творческим. В эти новогодние каникулы решил сделать метеостанцию своими руками. Готовиться начал заранее, все компоненты закупал и собирал перед новым годом, а основное программирование делал на каникулах.
(под катом много фотографий!)
Сначала пробегусь по компонентам, ссылки давать не буду, так как на eBay (в личном кабинете) товары ушли в архив. Многие компоненты покупал неспеша на аукционе eBay. Впервые опробовал аукцион, раньше всегда покупал «buy it now». Что могу сказать, если не спешить с покупками, то некоторые компоненты можно купить дешевле (разница иногда бывает в два раза).
Датчик давления ВМР085
Это основной датчик. Когда я увидел его на eBay, то понял, что хочу собрать именно домашнюю метеостанцию.
Прилетел датчик в обычном конверте, внутри обклеенном пупыркой.
Внутри конверта была визитка продавца и датчик, запакованный в антистатический пакет и завёрнутый в ещё один слой пупырки
Антистатический пакет был запаян, дабы влага во время перелёта не грозила датчику
Достаём датчик. С одной стороны припаяна линейка контактов, которые были вставлены в пенопласт, чтобы не погнулись. С другой стороны располагается сам датчик и маркировка контактов.
Все бы хорошо, но маркировка контактов нанесена в зеркальном виде.
Подключается датчик по шине I2C и питается от 3,3 В. То есть для нормального функционирования нужно 4 провода (+, -, SDA, SCL)
Опрашивать датчик можно 2 способами: или через библиотеку, или используя функции прямо скетче.
Пример программы:
Помимо этого в датчике есть собственный термо-сенсор для компенсации давления и альтиметр
Arduino Nano v3.0
Это сердце всей метеостанции. По простому говоря, контроллер в миниатюрном размере.
Покупал здесь
Рассказывать подробно про контроллер не буду, так как до меня уже это сделали:
Обзор 1
Обзор 2
Посылка с lightake была сборная, контроллер пришел в пакете, где был USB-кабель и Arduino в запаянном антистатическом пакете.
Чтобы оценить размеры, рядом с Arduino положил монетку номиналом 1 руб.
Плата контроллера вблизи
USB-кабель хороший, с ферритовым кольцом. Питается Arduino по USB кабелю. Среду разработки можно скачать отсюда (страница для скачивания здесь ). Язык «С»-подобный, с освоением проблем не было, так как на нем очень много программирую на работе.
LCD экран
На работе в закромах нашёл совместимый LCD 1602 экран. С подключением пришлось повозиться, так как даташита на него не нашёл. В результате LCD заработал.
Но после недолгой эксплуатации заметил, что мне этого экрана мало и вывести больше данных не получится, так как он имеет всего 2 строки по 16 символов в каждой. Поначалу кажется, что этих параметров хватит, но когда начинаешь программировать, то понимаешь, что максимум можно впихнуть 3-4 параметра. А если делать меню (я ведь подумывал сделать меню на этом экране), то свободного места остаётся на 1-2 параметра.
В итоге начал подыскивать себе другой экран. Сначала присматривался к графическому экрану от Nokia 3310 и даже в аукционе eBay участвовал, чтобы его купить, но не сложилось (чему я очень рад), поэтому мне пришлось отказаться от этого экрана. Сейчас я понимаю, что он был бы слишком мал для моих целей, так как есть с чем сравнивать.
Случайно просматривая шилды на Arduino, я наткнулся на графический экран 12864 на контроллере ST7920. У этого экрана и размер подходящий, и хорошее разрешение для моих нужд (128х64). То есть можно спокойно разместить 6-7 строк по 20 символов нормально читающегося шрифта. Так как экран графический, то помимо текста разными шрифтами можно разместить и графику. Короче, это именно то, что мне нужно было, все присутствовало в этом экране, поэтому я не выдержал и заказал.
Посылка пришла быстро и была упаковано стандартно: конверт-пупырка, внутри ещё слой пупырки и экран в антистатическом пакете:
Чтобы оценить размеры, рядом с LCD положил монетку номиналом 1 руб.
Чтобы быстро подключить экран к Arduino, к контактам LCD припаял линейку контактов. Подключать LCD можно по последовательной шине и по параллельной. Я выбрал первый вариант, так как свободных контактов Arduino и так мало.
Подключение (взято из сети):
Для того, чтобы программно подключить LCD к Arduino, используется библиотека u8glib. Скачать можно здесь. Если есть проблемы скачивания, то могу библиотеку залить на narod.ru.
Сама библиотека не сложная и позволяет выводить текст разным шрифтом, рисовать линию, рисовать простейшие геометрические фигуры (прямоугольник, круг), выводить на экран свои изображения, подготовленные специальным образом. В принципе, этого инструмента достаточно для большинства задач.
Вот результат простенькой программы:
Сама программа:
Часы реального времени DS1307
Ещё один компонент для моей метеостанции. На данном шилде реализованы часы реального времени. Заказывал их на аукционе eBay. Продавец прислал платку часов в нереально большой коробке
Внутри коробки было два листка А4 с рекламой и платка часов, обмотанная целлофаном
Хочу заметить, что плата не превышает размером 2 руб. монету, а коробка была размером 13х15х5 см.
Плата была упакована в антистатический пакет
Платка вблизи
С данным модулем мне пришлось повозиться. Во-первых, были трудности подключения. А во-вторых, кварц на данной плате никакой. Если бы знал, что на модуль потрачу столько времени, то, скорее всего, собрал бы его сам, благо в сети полно схем. Самая простейшая схема содержит 4-5 компонентов.
По поводу подключения. Я нашёл библиотеку, в которой было сказано, что интерфейс I2C можно подключать не на привычные аналоговые входы Arduino (А4 и А5), а на любые дискретные. Как написано, так и сделал. Сначала ничего не работало, после долгого танца с бубном часы завелись. Ну, подумал, всё, проблемы закончились, но после того, как я попытался этот же модуль подключить к другой Arduino, пляски с бубном продолжились. Много времени потратил на поиски решения данной проблемы и практически везде указывалось либо на неправильное подключение, либо на отсутствие подтягивающих резисторов на контактах SCL и SDA. Я уже хотел с паяльником в плату лезть, но на одном форуме случайно наткнулся на код, где было сказано, чтобы SCL и SDA подключать к стандартным портам I2C на Arduino. После стандартного подключения, все сразу заработало.
Теперь по поводу кварца. Не знаю, что там за кварц ставят китайцы, но часы с таким кварцем убегали в сутки на 10-11 сек. В месяц данная погрешность составляет 5 минут, а в год 1 час. Нафиг такие часы не нужны. Пришлось снова лезть в сеть и искать, как исправить данный баг. Первое попавшее решение говорит о том, что нужно заземлить кварц. Сделал — результат нулевой. Ещё где-то нашёл, что нужно найти старую материнку и выпаять оттуда часовой кварц. Сделал — результат есть. Теперь часы убегают не на 10-11 секунд, а на 1,5 секунды в сутки. Скажем так, стало лучше, но до идеала далеко. Так как больше с паяльником возится неохота, то было решено подводить часы программно, то есть раз в сутки подводить часы на нужную величину. После 10 суток, часы ушли не более, чем на секунду. Метод хорош, но только тогда, когда устройство синхронизации Arduino подключено к питанию, иначе часы работают от батарейки и все равно убегают.
Небольшая тестовая программа:
Здесь не использована библиотека, да и функции усечены, для чтения и записи времени.
Датчик температуры и влажности DHT11
Про данный датчик рассказывать нечего. Я бы его даже не стал использовать, если бы не нужна была влажность. К сожалению, я его не сфотографировал, когда получил, поэтому фотографий не будет. Фотографии датчика можно будет посмотреть ниже, где я его подключил к Arduino. Подключение датчика простое (+, цифровой выход, -). Обычно датчики делают четырёх контактные. При таком форм-факторе третий контакт ни к чему не подключают.
Для подключения к Arduino можно использовать библиотеку. Скачать можно здесь.
Небольшая тестовая программа c выводом информации на LCD дисплей 1602:
Минусы у датчика есть – данные с датчика идут только в целых числах, да и диапазон слабенький.
Вроде, про все компоненты написал. Осталось собрать все в единое целое.
Упс, чуть не забыл! Для того, чтобы все собрать устройство, нужен корпус. Корпус тоже заказывал на Ebay. Продавец оказался из Англии. Посылка дошла быстро, но фотографировать её не стал. Все фотографии корпуса ниже.
Сначала собрал все на столе с помощью специальных проводков. Написал тестовую программу и залил её в контроллер.
На самом деле синий цвет подсветки гораздо ярче. Даже при минимальной яркости (Bright=5) происходит засветка кадра.
Чтобы все собрать без проводов, было решено сделать мини материнскую плату, а платка Arduino и шилды надевались на разъёмы. В случае чего, их с лёгкостью можно быстро извлечь. LCD экран и кнопки для управления я решил также цеплять на разъёмах, только датчик температуры впаять на проводах.
Вот такая вышла платка
На последней фотографии я ещё до конца флюс не смыл. Под шилды рядом с разъёмами приклеил пористую резину, чтобы была хоть какая-то опора. Хотя на самом деле шилды в разъёмах на контактах и так прекрасно держатся.
Материнская плата с установленными шилдами и платой Arduino.
Вот так выглядит полное подключение к материнской плате
Вместо кнопок использовал самодельный шилд, спаянный на макетной плате. В качестве кнопок использовал кнопки из старых мышек.
Как видно, количество проводов убавилось.
Основная проблема размещения в корпус — это ровно выпилить паз под LCD экран. Как я ни старался, все равно идеально не получилось. Щели в некоторых местах были чуть больше 1 мм. Чтобы все смотрелось аккуратно, я взял чёрный герметик для аквариума и залил все щели, заодно экран крепил именно на этот герметик. После высыхания герметика снаружи обрезал излишки. При ярком освещении герметик видно, а при обычном — все сливается с корпусом.
Вот так выглядит корпус изнутри с установленным LCD экраном и материнской платой.
Вот так выглядит снаружи при ярком освещении (прошу прощения за отпечатки пальцев, увидел их, когда разбирал фотографии).
Долго думал, как приладить кнопки в корпус и, самое главное, какие использовать кнопки…
В радиоэлектронных магазинах приглянулись кнопка с длинным шпиньком и наконечники, которые надеваются на этот шпинёк. Эти кнопки используются для пайки на плату. Все бы хорошо, но у них есть минус – ход нажатия очень маленький и громкий.
Размещать кнопки пришлось в два этапа: первый — разместить кнопки на плате, второй — эту плату крепить ещё на одной плате. И все это потом засовывать в корпус на направляющие.
Вот так выглядит платка с кнопками:
Вот так выглядит плата-держатель:
Здесь видны направляющие, в которые вставляется плата с кнопками. Некоторые элементы паял для того, чтобы придать жёсткость плате.
Теперь все засовываем в корпус
Без подключения кнопок:
С подключением кнопок:
Закрываем корпус и включаем. Все прекрасно работает, кнопки отрабатывают, как нужно.
Здесь видно, что расхождения по давлению с домашней метеостанции нет, показания идентичные.
В конце размещаю небольшое видео работы устройства в разных режимах:
[video]http://www.youtube.com/watch?v=KsiVaUWkXNA&feature=youtu.be[/video]
У кого видео здесь не отображается, вот ссылка на Youtube
Пора заканчивать обзор.
Немного напишу о программе, а потом краткие выводы. Когда писал программу, не думал, что очень быстро упрусь в ограничение в 30720 байт.
Пришлось оптимизировать код. Многие куски кода выносил в подпрограммы. Никогда бы не подумал, что оператор switch… case в компилированном виде занимает больше места, чем несколько if… else. Ещё экономит место правильное объявление переменных. Если объявлять массив long, хотя вполне можно обойтись byte, то перерасход памяти достигает 500 байт в зависимости от размерности массива. Когда пишешь программу, то об этом не думаешь, а уже потом, когда анализируешь программу, то понимаешь, что некоторые вещи сделал неправильно, и начинаешь оптимизировать код. После того, как проблемы с размером программы были решены, я упёрся в ограничение оперативной памяти. Выражалось это в том, что программа начинала виснуть после загрузки. Пришлось вводить подпрограмму подсчёта свободной оперативной памяти. В результате, был вынужден отказаться от одного алгоритма предсказывания погоды, так как он должен выводить пиктограммы на экран. Сам алгоритм работает, а вот вывод пиктограмм пришлось заремировать. У меня есть ещё задумки, как оптимизировать код, но в ближайшем будущем оставляю работать устройство, как есть, чтобы оценить работоспособность и выявить все баги.
Теперь небольшие выводы
Минусы
1) Цена. Оправдание этому минусу – хобби никогда не бывает дешёвым.
Плюсы
1) Большой функционал устройства
2) Наращивание функций ограничивается только используемым контроллером и собственным желанием
3) Эстетическое удовольствие от созерцания и моральное удовльствие от того, что я все-таки собрал и доделал это устройство
Дело было вечером, делать было
(под катом много фотографий!)
Сначала пробегусь по компонентам, ссылки давать не буду, так как на eBay (в личном кабинете) товары ушли в архив. Многие компоненты покупал неспеша на аукционе eBay. Впервые опробовал аукцион, раньше всегда покупал «buy it now». Что могу сказать, если не спешить с покупками, то некоторые компоненты можно купить дешевле (разница иногда бывает в два раза).
Датчик давления ВМР085
Это основной датчик. Когда я увидел его на eBay, то понял, что хочу собрать именно домашнюю метеостанцию.
Прилетел датчик в обычном конверте, внутри обклеенном пупыркой.
Внутри конверта была визитка продавца и датчик, запакованный в антистатический пакет и завёрнутый в ещё один слой пупырки
Антистатический пакет был запаян, дабы влага во время перелёта не грозила датчику
Достаём датчик. С одной стороны припаяна линейка контактов, которые были вставлены в пенопласт, чтобы не погнулись. С другой стороны располагается сам датчик и маркировка контактов.
Все бы хорошо, но маркировка контактов нанесена в зеркальном виде.
Подключается датчик по шине I2C и питается от 3,3 В. То есть для нормального функционирования нужно 4 провода (+, -, SDA, SCL)
Опрашивать датчик можно 2 способами: или через библиотеку, или используя функции прямо скетче.
Пример программы:
ВМР085
#include <Wire.h>
#define BMP085_ADDRESS 0x77 // I2C address of BMP085
const unsigned char OSS = 0; // Oversampling Setting
// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
long b5;
short temperature;
long pressure;
void setup()
{
Serial.begin(9600);
Wire.begin();
bmp085Calibration();
}
void loop()
{
temperature = bmp085GetTemperature(bmp085ReadUT());
pressure = bmp085GetPressure(bmp085ReadUP());
Serial.print(«Temperature: „);
Serial.print(temperature/10.0, DEC);
Serial.println(“ C»);
Serial.print(«Pressure: „);
Serial.print(pressure/133.322, DEC);
Serial.println(“ mm Hg»);
Serial.println();
delay(1000);
}
void bmp085Calibration()
{
ac1 = bmp085ReadInt(0xAA);
ac2 = bmp085ReadInt(0xAC);
ac3 = bmp085ReadInt(0xAE);
ac4 = bmp085ReadInt(0xB0);
ac5 = bmp085ReadInt(0xB2);
ac6 = bmp085ReadInt(0xB4);
b1 = bmp085ReadInt(0xB6);
b2 = bmp085ReadInt(0xB8);
mb = bmp085ReadInt(0xBA);
mc = bmp085ReadInt(0xBC);
md = bmp085ReadInt(0xBE);
}
short bmp085GetTemperature(unsigned int ut)
{
long x1, x2;
x1 = (((long)ut — (long)ac6)*(long)ac5) >> 15;
x2 = ((long)mc << 11)/(x1 + md);
b5 = x1 + x2;
return ((b5 + 8)>>4);
}
long bmp085GetPressure(unsigned long up)
{
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;
b6 = b5 — 4000;
// Calculate B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
// Calculate B4
x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
b7 = ((unsigned long)(up — b3) * (50000>>OSS));
if (b7 < 0x80000000)
p = (b7<<1)/b4;
else
p = (b7/b4)<<1;
x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;
return p;
}
// Read 1 byte from the BMP085 at 'address'
char bmp085Read(unsigned char address)
{
unsigned char data;
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 1);
while(!Wire.available())
;
return Wire.read();
}
int bmp085ReadInt(unsigned char address)
{
unsigned char msb, lsb;
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 2);
while(Wire.available()<2)
;
msb = Wire.read();
lsb = Wire.read();
return (int) msb<<8 | lsb;
}
// Read the uncompensated temperature value
unsigned int bmp085ReadUT()
{
unsigned int ut;
// Write 0x2E into Register 0xF4
// This requests a temperature reading
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();
// Wait at least 4.5ms
delay(5);
// Read two bytes from registers 0xF6 and 0xF7
ut = bmp085ReadInt(0xF6);
return ut;
}
// Read the uncompensated pressure value
unsigned long bmp085ReadUP()
{
unsigned char msb, lsb, xlsb;
unsigned long up = 0;
// Write 0x34+(OSS<<6) into register 0xF4
// Request a pressure reading w/ oversampling setting
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();
// Wait for conversion, delay time dependent on OSS
delay(2 + (3<<OSS));
// Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF6);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 3);
// Wait for data to become available
while(Wire.available() < 3)
;
msb = Wire.read();
lsb = Wire.read();
xlsb = Wire.read();
up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
return up;
}
Помимо этого в датчике есть собственный термо-сенсор для компенсации давления и альтиметр
Arduino Nano v3.0
Это сердце всей метеостанции. По простому говоря, контроллер в миниатюрном размере.
Покупал здесь
Рассказывать подробно про контроллер не буду, так как до меня уже это сделали:
Обзор 1
Обзор 2
Посылка с lightake была сборная, контроллер пришел в пакете, где был USB-кабель и Arduino в запаянном антистатическом пакете.
Чтобы оценить размеры, рядом с Arduino положил монетку номиналом 1 руб.
Плата контроллера вблизи
USB-кабель хороший, с ферритовым кольцом. Питается Arduino по USB кабелю. Среду разработки можно скачать отсюда (страница для скачивания здесь ). Язык «С»-подобный, с освоением проблем не было, так как на нем очень много программирую на работе.
LCD экран
На работе в закромах нашёл совместимый LCD 1602 экран. С подключением пришлось повозиться, так как даташита на него не нашёл. В результате LCD заработал.
Но после недолгой эксплуатации заметил, что мне этого экрана мало и вывести больше данных не получится, так как он имеет всего 2 строки по 16 символов в каждой. Поначалу кажется, что этих параметров хватит, но когда начинаешь программировать, то понимаешь, что максимум можно впихнуть 3-4 параметра. А если делать меню (я ведь подумывал сделать меню на этом экране), то свободного места остаётся на 1-2 параметра.
В итоге начал подыскивать себе другой экран. Сначала присматривался к графическому экрану от Nokia 3310 и даже в аукционе eBay участвовал, чтобы его купить, но не сложилось (чему я очень рад), поэтому мне пришлось отказаться от этого экрана. Сейчас я понимаю, что он был бы слишком мал для моих целей, так как есть с чем сравнивать.
Случайно просматривая шилды на Arduino, я наткнулся на графический экран 12864 на контроллере ST7920. У этого экрана и размер подходящий, и хорошее разрешение для моих нужд (128х64). То есть можно спокойно разместить 6-7 строк по 20 символов нормально читающегося шрифта. Так как экран графический, то помимо текста разными шрифтами можно разместить и графику. Короче, это именно то, что мне нужно было, все присутствовало в этом экране, поэтому я не выдержал и заказал.
Посылка пришла быстро и была упаковано стандартно: конверт-пупырка, внутри ещё слой пупырки и экран в антистатическом пакете:
Чтобы оценить размеры, рядом с LCD положил монетку номиналом 1 руб.
Чтобы быстро подключить экран к Arduino, к контактам LCD припаял линейку контактов. Подключать LCD можно по последовательной шине и по параллельной. Я выбрал первый вариант, так как свободных контактов Arduino и так мало.
Подключение (взято из сети):
— Контакт 1 (GND) подключается к общей шинеПо этой инструкции я подключил все, кроме подсветки. В качестве питания подсветки я использовал ШИМ Arduino.
— Контакт 2 (VCC) подключается к шине питания +5V, причём потребляемый ток сравнительно небольшой и дисплей можно питать от встроенного стабилизатора Arduino.
— Контакты 4, 5 и 6 подключаются к цифровым выходам Arduino, образуя последовательный интерфейс SPI:
контакт 4 – (RS) – соответствует линии CS (например 7)
контакт 5 – (RW) – соответствует линии MOSI (например 8)
контакт 6 – (E) – соответствует линии SCK (например 3)
номера контактов Arduino могут быть любыми, главное не забыть потом правильно указать их в тексте программы при инициализации дисплея.
— Контакт 15 (PSB) соединяется с общей шиной.
— Контакты 19 (A) и 20 (K) – это питание подсветки (+5V и GND соответственно). Для регулировки яркости подсветки можно использовать переменный резистор 10кОм, включённый между шинами питания и GND. Напряжение с его движка подаётся на контакт 19 дисплея.
Для того, чтобы программно подключить LCD к Arduino, используется библиотека u8glib. Скачать можно здесь. Если есть проблемы скачивания, то могу библиотеку залить на narod.ru.
Сама библиотека не сложная и позволяет выводить текст разным шрифтом, рисовать линию, рисовать простейшие геометрические фигуры (прямоугольник, круг), выводить на экран свои изображения, подготовленные специальным образом. В принципе, этого инструмента достаточно для большинства задач.
Вот результат простенькой программы:
Сама программа:
LCD7920
#include «U8glib.h»
U8GLIB_ST7920_128X64 u8g(3, 9, 8, U8G_PIN_NONE); // SPI E = 3, RW = 9, RS = 8
// Подпрограмма определения свободной памяти
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v — (__brkval == 0? (int) &__heap_start: (int) __brkval);
}
void setup(void) {
u8g.setFont(u8g_font_6x10); // шрифт
u8g.setRot180(); //Перевернул экран
analogWrite(6, 115); // Устанавливаем яркость экрана (анод подсветки на 6 pin)
}
void loop(void) {
u8g.firstPage();
do {
u8g.setColorIndex(1); // белые чернила, черный фон
u8g.setPrintPos(1, 12); // позиция
u8g.print(«Hello!!!»); // вывод текста
u8g.drawBox(0,22,128,9); // Закрашиваем прямоугольник белым
u8g.setColorIndex(0); // белые чернила, черный фон
u8g.setPrintPos(1, 30); // позиция
u8g.print(«Word...»); // вывод текста
u8g.setColorIndex(1); // белые чернила, черный фон
u8g.setPrintPos(1, 50); // позиция
u8g.print(«After start =»); // вывод текста
u8g.setPrintPos(85, 50); // позиция
u8g.print(millis() / 1000); // вывод число секунд после старта
u8g.setPrintPos(1, 64); // позиция
u8g.print(freeRam ()); // вывод сколько памяти занято
} while( u8g.nextPage() );
delay(200);
}
Часы реального времени DS1307
Ещё один компонент для моей метеостанции. На данном шилде реализованы часы реального времени. Заказывал их на аукционе eBay. Продавец прислал платку часов в нереально большой коробке
Внутри коробки было два листка А4 с рекламой и платка часов, обмотанная целлофаном
Хочу заметить, что плата не превышает размером 2 руб. монету, а коробка была размером 13х15х5 см.
Плата была упакована в антистатический пакет
Платка вблизи
С данным модулем мне пришлось повозиться. Во-первых, были трудности подключения. А во-вторых, кварц на данной плате никакой. Если бы знал, что на модуль потрачу столько времени, то, скорее всего, собрал бы его сам, благо в сети полно схем. Самая простейшая схема содержит 4-5 компонентов.
По поводу подключения. Я нашёл библиотеку, в которой было сказано, что интерфейс I2C можно подключать не на привычные аналоговые входы Arduino (А4 и А5), а на любые дискретные. Как написано, так и сделал. Сначала ничего не работало, после долгого танца с бубном часы завелись. Ну, подумал, всё, проблемы закончились, но после того, как я попытался этот же модуль подключить к другой Arduino, пляски с бубном продолжились. Много времени потратил на поиски решения данной проблемы и практически везде указывалось либо на неправильное подключение, либо на отсутствие подтягивающих резисторов на контактах SCL и SDA. Я уже хотел с паяльником в плату лезть, но на одном форуме случайно наткнулся на код, где было сказано, чтобы SCL и SDA подключать к стандартным портам I2C на Arduino. После стандартного подключения, все сразу заработало.
Теперь по поводу кварца. Не знаю, что там за кварц ставят китайцы, но часы с таким кварцем убегали в сутки на 10-11 сек. В месяц данная погрешность составляет 5 минут, а в год 1 час. Нафиг такие часы не нужны. Пришлось снова лезть в сеть и искать, как исправить данный баг. Первое попавшее решение говорит о том, что нужно заземлить кварц. Сделал — результат нулевой. Ещё где-то нашёл, что нужно найти старую материнку и выпаять оттуда часовой кварц. Сделал — результат есть. Теперь часы убегают не на 10-11 секунд, а на 1,5 секунды в сутки. Скажем так, стало лучше, но до идеала далеко. Так как больше с паяльником возится неохота, то было решено подводить часы программно, то есть раз в сутки подводить часы на нужную величину. После 10 суток, часы ушли не более, чем на секунду. Метод хорош, но только тогда, когда устройство синхронизации Arduino подключено к питанию, иначе часы работают от батарейки и все равно убегают.
Небольшая тестовая программа:
RTC DC1307
#include «Wire.h»
#define DS1307_I2C_ADDRESS 0x68 // SDA A4, SCL A5
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.write(decToBcd(second));
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.endTransmission();
}
void getDateDs1307(byte *second,
byte *minute,
byte *hour)
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 3);
*second = bcdToDec(Wire.read());
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read());
}
void setup()
{
byte second, minute, hour;
Wire.begin();
Serial.begin(9600);
second = 45;
minute = 5;
hour = 16;
setDateDs1307(second, minute, hour);
}
void loop()
{
byte second, minute, hour;
getDateDs1307(&second, &minute, &hour);
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.println(second, DEC);
delay(1000);
}
Здесь не использована библиотека, да и функции усечены, для чтения и записи времени.
Датчик температуры и влажности DHT11
Про данный датчик рассказывать нечего. Я бы его даже не стал использовать, если бы не нужна была влажность. К сожалению, я его не сфотографировал, когда получил, поэтому фотографий не будет. Фотографии датчика можно будет посмотреть ниже, где я его подключил к Arduino. Подключение датчика простое (+, цифровой выход, -). Обычно датчики делают четырёх контактные. При таком форм-факторе третий контакт ни к чему не подключают.
Для подключения к Arduino можно использовать библиотеку. Скачать можно здесь.
Небольшая тестовая программа c выводом информации на LCD дисплей 1602:
DHT11
// include the library code:
#include <dht11.h>
#include <LiquidCrystal.h>
// Declare objects
dht11 DHT11;
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);
#define DHT11PIN 7
int i;
void setup()
{
lcd.begin(16, 2);
lcd.print(«Status: „);
i=0;
}
void loop()
{
int chk = DHT11.read(DHT11PIN);
lcd.setCursor(8, 0);
switch (chk)
{
case 0: lcd.print(“OK „); break;// lcd.setCursor(11, 0); lcd.print(millis()/2000); break;
case -1: lcd.print(“Checksum error»); mErr(); break;
case -2: lcd.print(«Time out error»); mErr(); break;
default: lcd.print(«Unknown error»); mErr(); break;
}
delay(500);
lcd.setCursor(15, 0);
switch (i)
{
case 0: lcd.print("^"); lcd.setCursor(15, 1); lcd.print(" ");break;
case 1: lcd.print(«v»); lcd.setCursor(15, 1); lcd.print(" ");break;
default: lcd.setCursor(15, 1); lcd.print(«E»); break;
}
i=i+1;
if (i>1) i=0;
lcd.setCursor(0, 1);
lcd.print(«H=»);
lcd.setCursor(2, 1);
lcd.print((float)DHT11.humidity, 0);
lcd.setCursor(4, 1);
lcd.print("%");
lcd.setCursor(8, 1);
lcd.print(«T=»);
lcd.setCursor(10, 1);
lcd.print((float)DHT11.temperature, 0);
lcd.setCursor(12, 1);
lcd.print(«C»);
}
void mErr()
{
lcd.setCursor(2, 1);
lcd.print("**");
lcd.setCursor(10, 1);
lcd.print("**");
i=5;
}
Минусы у датчика есть – данные с датчика идут только в целых числах, да и диапазон слабенький.
Вроде, про все компоненты написал. Осталось собрать все в единое целое.
Упс, чуть не забыл! Для того, чтобы все собрать устройство, нужен корпус. Корпус тоже заказывал на Ebay. Продавец оказался из Англии. Посылка дошла быстро, но фотографировать её не стал. Все фотографии корпуса ниже.
Сначала собрал все на столе с помощью специальных проводков. Написал тестовую программу и залил её в контроллер.
На самом деле синий цвет подсветки гораздо ярче. Даже при минимальной яркости (Bright=5) происходит засветка кадра.
Чтобы все собрать без проводов, было решено сделать мини материнскую плату, а платка Arduino и шилды надевались на разъёмы. В случае чего, их с лёгкостью можно быстро извлечь. LCD экран и кнопки для управления я решил также цеплять на разъёмах, только датчик температуры впаять на проводах.
Вот такая вышла платка
На последней фотографии я ещё до конца флюс не смыл. Под шилды рядом с разъёмами приклеил пористую резину, чтобы была хоть какая-то опора. Хотя на самом деле шилды в разъёмах на контактах и так прекрасно держатся.
Материнская плата с установленными шилдами и платой Arduino.
Вот так выглядит полное подключение к материнской плате
Вместо кнопок использовал самодельный шилд, спаянный на макетной плате. В качестве кнопок использовал кнопки из старых мышек.
Как видно, количество проводов убавилось.
Основная проблема размещения в корпус — это ровно выпилить паз под LCD экран. Как я ни старался, все равно идеально не получилось. Щели в некоторых местах были чуть больше 1 мм. Чтобы все смотрелось аккуратно, я взял чёрный герметик для аквариума и залил все щели, заодно экран крепил именно на этот герметик. После высыхания герметика снаружи обрезал излишки. При ярком освещении герметик видно, а при обычном — все сливается с корпусом.
Вот так выглядит корпус изнутри с установленным LCD экраном и материнской платой.
Вот так выглядит снаружи при ярком освещении (прошу прощения за отпечатки пальцев, увидел их, когда разбирал фотографии).
Долго думал, как приладить кнопки в корпус и, самое главное, какие использовать кнопки…
В радиоэлектронных магазинах приглянулись кнопка с длинным шпиньком и наконечники, которые надеваются на этот шпинёк. Эти кнопки используются для пайки на плату. Все бы хорошо, но у них есть минус – ход нажатия очень маленький и громкий.
Размещать кнопки пришлось в два этапа: первый — разместить кнопки на плате, второй — эту плату крепить ещё на одной плате. И все это потом засовывать в корпус на направляющие.
Вот так выглядит платка с кнопками:
Вот так выглядит плата-держатель:
Здесь видны направляющие, в которые вставляется плата с кнопками. Некоторые элементы паял для того, чтобы придать жёсткость плате.
Теперь все засовываем в корпус
Без подключения кнопок:
С подключением кнопок:
Закрываем корпус и включаем. Все прекрасно работает, кнопки отрабатывают, как нужно.
Фотографии разных экранов
Здесь видно, что расхождения по давлению с домашней метеостанции нет, показания идентичные.
В конце размещаю небольшое видео работы устройства в разных режимах:
[video]http://www.youtube.com/watch?v=KsiVaUWkXNA&feature=youtu.be[/video]
У кого видео здесь не отображается, вот ссылка на Youtube
Пора заканчивать обзор.
Немного напишу о программе, а потом краткие выводы. Когда писал программу, не думал, что очень быстро упрусь в ограничение в 30720 байт.
Пришлось оптимизировать код. Многие куски кода выносил в подпрограммы. Никогда бы не подумал, что оператор switch… case в компилированном виде занимает больше места, чем несколько if… else. Ещё экономит место правильное объявление переменных. Если объявлять массив long, хотя вполне можно обойтись byte, то перерасход памяти достигает 500 байт в зависимости от размерности массива. Когда пишешь программу, то об этом не думаешь, а уже потом, когда анализируешь программу, то понимаешь, что некоторые вещи сделал неправильно, и начинаешь оптимизировать код. После того, как проблемы с размером программы были решены, я упёрся в ограничение оперативной памяти. Выражалось это в том, что программа начинала виснуть после загрузки. Пришлось вводить подпрограмму подсчёта свободной оперативной памяти. В результате, был вынужден отказаться от одного алгоритма предсказывания погоды, так как он должен выводить пиктограммы на экран. Сам алгоритм работает, а вот вывод пиктограмм пришлось заремировать. У меня есть ещё задумки, как оптимизировать код, но в ближайшем будущем оставляю работать устройство, как есть, чтобы оценить работоспособность и выявить все баги.
Теперь небольшие выводы
Минусы
1) Цена. Оправдание этому минусу – хобби никогда не бывает дешёвым.
Плюсы
1) Большой функционал устройства
2) Наращивание функций ограничивается только используемым контроллером и собственным желанием
3) Эстетическое удовольствие от созерцания и моральное удовльствие от того, что я все-таки собрал и доделал это устройство
Самые обсуждаемые обзоры
+71 |
3340
133
|
+50 |
3545
66
|
+29 |
2535
47
|
+37 |
2871
40
|
+55 |
2043
37
|
Так держать, буду ещё ждать обзоров от Вас.
давно засматриваюсь на этот контроллер, жаба душит на хобби столько денег выкидывать… ведь стоит только начать(
плюсую!) и к карме тоже +
А вам респект и "+". Есть еще люди с правильно заточенными руками, радует это!
Помню к ZX Spectrum приделал контроллер с НГМД и принтером. Вот эта была вещь.
P.S.Вот и сейчас я сижу приклеиваю разъём к видеорегистратору, т.к. из-за особенностей крепежа, в моей машине штатный разъём использовать нельзя
Выкладывайте свои поделки на мой сайт самоделок, буду благодарен и никуда ваши поделки не пропадут)) Сам сайт o-samodelkah.ruДля полноты информации не хватает кода. Ардуино есть, тоже хочу смастерить что-то подобное.
Хоть все мои познания в радиоэлектронники были ограничены этим конструктором.
Автору обзора — моё почтение!
Китай нам помогает только вот такой вот штуковиной: www.znatok.ru/konstruktor_na_320_shem.html
Эх, два года в 10 и 11 классах я вряд и вряд, удив зрение…
Переделал магнитофон Томь 303 в стерео, приделал автостоп, поставил сендастовую головку, приделал включение магнитофона через геркон, так я в тайне включал магнитофон, проводя магические движения, со скрытым в руке магнитом от холодильника, чтобы сестренка не могла сама включить:) а потом пульты для телика, дециметровки для видика и собственно вход ав…
Ну а потом разработка запуска авто с пульта сигналки, используя только обычные реле 12 вольтовые…
Так жаль, что потерял схему и еще более жаль, что пропал украинский сайт по ладам, там была опубликована моя схема…
Программаня оболочка у вас классная получилась. Ещё б на русский переделать… Там контроллер русский не поддерживает или из-за экономии памяти?
P.S. этот дисплей навевает нехорошие воспаминания о российском контроллере «Термодат»… Ужасная вещь)
1) одни и те же слова в большинстве случаев на русском имеет больше букв
2) пришлось бы использовать собственный шрифт. В программе использовал 3 шрифта, так что пришлось бы все три шрифта переделывать.
3) английский язык, скажем так универсальный для подобных устройств. Слова clock, setting, trend, bright поймут большинство, а вот кириллица нацелена только на русскоязычное население.
А насчет 1307… я теперь и сам понял, что это неудачный шилд.
Потом уже я наткнулся на более интересную модель, с трёхцветным дисплеем (RGE), но я уже заказал одноцветные, да и более сложная по исполнению — там уже не ардуионо целиком, а, как я понял, лишь его контроллер timewitharduino.blogspot.ru/2011/01/introducing-wise-clock-3.html
Уверен Ваша статья железно пройдет в Хабр и Вам дадут инвайт.
автор поделится исходниками проекта? с целью повторения идеи, не настолько сильны в программировании что б повторить подвиг ;(
спасибо.
точно раздел самоделкин нужен
Вот мой корпус
У этих наборов есть выходы на силовые исполнители?
Дальше эту тему развивать не хотите? Допустим управление климатом: включить приточные вентиляторы, включить кондиционер? Опять же: есть ли возможность прикрутить датчики СО и других газов? Тему надо развивать и периодически публиковаться.
Зря отказываетесь от исполнения таких устройств на заказ, пусть и мелкие деньги, но нужен опыт и клиентская база… Стоит попробовать. И развивайте эту тему.
У моего начальника на работе есть мечта сделать инкубатор… Не знаю осуществима она или нет, но программировать скорее всего буду я :).
Лично сейчас у меня есть еще одна затея, сделать приставку к зарядному устройству, чтобы заряжать АКБ асиметричным током и разряжать АКБ до определенного напряжения. Точнее, эта задумка появилась раньше, чем метеостанция, просто комплектующие прилетели недавно. Скоро начну ее реализовывать.
И идея с АКБ интересна. Для обкатки есть время, а к следующему зимнему сезону можно ставить производство на поток. Хоби должно приносить деньги.
Блин пока писал, Вы уже ответили))
Использовал датчик абсолютного давления с i2c интерфейсом ( HP03SA ) (не смог тогда достать этот бош)
ds3231 — rtc
24512 — память
atmega128 — контроллер
экранчег 240x128 точек ( WG240128 на lc 7981)
датчик света с i2c APDS-9300 (для регулировки уровня подсветки)
Сейчас немного решил усовршенствовать, добавил расчет восхода-захода солнца на текущий день…
Потом планурую еще воткнуть gps-модуль для определения точного времени, беспроводный… Или встроить внутрь, если будет ловить спутники нормально…
Вообще надо на цветной tft-экран выводить, с разрешением повыше, и контроллер типа stm32, в ближайших планах планирую начать изучать…
Хотя если бы Вы всё это кучей даже в том виде, как есть, выложили, я бы был благодарен. Да, я с корыстными целями — очень хочется на реализацию графики взглянуть :) Я сколько ни пытался что-то нарисовать на графическом дисплее (у меня пока только 128х64 из отладочного набора easypic6), ничего красивого так и не выходило.
Я для своих будущих часов заказал вот такой модуль:
h**p://www.ebay.com/itm/DCF-77-Receiver-Module-DCF77-5-DCF-77-5-DCF-Modul-/230851230368?pt=LH_DefaultDomain_0&hash=item35bfce3aa0
Правда и эти сигналы не везде ловятся. У нас в Рыбинске (Ярославская область), в городе сигнал принимается не стабильно, но достаточно для синхронизации. За городом приём нормальный.
Код программ лучше класть на pastebin.com — там отступы не слетят
Недавно увидел шилд на чипсете Simcom SIM908 — www.open-electronics.org/gsm-gps-shield-for-arduino/ — который объединяет GSM и GPS на одном кристалле. Подумал — вот оно, счастье! На круг выходило EUR 100 (кусается, но терпимо), но доставка добавляла около 60 евро. До свидания.
В результате остановился на dx.com/p/34496 Там на конце разъём PS/2 (по форме, на самом деле — последовательный порт). К нему взял dx.com/p/80273 трёхметровый удлинитель — оторву у него один конец и подключу к Ардуине. Мне нравится, что тут всё запаяно, есть магнит на корпусе — в общем, готовый продукт, а не «полуфабрикат».
Приедет — попробую, отчитаюсь. Цель — сделать «компьютер» для машины — с приёмом команд (на разогрев двигателя и салона, например), отчёты о заряде АКБ, отчеты с OBD-II, складыванием на сервер GPS-треков и проч.
P.S. Надеюсь, оно согласится работать в TTL, и не потребуется морочиться с заказом level shifter'а…
Да, к минусам реализации отнесу отсутсвие трендов. Само по себе давление штука конечно интересная, но гораздо интересней его производная, т.к. именно по ней можно предсказывать погоду.
— температура за сутки дискретностью 1 час
— влажность за сутки дискетностью 1 час
— давление за сутки дискретностью 1 час
— температура дискретность 1 минута
— давление за 24 дня дискретность 1 сутки
не думал использовать датчик положения для переключения «экрана» отображаемой информации?
#102 пост
http://openweathermap.org
API подключения станции очень простой
openweathermap.org/wiki/API/data_upload
Ваши данные помогут получить актуальное представление о погоде множеству людей!
Автоматизирую квартиру -у меня в проекте компьютер служит для сохранения и вывода информации со всех этих датчиков.
Датчики влажности DHT11 в пути, но вот в будущем бы взял DHT22 — у его диапозон лучше, можно даже на улицу поставить
(+1$ к цене датчика, чтобы сделать его «сетевым»)
Выглядит в итоге примерно так:
Внутри — самопальный протокол одноранговый, манчестерское кодирование, сейчас скорость примерно 12кбит. топология общая шина, работает на стопке разнокалиберных проводов сейчас примерно до 30м от адаптера к десктопу. Более дальние выносы еще не монтировал. Пока в работе датчики DHT22, BMP085. В стадии внедрения симисторные ключи для управления освещением и прочим, IR трансиверы на бытовую технику (код уже есть, проверено — работает управляя светодиодной лентой). Позже еще и анализ нагрузки в сети.
На десктопе — система majordomo, на их форуме немного подробнее описывал.
smartliving.ru/forum/viewtopic.php?f=8&t=450
mk90.blogspot.ru/2009/04/1-arduino.html
learn.adafruit.com/arduino-tips-tricks-and-techniques/bootloader
У меня сейчас проблемы с оперативной памятью.
Хотел за некоторое время собрать статистику, а потом подкорректировать алгоритм.
Возможно со временем переделаю схему или другую метеостанцию сделаю с выносными датчиками, тогда над алгоритмом предсказания придется основательно думать.
Тот алгоритм, что делал я не работает из-за проблем с памятью.
В основе моего алгоритма лежит сравнение давления за последние часы и несколько суток. Если выходит за пределы, то проверяется какой на текущий момент сезон года и какое время. В зависимости от этого должна была выводится соответствующая пиктограмма. Сам понимаю, что алгоритм грубоватый, но у меня других источников небыло, кроме своих мозгов :-).
Сможете добавить передачу данных на проект Народный мониторинг? Хочу добавить Ваш пример реализации в каталог поддерживаемых устр-в. Заодно и примерную общую цену компонентов укажите для тех кто захочет повторить Ваш опыт.
А у автора обзора устройство офлайновое и не может отправлять данные в интернет.
Еще даже не пятница вроде бы)))
Вижу что устр-во оффлайновое, поэтому и прошу «допилить».
Сам просто пытаюсь сделать нечто гораздо более простое…
Поделитесь пожалуйста скетчем :)
Заранее признателен.
Поделитесь пожалуйста скетчем
Решил тоже сделать метеостанцию, все в принципе уже купил, пот только интересно, как реализовать предсказание погоды, если ответите, то буду очень благодарен!
Тут реализовано банально, вот что я нарыл:
«у меня тоже новостей не много
оказывается, теперь вся погода рассчитывается на основе показаний со спутников, а местные метеостанции просто нужны для контроля прогнозов и сохранения истории
к сожалению, более менее точный краткосрочный прогноз без измерения скорости ветра получить проблематично, но мне посоветовали сделать так:
измеряем температуру, влажность и давление раз в минуту в течении часа
смотрим общую тенденцию изменения
если ожидается кратковременный дождь, то температура будет падать за час на 1-2 градуса, давление может и не меняться, влажность может измениться только за считанные минуты до начала дождя, а вот ветер должен усиливаться
если температура упала на 3-5 (или более) градусов за час, давлени упало на 7 мм и ниже, то прячьтесь — будет гроза и шквалистый ветер
если увеличивается влажность, а температура и давление изменяются незначитально — парит, ночью или утром возможен проливной дождь
обратная сторона медали — если в течении нескольких дней изменение суточных данных примерно одинаковое, то это основной признак изменения погоды в худшую сторону
что я вынес для себя
буду оживлять свой логер погоды на PHP, но добавлю датчик дождя для контроля, а там уже в графическом виде может получится найти какие-то закономерности
по поводу неточности работы действующих метеоалгоритмов — они писались как унивесальные. к каждому требуется применять различные коэффициенты в зависимости от местности
Что я узнал — сейчас метеорологи — это просто операторы ЭВМ. Уже давно ушли на пенсию люди, которые что-то могли подробно рассказать.
ну ладно, будем рыть сами. с миру по нитке… что-то соберем»
Скопировано отсюда:
arduino.ru/forum/proekty/predskazanie-pogody-po-davleniyuvlazhnosti