Ещё один способ определения качества воздуха на Arduino — с передачей данных в сеть

Оригинал поста на хабре

Меня зовут Евгений, и я - веб разработчик. Уже есть десятки постов о различных метеостанциях на ардуино, но мне хотелось написать о том, что в 2016 году можно быстро, легко и без знания электротехники собрать полезный датчик, претендующий на IoT, который легко может работать с вашей инфраструктурой, написанной на чём угодно. Если вам интересно, зачем вообще измерять СО2, то полезные ссылки вы можете найти в конце поста.

Итак, наша цель - сделать датчик температуры, влажности и СО2 с отображением данных на дисплей и отсылкой на веб сервер. Что нам для этого понадобится:

Компоненты

1\. Ардуино. Я взял Wemos D1, Arduino совместимую плату, основанную на микроконтроллере ESP-8266EX. Wemos совместим с ардуино IDE, у него есть свой Wi-Fi, и стоит он 6.3$.

2. Датчик СО2. Ранее я пробовал обычный MQ-135, но даже после прожига, калибровки и учёта поправок на температуру и влажность погрешности был довольно заметные - около 300 ppm. Так что для гарантии точных измерений я взял MH-Z19 - самый дорогой компонент схемы, 27$.

3. Датчик температуры и влажности. Использовал стандартный и любимый всеми DHT11 за 1.44$. В комментариях подсказывают, что лучше брать DHT22, но для схемы и стоимости это не принципиально:

4. I2C совместимый дисплей. Я взял самый дешёвый hd44780 за 3.06$.

5. Чтобы это выглядело не очень ужасно, и было перемещаемо, так же неплохо иметь корпус. Чтобы не заморачиваться с выпиливанием, я взял корпус за 8$ с дырками и креплениям под usb и дисплей. Внимание - в корпусе должны быть дырки для проветривания, иначе он будет измерять только свою особую атмосферу.

6. Отладочный USB кабель и около 10 проводков. Цену учитывать не буду.

Итоговая стоимость - 44 доллара, если брать на алиэкспресс. Аналогичные устройства без возможности что-то передавать в сеть сейчас стоят у китайцев в районе 100$. Аналог от Tion, которые в количестве делают свои посты на гиктаймс с рекламой бризеров, пока в разработке (не имею к ним отношения, а жаль).

Заказал, обождал месяц - приступаем к сборке! Нет ничего проще.

Сборка

1. Подключаем датчик температуры и влажности. Земля к земле, прах к праху, плюс к пяти вольтам на ардуино, цифровой выход к цифровому выходу (я использовал D5).

2. Подключаем датчик СО2. У него есть богатый выбор интерфейсов - PWM, аналоговый и цифровой вывод. Единственный элемент пайки - надо приделать ножки на нужные выходы. Проверял лично - работают все. Остановился на получении цифровых данных - точно, красиво, лаконично, и так же есть возможность отсылать команды на калибровку, что мне впрочем не потребовалось. Опять же - земля к земле, плюс к другим пяти вольтам, TX и RX выводы на цифровые пины - в моём случае, на D6 и D7.

3. Подключаем дисплей. И снова - земля к земле, плюс на последний оставшийся выход на пять вольт, SDA на дисплее к SDA на ардуино, SCL так же к SCL.

И… Всё! Можно закручивать получившееся добро в корпус, если вы конечно не умудрились сделать какую-нибудь ошибку при подключении. Обратите внимание, чтобы у датчика СО2 не оказались прижаты воздухозаборники (или как это корректнее назвать, белые такие штуки). Как бонус, при сборке в корпусе значительно уменьшаются отклонения в измерении.

Прошивка

Отлично, нам осталось “только” написать софт. В ссылках ниже есть репозиторий на гитхабе, который можно просто залить и использовать. Единственный тонкий момент - у вашего дисплея может оказаться другой адрес. Воспользуйтесь мини программой из ссылок для сканирования адресов i2c и поменяйте на нужный, если сразу не заработает. Перед сканированием отключите остальные устройства, иначе можно получить много мусора.

Да, Wemos D1 является совместимым с Arduino, и вам нужно просто добавить в Arduino IDE соответствующую борду. Подключаем стандартным коротким кабелем по micro USB и заливаем прошивку. Если вы всё сделали верно, то устройство сначала постарается подключиться к Wi-Fi (сеть и пароль берётся из файла настроек), затем ждёт некоторое время для “разогрева” датчиков, и наконец покажет данные на дисплее. Если по сети данные отправить не получится, то будет об этом сообщать. Если уровень CO2 допустимый, то после загрузки подсветка выключится, и включится только если вам пора открыть форточку.

Результат

У меня это выглядит так (осторожно, трафик):

В разобранном виде

В собранном виде, с выключенной подсветкой

Пора проветрить!

А как же сеть?

Теперь насчёт работы с сетью. Не мудрствуя лукаво, я собираю данные в JSON и отсылаю его на сервер обычным POST запросом, где простой скрипт на PHP кладёт его в MySQL базу. Далее можно посмотреть, как изменялись ваши условия жизни в течении дня при помощи PHP и Google Charts - вся серверная часть тоже есть в ссылках.

В итоге по смешной цене, с нулевыми знаниями в электротехнике и с минимальными затратами времени мы может получить примерно такие симпатичные графики: Осторожно, трафик

Не скажу, что это прям срывает покрова с простой истины, что “меньше народу - больше кислороду”, и что нужно периодически проветривать, да и про это много раз говорили - в том числе и про вред пластиковых окон. Но на этом примере понятно, насколько просто, быстро, надёжно и красиво можно сделать практически любой датчик, который поставляет данные для какой-то более сложной системы.

Да, показания я сравнивал с вот таким китайским датчиком Green Life - показания практически идентичные, только мой немного быстрее реагирует на изменение обстановки:

На картинке поднята контрастность дисплея - на нём всё видно отлично, но телефон перекорёжило от его света:

Выводы

Конечно, многое можно было бы сделать лучше. Навскидку я вижу следующие минусы:

  1. Дисплей с выключенной обладает очень низкой контрастностью. Лучше брать другой, разорившись ещё центов на 10.
  2. При включенной подсветке экран немного мерцает. Не критично, но видимо не нравится ему, что от ардуины запитывается сразу три устройства на пять вольт. Вероятно, правильно было бы сделать раздельное питание.
  3. Конечно, всё это можно красиво спаять, а не просто покидать в коробку, кое как соединив.
  4. Датчик температуры и влажности иногда возвращает левые огромные значения. Их я просто отсекаю, но вообще неприятно. Возможно, сказывается общая запитка или некачественное соединение.
  5. Конечно, можно было бы накапливать статистику и периодически её отсылать (и накапливать в случае ошибок) - никому не нужно знать своё качество воздуха с точностью до 5 секунд.
  6. Чтобы не вбивать данные вайфайной точки при компиляции, можно было бы сделать, чтобы в случае, если коннект не удался, устройство переходило в режим вайфай точки (да, Wemos это умеет), подцепившись к которой, можно его перенастроить - в том числе ввести новое имя сети и пароль.
  7. Wemos D1 всем хорош, но у меня иногда вылетает (раз в 2-3 дня) по неизвестным причинам, и сам перегружается только через несколько часов. Вроде как не мой софт кривой, просто борда не очень стабильная. Можно с этим бороться подключением устройства к какой-нибудь ардуино нано, которая его перезапускает при необходимости, или просто поставить железку с таймером, которая будет раз в полчаса перезапускать устройство (благо у него есть вход RESET).
  8. При выдёргивании и возврате обратно питания, датчик СО2 сходит с ума, что лечится перезагрузкой. Я это решил простым способом - при накоплении некоторого количества непрерывных ошибок, устройство само себя перезапускает, после чего всё приходит в норму. Вероятно, можно было бы решить это более правильным способом на уровне железа.
  9. Температура измеряется с точностью до двух градусов, влажность - с точностью до десяти процентов. В бытовых целях достаточно, а для какого-то другого использования понадобится датчик поточнее.
  10. Если вам требуется отправить один небольшой пакет данных, то библиотека для работы с JSON это убийство воробьёв из пушки. Гораздо проще собрать JSON ручками, или вообще передавать параметры при помощи GET/POST, что я вначале и делал. Но при наличии огромного количества оперативки на Wemos - почему нет, так красивее. Но при портировании кода на маломощную ардуину скорее всего придётся переписать это.
  11. В текущей реализации нет управления яркостью подсветки - она может быть только включена и выключена. Можно убрать перемычку и поставить вместо неё сопротивление или ввести на ардуино - тогда вы сможете управлять яркостью подсветки.
  12. Так же можно сделать управление или получение информации при помощи приложения. Самый простой способ, как ни смешно - добавить телеграмм бота - библиотека для связи ардуино через телеграмм уже есть.

Что дальше

А дальше я хочу отдохнуть от рабочих будней и поиграть с друзьями в лазертаг. Одна проблема - стоит игра от 500 рублей в час на человека. Это при полном отсутствии расходников. А купить комплект для игры будет стоит каких-то совсем заоблачных денег - примерно от 8000. Так что для того, чтобы поиграть в лазертаг, надо сначала его собрать. Планирую сделать что-то вроде Skirmos - где каких-то денег будет стоит только сам ствол, который должен быть довольно прочным. Интересно? Следите за публикациями! А что вы делаете на Arduino?

Ссылки

Основное

  1. Код для ардуино
  2. Серверная часть
  3. Посмотреть на воздух в моём офисе можно тут
  4. Взять меня на работу (да, я её ищу) можно тут

Полезное

  1. Если вы ничего не знаете про СО2 - https://geektimes.ru/company/tion/blog/269134/
  2. О wemos d1
  3. Спецификации датчика MH-Z19
  4. Хорошая статья, примерно про то же самое, но без сети, с дисплеем от телефона, с работой по PWM и на Arduino nano
  5. Сканирование устройств на i2c
  6. Будущий аналог датчика от Tion (не имею к нему отношения)
  7. Решение для перезапуска ESP8266 на уровне железа
  8. Ещё одна хорошая статья про ESP, Lua и CO2
  9. А тут студенты МАМИ занимаются всякой хорошей элетроникой. Кстати, им требуются преподаватели. Скоро буду там вести лекции.

Использованные библиотеки

  1. Библиотека для работы с дисплеем
  2. Библиотека для создания JSON
  3. Библиотека для работы с семейством сенсоров DHT

Один день Зимы

Огромные кристаллы снежинок, порхая в воздухе, неумолимо стремились к грязному асфальту, превращаясь на нём в тёмную слякоть. Они могли танцевать, застывать на предметах, резкие порывы ветра иногда вскидывали их обратно вверх - но судьба их была предрешена. Я подставил им лицо, и они таяли, оставляя на нём длинные влажные следы. Неплохая судьба, если сравнить их с теми, что были безжалостно размазаны и стекали в канализацию тёмными лужами. А ведь когда-то я шёл сквозь снег и ни одна снежинка не посмела ко мне приблизиться, словно облетая невидимую преграду.

Бег с Microsoft Band

Не так давно стал счастливым обладателем Microsoft Band. До него бегал сначала с Endomondo на телефоне, потом с Strava, потом получил Suunto Quest с HR датчиком, и радостно использовал его. Поскольку у нас пока в продаже MS Band нету, то наверняка обзор будет интересен. Если что, купить это чудо можно примерно за 10.000 рублей на ebay. Не за 17, как у нас продают :)

Итак, что же мы хотим от устройства?

  1. Пульс. Думаю, комментировать очевидное не стоит.
  2. GPS. Важно знать пройденное расстояние и интересно смотреть на маршруты, которые пробежал. На той же Strava можно ещё сравнивать своё время на известном маршруте с другими бегунами. Бывает интересно - побегал в произвольной местности, а потом оказалось, что там тоже кто-то бегал. Сравниваешь, радуешься… Или огорчаешься и мотивируешься :)
  3. Количество шагов. Не так важно, но интересно.

Маскировка ссылок в произвольных полях с wp-noexternallinks

Внимание! Я более не занимаюсь поддержкой этой плагина, после версии 3.5.9.9! Пожалуйста, задавайте вопросы на странице поддержки wordpress.

Маскировать ссылки в произвольных полях при помощи wp-noexternallinks очень просто. Сначала, нужно найти место, где идёт вывод вашего произвольного поля. Скорее всего, он идёт в файле вашей темы, single.php. Выглядеть он должен как-то так:

echo get_post_meta(get_the_ID(), 'имя_вашего_поля', 1);

Затем редактируем его, чтобы он выглядел так:

//получить содержимое поля
$text=get_post_meta(get_the_ID(), 'имя_вашего_поля', 1);
//Использовать на содержимом поля все те же фильтры, что на стандартном выводе контента страницы
//В эти фильтры так же входит фильтр wp-noexternallinks:
$text_filtered=apply_filters('the_content',$text);
//Вывести отфильтрованный текст:
echo $text_filtered;

Заметьте, что если вы не маскируете ссылки в тексте поста, а маскируете их в комментариях, то пятая строчка должна выглядеть так:

//Использовать на содержимом поля все те же фильтры, что на стандартном выводе комментария пользователя
//В эти фильтры так же входит фильтр wp-noexternallinks:
$text_filtered=apply_filters('comment_text',$text);

Заметьте, что если произвольное поле выводится при помощи плагина, то вам придётся править его код или как-то ещё обрабатывать его вывод.

Обновление Я так же добавил фильтр, который можно вызывать в коде без остальных, вот так:

$text_filtered=apply_filters('wp_noexternallinks',$text);

Masking links in custom fields with wp-noexternallinks

Warning! I no longer support this plugin after version 3.5.9.9! Please ask questions on wordpress support page.

Masking links in custom fields with wp-noexternallinks is really simple. At first, you need to find the place where your custom field is being output. It should be in your theme file, single.php.

Then edit output so it looks like this (you should change custom_field_name to your field name):

//get custom field text with links:
$text=get_post_meta(get_the_ID(), 'custom_field_name', 1);
//Apply all the filters that are used for post content on custom field text.
//It will also apply wp-noexternallinks filter:
$text_filtered=apply_filters('the_content',$text);
//output filtered text:
echo $text_filtered;

Notice that if you don’t mask links in your posts’s content but mask them in comments, your fifth line should look like this:

//Apply all the filters that are used for user comments on custom field text.
//It will also apply wp-noexternallinks filter:
$text_filtered=apply_filters('comment_text',$text);

If custom field output is generated by plugin then unfortunately you will have to edit plugin code or try to preprocess it’s output.

UPDATE I also provided custom filter to process links. You can call it like this:

$text_filtered=apply_filters('wp_noexternallinks',$text);

Encrypting links for WP-NoExternalLinks

Warning! I no longer support this plugin after version 3.5.9.9! Please ask questions on wordpress support page.

This article is based on this one and the latest version of plugin. Now you can easily encrypt your links without changing plugin code.

  1. Ensure that you have php-mcrypt installed:

For CentOS, type

sudo yum install php-mcrypt

For ubuntu, type

sudo apt-get install php5-mcrypt

For windows, enable this extension in php.ini:

extension=php_mcrypt.dll
  1. Create file wp-content/uploads/custom-parser.php and add here the following:
salt ='ms8-sRt-kBs5-s1wQ';
    $this->iv=mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
  }
  function encode_link($url)
  {
    if(!$this->salt)
      $this->init_crypt();
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->salt, $url, MCRYPT_MODE_ECB, $this->iv)));
  }
  function decode_link($url)
  { 
    if(!$this->salt)
      $this->init_crypt();
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->salt, base64_decode($url), MCRYPT_MODE_ECB, $this->iv));
  }
}
?>

Do not forget to change $salt to any custom value! Also, add statistic handling from the original function if you use statistics.

Custom parser for WP-NoExternalLinks

Warning! I no longer support this plugin after version 3.5.9.9! Please ask questions on wordpress support page.

Recently I added a new feature to this plugin. Now you can extend it yourself without danger of plugin update which could remove all your changes in plugin code.

In this sample, we will overwrite function check_follow, which checks if link is posted by admin and has rel=”follow” attribute. Let’s imagine we want all our authors to have the same options. How can we accomplish it? Easily! Just create file custom-parser.php in directory wp-content/uploads and replace

user_can($author,'manage_options' );
from original function with
user_can($author,'publish_posts' );
- voila!

Here is the full code of our new modified class which will be loaded instead of basic one:

wp-content/uploads/custom-parser.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
if(!defined('DB_NAME'))
die('Error: Plugin "wp-noexternallinks" does not support standalone calls, damned hacker.');

#include base parser
include_once(ABSPATH . 'wp-content/plugins/wp-noexternallinks/wp-noexternallinks-parser.php');

class custom_parser extends wp_noexternallinks_parser
{
function check_follow($matches)
{
#support of "meta=follow" option for admins. disabled by default to minify processing.
if(!$this->options['dont_mask_admin_follow'])
return false;
$id=array(get_comment_ID(),get_the_ID());//it is either page or post
if($id[0])
$this->debug_info('It is a comment. id '.$id[0]);
elseif($id[1])
$this->debug_info('It is a page. id '.$id[1]);
$author=false;
if($id[0])
$author=get_comment_author($id[0]);
else if($id[1])
$author=get_the_author_meta('ID');
if(!$author)
$this->debug_info('it is neither post or page, applying usual rules');
elseif(user_can($author,'publish_posts' )&&(stripos($matches[0],'rel="follow"')!==FALSE || stripos($matches[0],"rel='follow'")!==FALSE))
{
$this->debug_info('This link has a follow atribute and is posted by author, not masking it.');
#wordpress adds rel="nofollow" by itself when posting new link in comments. get rid of it! Also, remove our follow attibute - it is unneccesary.
return str_ireplace(array('rel="follow"',"rel='follow'",'rel="nofollow"'),'',$matches[0]);
}
else
$this->debug_info('it does not have rel follow or is not posted by author, masking it');
return false;
}
}
?>

One more sample is encrypting links.

Бегущий в лабиринте - победа маркетинга над разумом

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

  1. за всю трилогию нет никакой эволюции персонажей. Какими они были с самого начала - такими и остались.
  2. “глубокие переживания” и эмоции персонажей поднимаются не выше пятого класса средней школы. Всё просто как сценарий телевизионного ток шоу на канале тнт. С учётом того, что нам ещё и пытаются скормить, что это самые умные и наиболее эмоциональные подростки… It smells.
  3. рояли выпрыгивают из кустов с такой скоростью и в таком количестве, что повествование даже нельзя воспринимать всерьёз. Ты заранее знаешь, что тебя наёбывают. Причём делают это крайне топорным методом - например, загадка разрешается ответом “просто всемогущие наблюдатели, которые могут делать что угодно с их мозгом, подменили их восприятие”.
  4. на корню отсутствует хоть какая-то оригинальность мира и сюжета. Впрочем, даже автор признаётся, что именно он так убого копировал.
  5. главной идеи, озарения, катарсиса к концу трилогии - ничего нет. Всё те же рояли.
  6. так же полностью отсутствует какая-либо выразительность и колорит, который раскрашивает черновик повествования. Даже сленг в книге состоит менее чем из десятка слов, и убог донельзя.
  7. персонажи картонные. У большинства даже нет имён. Так и говорится “и тут погибло ещё десять человек, имён которых Томас не знал”. Именные персонажи в общем-то тоже никакие, безо всякой индивидуальности.
  8. абсолютно никак не раскрыты многие идеи и фишки. Например, практически немая и безымянная группа девушек, или сама телепатия. Недаром из фильма её вообще убрали - зачем собаке пятая нога?
  9. на закуску дабы показать примером общую характеристику трилогии. Главный герой убегает из рушащегося строения с двумя неравнодушными к нему девками. Я уже какое-то время задаюсь вопросом, как автор это разрешит. И тут автор разрешает. Одна из них выпихивает его из-под подающих обломков и умирает. Наверное, один из самых скучных штампов за всю историю книгопечатания, в котором автор полностью расписывается в своей беспомощности относительно того, чтобы как-то решить повествовательную задачу. Кстати, только сейчас подумал, что за трилогию это вторая такая идиотская смерть - первым был Чак, который заслонил главного героя грудью от ножа. Феерически бездарный и неправдоподобный штамп.

В общем, смотрите “обитель зла” и читайте “игру эндера” (на самом деле, можно и читать и смотреть и то и другое). А это… Обойдите стороной, сэкономьте время. Дико обидно, что такие вот бездушные и пустые подделки как-то находят путь на прилавки и в кинотеатры.

Пожалуйста, не здоровайтесь со мной

Немного о наболевшем. Есть люди, которые в рабочем общении (скажем, в скайпе) пишут тебе “привет”. И ждут потом. Могут ждать минуты, часы, дни. А суть вопроса так и не напишут. Видимо, они считают это вежливым общением - то ли просто не делают разницу между живым и электронным общением. Мне очень хочется, чтобы к концу прочтения этой статьи они так уже не считали.

  1. Когда вы пишете “привет”, я знаю, что вам от меня что-то нужно. И вы не просто так здороваетесь и интересуетесь, что у меня нового. Так что всё это лирическое вступление без какого-либо рабочего наполнения по определению является мусором.

  2. Вы пишете штук пять бессмысленных тирад, и на каждую из них мне приходится переключиться, чтобы выдать вам бессмысленный ответ. Это занимает время на то, чтобы переключиться на вас, прочитать бессмысленный текст, придумать пустой ответ и попытаться вернуться к своей задаче. Таким образом, на эти предварительные ласки у меня может уйти 5-10 минут, в течении которых я мог бы в концентрации делать свои задачи. Я понимаю, что вам наплевать на моё время, но мне-то нет.

  3. Вы упрямо ждёте, что я окажусь онлайн вместе с вами. А что если нет? Тогда мы потратим трое суток на обмен любезностями, прежде чем вы мне наконец расскажете, в чём дело?

  4. Когда мы наконец перейдём к сути вопроса, вы будете выдавливать в чат по одному предложению, заставляя меня таращиться на этот грёбаный карандаш. Скайп будет непрерывно булькать, чат-мигать, и я вообще ничего не смогу делать. Ещё 10 минут на этот бардак.

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

Вместо заключения.

Быть вежливым очень просто - пожалуйста, пишите сразу и своё приветствие и суть вашего вопроса. Целиком, одним сообщением. Подробно. Со всем, что, как вы знаете, я у вас спрошу. Если у вас не работает программа - не надо писать “у меня не работает программа”. Вы же не только что с горшка встали. Вы можете написать мне её лог, текст или номер ошибки, в конце концов - скриншот.

Тогда я максимально быстро смогу вам помочь в один присест.

Ну или хотя бы, когда вы пишете приветствие - считайте, что я вам молча пожал руку - и продолжайте дальше.

Searching through skype history

If you have more then 300 contacts and they have overlapping conversations - you understand that it’s impossible to find anything with simple Ctrl+F approach.

Fortunately, Skype uses SQLite database and we can make a direct connect to it and search there directly. So, you need to:

  1. Download SQLite client (i used http://sqlitebrowser.org/ but you can install any client you like)
  2. Find your history file as it is decribed on skype web site:
Hold down the Windows key The Windows key on your keyboard, then press R to bring up the Run window. If you are using a touch screen device on Windows 8, you can bring up the Run window from the Search charm. Type %appdata%\Skype into the Run window and press Enter. Open the folder named after your Skype Name. Find the main.db file in the folder, this file is your chat history.
3) Use your SQLite client to open this file. 4) Open database table "messages" 5) Use any SQL queries you want to search for message you need. Here's an example of me searching for "git" word in conversations - but there are many field that you can use for searching and ordering.