Кластер против облака …

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

На всякий случай у меня под боком есть два компьютера. Ну как компьютеры … по нынешним меркам они скорее обзываются калькуляторами. Но тем не менее все необходимое у них есть. Пару-тройку виртуалок они потянут, а больше для меня и не надо.

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

cloud1

Вот вам пример. В одном окошке я запустил миграцию виртуальной машины с одной ноды “калькуляторного кластера” на другую, а во втором – просто посылал в сторону мигрируемой машины по пакету в секунду. Как видно на скриншоте, время недоступности машины составило 9 секунд. Общее время миграции было около 30 секунд. На настоящих кластерах время недоступности обычно не превышает и половины секунды. Много ли сервисов требуют для себя такого уровня доступности?

Или вот еще один пример, опять же многократно описываемый. Есть сервис, которому не хватает ресурсов.

cloud2

Если посмотрите на правое окошко (там консоль одной из виртуалок), то там openssl показывает, что он может подсчитать только 11 тысяч хешей md2 за 0.15с. А потом команда free докладывает, что памяти всего 256 мегабайт. Одна команда в левом окошке (на ноде) и openssl уже подсчитывает 540 тысяч за 3 секунды (или 27 тыщ за то же время), а памяти стало уже гигабайт. И все это без остановки или перезагрузки сервиса.

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

Для интереса предлагаю прикинуть, сколько потребуется времени и сил, что бы проделать подобное в обычной инфраструктуре. Удобно? Не то слово!

Надо развернуть новый сервер? Легко!

cloud3

17 секунд (калькулятор, да) и у вас есть готовая машина, которой надо только выделить ресурсы.

cloud4

А когда нужда в ней отпадет … секунда и ненужной машины больше нет.

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

Повторюсь, все это сейчас позволяет делать любая система виртуализации.

Но все-таки, чем отличаются облака от кластеров? Ведь они построены на одних и тех же принципах, позволяют делать одно и то же с одним и тем же результатом.

Отличаются они одним. Системой управления всем этим великолепием.

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

Во-вторых, системы управления заточены на разделение ресурсов. В кластере редко возникает необходимость отделить одну группу серверов от другой. В результате все сидят в нескольких VLAN’ах, разрулить которые легко руками. А в облаках тысячи (десятки, сотни – подставьте по вкусу) пользователей, которых надо развести по своим сетям и не давать серверам одного пользователя прямого доступа к серверам другого. Без системы управления, заточенной на облака, подобная затея попросту обречена на провал.

И наконец, облака тащат в себе всю … скажем так, специфику виртуализации. Скажем, для одного сервиса необходимы ноды, которые используют локальное хранилище, да и еще на SSD. А для другого хватит кусочка общего стораджа. Для каждого сервиса есть свои ограничения, требования, правила. И системы управления следят за тем (скажем, при миграциях), что бы каждый сервис работал на ресурсах того класса, который ему выделен, что бы не происходило overselling (или он был с заранее определенными параметрами) и так далее и тому подобное.

Поверьте, все это удержать в голове и рулить этим через консоль или какую-нибудь утилитку – абсолютно нереальная задача.

И вот за вот это вот снятие “головной боли админа” и просят производители денег. А так-то все можно сделать руками и из консоли …

Что нести в облачный офис?

Итак, несмотря на мои страшилки в предыдущих постах, вы все-таки решили использовать “облака” в своей деятельности. Хоть чуть-чуть, но использовать. Как выбрать то, что стоит нести в облака, а что не стоит?

Для этого есть несколько методик, ниже я попробую объяснить наиболее … подходящие, что ли.

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

“Ну ладно, веб-сайт понятно, а как же с почтой и телефоном? Их смогут читать/слушать чужие люди?”. Да, при наличии соответствующих навыков или всяких судебных решений их и так будут читать и слушать чужие люди. Если говорить про телефон, то на операторе (тот, который выдал вам телефонный номер) уже стоит система, позволяющая прослушивать все телефонные разговоры, проходящие через него. А что касается внутренних переговоров, то они в большинстве случаев абсолютно никому не интересны и способны забить любой сервер. То же самое касается и почты. Буквально пара команд у провайдера, который предоставляет вам доступ в интернет, как весь ваш трафик оказывается у него как на ладони. И не обольщайтесь насчет страшных слов SSL/TLS – в подавляющем большинстве случаев все вскрывается так же легко, особенно при наличии административного ресурса. Правда, вынужден добавить ложку меда: по разговорам со знакомыми, такое используют очень редко, ибо во-первых, принцип “неуловимого джо” никто не отменял, а во-вторых, через налоговую сделать все необходимое гораздо проще.

Следующая методика “берите все, что нам негоже”. Тут в облака отправляются данные, которые вам не нужны прямо сейчас или которые нужны всем. Тут главное установить принцип, насколько эти данные вам не нужны. Скажем, данные от систем резервного копирования вам именно сейчас не нужны, занимают много места и хранение их рядом с резервируемыми системами прямо противоречит всем нормам. Так зашифруйте их посильнее и пусть лежат где-нибудь в Америке. Что касается данных которые нужны всем: зачем устраивать на своем сервере каталог “для скачки”? Ролики, дистрибутивы программ и прочие подобные штуки с удовольствием примут к себе системы CDN. Будут довольные и пользователи, которые будут скачивать необходимое им быстро и Вы, так как канал до вас (или вашего сервера) не будет загружаться.

И наконец, в облака удобно/выгодно отправлять то, что относится ИТшному понятию R&D. Говоря кратко, то, что запускается “на посмотреть”, меняется по двадцать раз на дню и наполняется тестовыми или сильно устаревшими данными.

Теперь про данные, которые нельзя отправлять в облака. Понятное дело, Вы сами сможете определить список того, что позволить прочитать другим нельзя. У кого-то это будет бухгалтерия, у кого-то данные о техпроцессе, в общем, у каждого свое. Тут надо просто садиться и разбираться.

Но (по крайней мере для России) есть одна категория, которую нельзя отправить в “облако”: персональные данные. Говоря простыми словами туда попадает все от паспортных данных и места проживания и до всяких медицинских анализов и выписок. Нельзя не потому что не получится, а потому что “атата, если обнаружат”: ни одно известное мне “облако” не использует сертифицированных средств защиты информации. Вроде в России потихоньку начали появляться провайдеры, которые обеспечивают обработку персональных данных, но там от облаков только название, да и ресурсы, которые они могут предоставить, вызывают лишь недоумение.

А теперь абзац неприкрытой рекламы меня любимого: мне нравятся “облака” и я готов совершенно бесплатно (конечно, не откажусь и от оплаты, если предложите 🙂 ) поконсультировать/помочь/рассказать как сделать по поводу “облаков”. Просто из любви к теме. Я не связан с каким-либо провайдером или сервисом “облаков” или производителем систем виртуализции, поэтому мне абсолютно начхать на маркетинговые заморочки. Пишите письма на multik@multik.org, в skype пользователю kiltum или оставляйте комменты.

Дорогие мои облака …

В прошлый раз я обещал на пальцах показать, что облака дороже, но они дешевле. В принципе я уже писал про это, но это было давно и не правда.

Наверняка вы уже задумывались о использовании “облаков” в своем бизнесе, но простые расчеты на калькуляторе и консультации с ИТшниками неизменно приводили к обескураживающим результатам: стоимость аналогичного, но “облачного” сервиса неизменно оказывалась в 1,5-2 раза выше. Как же так? Ведь вон сколько компаний использует облака в своей работе и рапортуют о снижении расходов … А тут ИТшники опять начинают свою вечную волынку про недостаток серверов … Что делать?

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

1. Фаирволл. Он же брэндмауэр. Штука, которая выпускает вас в интернет, фильтрует лишнее и иногда служит HR-инструментом под названием “на какие сайты ходят сотрудники”. Хватит 50 тыщ.
2. Почтовый сервер. Без почты нынче никуда. Тут лучше заложить где-то в районе 100 тыщ.
3. Веб-сервер. Сайтик обычно много нагрузки не требует, поэтому тоже 50.
4. Сервер телефонии. Положим те же 50 тыщ.
5. Сервер бухгалтерии. Бухгалтера люди нервные, поэтому 100 тыщ и не надо экономить.
6. Файлопомойка. Сотрудникам надо файликами обмениваться. Возлагать это на почту – моветон. Тыщ 80 надо.
7. Резервное копирование. Есть компании, где уже теряли данные, а есть, где еще только будут. Тыщ 100.

Для начала хватит. Конечно, в реальности часть функций обычно объединяется на одном сервере, но у нас админ печется о безопасности, поэтому старается разнести все. Ну и в разных компаниях добавляются другие сервера: для разработки, тестирования и прочих штук. Но я их учитывать не буду.

Итого получается в районе 550 тысяч рублей. Эти 7 коробок жрут электричество, требуют охлаждения, запасных частей и квалифицированного присмотра. Через некоторое время их мощности начинает не хватать и начинаются узаконенные репресии пользователй в духе “более 500 мегабайт в почтовом ящике не хранить” и “бухгалтерия тормозит, потому что в сервере винт сдох” (хорошо, что тормозит. у некоторых просто падает). Знакомо?

Что делать? Бизнес растет, но на одних серверах разориться же можно … И тут в дело вступает хороший, качественный ИТшник. Срываю так сказать, покровы. Для начала: одиночные сервера никогда не загружены на 100%. Из-за разных там особенностей больше 60-70% нагрузку поднимать попросту нельзя: будет все ломаться.

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

Отсюда вытекает вполне логичное предложение: почему бы серверу резервного копирования не поделиться днем своими ресурсами? А серверу бухгалтерии и файлопомойки ночью? С использованием современных технологий – легко.

Сам процесс объединения стайки серверов в “облако” я пропущу. Вам это во-первых попросту неинтересно, а во-вторых, там слишком много нюансов, описанию которых пришлось бы посвятить много места.

В общем, сразу перескочу к моменту, когда из уголка админа раздаются невнятные, но несомненно радостные возгласы. Пропущу так же сложный процесс ломки мышления того же админа, пока он осознает, какие возможности он получил в свои руки.

Вам же главное знать то, что у вас теперь есть свое “облако”. Персональное, частное – называйте как хотите.

Что вы получаете?

– Возможность продать один-другой сервер. Подчеркиваю – возможность (ИТшники просто так не выпустят из своих рук 🙂 ). Ибо если одиночные сервера нельзя грузить на 100%, то в “облаке” вполне.
– Более высокую доступность серверов. Теперь в случае поломки одного из “железных” серверов есть возможность попросить “пододвинуться” другие, пусть и за счет уменьшения скорости работы.
– Возможность отдавать более мощный сервер (у нас же сервера не одинаковые изначально) на более необходимую сейчас работу. Скажем, днем самый мощный сервер будет помогать процессу сдачи бухгалтерского отчета, а ночью обрабатывать данные для системы резервного копирования.
– Более разумно распределять нагрузку. Скажем, отобрать ночью у почтового сервера ресурсы процессора в пользу других. Пусть письмо ходит не 1-2 секунды, как днем, а 10-20. Кому какая разница?

А теперь о более приятном. Если делать подобное с “нуля”, то более высокую производительность и бОльший запас по мощности всего комплекса можно получить с помощью пары серверов, каждый из которых стоит по 200тр. И эти серверы будут жрать меньше электричества, меньше греть окружающую среду и требовать меньший уход. 150 тысяч экономии прямо “в лоб”!

Но это “частное облако”. Как же можно заработать или сократить расходы с помощью публичных облаков?

Для начала можно легко увеличить безопасность вашего бизнеса. Не знаю как в других странах, но в России до сих пор не изжили “изъятие вещественных доказательств”. С одной стороны, счет не заблокирован и на нем есть деньги, а с другой – все данные остались на тех самых “вещественных доказательствах”. Вот для примера бухгалтерия. Объемы базы данных очень редко превышают еденицы гигабайт. Вот возьмите и дайте задачу, что бы система резервного копирования попутно заливала данные еще и туда. Для безопасности – хорошо зашифрованными. Сейчас стоимость хранения одного гигабайта на S3 – $0.03 в месяц. Да, я не ошибся – три цента за гигабайт в месяц. Добраться до архивов можно будет с любого компьютера, подключенного к интернету, а уж что с ними делать – дело ваше. Сравните со стоимостью хранения подобного где-нибудь на стороне “обычным” способом.

Затем рассмотрите свои бизнес-процессы и выделите те, которые требуют непродолжительных, но больших компьютерных ресурсов. Скажем, в каком-нибудь рекламном агенстве это может быть процесс рендеринга роликов. Покупать для этого отдельный мощный сервер, который будет 90% времени пинать балду – не выгодно. А без него никак. Куда лучше за $3 в час арендовать гораздо более мощный сервер в облаке и использовать его только тогда, когда надо. И кто мешает арендовать не один сервер, если роликов много?

Надо изредка рассылать большие объемы писем (и которые ни разу не спам)? Вон, SES берется доставить со всеми заморочками тысячу писем за 10 центов. Стоимость обычного почтового сервера, способного переварить хотя бы 20-30 тысяч писем за час, предлагаю узнать самостоятельно.

И так далее и тому подобное. Везде, где требуются большие объемы, гораздо дешевле воспользоваться мощностями гигантов, чем пытаться сделать свое и на коленке.

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

И подобных возможностей в каждой компании – уйма. Честно.

Если все так хорошо, то почему все так плохо? Во всем этом есть одна большая ложка дегтя: без квалифицированных специалистов подобное реализовать нельзя. В смысле реализовать можно, но вы скорее потеряете деньги, чем сэкономите. И пока технологии “молодые”, нет никаких сертификатов, лицензий и прочих документов, свидетельствующих о том, что тот или иной ИТшник умеет “нырять” в облака и что более важно, “выныривать” из них …

А таких – мало.

Облака, белогривые лошадки …

… или о облаках простыми словами.

Покупайте наших слонов, теперь и в облаках! Самые облачные облака по выгодным тарифам!

Такое или примерное такое сейчас можно увидеть и услышать в любой рекламе услуг, связанных с компьютерами. Что же такое облака и чего с ними можно делать?

Для начала маленький экскурс в историю. Давным-давно компьютеры умели выполнять только одну задачу за раз. И если он начинал считать, сколько будет 2+2, то нипочем не хотел останавливаться. Потом компьютеры научили делать сразу несколько задач. Они могли одновременно считать сколько будет 2+2 и спрашивать у пользователя, сколько ему лет. Потихоньку увеличивая мощность компьютеров дошли до того, что один мощный компьютер мог представляться для окружающих кучей слабых. Ведь для очень многих задач куча слабых компьютеров гораздо удобней и выгодней одного, но очень мощного.

Но тут пришли продавцы и маркетологи. Первым надо было увеличить продажи, а вторые помогали первым, ведь им тоже перепадал кусок пирога.

Поначалу шаги было очень осторожными. Практически все шло под лозунгом “сократи расходы на сервера”. Ведь в самом деле, поставить и обслуживать один мощный сервер гораздо дешевле, чем кучку маленьких. Тут и стали называть эти маленькие сервера виртуальными. Ведь их нельзя пощупать, но они есть. Постепенно технологии дошли до того, что стало возможно объединять мощные сервера между собой так, что они могли “делиться” с соседями виртуальными серверами без их остановки. И на всех схемах сети такая конструкция обозначалась облаком. Типа мы знаем, что сервер там, но детали реализации от нас скрыты.

Ушлые маркетологи мгновенно раскопали ассоциацию и начали толкать “облака” в массы. В результате вышеописанное (несколько мощных серверов, которые стоят в серверной у вас за стенкой) стали называть “частное облако” или private cloud.

Тут же появились провайдеры, которые стали предлагать “облака” для всех страждущих. Такие облака стали называть “публичными облаками” или public cloud. Услуга довольно быстро стала популярной: ведь большинству людей не нужны для своих задач мощные компьютеры, а провайдерам очень дорого обслуживать обычные слабые сервера.

Следующим появились на свет “гибридные облака”. Это когда часть виртуальных серверов работает в серверной за стенкой, а часть – у провайдера. А для вас – ну абсолютно никакой разницы, где они размещены. Вы работаете с ними одинаково во всех случаях.

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

Итак, в чем же основное преимущество облаков?

– Снижение расходов на серверный парк. По моим прикидкам, переход с классической схемы (один сервис – один сервер) на облачную (много серверов – много сервисов) дает экономию примерно в 20-30% просто от самого факта использования.
– Снижение времени простоя. Теперь для обслуживания “железного” сервера нет необходимости останавливать работу размещенных на нем сервисов.
– Резкое ускорение специфических для ИТ задач. Поднять новый сервер или скопировать работающий – дело минут, но никак не часов.
– Возможность при наличии соответствующих навыков кратковременно и очень резко увеличивать мощность какого-либо сервиса.

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

“Старые” облака (провайдер вам предоставляет один или несколько серверов, возможно объединяя их в одну сеть с вашей) стали называть IaaS (Infrastructure as a service). Инфраструктура как сервис. Легко понимаемая всеми ИТшниками модель. Яркий пример – Amazon

Вон та возможность резко увеличивать мощность (повторюсь, при наличии навыков!) привела к следующему варианту облаков: PaaS (Platform as a service). Платформа как сервис. Пример – Azure. Суть простая. Берет провайдер толковых спецов, которые настраивают какой-либо сервис как надо. А потом продает этот сервис вам. Скажем, у вас есть веб-сайт, на который приходит 1000 человек в день. Ваши маркетологи, продавцы и прочие товарищи что-то такое замутили, что к вам внезапно пришло 100000 человек. Обычно веб-сайт в таких случаях тупо умирает под нагрузкой. В случае PaaS правильно настроенный сервис начинает поднимать для внезапно свалившейся нагрузки еще сервера. Десять, сто, тыщу. В общем пока не переварит весь поток. А потом точно так же берет и “убивает” ставшие ненужными сервера. В итоге все довольны: пользователи увидели ваш сайт, а не сообщение о недоступности, вы получили новые заказы, а провайдер – деньги.

Очень это понравилось маркетологам и они придумали SaaS (Software as a service) или программа как сервис. Оно очень похоже на PaaS, но про отдельный сервис. Скажем, вам нужен почтовый сервер. Можно сказать админу, он купит сервер, настроит его … А можно пойти к провайдеру и купить доступ к его почтовому серверу. Если у вас в компании 100 человек, так и купите кусочек провайдерского сервера на 100 человек. А провайдер пусть уже сам мучается с антивирусами, антиспамами и прочей фигней. Яркий пример – Office 365.

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

Думаете это кого-то остановило? Неа, просто стали продавать старое под новым соусом.

И для резюме нужно подвести итоги. Сравним их с привычной всем “своей серверой”

Преимущества:
– Быстрота развертывания. При наличии денег на карточке можно получить полностью готовый сервер или сервис за десятки минут. Причем в стране на выбор.
– Более высокая доступность. У провайдеров просто больше возможностей это обеспечить.
(ТОЛЬКО для частных облаков) – Более низкая стоимость обслуживания

Недостатки:
– Более высокая стоимость обслуживания. На данный момент – в 1,5-2 раза дороже. За тренд надо платить.
(для всех КРОМЕ частных облаков) – Полная потеря контроля за вашими данными. Что бы там не писали маркетологи в пресс-релизах и зазывалках, данные из облака очень легко (по сравнению с классической схемой) могут быть взяты без возможности какого-либо контроля с вашей стороны. Люди, которые имеют доступ к физическим серверам, всего лишь люди.

Тут обычно возникает мысль про то, что я (в смысле автор) ничего не понимаю. Ведь если “облака” стоят дороже, то почему ими пользуются? Люди же не настолько глупые …

Но где можно “выиграть в облаках”, я напишу в другой раз. Вдруг никому не надо и я только зря клавиатуру терзал? 🙂

Добавляем гламура

Решил вылечить очередную родовую болезнь Дрыня: не фиксирующиеся крышки бензобаков. Быть “лопоухим” как-то не комильфо, все-таки не запорожец ..

Для лечения этой болезни на просторах сети я нашел аж целых четыре рецепта:

– Врезать замок.
– Высверлить крепление пружинной пластины и подогнуть ее. Потом прикрепить ее обратно.
– Ближе к оси крышки приделать дополнительную пружину.
– Заменить резиновый демпфер болтом и на крышку прицепить магнит.

После сборки часов для тещи у меня остались шикарные неодимовые магниты. Я убрал резинку, вкрутил на ее место болтик (М5 или М6 – не помню), шлепнул на крышку магнит … Да, крышка теперь держится хорошо, но звук, с которым она закрывается … Этакий “бам с жестяным скрежетом и дребезгом”. Попытка смягчить звук путем наклеивания нескольких слоев изоленты не удалась: просто добавилось “причмокивание”. Вроде бы и так пойдет, но машина-то для удовольствия, а на каждой заправке слушать этот дребезг с чмоканьем не хочу. На виброизоляцию крышки я был морально и материально не готов, поэтому вернул все в первоначальное состояние.

Сел думать. Пошерстил интернет. Взапно озарило: кто сказал, что магниты могут быть только прямоугольными или квадратными? Цилиндрические тоже есть!

Мухой в магазин, где закупил кучку цилиндрических магнитов диаметром 4мм и длиной от 3 до 6 мм. Пригодятся.

Из магазина к машине на примерку. У меня получилось, что “сверху” от крепления до дверцы 9мм, а “снизу” – 10мм.

Десять раз примеряю и клею!

20131215_153616

20131215_153630

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

Получилось просто изумительно: крышка закрывается, потом с легким таким стуком фиксируется. Куда там дверцам всяких майбахов и ройсов … Доволен.

Никто не останется без снимка на память …

Для некоторых первые километры на машине сродни первым шагам ребенка – точно такие же незабываемые и волнующие. А для кого-то наоборот, очень волнующими являются последние метры.

Когда я анализировал свою последнюю аварию, совершенную еще на Д2, то я очень огорчался, что у меня не стоял видеорегистратор. Человеческая память крайне избирательная и не желает хранить самые неприглядные моменты жизни, а надо. В последующем я подобные промахи не повторял: у меня всегда в машине стоял видеорегистратор. Кстати, видеорегистраторы не всегда используются для записи аварий – ингда на них попадают и просто смешные моменты, особенно если регистратор поддерживает функцию “детектор движения”. Опять же некоторые утверждают, что вид стоящего видеорегистратора дисциплинирует представителей полиции, но тут утверждать не берусь, ибо как-то у меня с ними получается ладить и без применения подобных средств массового поражения.

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

Какие же регистраторы бывают и чем различаются?

Регистраторы бывают стационарные – когда блок, где происходит запись размещается отдельно и мобильными – когда сам блок объединен с камерами. Стационарные обычно ставят на коммерческий транспорт, когда необходимо регистрировать картинку с 3-4 камер, попутно обрабатывая данные от нескольких датчиков. Нам они не интересны. А вот мобильные, которые включаются в прикуриватель, крепятся на стекло и ведут съемку с 1-2 камер, нам и нужны. А различий у них море. Скажем, вот вы пришли в магазин, потерялись в море моделей регистраторов и жаждете помощи от продавца …

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

Второй момент, к которому обычно привлекают внимание: наличие ИК подсветки. Дескать, это помогает лучше снимать в темноте. 100% обман. Ибо регистратор обычно находится близко к лобовому стеклу и все излучение ИК-светодиодов просто отражается от стекла. И хорошо, если не назад в объектив … Нет, конечно бывают случаи когда видеорегистратор снимают с крепления и идут с ним снимать куда-то в темноту. Но я ни разу не видел такой вариант использования.

И наконец, наличие GPS приемника. Без него регистратор – не регистратор, а так, камера на лобовом стекле. Опять же из личного опыта могу сказать, что GPS приемники в регистраторы ставят очень слабые и получить с ними “картинку со скоростью” получается не всегда. Плюс в спорных ситуациях показания GPS помочь не могут (у вас же нет сертификата точности на измеритель скорости?), а вот испортить отношение судьи – легко (кто из нас 100% соблюдает скоростной режим?).

На что же надо реально смотреть?

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

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

Следующий аспект, на который надо обратить внимание – это жесткость крепления. У нас не идеально ровные дороги. И если крепление будет хлипким, то к вибрации машины добавится еще и собственная вибрация регистратора, болтающегося на креплении. В результате даже самая лучшая камера запишет очень посредственную картинку. По моим наблюдениям, особенной хлипкостью отличаются крепления, где фиксация положения осуществляется “гайкой на шаре”.

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

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

“А еще?”. Если ваш выбор сократился до нескольких моделей, можно обратить внимание на другие, менее важные возможности регистраторов.

Запись звука. Очень полезно при конфликтах на дороге. Представьте себе “картинку с регистратора”: перед вами резко останавливается машина, из нее выходит водитель, подходя к водительской двери исчезает из поля зрения камеры, а через некоторое время прямо перед капотом происходит “битва нанайских мальчиков”, доведенная в последствии до суда. Без звука ваша версия может быть “остановился, он вышел, словесно оскорбил меня, я решил не спускать на тормозах”. А версия оппонента будет “вышел спросить как проехать в библиотеку, а он как кинется на меня”. Согласитесь, со звуком такие разбирательства пойдут гораздо продуктивней.

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

Форматы записей. Чем формат распространенней, тем больше шансов, что инспектор или судья увидят видео без лишних телодвижений.

“А можно дешево, но не сердито?”. Можно, хоть “кроилово и ведет к попадалову”. Самый простой вариант – использование специальных программ для смартфонов. Они используют встроенную камеру и пишут видео. Сам так ездил наверное с год.

Основные проблема заключается вовсе не в том, что смартфон надо включать-выключать. Проблема в том, что смартфон хочется поиспользовать еще для чего-то. Для карт с пробками, для звонков … Одновременную работу регистратора и навигатора тянут только современные смартфоны. Но есть и неочевидные проблемы. Например, когда я использовал Samsung Galaxy S для работы в качестве регистратора, то в солнечные дни смартфон выводил сообщения о недопустимо высоком уровне температуры батареи и прекращении заряда. Просто солнце нагревало. И ладно бы он прекращал заряжать батарею, так это окошко висело прям посредине экрана и при попытке закрыть его выскакивало снова.

Но рано или поздно может наступить момент, когда запись с регистратора запечатлеет момент аварии. Что делать? По этому поводу в интернете гуляет куча рассуждений про цифровую подпись и прочие ужастики. Но все проще. 

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

Если в аварию попали не вы, то обязательно оставьте свой телефон участникам. Существует очень большая вероятность, что этот шаг поможет невиновному отстоять свою правоту. А если есть возможность, то скопируйте ролик на запасную карточку  и отдайте (или просто отдайте свою). Деньги не большие, а хорошие дела обязательно вернулся сторицей.

Если к сожалению в аварию попали вы, то помимо обычных действий по вызову полиции, прикидыванию суммы убытков и прочего вы должны сделать только одно: максимально быстро легализовать свою запись.

Особенности российского законодательства таковы, что суду абсолютно пофиг на цифровые подписи видео, модель регистратора и остальные технические параметры. В случае каких-либо вопросов судья просто отправляет запись эксперту с вопросом: могла ли быть запись изменена/модифицирована/ещечто, при условии, что она сделана на дату Х.У.З, а легализована на дату З.Х.У?  И эксперт обязан предположить, что у потерпевшего/истца за спиной голливудская киностудия с кучей техники и аппаратуры. Да, это маразм, но это так.

В результате если запись легализована быстро, то ответ эксперта будет отрицательным и запись будет принята судом во внимание. А если вы притащили запись через месяц после аварии, на слушанье … В общем, суд даже не будет рассматривать запись, какой бы подлинной она не была бы.

Как легализовать? Самое простое: прямо на месте составления протокола указать, что у вас есть видеозапись и сделав конвертик, отправить флешку прямо с инспектором. Минус тут один: обычно конвертик сделать не из чего, инспектор открещивается от такого подарка, на флешке могут быть другие фрагменты, которые характеризуют вас с отрицательной стороны …

Алгоритм действий меняется незначительно: выясняете у инспектора его территориальную принадлежность и уже подготовившись (написав заявление, приложив флешку) сдаете все это в дежурку. В ответ вам должны будут (обязаны! они реально должны проверить каждое заявление) выдать талон, который и будет аргументом для суда.

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

Стоит ли делать копии записи? На мой взгляд стоит, как и стоит об этом указать в протоколе, хотя я ни разу не слышал, что бы полиция “потеряла” правильно оформленные флешки. Обычные записи – да, “теряет” с завидной регулярностью.

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

PS Я специально не стал описывать версию программы для смартфона и модель регистратора, стоящего у меня. Хотя это DailyRoads Voyager и Street Storm CVR-A7510.

Часы для любимой тещи.

Жили-были часы. Обычные, стрелочные. И постоянно с ними что-то случалось. То они отставали, то наоборот вперед убегали. И тикали. И ночью их было не видно.

Но у нас же на дворе 21 век! Меняем часы на цифровые. С большими цифрами! Пробег по магазинам показал, что хоть часы с большими цифрами и присутствуют на прилавках, но все поголовно имеют один большой минус: они светятся одной и той же яркостью. В итоге солнечным днем их не видно, а ночью они подобно прожектору слепят всех. Не годится.

Одновременно все магазинные часы требуют полочки или какой-либо ровной горизонтальной поверхности. Опять минус для отдельно взятого дома.

В общем, было решено взять и сделать часы самому.

Из закромов был извлечен большой индикатор, с 256 красными светодиодами, расположенными в 32 ряда по 8 штук. Ссылки на магазин давать не буду, но ищется по ключевому слову HT1632.

Далее была взята Arduino Leonardo (можно взять абсолютно любую ардуинку, её возможности будут использованы процентов на 5). Почему леонарда? Просто потому что  была под рукой.

В качестве хранилки времени был взят наборчик от мастеркита, рядом нашлось пара кнопок и фотодиод. Как их подключать, можно прочитать в предидущем тут https://blog.kiltum.tech/2013/09/22/Многофункциональный-термометропока/

Внимание! Индикатор подключается абсолютно точно так же, как и тут: http://www.lucadentella.it/en/category/ledmatrix_ht1632c/ Расположенные в сети библиотеки с похожими названиями не работают, так как рассчитаны на другую схему подключения.

Самым сложным оказалось найти подходящий корпус. В результате я просто купил подходящий пластмассовый, долго его резал-штукатурил-красил, но так до гламурного состояния и не довел. Опыта мало, ошибок много …

Все это долгое время валялось у меня на столе разобранным, пока я не взял себя за шкирку и не собрал все в одну кучу. Так как схема не просто простая, а очень простая, то я тупо собрал все навесным монтажем.

20131113_141210

Заодно опробовал и клеевой пистолет: вещь! Особенно для монтажа такого уровня.

Итак, что и как соединено по фотографии. Слева – направо.

Снаружи подходит обычный micro-usb кабель. Лично мне оказалось проще всего  обеспечить схему питанием +5В – у меня валяется много зарядок от телефонов.

Далее две кнопки, посаженные на analog in и фотодиод, выведенный на верхнюю поверхность часов.

С батарейкой – это часы реального времени от мастер-кита.

Далее сама ардуинка и провода, уходящие на индикатор.

Внимание! Индикатор в режиме “все включено на максимум” потребляет примерно 300мА. Встроенный в ардуинку стабилизатор попросту не выдержит. В данной схеме я воспользовался грязным хаком и подцепил питание индикатора на VIN. По схеме он зацеплен прямо на +5В от USB, а там предел 500мА. В общем, не повторяйте этого, если не знаете что делаете.

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

Ну и как же без кода.

#include “Wire.h”
#include “RTClib.h”
#include <avr/pgmspace.h>

// HT1632C PINs

#define DISPLAY_CS 5
#define DISPLAY_WR 6
#define DISPLAY_DATA 7

// HT1632C Commands

#define HT1632C_READ B00000110
#define HT1632C_WRITE B00000101
#define HT1632C_CMD B00000100

#define HT1632_CMD_SYSON 0x01
#define HT1632_CMD_LEDON 0x03
#define HT1632_CMD_PWM 0xA0

// where PIN button is
#define BUTT_H A8
#define BUTT_M A10

int photoRPin = 0; // where photo is
int minLight;
int maxLight;
int lightLevel;
int adjustedLightLevel;
byte display_buffer[32];
long previous_millis;

RTC_DS1307 RTC;

// 7 width 8 – height
PROGMEM char font[] = {
B01111110, // 0
B11111111,
B10000001,
B10000001,
B11111111,
B01111110,

// 1
B01000001,
B11111111,
B11111111,
B00000001,
B00000000,
B00000000,

B01100001,
B11100011, // 2
B10000111,
B10001101,
B11111001,
B01110001,

B01100110, // 3
B11100111,
B10000001,
B10010001,
B11111111,
B01101110,

B11110000,
B11111000, // 4
B00001000,
B00001000,
B11111111,
B11111111,

B11110010,
B11110011, // 5
B10010001,
B10010001,
B10011111,
B10001110,

B01111110,
B11111111, // 6
B10010001,
B10010001,
B11011111,
B01001110,

B10000000, // 7
B10000111,
B10001111,
B10011000,
B11110000,
B11100000,
B01101110,
B11111111, // 8
B10010001,
B10010001,
B11111111,
B01101110,
B01110010,
B11111011, // 9
B10001001,
B10001001,
B11111111,
B01111110,
};

PROGMEM int fontwidth[] = {
6,4,6,6,6,6,6,6,6,6
};

void show_string(String st)
{
ht1632c_clear_display();

int middle=15-1;

show_digit(middle-pgm_read_byte_near(fontwidth+st.charAt(1)-‘0’)-pgm_read_byte_near(fontwidth+st.charAt(0)-‘0’)-1,st.charAt(0)-‘0’);

show_digit(middle-pgm_read_byte_near(fontwidth+st.charAt(1)-‘0’),st.charAt(1)-‘0’);

middle=17+1;

show_digit(middle,st.charAt(2)-‘0’);

show_digit(middle+pgm_read_byte_near(fontwidth+st.charAt(2)-‘0’)+1,st.charAt(3)-‘0’);

}

 

void show_digit(int pos, int digit)
{
for(int i=0;i<pgm_read_byte_near(fontwidth+digit);i++) display_buffer[pos+i]=pgm_read_byte_near(font+digit*6 + i);
}

void show_dots(int on)
{
if(on==1)
{
display_buffer[15]=B01100110;
display_buffer[16]=B01100110;
}
else
{
display_buffer[15]=0;
display_buffer[16]=0;
}
}
// —————————————-
// HT1632C functions
// —————————————-

void ht1632c_clear_display() {
for(int i = 0; i < 32; i++) display_buffer[i] = 0x00;
//ht1632c_display_buffer();
}

void ht1632c_display_buffer() {

digitalWrite(DISPLAY_CS, LOW);
ht1632c_send_bits(HT1632C_WRITE, 1 << 2);
ht1632c_send_bits(0x00, 1 << 6);
for(int i = 0; i < 32; i++) ht1632c_send_bits(display_buffer[i], 1<<7);
digitalWrite(DISPLAY_CS, HIGH);
}

void ht1632c_send_command(byte command) {

digitalWrite(DISPLAY_CS, LOW);
ht1632c_send_bits(HT1632C_CMD, 1 << 2);
ht1632c_send_bits(command, 1 << 7);
ht1632c_send_bits(0, 1);
digitalWrite(DISPLAY_CS, HIGH);
}

void ht1632c_send_bits(byte bits, byte firstbit) {

while(firstbit) {
digitalWrite(DISPLAY_WR, LOW);
if (bits & firstbit) digitalWrite(DISPLAY_DATA, HIGH);
else digitalWrite(DISPLAY_DATA, LOW);
digitalWrite(DISPLAY_WR, HIGH);
firstbit >>= 1;
}
}

void setup()
{
Serial.begin(9600);

pinMode(DISPLAY_CS, OUTPUT);
pinMode(DISPLAY_WR, OUTPUT);
pinMode(DISPLAY_DATA, OUTPUT);

pinMode(BUTT_H,INPUT);
pinMode(BUTT_M,INPUT);
digitalWrite(BUTT_H,HIGH);
digitalWrite(BUTT_M,HIGH);

// enable System oscillator and LED duty cycle generator
ht1632c_send_command(HT1632_CMD_SYSON);
ht1632c_send_command(HT1632_CMD_LEDON);
ht1632c_send_command(HT1632_CMD_PWM+15); // full light!

ht1632c_clear_display();
previous_millis=0;
Wire.begin();
RTC.begin();
RTC.adjust(DateTime(__DATE__, __TIME__));

minLight=200;
maxLight=800;
}

int dig=1000;

String c_to(int dig)
{
String ret(dig);
if(dig<10)
return “0”+ret;
else
return ret;
}

char s;
String txtMsg;

void loop ()
{

while (Serial.available() > 0) {
s=(char)Serial.read();
if (s == ‘n’) {
if(txtMsg.charAt(2)==’:’)
{
DateTime nw = RTC.now();
DateTime nq = DateTime(nw.year(),nw.month(),nw.day(),String(txtMsg.substring(0,2)).toInt(),String(txtMsg.substring(3,5)).toInt(),0);
RTC.adjust(nq);
Serial.println(“Time is changed”);
}
else
{
Serial.println(“To change time, just print current time like ’12:24′”);
}
txtMsg=””;
} else {
txtMsg +=s;
}
}

if(analogRead(BUTT_H)<500)
{
delay(150);
if(analogRead(BUTT_H)<500) // if still pressed
{
DateTime nw = RTC.now();
DateTime nq = DateTime(nw.year(),nw.month(),nw.day(),nw.hour()+1,nw.minute(),nw.second());
RTC.adjust(nq);
previous_millis=millis()-1100;
//delay(100);

}}

if(analogRead(BUTT_M)<500)
{
delay(150);
if(analogRead(BUTT_M)<500) // if still pressed
{
DateTime nw = RTC.now();
DateTime nq = DateTime(nw.year(),nw.month(),nw.day(),nw.hour(),nw.minute()+1,nw.second());
RTC.adjust(nq);
previous_millis=millis()-1100;
//delay(100);

}}

long current_millis = millis();

if(current_millis – previous_millis > 1000) {
previous_millis = current_millis;
// do it

DateTime now = RTC.now();

show_string(String(c_to(now.hour())+c_to(now.minute())));

if((now.second() % 2) == 0)
show_dots(1);
else
show_dots(0);

Serial.print(now.day());
Serial.print(“/”);
Serial.print(now.month(), DEC);
Serial.print(“/”);
Serial.print(now.year(), DEC);
Serial.print(” “);

Serial.print(now.hour(), DEC);
Serial.print(“:”);
Serial.print(now.minute(), DEC);
Serial.print(“:”);
Serial.print(now.second(), DEC);
Serial.print(” l:”);

ht1632c_display_buffer();

// now ajust brightness

lightLevel=analogRead(photoRPin);
// Serial.println(lightLevel);
if(minLight>lightLevel)
{
minLight=lightLevel;
}
if(maxLight<lightLevel)
{
maxLight=lightLevel;
}

//Serial.println(maxLight-minLight);
adjustedLightLevel = map(lightLevel, minLight, maxLight, 0, 15);
Serial.println(adjustedLightLevel);

ht1632c_send_command(HT1632_CMD_PWM+adjustedLightLevel);

}
}

На мой взгляд, ничего ранее не описанного в нем нет (но если что непонятно, то спрашивайте), поэтому я сразу перехожу к готовому результату.

20131113_165232

 

Здесь часы собраны и расположены на испытательном стенде – обычной маркерной доске.

Практика использования в течении пары дней (больше просто времени не было и мы уезжали) показала, что все выбранные решения были верны. Днем часы было видно далеко, а ночью они не слепили. В общем, теперь можно сваять нечто и более монструозное.

Многофункциональный термометропоказометр

После пары постов о возможных направлениях развития показометра меня попросили спроектировать некий многофункциональный показометр с функцией пускания пыли в глаза. В общем, после обмена несколькими письмами получился следующий набор задач:

– Иметь вход для ACC с замка зажигания.
Пока зажигание выключено: мигать светодиодом, как будто это сигналка.
При включении зажигания: первые 10 секунд показывать  показания заранее выбранного датчика температуры. Потом показывать время.
– Иметь вход для CarPC. Плата должна уметь рассказывать о себе, сообщать что к ней подключено и показывать то, что попросят.

– Иметь возможность обрабатывать 4 “ветки” датчиков. Скорость обработки 1 секунда на один датчик на каждой ветке.
– Иметь возможность регулировки яркости.
– Все светящееся должно светить зеленым светом. За синее – расстрел на месте.
– Работать должно на Arduino Micro.

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

Для начала решил выяснить, чем отличается Arduino Micro от CarDuino

– Первый итальянский, второй наш. Без разницы.
– Первый дороже второго почти на 500 рублей. 1200 супротив 700. Плохо, но терпимо.
– У micro по другому сделано общение с компьютером. Драйвера стандартные, при подключении компьютера сброса по умолчанию нет, можно спокойно пользовать RX и TX ножки. Это очень хорошо.
– У micro стандартные значения питания. Его, в отличии от CarDuino, напрямую от бортсети не запитаешь. Мелочь, но потребует как минимум одного лишнего элемента в схеме.
– У micro нет ножек SPK и HV12. Беда, печаль и огорчения. Абсолютно несущественно.

Теперь к индикаторам. Беглый поиск показал, что хотя у меня есть зеленый светодиодик, но вот индикатора с таким светом нет. Гугл дал ссылку на http://pacpac.ru/product/com-11440-7-segment-serial-display-green/ , он же COM-11440. Зелененький, 4 цифры, умеет дофига всего. Беру.

Для определения освещенности нужен фоторезистор. Опять же, у меня есть в закромах, но пойдет любой. Вот ссылка на тот же ПАКПАК http://pacpac.ru/product/sen-09088-mini-photocell/

Про часы и прочее можно прочитать в предыдущем посту.

Итак, собираем схему.

Первыми идут часы. Подключаем GND к GND, VCC к +5V, SDA к D2, SCL к D3.

Проверяем работоспособность

#include "Wire.h"
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {
Serial.begin(57600);
Wire.begin();
RTC.begin();

if (! RTC.isrunning()) {
Serial.println(“RTC is NOT running!”);
}
//RTC.adjust(DateTime(__DATE__, __TIME__));
}

void loop () {
DateTime now = RTC.now();

Serial.print(now.day());
Serial.print(‘/’);
Serial.print(now.month(), DEC);
Serial.print(‘/’);
Serial.print(now.year(), DEC);
Serial.print(‘ ‘);

Serial.print(now.hour(), DEC);
Serial.print(‘:’);
Serial.print(now.minute(), DEC);
Serial.print(‘:’);
Serial.print(now.second(), DEC);
Serial.println();

delay(1000);
}

В выводе serial monitor должны увидеть строчки с текущим временем.

Теперь подключаем светодиод.  К 5й ножке, затем резистор 1кОм, затем земля. Почему 5я ножка? Просто это первый PWM выход на микре. Проще будет красиво мигать светодиодиком. Проверяем


int led = 5;
int brightness = 0;
int fadeAmount = 10;

void setup() {
pinMode(led, OUTPUT);
}

void loop() {
analogWrite(led, brightness);

brightness = brightness + fadeAmount;

if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount ;
}
delay(30);
}

Светодиодик должен начать “взмаргивать”.

Теперь следующий шаг: фотодиод. Подключаем одной ножкой к А0, второй к +5В. И “опускаем” А0 через резистор в 10кОм на землю. То есть должно получиться А0-фотодиод-5В и А0-резистор-GND.

Проверяем


int photoRPin = 0;
int minLight;
int maxLight;
int lightLevel;
int adjustedLightLevel;

int led = 5;

void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);

lightLevel=analogRead(photoRPin);
minLight=lightLevel-20;
maxLight=lightLevel;
}

void loop(){
lightLevel=analogRead(photoRPin);
if(minLight>lightLevel){
minLight=lightLevel;
}
if(maxLight

В результате у нас должена получиться супер-пупер адаптивная подсветка из одного светодиода. Чем больше падает света на фотодиод, тем сильнее светится светодиод. При этом яркость подсветки адаптируется и самое яркое свечение светодиода будет при самом ярком свете. Вывод текущего значения подсветки в serial monitor - маленький бонус.

Следующим идет "дисплей". Он умеет общаться по разным протоколам, но я выбираю обычный последовательный, тем более что на micro аппаратный порт свободен.

Соединяем VCC с +5В, GND с GND, а rx индикатора с tx ардуинки. Всё, всего 3 проводка (сравните с предидущим индикатором). Если просто так все включить, то индикатор должен загореться с 0000 на экране. Проверяем остальное.


#include "SoftwareSerial.h"

int ar_tx=1;
int ar_rx=0;

SoftwareSerial sp(ar_rx,ar_tx);

void setup() {
pinMode(ar_tx,OUTPUT);
pinMode(ar_rx,INPUT);
sp.begin(9600);
sp.print("v");
sp.print("8888");
}

void loop() {
// put your main code here, to run repeatedly:
sp.print("1234");
sp.print("w");
char s=16;
sp.write(s);
delay(500);
sp.print("4321");
sp.print("w");
s=0;
sp.write(s);
delay(500);
}

На экране должны меняться 1234 и 4321 с мигающим двоеточием. Более подробное объяснение команд дисплейчика можно найти в его документации. Или тут http://www.arunet.co.uk/tkboyd/ec/ec1led4x7ser.htm

Следующим сделаем вход для сигнала ACC. Так как в машине напряжение может скакать от 9 до 15-16 вольт (в крайних случаях), а ардуинка понимает только 5В, то я не долго думая, сделал обычный делитель из двух сопротивлений: 1кОм и 4,7кОм.

Что бы не мучаться, воспользуемся сервисом http://www.bezkz.su/index/delitel/0-9. R1=4700, R2=1000, U1 - то, что "входит", U2 - то, что выходит.

Сопротивление 1кОм включаем между GND и A1, а сопротивление 4,7кОм, между А1 и "+" измеряемого. "-" измеряемого соединяем с GND.

Теперь по появлению чего-либо на A1 можно судить, включено ли зажигание. Но это как-то не функционально. В общем, надо превратить этот вход еще и в вольметр. Судя по вышеприведенному сервису, с данными номиналами можно будет измерять напряжение в диапазоне от 0 до 28 вольт. Для машины более чем достаточно. Но тут есть одна большая проблема: резисторы вообще-то не идеального номинала и поэтому ожидать от полученного вольтметра точности прямо с нуля не стоит.

Берем вот такой вот маленький скетч

void setup()
{
Serial.begin(115200);
}
void loop()
{

Serial.println(analogRead(1));
delay(100);
}

Он просто выводит значения измеренного с порта А1. Значения могут колебаться от 0 (ноль) до 1023 (5В). Я подключился к лабораторному блоку питания и при напряжении 12В оно мне выдало 430, 9В - 320, 6В - 215, 5В - 176. То есть теоретическая точность (и шаг измерения) данного показометра будет ...

12/430 = 0.027
9/320 = 0.028
6/215 = 0.027
5/176 = 0.028

Ну, цельных 3 сотых вольта. Можно в принципе до 15 тысячных догнать, (снизив диапазон измеряемого напряжения) но зачем? Нам и десятых хватит за глаза.

Модифицируем программу вольметра


void setup()
{
Serial.begin(115200);
}
void loop()
{

Serial.println(analogRead(1)/35.8); // 430/12=
delay(100);
}

Теперь у нас в SerialMonitor показывается текущее напряжение с точностью до сотых. Немного изменив скетч проверки дисплея, мы получим вольметр


#include "SoftwareSerial.h"

int ar_tx=1;
int ar_rx=0;

SoftwareSerial sp(ar_rx,ar_tx);

void setup() {
Serial.begin(115200);
pinMode(ar_tx,OUTPUT);
pinMode(ar_rx,INPUT);
sp.begin(9600);
sp.print("v");
sp.print("8888");
sp.print("w");
char t=2;
sp.print(t);
}

void loop() {
int napr=int(analogRead(1)/35.8*100); // 430/12=
Serial.println(napr);
if(napr<1000) { sp.print(" "); } sp.print(napr); delay(100); }

При этом уже полученная штука может мерять напряжения еще в куче мест, ибо ножек свободных у нас дофига, даже если учесть, что нам надо куда-то подключить еще 4 ветки для датчиков температур. Ну разве это не прекрасно?

Тем, кто будет воплощать все это "в металл", еще раз следует учесть, что показания этого "вольметра" будут очень сильно плавать в зависимости от величины сопротивления используемых резисторов, проводов и соединений. Поэтому готовое изделие надо будет откалиборовать, просто подогнав выдаваемые им значения под измеренное в точке подключения каким-либо сторонним вольтметром. При этом учитывайте, что обычно вольтметры в бортовых компьютерах врут примерно на 0.3-0.5 вольт (так было на всех "ощупанных" мной машинах).

И наконец, почти последний шаг: измерение температуры. Я использую в своих проектах DS18B20. Это совершенно шикарный цифровой датчик, который с точностью 0,5 градуса измеряет свою температуру.

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

С картинками разницу между схемами можно прочитать тут http://openenergymonitor.org/emon/buildingblocks/DS18B20-temperature-sensing

Я лишь сопру картинку с нормальным питанием

normal power conection diagram

И схему подключения

temp sensors connection diagram 3 wire

Как видно, датчики подключаются гирляндой, один за одним, к одним и тем же проводам. Максимальное количество датчиков на одной гирлянде по-моему 127. Или 64. В общем, дофига. Каждый датчик имеет свой уникальный адрес, поэтому вероятность, что они "перепутаются", нет. Правда, совершенно не факт, что первый физически по проводу будет первым и по адресу ...

Для сборки датчиков надо следующее: 3 провода (желательно разных цветов, многожильных), сам датчик и 2 разных термоусадочных трубочки. Одна чуть больше диаметром, чем сам провод, другая на 4,3мм.

IMG_0107

Тут я показал процесс изготовления датчика: сначала припаиваем провода, затем изолируем выводы датчика первой термоусадочной трубкой, а затем собираем все "в кучу" с помощью второй. Данная конструкция показала свою надежность с 2004 года: до сих пор все датчики работают (а среди них есть и уличные, и домашние и те, которые все время в воде).

Для начала подключаем один датчик. VCC +5В, GND-GND, DQ-D6 и DQ-R4K7-+5В


#include "OneWire.h"
#include "DallasTemperature.h"

// Data wire is plugged into pin 6 on the Arduino
#define ONE_WIRE_BUS 6

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

void setup(void)
{
// start serial port
Serial.begin(9600);

// Start up the library
sensors.begin(); // IC Default 9 bit.
}

void loop(void)
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");

Serial.print("Temperature for Device 1 is: ");
Serial.println(sensors.getTempCByIndex(0));

}

И в Serial Monitor вы увидите похожее на следующее

Requesting temperatures...DONE
Temperature for Device 1 is: 21.69

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

Ну и совершенно аналогично поступаем, подключая датчики в D7, D8 и D9.

Да, опять не могу удержаться

#include "SoftwareSerial.h"
#include "OneWire.h"
#include "DallasTemperature.h"

// Data wire is plugged into pin 6 on the Arduino
#define ONE_WIRE_BUS 6

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

int ar_tx=1;
int ar_rx=0;

SoftwareSerial sp(ar_rx,ar_tx);

void setup() {
Serial.begin(115200);
pinMode(ar_tx,OUTPUT);
pinMode(ar_rx,INPUT);
sp.begin(9600);
sp.print("v");
sp.print("8888");
sp.print("w");
char t=2;
sp.print(t);
sensors.begin(); // IC Default 9 bit.
}

void loop() {
sensors.requestTemperatures();
int temp=sensors.getTempCByIndex(0)*100;
Serial.println(temp);
sp.print(temp);
}

И у нас готовый термометр с цифровой индикацией температуры.

IMG_0134

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

Часовой показометр

Итак, хватит разговоров, надо сделать что-либо полезное и приятное. А начнем мы с часов, совмещенных с показометром чего-нибудь. Чего именно и конкретно – пока я не определился.

В общем, сгребаем всё, что есть в предидущем посту и складываем на стол. Первым делом подключаем кабелем ардуинку к компьютеру и скачиваем весь необходимый для нее софт. Я останавливаться на этом не буду, ибо в интернете этих описаний – тьма и на любом языке. Точно так же я не буду останавливаться на том, что делает каждая конкретная функция.

Проверка для перехода к следующему шагу – стандартная “мигалка” компилируется, заливается в ардуинку и мигает светодиодиком, как положено.

Теперь подсоединяем индикатор к ардуинке. Ножку индикатора VCC цепляем к выводу +3.3V ардуинки. Не стоит занимать 0 и 1 ножку (там работа с компьютером) и 13й – там светодиодик.

IMG_0061

В начале каждого  скетча я сделал определение, какая ножка индикатора подключена к какому выводу ардуинки. Это при необходимости позволит быстро поменять схему.

int pinA=2;
int pinB=3;
int pinC=4;
int pinD=5;
int pinE=6;
int pinF=7;
int pinG=8;
int pinDP=9;
int pinPP=10;
int pinDIG1=11;
int pinDIG2=12;
int pinDIG3=A0;
int pinDIG4=A1;

Затем я делаю определение, в каком режиме должны работать порты ардуинки (у нас все работают на вывод)

pinMode(pinA, OUTPUT); //A
pinMode(pinB, OUTPUT); //B
pinMode(pinC, OUTPUT); //C
pinMode(pinD, OUTPUT); //D
pinMode(pinE, OUTPUT); //E
pinMode(pinF, OUTPUT); //F
pinMode(pinG, OUTPUT); // G
pinMode(pinDP, OUTPUT); // DP
pinMode(pinPP, OUTPUT); // PP

pinMode(pinDIG1, OUTPUT); // DIG 1
pinMode(pinDIG2, OUTPUT);
pinMode(pinDIG3, OUTPUT);
pinMode(pinDIG4, OUTPUT); // DIG 4

И переключаю эти порты в соответствующее состояние. По нашей схеме, что бы светодиод загорелся, надо порт включить в режим LOW.
Что бы погас – в HIGH.

Ну и что бы добавить “оживляжа”, зажгем первую и третью цифру

digitalWrite(pinDIG1,LOW);
digitalWrite(pinDIG2,HIGH);
digitalWrite(pinDIG3,LOW);
digitalWrite(pinDIG4,HIGH);

… восьмерками
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
digitalWrite(pinDP,HIGH);
digitalWrite(pinPP,HIGH);

и начнем включать/выключать точки с интервалом в одну секунду
digitalWrite(pinPP,LOW);
delay(1000);
digitalWrite(pinPP,HIGH);
delay(1000);

В итоге в ардуинке должен залиться вот такой вот скетч
int pinA=2;
int pinB=3;
int pinC=4;
int pinD=5;
int pinE=6;
int pinF=7;
int pinG=8;
int pinDP=9;
int pinPP=10;

int pinDIG1=11;
int pinDIG2=12;
int pinDIG3=A0;
int pinDIG4=A1;

void setup() {
Serial.begin(9600);
pinMode(pinA, OUTPUT); //A
pinMode(pinB, OUTPUT); //B
pinMode(pinC, OUTPUT); //C
pinMode(pinD, OUTPUT); //D
pinMode(pinE, OUTPUT); //E
pinMode(pinF, OUTPUT); //F
pinMode(pinG, OUTPUT); // G
pinMode(pinDP, OUTPUT); // DP
pinMode(pinPP, OUTPUT); // PP

pinMode(pinDIG1, OUTPUT); // DIG 1
pinMode(pinDIG2, OUTPUT);
pinMode(pinDIG3, OUTPUT);
pinMode(pinDIG4, OUTPUT); // DIG 4

digitalWrite(pinDIG1,LOW);
digitalWrite(pinDIG2,HIGH);
digitalWrite(pinDIG3,LOW);
digitalWrite(pinDIG4,HIGH);

digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
digitalWrite(pinDP,HIGH);
digitalWrite(pinPP,HIGH);
}

// the loop routine runs over and over again forever:
void loop() {

digitalWrite(pinPP,LOW);
delay(1000);
digitalWrite(pinPP,HIGH);
delay(1000);
}


И этот скетч должен произвести такой результат:

Если получилось, можно радостно ухмыльнуться и перейти к следующему шагу – сделаем другие циферки.

Для начала добавим функцию, которая будет рисовать нам циферки
void showDigit(int digit)
{
switch(digit) {
case 0:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,HIGH);
break;
case 1:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 2:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,HIGH);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 3:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 4:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 5:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 6:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 7:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 8:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 9:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
}
}

Суть её простая: просто зажигаем или гасим нужные сегменты в зависимости от того, какую циферку нам надо нарисовать.

И просто перебираем циферки по порядку:

void loop() {
showDigit(count);
count++;
if(count>9)
{
count=0;
}
digitalWrite(pinPP,LOW);
delay(500);
digitalWrite(pinPP,HIGH);
delay(500);
}

Все просто: зажигаем циферку, затем увеличиваем ее и если она превышает 9, сбрасываем на 0. И затем с меньшим интервалом мигаем. В результате должен получиться вот такой вот скетч
int pinA=2;
int pinB=3;
int pinC=4;
int pinD=5;
int pinE=6;
int pinF=7;
int pinG=8;
int pinDP=9;
int pinPP=10;

int pinDIG1=11;
int pinDIG2=12;
int pinDIG3=A0;
int pinDIG4=A1;

void showDigit(int digit)
{
switch(digit) {
case 0:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,HIGH);
break;
case 1:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 2:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,HIGH);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 3:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 4:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 5:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 6:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 7:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 8:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 9:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
}
}

void setup() {
Serial.begin(9600);
pinMode(pinA, OUTPUT); //A
pinMode(pinB, OUTPUT); //B
pinMode(pinC, OUTPUT); //C
pinMode(pinD, OUTPUT); //D
pinMode(pinE, OUTPUT); //E
pinMode(pinF, OUTPUT); //F
pinMode(pinG, OUTPUT); // G
pinMode(pinDP, OUTPUT); // DP
pinMode(pinPP, OUTPUT); // PP

pinMode(pinDIG1, OUTPUT); // DIG 1
pinMode(pinDIG2, OUTPUT);
pinMode(pinDIG3, OUTPUT);
pinMode(pinDIG4, OUTPUT); // DIG 4

digitalWrite(pinDIG1,LOW);
digitalWrite(pinDIG2,HIGH);
digitalWrite(pinDIG3,LOW);
digitalWrite(pinDIG4,HIGH);

digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
digitalWrite(pinDP,HIGH);
digitalWrite(pinPP,HIGH);
}

int count=0;

// the loop routine runs over and over again forever:
void loop() {
showDigit(count);
count++;
if(count>9)
{
count=0;
}
digitalWrite(pinPP,LOW);
delay(500);
digitalWrite(pinPP,HIGH);
delay(500);
}

С вот таким вот результатом

Ура? Ура конечно. Следующим шагом надо вывести какое-нибудь число. Я взял 1234.

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

Добавляем функцию, которая будет разбивать число на циферки и показывать их по порядку
void showNumber(int num)
{
int divide=0;
for(int c=1;c<5;c++) { switch(c) { case 1: digitalWrite(pinDIG1,LOW); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); divide=1000; break; case 2: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,LOW); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); divide=100; break; case 3: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,LOW); digitalWrite(pinDIG4,HIGH); divide=10; break; case 4: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,LOW); divide=1; break; } // switch String s(int(num/divide)); char c=s.charAt(s.length()-1); showDigit(c-'0'); delay(100); } }

Самым сложным тут является кусок кода
String s(int(num/divide));
char c=s.charAt(s.length()-1);
showDigit(c-'0');

Вся его функция - "выкусить" нужную цифру из числа и затем показать.

скажем, нам нужна цифра 2 из 1234.

int(num/divide) - это "взять целую часть из деления num на divide". В нашем случае 1234/100=12

String(s - это "превратить данное число в строку"

s.length() - узнать длину строки в символах

s.charAt - взять Нный символ из строки

В итоге s.charAt(s.length()-1) значит "взять последний символ из строки". -1 нужен из-за того, что ардуинка считает, что 1й символ имеет "адрес" 0

c-'0' - превращаем символ назад в число. Отнеситесь к этому как к магии, иначе мне надо будет рассказывать вам про то, что такое ASCII

И заставляем ардуинку показать нам циферку

void loop() {
showNumber(1234);
}

Как обычно, скетч целиком

int pinA=2;
int pinB=3;
int pinC=4;
int pinD=5;
int pinE=6;
int pinF=7;
int pinG=8;
int pinDP=9;
int pinPP=10;

int pinDIG1=11;
int pinDIG2=12;
int pinDIG3=A0;
int pinDIG4=A1;

void showDigit(int digit)
{
switch(digit) {
case 0:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,HIGH);
break;
case 1:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 2:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,HIGH);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 3:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 4:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 5:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 6:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 7:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 8:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 9:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
}
}

void setup() {
Serial.begin(9600);
pinMode(pinA, OUTPUT); //A
pinMode(pinB, OUTPUT); //B
pinMode(pinC, OUTPUT); //C
pinMode(pinD, OUTPUT); //D
pinMode(pinE, OUTPUT); //E
pinMode(pinF, OUTPUT); //F
pinMode(pinG, OUTPUT); // G
pinMode(pinDP, OUTPUT); // DP
pinMode(pinPP, OUTPUT); // PP

pinMode(pinDIG1, OUTPUT); // DIG 1
pinMode(pinDIG2, OUTPUT);
pinMode(pinDIG3, OUTPUT);
pinMode(pinDIG4, OUTPUT); // DIG 4

digitalWrite(pinDIG1,HIGH);
digitalWrite(pinDIG2,HIGH);
digitalWrite(pinDIG3,HIGH);
digitalWrite(pinDIG4,HIGH);

digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
digitalWrite(pinDP,HIGH);
digitalWrite(pinPP,HIGH);
}

void showNumber(int num)
{
int divide=0;
for(int c=1;c<5;c++) { switch(c) { case 1: digitalWrite(pinDIG1,LOW); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); divide=1000; break; case 2: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,LOW); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); divide=100; break; case 3: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,LOW); digitalWrite(pinDIG4,HIGH); divide=10; break; case 4: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,LOW); divide=1; break; } // switch String s(int(num/divide)); char c=s.charAt(s.length()-1); showDigit(c-'0'); delay(100); } } // the loop routine runs over and over again forever: void loop() { showNumber(1234); }

Превращается в ...

А теперь уменьшаем задержку, меняя delay(100) на delay(1) и получаем ...

... циферку! Такую, какую я попросил! Очередное ура!

Но если вы приглядитесь к результату ...

IMG_0070

Какая-то фигня, не правда ли? Почему-то вокруг циферок светятся лишние сегменты. Хоть и тускло, но некрасиво же. Почему так?

Дело в скорости работы ардуинки. Скажем, откуда появились лишние сегменты у цифры 1?

Если посмотрите на логику работы скетча, у нас получится следующее

(много пропущено)
1. Включить 4й индикатор
2. Показать цифру 4
3. Включить 1й индикатор
4. Показать цифру 1
(опять пропускаем)

И вот обратите внимание, во время между шагами 3 и 4 на индикаторе горит 4! Да, это время невелико, но хватает, что бы мы заметили это.

Вывод? Надо между шагами 2 и 3 выключить показ циферок.

Добавляем вывод спец-цифры "10"

case 10:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,HIGH);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;

Она просто будет гасить все сегменты. И вставим ее вызов самое начало ShowNumber

for(int c=1;c<5;c++) { showDigit(10);

IMG_0073

Как видим, все получилось. Все красиво и никаких засветов нет. Можно побаловаться с разными циферками, поделать секундомеры.

Но нам нужны часы. Выключаем ардуинку, и вставляем на плату блок часиков. Предварительно вставьте туда батарейку, иначе чуда не будет. Соединения простые:

GND к GND,
VCC к +5V (НЕ к 3.3!)
SDA к A4
SCL к A5

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

IMG_0077

Теперь для проверки уже блока часов скачиваем с https://github.com/adafruit/RTClib библиотечку RTC, добавляем ее в проект и заливаем вот такой вот скетч:

#include
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {
Serial.begin(57600);
Wire.begin();
RTC.begin();

if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
//RTC.adjust(DateTime(__DATE__, __TIME__));
}

}

void loop () {
DateTime now = RTC.now();

Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();

Serial.print(" since 1970 = ");
Serial.print(now.unixtime());
Serial.print("s = ");
Serial.print(now.unixtime() / 86400L);
Serial.println("d");

// calculate a date which is 7 days and 30 seconds into the future
DateTime future (now.unixtime() + 7 * 86400L + 30);

Serial.print(" now + 7d + 30s: ");
Serial.print(future.year(), DEC);
Serial.print('/');
Serial.print(future.month(), DEC);
Serial.print('/');
Serial.print(future.day(), DEC);
Serial.print(' ');
Serial.print(future.hour(), DEC);
Serial.print(':');
Serial.print(future.minute(), DEC);
Serial.print(':');
Serial.print(future.second(), DEC);
Serial.println();

Serial.println();
delay(3000);
}

Если все в порядке, то в выводе Serial Monitor вы должны увидеть ужас, похожий на

2000/61/120 0:81:4
since 1970 = 1023758464s = 11849d
now + 7d + 30s: 2002/6/18 1:21:34

Теперь меняем кусочек скетча в начале на

if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled

}
RTC.adjust(DateTime(__DATE__, __TIME__));
}

(если кто не понял, строчку одну перенес) И снова заливаем.

Теперь в выводе должно появиться реальное время. Ибо компьютер подставил их вместо __DATE__ и __TIME__, а функция
RTC.ajust "поставила часы" как надо.

Теперь выдыхаем и модифицируем скетч вот так:

#include

#include

int pinA=2;
int pinB=3;
int pinC=4;
int pinD=5;
int pinE=6;
int pinF=7;
int pinG=8;
int pinDP=9;
int pinPP=10;

int pinDIG1=11;
int pinDIG2=12;
int pinDIG3=A0;
int pinDIG4=A1;

RTC_DS1307 RTC;

void showDigit(int digit)
{
switch(digit) {
case 0:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,HIGH);
break;
case 1:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 2:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,HIGH);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 3:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 4:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 5:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 6:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 7:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 8:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 9:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 10:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,HIGH);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
}
}

void showNumber(int num)
{
int divide=0;
float z;
for(int c=1;c<5;c++) { showDigit(10); switch(c) { case 1: digitalWrite(pinDIG1,LOW); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); divide=1000; break; case 2: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,LOW); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); divide=100; break; case 3: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,LOW); digitalWrite(pinDIG4,HIGH); divide=10; break; case 4: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,LOW); divide=1; break; } // switch String s(int(num/divide)); char b=s.charAt(s.length()-1); showDigit(b-'0'); delay(5); } } void setup() { Serial.begin(115200); Wire.begin(); RTC.begin(); pinMode(pinA, OUTPUT); //A pinMode(pinB, OUTPUT); //B pinMode(pinC, OUTPUT); //C pinMode(pinD, OUTPUT); //D pinMode(pinE, OUTPUT); //E pinMode(pinF, OUTPUT); //F pinMode(pinG, OUTPUT); // G pinMode(pinDP, OUTPUT); // DP pinMode(pinPP, OUTPUT); // PP pinMode(pinDIG1, OUTPUT); // DIG 1 pinMode(pinDIG2, OUTPUT); pinMode(pinDIG3, OUTPUT); pinMode(pinDIG4, OUTPUT); // DIG 4 digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); digitalWrite(pinA,LOW); digitalWrite(pinB,LOW); digitalWrite(pinC,LOW); digitalWrite(pinD,LOW); digitalWrite(pinE,LOW); digitalWrite(pinF,LOW); digitalWrite(pinG,LOW); digitalWrite(pinDP,HIGH); digitalWrite(pinPP,HIGH); } long previousMillis = 0; long interval = 1000; DateTime now; // the loop routine runs over and over again forever: void loop() { unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
now = RTC.now();
if((now.second() % 2) == 0)
{
digitalWrite(pinPP,LOW);
}
else
{
digitalWrite(pinPP,HIGH);
}
}

showNumber(now.hour()*100+now.minute());

}

Кака работает код, в принципе понятно из него самого. Но все-таки прокомментирую.

Система просто смотрит, не прошел ли уже заданный интервал и если прошел, то считывает время из часов точного времени и мигает двоеточием.

Почему я просто не поставил посередине что-нибудь типа delay(995)? Ответ опять же в том, что разные ардуинки имеют разную скорость работы. И код, который выполняется между delay,
выполняется за разный промежуток времени. А значит, в реальности между delay проходит разное количество времени. И чего, мне после каждого изменения кода или логики подбирать
задержку? Бессмысленное занятие при наличии под боком нормальных часов.

Код "now.second() % 2" означает "дробная часть при делении на два". Попросту говоря, я зажигаю светодиод каждую четную секунду (14/2=7.0), а гашу - нечетную (15/2=7.5).

Ну и now.hour()*100+now.minute() из часов и минут делает большое число.

Запускаем!

Ура! Работает! Теперь у нас есть часики. Свои, персональные! Можем танцевать и бросать в воздух чепчики!

Но мне же надо еще и показометр ...

Добавляем в loop

while (Serial.available() > 0) {
s=(char)Serial.read();
if (s == 'n') {
char ca[5];
txtMsg.toCharArray(ca, 5);
number_to_show = atoi(ca);
time_to_show=2;
digitalWrite(pinPP,HIGH); // we do to need dots
txtMsg = "";
} else {
txtMsg +=s;
}
}

if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
if(time_to_show > 0)
{
time_to_show--;
}
else
{
now = RTC.now();

Суть кода простая: если компьютер послал что-либо в ардуинку, то тупо собираем все, пока не попадется спецсимвол n - это Enter или Return.
Затем превращаем полученное в число и на две секунды показываем вместо часов. Думаю, что если вы одолели предидущее, то этот будет просто понять.

Вот он целиком (для тех, кто не просто копипастит, внутри сюрприз):

#include

#include

int pinA=2;
int pinB=3;
int pinC=4;
int pinD=5;
int pinE=6;
int pinF=7;
int pinG=8;
int pinDP=9;
int pinPP=10;

int pinDIG1=11;
int pinDIG2=12;
int pinDIG3=A0;
int pinDIG4=A1;

RTC_DS1307 RTC;

void showDigit(int digit)
{
switch(digit) {
case 0:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,HIGH);
break;
case 1:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 2:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,HIGH);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 3:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,LOW);
break;
case 4:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 5:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 6:
digitalWrite(pinA,LOW);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 7:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
case 8:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,LOW);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 9:
digitalWrite(pinA,LOW);
digitalWrite(pinB,LOW);
digitalWrite(pinC,LOW);
digitalWrite(pinD,LOW);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,LOW);
digitalWrite(pinG,LOW);
break;
case 10:
digitalWrite(pinA,HIGH);
digitalWrite(pinB,HIGH);
digitalWrite(pinC,HIGH);
digitalWrite(pinD,HIGH);
digitalWrite(pinE,HIGH);
digitalWrite(pinF,HIGH);
digitalWrite(pinG,HIGH);
break;
}
}

void showNumber(int num)
{
int divide=0;
float z;
for(int c=1;c<5;c++) { showDigit(10); switch(c) { case 1: digitalWrite(pinDIG1,LOW); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); divide=1000; break; case 2: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,LOW); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); divide=100; break; case 3: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,LOW); digitalWrite(pinDIG4,HIGH); divide=10; break; case 4: digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,LOW); divide=1; break; } // switch String s(int(num/divide)); char b=s.charAt(s.length()-1); showDigit(b-'0'); delay(5); } } void setup() { Serial.begin(115200); Wire.begin(); RTC.begin(); pinMode(pinA, OUTPUT); //A pinMode(pinB, OUTPUT); //B pinMode(pinC, OUTPUT); //C pinMode(pinD, OUTPUT); //D pinMode(pinE, OUTPUT); //E pinMode(pinF, OUTPUT); //F pinMode(pinG, OUTPUT); // G pinMode(pinDP, OUTPUT); // DP pinMode(pinPP, OUTPUT); // PP pinMode(pinDIG1, OUTPUT); // DIG 1 pinMode(pinDIG2, OUTPUT); pinMode(pinDIG3, OUTPUT); pinMode(pinDIG4, OUTPUT); // DIG 4 digitalWrite(pinDIG1,HIGH); digitalWrite(pinDIG2,HIGH); digitalWrite(pinDIG3,HIGH); digitalWrite(pinDIG4,HIGH); digitalWrite(pinA,LOW); digitalWrite(pinB,LOW); digitalWrite(pinC,LOW); digitalWrite(pinD,LOW); digitalWrite(pinE,LOW); digitalWrite(pinF,LOW); digitalWrite(pinG,LOW); digitalWrite(pinDP,HIGH); digitalWrite(pinPP,HIGH); } long previousMillis = 0; long interval = 1000; DateTime now; String txtMsg = ""; char s; int number_to_show=0; int time_to_show=0; // the loop routine runs over and over again forever: void loop() { unsigned long currentMillis = millis(); while (Serial.available() > 0) {
s=(char)Serial.read();
if (s == 'n') {
//if(txtMsg=="HIGH") { digitalWrite(13, HIGH); }
//if(txtMsg=="LOW") { digitalWrite(13, LOW); }
//Serial.println(txtMsg.charAt(0));

char ca[5];
txtMsg.toCharArray(ca, 5);
number_to_show = atoi(ca);
time_to_show=2;
digitalWrite(pinPP,HIGH); // we do to need dots
txtMsg = "";
} else {
txtMsg +=s;
}
}

if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
if(time_to_show > 0)
{
time_to_show--;
}
else
{
now = RTC.now();
if((now.second() % 2) == 0)
{
digitalWrite(pinPP,LOW);
}
else
{
digitalWrite(pinPP,HIGH);
}
number_to_show=now.hour()*100+now.minute();
}
}

showNumber(number_to_show);

}

И в реальности:

Все закадровые звуки принадлежат игрушке на айпадике, в который играет сын.

Ну вот и все. Первый этап завершен. Часики тикают и показывают то, что в них плюнет компьютер.

Но это еще не финал, поэтому паять проводки и собирать полученное в одну кучку я бы не спешил. Хотя дело ваше 🙂

Что и для чего надо взять.

Итак, основа получения результата – это отсутствие заморочек.

Всё, что я использую, можно легко купить в любом магазине, занимающимся электроникой. ЧипИДип, Терраэлектроника, Вольтмастер, Амперка, Электронщик … в общем, поищите, наверняка рядом с вами есть фирмы, которые обеспечивают радиолюбителей полезными штуками.

Повторюсь, для повторения не надо будет даже паяльника. Но лучше с ним.

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

Wisher_WB-102_J_big

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

Главная цель макетной платы это позволить быстро и более-менее надежно собрать схему для проверки работоспособности. И так же быстро ее поправить или разобрать.

Вторым пунктом идет сам микроконтроллер. Я выбрал наиболее широко распространенный: arduino. Этих контроллеров и их клонов в магазинах как грязи по самым разным ценам. Для наших целей подойдет абсолютно любой.

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

Итак, в качестве микроконтроллера я взял CarDuino. Он же Arduino Nano или Nano Duo. Процессор ATmega328, документации очень мало, но есть русскоязычный форум. Использовать всякие “фишки carduino”, типа порта HV12 или SPK не буду (нет документации, не совместимы с другими ардуинками).

carduinov7_mid1

Для показометра я взял набор MP1091 от МастерКит. Четыре семисегментных индикатора, объединенных в один блок. Из документации только одна схема и черезжопу написанная  библиотека.

mp1091

Ну и венцом всего будет MP1095, в который спрятали уже готовую схему часов с батарейкой.

DOC000867115

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

Думаю, что обычный USB-miniUSB кабель, как и компьютер, вы найдете уж как-нибудь без моих подсказок.

Примерная стоимость набора в самом дорогом магазине Москвы:

Макетная плата с набором проводов – 1400 рублей.

CarDuino – 1180 рублей.

Индикатор MP1091 – 450 рублей

Часы MP1095 – 440 рублей

Итого 3500 рублей, из которых половину можно сэкономить, просто поспрашивав на форумах: многие отдают “макетки” и остальное за пиво-соки.

В дальнейшем в качестве “центрального компьютера” я буду использовать Raspberry Pi. Он точно так же доступен, обладает приличными характеристиками и при желании на нем можно собрать что угодно – от новогодней гирлянды до мультимедийного центра. Стоит ли вам его покупать сейчас, решать вам, но “часики/показометр” можно повторить за пару-тройку вечеров под пиво.

pi1l

 

Опять же, к нему (хотя бы на начальном этапе) надо USB-клавиатуру, мышку, монитор с HDMI или RCA входом и еще один USB-miniUSB шнурок.

В общем, по ходу дела расскажу с фотографиями, что зачем надо и куда что во что включать.

Микроконтроллеры или компьютеры?

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

Собрать стандартную схему “музыку играем, навигатор показываем, в интернет ходим” достаточно легко. Обычный CarPC обходится примерно в 15-20 тысяч рублей и по своему функционалу не напрягаясь переплевывает то, что производители машин предлагают автолюбителям.

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

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

Вот, к примеру, моя первая хотелка: обычные маленькие часики в машину. Давайте прикинем, как можно их сделать.

Берем 4 индикатора для циферок и двоеточие для мигания секунд. Берем самое простое, а значит у каждого индикатора 7 ножек (по числу светящихся сегментов), итого 28 ножек. Еще по ножке для “двоеточия” и питания. Итого 30 ножек. Ладно, я знаю как упростить схему до 13 ножек (знание будущего, так сказать).

И? Куда такое количество ножек втыкать в компьютер? Значит надо сидеть придумывать и разрабатывать свою плату расширения.

А затем? Представляете, что будет твориться в компе? “так, надо проиграть следующие 5 секунд музыки, зажечь вон тот индикатор, а вон тот погасить, а там кнопку не нажали? так, надо снова зажечь индикатор, оп-па, GPS чего-то хочет нам рассказать” … Ничего не напоминает? Правильно, мысли новичка за рулем, когда мозг одновременно решает, насколько надо повернуть руль, какую педаль нажать и попытаться вспомнить пункт правил, регламентирующий разъезд на нерегулируемом перекрестке. В большинстве случаев спасает то, что компьютеры все-таки умеют делать это быстро и не свихнувшись при этом.

Но для микроконтроллера задачи позажигать индикторы вообще не стоит. У навороченных контроллеров число ножек для подобных целей измеряется десятками. А с платами расширения их число может легко измеряться сотнями. Зато задачи типа “проиграть mp3” или “показать пользователю картинку” в рамках одного контроллера не решаются никак. Для каждого действия вне установленных рамок требуется свой, отдельный микроконтроллер. В итоге музыку играет один контроллер, голоса типа “поверните налево” обеспечивает второй, а картинки рисует вообще третьий. А все это между собой связано какой-нибудь хитрой шиной … В общем, ужас. И этот ужас старательно поддерживается всеми, кто кормится с этой отрасли. А пользователи недоумевают: как же так, навигатор за 5 тысяч круче и навороченней встроенного в машину, за который отдали 100?

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

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

А вот узнать положение машины по GPS, распознать код ошибки или сходить в интернет – этими задачами пусть занимается компьютер.

Мир, дружба и жевачка в одном флаконе.

 

Телефонизируй это!

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

В общем, надо было решать этот вопрос с телефонией. Главная задача: обеспечить канал связи между мной и женой. Второстепенные задачи: сделать это максимально дешево, незатратно и ненапряжно. Шикарно, если получится сделать городской номер, что бы раздавать знакомым и который не будет меняться при переездах.

Первое, что пришло в голову, это воспользоваться сервисом МультиФон от Мегафона, благо все мобильные номера от него и дома беспроводного интернета завались. В плюсах у него достаточно простая настройка, но в минусах продолжает танцевать жаба: все звонки оплачиваются по мобильным тарифам.

Следующим шагом стала мысль поставить на свой сервер VoIP АТС, на смартфоны sip клиентов, настроить все это и начать радоваться жизни.  В принципе задача совершенно реальная для меня, но в последнее время я стал предпочитать отдавать решение задач людям, которые специализируются на решении именно таких задач … В общем, надо идти к телефонным провайдерам.

Первым естественно в голову пришел sipnet. Старейший, толстейший и теде и тепе. Есть как свой клиент, так и наработанная база по подключению всего и всех. Из минусов – какая-то запредельная стоимость телефонного номера.

Дальше поиск привел к YouMagic от МТТ. В свое время я его тестировал и у меня остались двоякие впечатления: с одной стороны все есть, но с другой, это все подано таким винегретом … Но все равно зашел посмотреть что изменилось. Из наиболее видимого стала полная смена клиентов: когда я его тестировал, главным у них был клиент, написанный на java. Все прелести в виде тормозов, ресурсожручести и прочего в комплекте. Сейчас они договорились и сделали брендированную версию Bria (Её делает та же контора, которая делает X-Lite). А самый главный плюс был в том, что МТТ – ну очень толстая контора и владеет своей телефонной сетью, поэтому может позволить себе небольшие цены.

Следующим в списке стал Mango Office. Опять же, я давно его тестировал и он мне понравился. А сейчас у них всякие штучки, дрючки и свистелки с перделками. Я полюбовался на интеграцию их АТС с CRM и практически пошел создавать акканут, но по пути заглянул в раздел “тарифы” … В общем, по мобильникам с Дальнего Востока в Москву звонить дешевле.

Остальные мне не показались достойным упоминания. Они были или тупыми реселлерами кого-нибудь из потолще, либо обладали настолько невнятным сайтом, что я не мог в течении минуты-другой определить, что у них есть и за сколько …

Где-то на этом этапе я пришел к варианту взять номер у МТТ, поднять на своем сервере астериск, купить приличный sip клиент для iOS и Android, sip телефон домой и закрыть эту тему.

Стал читать интернет на предмет подводных камней и прочих заморочек с выбранной схемой. И внезапно обнаружил, что у МТТ есть youmagic.pro. Грубо говоря, виртуальная АТС с минимумом свистелок и перделок. За 300 рублей в месяц я получаю телефонный номер в Москве, 5 аккаунтов к нему, возможность создавать всякие простейшие диалпланы и голосовую почту в емаил.  Почему они не рекламируют эту услугу … в общем, наверняка руководству известно.

Быстрый чёс по интернету показал, что больших подводных камней нет. Есть куча мелочей, которые свойственны большой конторе, но все решаемо.

Ок, “заткнись и возьми мои деньги!”. Регистрация, выбор номера, я внутри. 5 дней на оплату, а то заблокируют.

Первый камешек меня ожидал на страничке оплаты. Она не изменилась с бета-тестовых времен. То есть то что там написано в реальности не применимо. Фигня, метод тыка и система соглашается с тем, что у нее есть этот аккаунт (если что, то валидным для нее является не 8499номер, не номер, а 499номер).

Второй камешек – то, что после оплаты вас пытаются послать на страницу magic.mtt.ru, которой так же нет еще со времен теста.

Но это все мелочи. На счете появились деньги и можно начинать звонить.

Первый звонок был совершен с компьютера на мобильный телефон. Слышимость нормальная, только голос глуховат. Пойдет …

Но все время так звонить “некузяво”. Надо стационарный sip телефон.

Опрос знакомых в мордокниге ожидаемо вывел на сименс гигасет с суффиксом ip на конце. Первая попытка купить его на горбушке или околометрошных магазинах электроники закончилась провалом: его нигде не было. Только развалы дектовских панасоников.

Вторая попытка была предпринята уже в магазине около работы. Там внезапно было обнаружено аж 3 точки, где наличествовал этот телефон. Методом “да и ну его” был выбран самый дорогой вариант – Siemens C610A IP. Почти четыре тысячи рублей.

Что было получено? Раздельные “стакан” и “база”. Очень удобно – не надо мучаться с выбором места установки. Обычные пальчиковые аккумуляторы – на предидущем телефоне были какие-то свои. В итоге оказалось дешевле выкинуть телефон, чем купить новый аккумулятор. Возможность работы с 5 sip провайдерами одновременно и какое-то слабое подобие диалплана. Ну и для резерва остается обычная телефонная линия, куда его тоже можно воткнуть.

Остальные фиговинки типа клиента электронной почты … в общем, маркетоидный бред, даже смотреть в ту сторону не стал.

Итак, финальная стадия в виде попытки все это собрать в одну кучу.

Базу в розетку, телефонную линию и ethernet в нее. Трубку на место старого телефона и тоже в розетку … Все сверкает и переливается, поэтому тупо понажимал “ок”, пока не прекратилось мельтешение.

Что получил в результате? Телефон с обновленной прошивкой, подключенный в обычную линию, к какому-то gigaset.net и аккаунт sipnet с кучей циферок. С sipnet получилось прикольно: телефон спросил меня, имею ли я какой-нибудь код автонастройки, а вместе с ним была бумажка от сипнета с этим самым кодом. Ну я и ввел его.

Но мне-то надо на МТТ! Пошел читать, как все это настраивать. На wiki от МТТ есть аж три варианта настроек именно этого телефона. Правда, отличаются они только методом “проникновения” на телефон. И опять же, если следовать им, то телефон даже в принципе не будет способен соединиться. Ибо прошивки новые, пункты не совпадают и так далее.

Потом сделал попытку воспользоваться автонастройкой. Толку было столько же, то есть нифига. Registration failed. Спасибо вам, маркетолухи сименса за сокрытие подробностей от пользователя! Ни логов, ни … в общем, вообще ничего нет. Почему оно не может – догадывайся сам. В качестве спасительного круга можно воспользоваться “вызовом мастера настройки АТС”, но это уже крайний случай …

(тут пропущены tcpdump, маты, расколупывание потока и конфигурирование роутера). В общем и если кратко, про хотя бы UPnP оно не в курсе, и надо давать ему “все на всех и везде”.

Наконец в страничке статуса я увидел registered. Тестовый звонок подтвердил, что все работает. Ура! Пошли настраивать дальше.

Тут в принципе можно было бы и завершать рассказку, ибо дальше каждый настраивает все под свой вкус … Но я оставлю резюме.

Итак, что я получил за четыре тысячи единовременных и 300 рублей постоянных затрат?

– Москвовский номер с кодом 499

– Возможность приема звонков с него как на мобильные телефоны (после установки клиентов), так и обратно.

– Стационарный телефон, с которым теперь можно бегать по квартире.

– Голосовую почту и возможность “наберите добавочный номер или дождитесь ответа оператора”. Слабенькое, дохлое, но есть.

– Практически мгновенную связь между внутренними клиентами. С мобильного-3G на стационарный-sip часто даже “гудков вызова” нет.

Что плохо?

– Тормозной сайт. Все выполняется медленно и печально.

– Куча бессистемно сваленной документации в формате “наотеб.сь”. Толку чуть больше нуля.

– На iOS запуск клиента приводит к остановке музыки (запуск, а не звонок!) и пожиранию батарейки. На андроиде не пробовал.

– Сименс страдает тем же, что и МТТ. К примеру, не умеет перерегистрироваться сам, без пинка в виде перезагрузки. Обещает индикацию состояния лампочкой на базе, но не показывает и так далее и тому подобное. Зато регулярно обещает “риск урагана” в Москве.

В общем, больше хорошего, чем плохого.

Мониторинг – великая вещь!

chart-1

Я люблю смотреть на всякие графики. Температуры, объемы  или скорости. Не важно. Главное в этом деле – легкий сбор данных и последующая их визуализация.

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

Не так давно в арсенал моих программ попала Runtastic HeartRate. У нее одна-единственная функция – измерять пульс или по-научному частоту сердечных сокращений (ЧСС).

Screen Shot 2013-04-03 at 12.08.40

Есть для всех устройств, для работы требует только одного: что бы камера на смартфоне располагалась рядом со “вспышкой”/фонариком. Так, что бы можно было закрыть одним пальцем.

Принцип работы прост: яркий светодиод от “вспышки” светит в палец, а кровоток в такт пульсу меняет поток света, попадающий в камеру смартфона. Остается только это зафиксировать и подсчитать.

Но просто так показывать не интересно. Во-первых, HeartRate заинтегрирована с основным порталом runtastic, куда сливает информацию и там позволяет рисовать всякие графики. Это мелочь, так много программ умеют.

А во-вторых, у HeartRate есть полезная функция ежедневного “теребления” пользователя о необходимости померить пульс. С учетом того, что сам процесс измерения занимает 15-20 секунд, это совершено не создает неудобств. Главное, что бы измерения происходили примерно в одном и тоже время в одном и том же состоянии.

И наконец, результатом этого стало  изобретение велосипеда: теперь когда я болею, я получаю не только субъективные подтверждения болезни, но и объективные. Если кому интересно, то по графику можете прикинуть, когда за последние два месяца моей тушке было плохо (Hint: ЧСС больше 90).

Ну и вдруг в случае чего, для врача однозначно не будет лишним такой график.

Теперь бы найти точно такое же ненапряжное решение для измерения давления …

 

Как я живу без Google Reader

.. и даже не подозреваю, что я теряю.

Скажу честно, я до сих в некотором удивлении, наблюдая в сети форменную истерику о невозможности жить без Google Reader. Расскажу, как я сам живу. И вроде даже комфортно.

К сожалению, это доступно только OS X пользователям. Ибо в основе всего лежит iCloud, OS X и Safari. Это одна из немногих штук, которые у Apple получились не просто хорошо, а так, что ими можно пользоваться. Хотя наверняка можно аналогичного собрать их дополнений к другим браузерам.

Взглянем на левую верхнюю панель моего бразуера.

ыфафкш

 

Для начала первая иконка во втором ряду. Reading List. Сохраняет страницы, которые вы решили прочитать попозже. Подчеркну, safari сохраняет целиком страницы, а не ссылки на них. То есть их можно будет читать без доступа к сети и так далее. Почти как у evernote с его web clipper, только в браузере.

Затем иконка облачка.

safari iCloud

 

Эта штука показывает открытые табы на всех устройствах, зацепленных под одной учеткой в iCloud. Минус только в том, что куки (а значит всякие авторизации обычно) не перемещаются. И положение на странице.

Опять же напомню, это синхронизируется практически в онлайне. То есть я могу в любой момент бросить комп зная, что доберусь до открытого в любом месте.

Это так сказать, инструменты одноразового пользования. В смысле я их использую по необходимости, а не регулярно.

И наконец, закладки. Основной функционал в сафари абсолютно точно такой же, как и у всех браузеров. Нажал Cmd-D, урл попал в закладки. Открыл редактор закладок (он в виде книжечки открытой), рассовал закладки куда и как надо. Но есть и одно большое преимущество. Поглядите на “Утренняя почта”

tabs

Казалось бы, такое есть во всех браузерах. Но обратите внимание на последнюю строку “Open in Tabs”. При ее выборе браузер закрывает все открытые вкладки и открывает новые с адресами из закладки.

В итоге “чтение новостей” у меня происходит так:

– Пришел, открыл все вкладки в текущем окне. Ну или если во вкладках что-то нужное осталось со вчера, Cmd-N и в новом окне.

– Читаем сайты по порядку. Ссылки на интересное открываются в новых табах того же окна.

– Если сайт не обновлялся (чем грешил Бобук в последнее время) – Cmd-W и вкладка закрыта. Если уже надоедает необновление – пара жестов на тачпаде и сайт вынесен в другую категорию.

– Переходим следующей вкладке, закрывая текущую тем же Cmd-W. Если интересно – читаем сразу. Интересно и надо бы перечитать – заносим в Reader List. Совсем интересный сайт – в закладки.

– Вкладки кончились и браузер закрылся? Значит все, новости тоже кончились и можно начинать работать.

Изредка по выходным я делаю ревизию закладок и рассовываю их по группам. Сейчас у меня их три:

– “утренняя почта”. Сайты которые я открываю каждое утро.

– “Обычное”. Сайты, которые я открываю под настроение или использую в текущей работе.

– Остальное. Так, мусорка с кучей когда-то нужных сайтов. Регулярно чистится.

Ну и зачем мне какой-то агрегатор RSS?

Музыкальный матч

Я люблю слушать музыку. Дома, на работе, в машине и в метро. В общем, везде. И так как я очень ленивый, я довольно долгое время пытался оптимизировать сам процесс закачки, обработки и прослушивания музыки. В свое время у меня компьютер был обвешан кучей скриптов, которые были готовы сделать все что угодно: от быстрого рипа сидюка до полуавтоматического поиска картинок для обложек и проставления тегов.

Вообще-то у меня задача по прослушиванию музыки стоит очень простая: “Я хочу максимально не заморачиваясь слушать музыку со всех доступных мне устройств. И я не хочу повторно слушать то, что я слышал недавно”.  И именно из-за второй части хотелки я не могу слушать плэйлисты наших радиостанций – они там по 30-50 песен.

Я перепробовал кучу программ, пытался писать свое, пока разными путями я не вышел на iTunes. Он умеет все, что я от него хочу. Скормил ему свежезарипанное и забыл. Сделал умный плэйлист и забыл. Засинхронизировал этот плэйлист с айфончиком или андроидом и забыл. Практически полное благолепие и красота.

Если бы не одно но: у меня больше одного компьютера и больше одного мобильного устройства. И если с мобильниками особых проблем нет – их всех можно подключить к одной библиотеке, то с компьютерами проблемы.

Во-первых, у меня довольно большая библиотека. 160+ гигов и под 30 тысяч песен. А на ноутбуке винт всего 64Гб. Вроде можно включить “шаринг” на большом компе, но это надо иметь постоянную связь с ним, да и вся идеи с умными плэйлистами тут же становятся неразрешимыми.

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

В-третьих, я стараюсь жить честно. И по моим прикидкам, примерно 80% моей библиотеки это легально купленные диски. Легально – это значит я отнес большую кучу денег в магазины типа “Союз” и затем попросту сграбил купленные диски. Не так давно я тупо выбросил 4 ашановских сумки с дисками. Ибо 99% дисков открывались один раз – на процесс рипа.

Остальные диски в моей коллекции – пиратка. Но пиратка эта от простой невозможности купить эти диски: они попросту неинтересны для производства. А я хочу иметь у себя “Мальчишник”, “Ласковый май” и газмановское “Люси”. И кучу другого хочу, но как говорится, не имею физической возможности …

Отдельной проблемой моей библиотеки стоит качество оригиналов. У меня есть сборники в духе “Гранды русского рока”, где заявлено качество 128Кбит/с, а в реальности там 96VBR … У меня есть треки, которые сграблены с сидюков, которые хоть и продавались в огромной сети музыкальных магазинов, но в реальности являются обычной записью mp3 на диск … В общем, давно ее надо привести в порядок, но то времени нет, то желания.

И тут как-то более менее сразу совпало два события: в качестве основного телефона я был вынужден перейти на iPhone 4S со старого SGS и в России Apple официально открыла свой музыкальный магазин.

Конечно, можно было и раньше им пользоваться через подарочные карты и прочие ухищрения, но это все было слишком неудобно (вы ведь помните, что я ленивый? 🙂

А вдобавок к магазину открыли для России и сервис iTunes Match. Поэтому вы сможете меня понять, когда я обратил самое пристальное внимание на эту штуку, ибо именно музыка вытащила Apple из жопы и вознесла на всяческие вершины. А поэтому можно ожидать, что все связанное с этим будет работать практически безупречно.

Итак, что мне обещает iTunes Match?

– Хранение всей моей музыки в “облаке”.

– Возможность закачки до 25 тысяч своих песен в “облако”. Даже тех, которые вы собственноручно сграбили.

– Обновление треков с плохим битрейтом до формата 256Кбит/с.

– Возможность как проигрывания песен напрямую из “облака”, так и предварительное закачивание на диск.

– Один аккаунт могут использовать до 10 устройств.

– Все это стоит 800 рублей в год (для России).

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

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

В общем, хватит расползаться клавишами по клавиатуре, пора попробовать это в реальности.

Для начала я в лоб пошел в iTunes Match. И так же в лоб получил ответ

В общем, товарищам с большой библиотекой казалось бы делать там нечего … Ладно, зайдем с другой стороны.

Решил я взять первую попавшуюся музыку (примерно 5 тысяч треков) на работе и скормить ее. Как ни странно, примерно 2/3 библиотеки залетели туда мгновенно. А вот с остальными возникла проблема. Они добавлялись в библиотеку очень медленно, по 1 песне в 5-10 минут и при этом процесе жрало 1,5 ядра процессора.

И при этом, сколько я не разглядывал тестовую библиотеку в iCloud, я так и не понял, на каких принципах отбираются туда треки.

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

Выводим в библиотеке iCloud status и получаем следующее:

– “waiting”. Вот чего оно ждет, я так и не понял. Статус снимается от 1-2 секунд до бесконечности на трек.

– “error”. Это судя по всему из-за банальной перегрузки эппловских серверов, потом что потом ошибка исчезла.

– “purchased”. Тут и так понятно, это я купил.

– “matched”. Это как раз те треки, которые я не покупал, но которые сервис распознал как уже имеющиеся у него. При этом ни название, ни теги не меняются!

– “uploaded”.  Те треки, которые он типа не нашел у себя и поэтому закачал к себе.

Функций типа “давай я покажу тебе, какому треку это соответствует” нет.

Теперь приступлю к тестированию обещанных фичек.

1. Стриминг, то есть проигрывание файликов по сети.

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

А вот iPhone тут оказался полностью провальным. Он тормозил и запинался как при работе через WiFi, так и через 3G. При этом по поведению телефона становилось понятно, что ему просто не хватает “мощи”.

2. Скачивание из облака на диск.

Тут никаких проблем не было. Всё, как обещано: то, что распозналось, то приехало назад в 256ААС. То, что не распозналось и залилось “как есть”, приехало в том же виде.

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

3. Плейлисты.

Вот тут и скрывается пока для меня самое странное.

С обычными плэйлистами все просто. Создав на одном компьютере плэйлист, мы получаем их копию на других. Мы можем проиграть песни из плэйлиста, скачать всех скопом на  диск или нарезать на болванку. В общем, абсолютно ничего неожиданного за исключением того, что часть или все песни в плэйлисте могут быть в облаке.

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

Одно “НО” – я так и не понял, как и когда он синхронизирует плэйлисты. Иногда практически мгновенно, а иногда приходится ждать несколько часов. Есть и ручное проталкивание: Надо просто выбрать “обновить iTunes Match” последовательно на всех компьютерах, при этом первым должен быть тот, где делали последние изменения.

iPhone и тут не смог не подложить пакость. На смарт-листах размером где-то больше 3-4Гб программка Music попросту падает. Без всяких сообщений и прочего. Р-р-раз и вы на главном экране.

Я пока выключил iTunes Match и iPhone синхронизирую через ноутбучный iTunes. Получается гораздо быстрее и безпроблемней.

Итак, как на мой взгляд надо рассматривать iTunes Match:

– Легализация свой музыкальной библиотеки за 800 рублей в год.

– Удаление дубликатов из библиотеки.

– Обновление большинства содержащихся в библиотеке песен до приемлимого качества

– “Растягивание” свой библиотеке на 10 компьютеров

– Снятие такой задачи как синхронизация музыки между несколькими устройствами.

– Облако – вполне неплохая замена резервному копированию в этом случае.

Для кого эта вся штука категорически не подойдет:

– Любители многоканальной и lossless музыки.

– Владельцы библиотек, где больше 25 000 треков.

– Те, у кого неприятие продукции Apple как класса.

– Любителям поделиться со всеми. Ибо в треках записывает ваш Apple ID и по нему легко можно добраться до вас …

Ну а если вернуться назад, к моей большой библиотеке …  iTunes Match решил мою задачу. Я просто разбил свою библиотеку на две части и по частям залил туда. Попутно Match вычистил мои дубликаты (у некоторых было аж по 4 копии с разным битрейтом), а я вычистил всякие track01 и track02.

В общем, пока категорически рекомендую, я буду дальше тестироватьи искать какие-нибудь неприятности …

 

Флюсуемся …

В прошлом посте я рассказал, как правильно подготовиться, что бы перевернуть мир. В смысле делать тоже самое за меньшее время. Теперь пришла пора подумать, как все это делать гораздо удобнее.

Что значит удобней? Как ни странно, большинство считают слово удобство синонимом слова привычно. Привыкли копать огород лопатой, вот и копают от зари и до зари, хотя на заднем дворе стоит трактор со всем навесным оборудованием … Почему? Ну дык его заводить надо, обслуживать … А лопатой раз-раз и все …

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

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

У нас уже есть распределение, как мы тратим время. Даже в бесплатной версии rescuetime доступен отчет, где задачи отсортированы по уменьшению затраченного времени. Берем задачу, отнимающую наибольшее число времени и смотрим на нее.

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

Ставим мысленно галочку “попридираться” и при работе с этим начинаем задавать себе вопросы “а нафига?”. И просто скидывать их куда-нибудь. Скажем, в тот же Evernote или WorkFlowy.

Просто скидывать, не задумываясь над сутью. Поначалу будет тяжело, ибо вы ко всему привыкли, все кажется привычным и не требующим изменений. Тут главное поймать даже самое легкое раздражение и зафиксировать его.

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

Как и в случае с учетом времени, через некоторое время я обозрев список, подумал что-то вроде “как с этим я вообще живу?”. Честно, список касался всего: от обстановки в машине и заканчивая ssh клиентом.

Раз упомянул ssh клиента, то вот на его примере и раскрою этот конкретный случай.

У меня есть куча серверов под линуксом. И мне, как ни странно, регулярно туда надо заходить. И заходить из-под Windows. Раньше я использовал решение в лоб: после установки windows, я качал putty, менял в нем трансляцию на utf-8 и успокаивался. Однако после проведения инвентаризации раздражалок у меня получился следующий список:

– Неадекватная работа с copy-paste. Невозможно сделать это через меню в духе Edit-Paste. А если на клавиатуре нет кнопки Ins, то только через 3ю кнопку мыши. Да с cr/lf как-то все время ляпы происходят.

– Почему-то регулярно pscp отказывается не в путях и его надо тащить вручную. И процесс “мы на сервере, надо бросить туда файлик” какая-то корявая …

– Зачем-то вместо обычных форматов ключей он требует .ppk

– Некоторые клавиатурные комбинации отрабатывают не так и фиг его знает, кто виноват – я или сервер. Лень разбираться.

– При обрыве выкидывает окошко, которое сволочь модальное.

– Где табы?

Повторяюсь, это лично мои заморочки с этим. У вас их может не быть или будут другими. Главное – поймать их.

Ну вот я посмотрел на эти заморочки и понял, что для удобства надо сменить ssh клиента. Прогулялся по интернету и понаставил триальных и не очень версий. Выбрал наиболее понравившийся, заплатил и расслабился. Скорее всего, у него тоже окажутся свои неудобности, но это будет потом. Главное, я снял текущие неудобства.

Через некоторое время вы обнаружите, что жить стало гораздо удобней. А ведь ничего сложного же, да?