Карпутер. 5. Пора программировать!

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

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

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

Возьмем наш первоначальный алгоритм. Если напряжение поднялось больше 13В, то замкнуть реле ближнего света. Где мы тут можем ошибиться? Да везде – от подбора резисторов для делителя напряжения до распайки реле и неправильного подсоединения. Поэтому сокращаем возможность ошибки до минимума: вместо делителя напряжения бортовой сети воспользуемся обычным переменным резистором, а вместо реле – обычным светодиодиком. Как подключать – я уже писал в предидущем посте. Но если у вас, как и у меня, плата discovery, то там уже есть светодиодики (а значит, вероятность ошибки снижается еще сильнее).

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

01a9541850ca680e486975cc6dcf78e69f85d7241d

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

Теперь пора описать, где и как писать код. Открываем сгенерированный пару постов назад код и находим в левой панели фаил main.c. В нем ищем кусок кода while(1), как показано на картинке

p1

Вот все, что будет расположено между фигурными скобочками и будет выполняться бесконечно (для тех. кто знаком с ардуиной, это void loop()). Писать надо на языке С, обучать которому я тоже тут не буду.

Еще одно отступление – как управлять выводами. У ардуины есть кошмар под названием port mapping (это когда при смене контроллера все назания ножек меняются и программы перестают работать), на stm тоже до недавнего времени такой кошмар был. Именно был, сейчас все проще.

Итак, если вы посмотрите на микроконтроллер, что обнаружите, что ножки нумеруются от PA0 до PF15. Все функции используют следущую нумерацию ножек – Блок от А до F и номер ножки в блоке.

Переведение ножки PC12 в “высокое” состояние

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_SET);

А ножку PE15 – в “низкое”

HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15,GPIO_PIN_RESET);

Выдаем на 1й канал ЦАП значение переменной s

HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, s);

И мной написанная (или подправленная) функция для чтения значения АЦП

static int GetADCValue(uint32_t Channel,uint32_t Count)
{
int val = 0;
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel=Channel;
sConfig.Rank=1;
sConfig.SamplingTime=10;
HAL_ADC_ConfigChannel(&hadc,&sConfig);

for(int i = 0; i < Count; i++) { HAL_ADC_Start(&hadc); HAL_ADC_PollForConversion(&hadc,1); val += HAL_ADC_GetValue(&hadc); } return val / Count; }

Как видно из кода, работает только с ADC1 (ссылки hadc).

В посте описать все невозможно, поэтому рекомендую заглянуть в "Firmware", которую скачал STMCube, и посмотреть там примеры.

Итак, вот мой код

if(GetADCValue(2,3)>2048)
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15,GPIO_PIN_RESET);
}

В чем его суть? Если значение, которое прочитали из АЦП, больше 2048, то перевести ножку PE15 на высокий уровень. Если меньше, что наоборот, на низкий.

В чем магия? Магия в двух вещах. Первое, это значение АЦП. Оно может быть от 0 до 4095 (3В на ножке). Как им распорядиться, решать вам. А второе - ножка PE15 на плате подключена с зеленому светодиоду.

Компилируем, заливаем (иконка с буковками LOAD во втором ряду) и наслаждаемся своей первой программой.

Сам код (полностью готовый и скомпилированный) можно взять отсюда http://multik.org/carsim/carputer.rar

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

Желаю удачи в написании своих проектов!

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

Карпутер 4. Кормим микроконтроллер

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

Итак, перед нами стоит 3 задачи.

1) Накормить микроконтроллер.
2) Дать данные. То есть позволить микроконтроллеру собирать всякую нужную ему информацию.
3) Позволить ему чем-либо управлять.

В чем основная проблема? Проблема как ни странно, в бортовой сети автомобиля. Напряжение в ней гуляет от 9 вольт до 14,5 вольт с возможными выбросами до 60 вольт. Попутно в этом самом “напряжении” есть куча шумов, всплесков и прочей гадости.

А микроконтроллеры очень нежные. Питаются только 5ю вольтами или 3,3мя. И желательно, что бы эти вольты не гуляли туда сюда больше 5%. То же самое и с входами-выходами. Те же самые условия, только еще желательно, что бы ток, проходящий по ним, не превышал единицы миллиампер. В случае необходимости ток может быть поднят до десятка-другого миллиампер, но это уже черевато.

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

Для питания “на быструю руку” давно придуманы готовые схемы. В любом приличном магазине электроники можете произнести слово “L7805” и вам за 10-15 рублей вынесут маленькую черную штучку, которая получает на входе от 8 до 30 вольт, а на выходе выдает стабильные 5 вольт. Вот тут (multik.org/carsim) вам собранная в proteuse схема на поиграться (carsim-power).

car-power1

Сколько бы вы не давали на “вход” напряжения, на выходе всегда будет около 5В. В чем подвох? Подвоха два. Во-первых, на холостом ходу (когда к ней ничего не подключено) эта штука потребляет единицы миллиампер. Для обычных условий эксплуатации это нормально, а вот если делать что-то типа сигналки, когда схема постоянно подключена к аккумулятору, это .. некрасиво. Во-вторых, если вы задумаете “снимать” с стабилизатора 1-1,5 ампера (хинт – это почти готовая зарядка для телефона), то вы внезапно обнаружите, что стабилизатор греется. Почему? Потому что он вынужден куда-то тратить те вольты, которые оказались ненужными. Считайте сами: пусть будет в бортовой сети 13,4 вольта. Телефон хочет 5В и 1А для своего заряда. Значит стабилизатору надо рассеять где-то (13,4-5)*1=8,4 ватта. Это вполне себе нехилая грелка. И именно поэтому у этого стабилизатора есть металлическое ушко, за которое его прикрепляют к радиатору (Кстати, радиатором может быть любая массивная железная часть автомобиля). Но повторюсь, для обычных применений это вполне себе штуковина.

Но если мы заранее задумаемся о снижении напряжения и тока питания, то есть варианты. К примеру LP2950. Он включается точно так же, как и 7805, но во-первых, на холостом ходу ест десятки микроампер, а во-вторых, больше 100 миллиампер с него не снять. Для многих схем этого может хватить.

Но что делать, если по каким-то причинам надо больше 1,5 ампер и радиолюбителей (что бы собрать блок питания) нет под боком? Тогда на выручку придут готовые DC-DC преобразователи. По сути это собранные и оттестированные блоки питания в миниатюрных корпусах. Например NSD15-12S5 (вход 9.4-36В, выход 5В и 3А) или наш МПА15А (вход 9-18В, выход 5В и 3A). На самом деле их куча, стоит только поискать. В чем их плюсы? Ну, они не греются, имеют встроенные фильтры, управление, защиту от КЗ и прочее, что полагается иметь блокам питания. Основной их минус в цене: от тысячи рублей и выше.

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

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

Первый: делитель на резисторах. Просто ставим в цепь два резистора, в точке их соединения забираем данные. Уровень напряжения в точке будет равен входному напряжению * соотношение номиналов резисторов. А ток можно подсчитать по закону Ома – i=u/r Опять же, я понимаю, что это тяжко, поэтому вот очередная схема в протеусе, которая позволит “поиграться” (там же файл carsim-power-res). Ну или набрать в поисковике “калькулятор делителя напряжения”.

carsim-power-res copy

Справа можно увидеть амперметр (показывает миллиамперы) и вольтметр. Наша задача – добиться таких сочетаний резисторов R1 и R2, что бы на микроконтроллер не приходило больше 3В (если ардуино, то 5) и потребление тока было минимальным (а то так повесим с десяток датчиков, сжигающих на резисторах по 10 миллиампер и получим 0,1 ампера, способных посадить аккумулятор в “ноль”). Казалось бы, простая задача? Но давайте снова посмотрим на то, что может происходить в бортовой сети. От 9 до 60 вольт … Если сделать совсем классический вариант, то 99% времени напряжение на ножке контроллера будет составлять доли вольта. Как-то некрасиво.

Поэтому обычно рассчитывают делитель на входное напряжение 0-15В, а всплески (которых может и не быть) убирают отдельным элементом. Есть много схем, но я предпочитаю самую простую в изготовлении: на вход, перед делителем, ставлю защитный диод (он же супрессор, он же TVS). Скажем, китайский SA15 пропускает через себя все, что попадает в диапазон 0-15 вольт. Остальное он убирает и убирает довольно качественно (в смысле после него конденсатор если и нужен, то только для сглаживания). Минус у него только один – если что, то он (диод) превращается в простое короткое замыкание, заставляя сгорать всё что можно перед собой. Для 99% случаев этого достаточно, а для оставшегося 1% существуют предохранители. Схемы я нарисую в следующем посте.

ВАЖНО: нельзя использовать “делители напряжения” для схем, где есть напряжения больше нескольких десятков вольт. Просто небезопасно для здоровья. Для этого есть второй вариант.

Вторым вариантом ввода сигнала в микроконтроллер является оптопара. Внутри оптопары стоит светодиодик, который своим светом управляет транзистором, “включая” или “выключая” выходы. У оптопары главный плюс в следующем: легко можно измерять наличие сотен и тысяч вольт. Самая обычная оптопара легко “развязывает” до 1500 вольт. Минус же тоже существенный: с её помощью нельзя (практически, да) измерять уровень сигнала. Только “есть” или “нет”.

Кнопки и прочие выключатели обычно присоединяются в микроконтроллер напрямую – там обычно неоткуда возникнуть “бякам”. Если возможность есть, то либо опять поставить на входе супрессор, либо стабилитрон с керамическим конденсатором. Опять же, страшные схемы в следующем посту.

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

062-Как подключить к микроконтроллеру нагрузку?

Моими любимыми способами являются использование “составного транзистора Дарлингтона” и “полевой транзистор”. Тут их переписывать не буду, ибо все прекрасно описано по ссылке выше. Мой выбор между способами простой: если надо коммутировать что-то до 5-10 ампер или быстро включать-выключать, выбираем транзистор. Выше – реле через составной транзистор. Быстро включать-выключать большие нагрузки мне не приходилось, но думаю, схем на всяких тиристорах и симисторах навалом.

Что бы проиллюстрировать вообще все вышеприведенное, вот вам очередная схема (она же в файле carsim-final)

carsim-final

Думаю, вдумчиво читающим уже почти все понятно, но на всякий случай прокомментирую. Слева вверху я сымитировал бортовую сеть автомобиля. Можно переключиться на 12В, 13,4, 16В и на регулируемое. Правее – стабилизатор напряжения на 5В. Слева внизу – делитель напряжения на резисторах R1 и R2 и развязка через оптопару U2. Правее стабилизатора две схемы включения нагрузки – через N-канальный полевой транзистор IRF610 и через сборку Дарлингтона ULN2003A.

К моему сожалению, proteus довольно небрежно относится (или у меня такая версия) к мощностям элементов, поэтому симуляция иногда прерывается (как и игнорируется D2). Если такое случилось, просто запустите заново.

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

Карпутер. 3. Выбираем микроконтроллер.

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

Как выбирают контроллер?

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

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

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

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

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

Какой будет алгоритм работы?

1. Измеряем напряжение бортовой сети
2. Напряжение меньше 13В? если да, иди на п.1
3. Подождать 5 секунд.
4. Включить фары.

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

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

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

Теперь готовимся скачать много из сети. Для начала нам нужна программа STM32CubeMx. (Все поисковики ее легко находят, но вот прямая ссылка http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1533/PF259242?sc=stm32cube там мотайте страницу в самый низ и справа будет маленькая красная кнопочка Download).

Зачем нужна эта программа? Как я писал в первом посте, STM32 имеют один, но очень большой и неприятный минус – очень сложно начать с ними работать. В этих микроконтроллерах очень много возможностей и вариаций, поэтому даже просто запустить его составляет очень большую проблему. Команды инициализации, предназначенные для одной серии, не подходят для другой. Один и тот же порт может выполнять разные функции на разной частоте, причем все это настраивается в четырех или пяти местах. В общем, реальный кошмар после атмеловских контроллеров и 99% причин неработащих программ.

Вот и придумали этакий “генератор кода инициализации”, когда можно мышкой не торопясь повыбирать порты и их функции. При этом идет одновременный контроль правильности использования порта и непересечение его с другими функциями. В общем, скачивайте, распаковывайте и запускайте программу (может потребовать java, так что тоже ставьте). Как ставить программы, нажимая next, я рассказывать не буду 🙂

stmcube1

Перед вами откроется очень информативное окно. New Project – это создать новый проект, Load Project – загрузить старый, который редактировали раньше. Нам естесственно надо выбрать создать новый. И тут …

stmcube2

И тут перед вами откроется окно, в котором собрана вся (почти) линейка микроконтроллеров. Первая вкладка – MCU Selector позволяет выбрать подходящие контроллеры в их голом виде. Слева в табличке функционал, справа – подходящие контроллеры. Скажем, нужно нам в нашем проекте использовать одновременно ethernet и часы реального времени, так значит ставим галочки и получаем, что нам подходят 88 микроконтроллеров из 590 (на момент написания). Но эта вкладка для продвинутых пацанов.

Нам нужна следующая вкладка, которая называется Board Selector. Тут уже можно выбрать готовые платы, со всем распаянным. Сразу рекомендую нажать кнопку “>>”, которая будет показывать изображение платы.

stmcube3

Механизм тот же самый – слева выбираем что хочется, а справа получаем список того, где это есть. Потом открываем веб-сайт ближайшего магазина электроники и смотрим на наличие и цену. Лично у меня есть платы STM32L100 и STM32F3 (именно она изображения на скриншоте). Так как F3 мне нравится больше, то и в дальнейшем я буду использовать именно эту плату. Но повторюсь, вы можете использовать любую плату или процессор – главное, что бы он вам подошел по характеристикам.

Выбрав плату или процессор, жамкаем на кнопоку ОК в самом низу. Компьютер немного подумает и потом выдаст примерно вот такую картинку.

stmcube4

Слева будут всякие возможности, которые умеет процессор, а справа – как и на что распределены ножки и процессора. Если вы вышли сюда из выбора плат, то программа сама показала, что на плате куда подключено. Как видите, все ножки помечены разными цветами.

Желтенькие и светлозеленые – ножки, назначение которых изменить нельзя. Питание, земля и прочие подобные ножки.
Оранживенькие – ножки, на которые повешено то, что есть на плате и что можно либо отключить, либо заиспользовать. У меня это кварцевые резонаторы, гироскоп с компасом, USB порт и так далее.
Зелененькие – это ножки, на которые тоже повешено то, что есть на плате, но это ТО – кнопки, светодиодики и прочее. Грубо говоря, отличие только в сложности с точки зрения контроллера. Таким же цветом будут обозначаться и ножки, которые вы выделили для вашего проекта.
Серенькие – свободные ножки, которые можно использовать.

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

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

stmcube5

Как видите, эта ножка может выполнять аж 17 функций, но сейчас она работает как GPIO_Input (я ниже объясню, что это значит).

А второй способ – воспользоваться левой вкладкой и включить нужную функцию.

stmcube6

Как видим, у функции вообще горит желтый предупреждающий знак, который показывает, что что-то с ней не то. Открыв ее, можно увидеть подсвеченным красным подфункцию. В данном случае это IN1. Подведя мышку к красному, можно узнать, что с чем конфликтует. В данном конкретном случае можно увидеть, что 1й канал 1го аналого-цифрового преобразователя конфликтует на ножке процессора PA0, которая уже стоит в режиме GPIO_Input. Белиберда, да? Но ничего. Для примера можно обидеться и раз нам не дают использовать IN1, выбрать IN3, что бы это не значило. И обратите внимание, на рисунке процессора справа одновременно начнет показываться как “занятая” соответствующая ножка процессора. В нашем случае это PA3, в левом нижнем углу.

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

Итак, как же понять, какие функции можно повесить на ножку? Что бы не забивать голову, я опишу только наиболее нужные и часто используемые функции. Назначение других можете узнать сами, когда прижмет (но 90% это никогда не понадобится).

Итак, что можно выбрать?

ADC – Или АЦП, аналогово-цифровой преобразователь. Показывает значение напряжения. У большинства АЦП есть каналы, к которым он может подключаться. А каналы напрямую подключены к ножкам. То есть когда вам надо измерить напряжение на 1,2 и 3й ножке, то микроконтроллер на самом деле будет выполнять примерно следующее “подключить ацп к ножке 1, измерить, подключить ацп к ножке 2, измерить, подключить ацп к ножке 3, измерить”. В принципе, для большинства задач этого достаточно, ведь измерение одного канала занимает от 1 до 10 мс. Но есть задачи, когда необходимо реально одновременно измерить напряжение на несколких ножках. В таком случае используют два или больше АЦП. Например, в F3 серии аж 4 АЦП, поэтому мы можем измерять 4 уровня одновременно. Если мы заиспользуем все доступные ресурсы, то сможем за 0,1с измерить 59 аналоговых выводов (ардуинщики, вы рыдаете? :).

DAC – или ЦАП. Цифро-аналоговый преобразователь. Преобразует некоторое значение в уровень сигнала на выходе. Обычно один DAC имеет от 1 до 10 выходов, каждый из которых можно регулировать отдельно.

TIM – таймеры. Срабатывающие “раз в нное время” сигналы. На таймерах в stm делается очень многое – от PWM (управление сервомоторами и яркостью) до подсчета частоты смены сигнала на входе. Немножко к ним имеют отношение RTC – часы реального времени (которые считают минуты и секунды, а не тики и такты) и WDG – системы, которые автоматически перезагружают контроллер, если он завис, но я их касаться не буду

USART/UART – контроллеры для связи с “внешним миром”: с компьютерами, с другими контроллерами и так далее.

И наконец GPIO. Это порты общего назначения. То есть на них можно вешать все, что душе угодно. Они могут быть GPIO_Input – порт, работающий на вход (который принимает сигнал “есть” и “нет”) и GPIO_Output – порт, работающий на выход (который выдает сигнал “есть” и “нет”). Вы можете увидеть GPIO_Reset – это означает, что порт находится в хз каком стоянии и GPIO_EXTI – это выход прерывания. В общем лишнее на данном этапе.

Все ножки маркируются следующим способом: [подсистема]_[функция]. Пример:

ADC1_IN6 – 6й вход 1го АЦП контроллера
DAC1_OUT1 – 1й выход 1го ЦАП контроллера
USART1_TX – порт передачи 1 контроллера связи.

Но вернемся назад. Из всего выше перечисленного нам нужен один ADC ввод и один GPIO_Output вывод. Для ввода я заиспользую ADC1_IN2 (ножка PA1), а для вывода GPIO_Output – PC5. Они расположены на одной стороне реальной платы, поэтому мне будет удобно с ними работать. И что самое главное, они не конфликтуют ни с чем, что уже есть на плате.

stmcube7

Щелкаем и меняем назначение нужных нам ножек. Обратите внимание на то, что у PA1 нет булавки, а у PC5 – есть. Это та самая функция переназначения портов, когда вдруг функционал будет конфликтовать, а нам нет разницы, откуда его брать. Что бы “прикрепить” функционал к ножке, надо просто правой кнопкой мышки по ней щелкнуть и выбрать Signal Pinning. Теперь ни одна сволочь не отберет у нас ее :). Кстати, там же можно и дать название ножке, что бы не запутаться.

stmcube8

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

Можно сохранить проект на всякий случай, ибо это только начало.

Теперь щелкаем следующую вкладку – Clock Configuration. И у некоторых сейчас порвет мониторы 🙂

stmcube9

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

stmcube10

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

На картинке мы видим включенный контроллер ADC1 (для него нужны контроллер DMA, NVIC и RCC) и контроллер GPIO (Для него нужен RCC). В общем, давайте поверим, что нам это надо.

На этом экране у нас есть возможность тонкой настройки. Жмем на ADC1

stmcube11

Тут собраны все тонкие настройки для данного контроллера. Особо менять нечего, за исключением подсвеченного – Continuous Conversion Mode. Поставьте его в Enabled. Данная галочка говорит, что мы желаем запрограммировать контроллер так, что бы он постоянно мерял свои входы. И более того, измерянные значения сразу присваивал переменным. Ну ленивый я, пусть железка сама все делает 🙂

Аналогичную картинку можно получить и по GPIO портам.

stmcube12

Тут можно тоже поизменять разные параметры, но нам тут менять тоже ничего не надо.

В общем, полезная вкладка, особенно когда начинаешь использовать более сложные вещи, как USART или USB – здесь можно настроить все.

И наконец, последняя вкладка – Power Consumption Calculator. Тут можно прикинуть, сколько электричества будет потреблять микроконтроллер.

stmcube13

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

Итак, остался один последний шаг. Сгенерировать исходный код, котрый будет компилироваться и прошиваться в контроллер. На панели сверху есть кнопка “шестеренка с палкой”. Нажимаем ее и …

stmcube14

Заполняем, где будут располагаться файлики и как мы обзовем проект. Так же выберем, для какой среды разработки будет генерироваться исходный текст. Выбор небольшой и все предлагаемые системы – полный шлак (тут конечно у каждого свои фломастеры, но тот же бесплатный CoCox уделывает Keil как бог черепаху), поэтому выберите MDK-ARM, как наиболее описанную в русском интернете.

Если вы запускаете генерацию в первый раз, система предложит скачать Firmware Package именно для вашего процессора. Ждем пока скачает и нагенерирует.

stmcube15

Увидели это окошко? Поздравляю! Вы прошли большую часть пути. Остался еще один шаг. Всего один …

Открываем браузер на https://www.keil.com/download/product/ и выбираем MDK-ARM v5. Вам дадут анкету, в которой реально проверяется только email. Проверяется – в смысле их сервер подключается к вашему серверу и проверяет валидность ящика, поэтому емайлы типа 2@1.co не проходят. Остальное нужно только для того, что бы выбрать, на каком языке потом вам напишет продавец со словами “купите у нас”. Как обычно, у данной версии есть ограничения и самым главным из которых является ограничение в объеме кода в 32 килобайта. Поверьте, это довольно приличный объем для микроконтроллеров и вам его хватит надолго. Но если вас это напрягает, то сами знаете где можно найти вылеченную версию совершенно бесплатно.

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

Как обычно, рассказывать как ставить программы с помощью нажатия кнопки next, я не буду. Единственное, что при первом запуске вылезет Packs Installer – дождитесь, пока он отработает и закрывайте его. Так что ставьте Keil и в той папочке, куда сохранили проект, найдите каталог Projects, в нем MDK-ARM и там ваш файл с типом mVision4 Project. Нажимаем на него …

stmcube16

Я тут его немного сплющил, но вы увидите именно это. Теперь нажимаем на кнопочку, которая во втором ряду, под “открыть”. Похожа на папку для бумаг, в которую входит стрелочка. Ну или на клавиатуре F7. Этим мы запускаем компиляцию всего того, чего мы нагородили выше.

stmcube17

И только после того, как вы увидели в окошке снизу строчку 0 Errors(s), 0 Warning(s) вы можете поздравить себя – у вас есть полностью готовая прошивка для микроконтроллера. Ну и что, что она пока ничего не делает, зато 90% нашей первоначальной задачи уже выполнено. Теперь вы можете идти в магазин и покупать реальный микроконтроллер за реальные деньги. И у вас есть уверенность, что он заработает.

А вот как и что подключать к контроллеру – это уже в следующем посте.

Карпутер. 2. Все не так страшно …

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

Раз вы читаете это, значит у вас есть компьютер и браузер. Открываете браузер и идете на http://www.labcenter.com/. Там все по английски, но вам нужен раздел Downloads, а там скачать prodemo.exe. В этом здоровом файле находится редактор схем и печатных плат. А так же симулятор этих самых электрических схем. То есть вы можете как угодно “коротить”, “вешать сопли” и развлекаться другими способами: никакого урона электронике вы не нанесете.

proteus_screen

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

Вот тут http://multik.org/carsim/ лежит готовый проект для proteus (просто скачайте файл carsim.dsn и кликните на нем – он откроется в proteus). Он довольно приблизительно имитирует электропроводку обычной машины. Знающие электрику начнут кривить носом и искать ошибки (а они там есть), а незнающие могут нажать слева внизу кнопочку “play” (треугольник вправо, если кто не понял) и поиграться. Поиграться в буквальном смысле: выключатели выключают и включают лампочки, а пипикалка пипикает.

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

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

proteus1

Здесь имитация генератора и ключа зажигания (SW1), аккумулятора и отключателя массы (SW2) вместе с главным предохранителем. Вольтметр показывает напряжение в “бортовой сети”.

proteus2

Тут имитация работы ближнего и дальнего света. Переключатель SW3 имеет три положения – выключено, ближний свет и дальний свет. Лампы L1 и L2 отвечают за “ближний”, а L3 и L4 – за “дальний”.

proteus3

Эта часть имитирует салонный свет. 5 выключателей – это концевики дверей и багажника. Пока любой из них замкнут (соответствующая дверь открыта), будет гореть свет в салоне или лампочка L5.

proteus4

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

С последней частью предлагаю разобраться самим, главное громкость поменьше сделайте 🙂

Итак, я буду считать, что наиболее нетерпеливые наигрались, а некоторые даже пошли читать инструкции или даже смотреть (в гугле “proteus начинающим” выдаст все необходимое).

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

Кнопки. Бывают нормально замкнутые (концевики в дверях) и нормально разомкнутые (кнопка сигнала). Принцип простой: нажал, она сменила состояние (замыкала цель – теперь размыкает) и будет в таком состоянии, пока ее не отпустить.

Выключатель. Такой же, как кнопка, только состояние фиксируется (держать не надо)

Переключатель. Полностью аналогичен выключателю, только коммутирует несколько выходов. Пример – SW3 выше. Или замок зажигания.

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

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

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

Да, особняком стоят всякие OBD, CAN и прочие, но там все в цифре и я этого коснусь потом.

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

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

Согласитесь, совсем не страшно же? Тогда в следующем посту будем выбирать конкретный микроконтроллер под ваши нужды.

Карпутер. 1. Предисловие и выбор микроконтроллера

Хотел начать с обычного отсыла к классике (“этим постом я начинаю …”), но потом передумал. Начну обыкновенно.

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

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

Для начала я решил составить список того, что у меня недоделано (просто скопирую из форумных постов)

1) Контроллер второго аккумулятора. Штука с вольтметрами, контролирующая подключение второго аккумулятора. Есть подобная у t-max, но она вся в светодиодиках и тупая. Алгоритм грубо говоря такой: смотрим на напряжение на первом аккумуляторе, как превысило 13В (значит завелись), подключаем второй (для зарядки и теде). Если на первом долгое время 12В, значит можно отключить второй — мы на стоянке. Если ниже, то не отключать — мы лебедимся и второй аккумулятор нужен. Ну и кнопочка принудительного подключения второго, если первый на стоянке разрядился по каким-то причинам. У водителя индикатор с вольтами и кнопочка.

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

3) “Корректор спидометра”. Меня напрягает 10-15% погрешность спидометра даже на штатных колесах. Меня напрягает нелинейность этого вранья. И стоит сменить размерность колес, как все привычки типа “раз стрелка на 90, значит я еду 85” приходится “перепривычивать”. Дополнительно была мысль сделать вывод “поехали — включи ближний свет/ДХО”, что бы не дергать переключатели руками и не зажигать фары перед заводом зимой.

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

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

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

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

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

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

AtMega или Adrduino. Те же самые плюсы, что и у “тинек”, но добавляется то, что все решения уже идут готовыми. Подключил плату к компьютеру, настучал в окошке код и он уже выполняется. Главный минус же состоит в том, что все эти решения рассчитаны на “сделал максимально быстро, не считаясь с затратами”. Отсюда совершенно дикие цены как на сами платы, так и на модули расширения (shield, шилд). Скажем, самая дешевая плата в классическом (для ардуинки) формате стоит от тысячи рублей, при этом функционала на ней – кот наплакал. А цены на самые дорогие, с чуть-чуть большим набором портов легко упрыгивают за сотню баксов.

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

Следующими идут миниатюрные компьютеры. Paspberry Pi, OLinuXino и так далее. Основной плюс – внутри них работает привычный многим Linux, код можно писать практически на чем угодно и они подключаются к монитору или обычному телевизору. Так как основное предназначение у них тоже самое, что и у ардуинок, то и минусы те же самые – дикие цены как на сами компьютеры, так и на платы расширения к ним. Плюс все эти компьютеры совершенно (ну по сравнению с вышеперечисленным) не имеют портов ввода вывода и обладают диким энергопотреблением.

К этому описанию можно смело добавить разные платы с Android внутри. Плюсы и минусы абсолютно те же самые. Для планшетов еще пойдет, а для встраиваемой электроники – никак.

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

Скажем, возьму самую дешевую плату для разработки на stm32 – STM32L100C-DISCO. 256 килобайт памяти для программ (ардуинки и прочие уже рыдают), 16 килобайт ОЗУ, работает на 32Мгц, кроме АЦП (16 каналов!) и ЦАП имеет кучу аппаратных(!) интерфейсов типа I2C и 40 с лишним портов ввода-вывода. По меркам stm – это микроконтроллер начального (нет, начальнейшего) уровня. И вот эта плата, с уже готовым программатором и парочкой светодиодиков стоит в два раза дешевле самой дешевой ардуинки.

А стоит сравнять стоимость, как уже можно получить STM32F3DISCOVERY, где добавят гироскоп с компасом, кучку светодиодиков, поднимут объем ОЗУ до 48килобайт и частоту процессора до 72Мгц. После этого увеличат число портов ввода-ввывода практически в два раза и добавят горку аппаратных интерфейсов.

А за цену какой-нибудь arduino mega можно взять офигенный набор разработчика с LCD экраном и дичайшими возможностями.

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

Думаю, после этого вам станет понятным, какие микроконтроллеры я буду использовать в дальнейших разработках 🙂

Безопасность – она превыше всего …

… или день адреналина.

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

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

IMG_0046

IMG_0047

Просто отрываем защитный слой и наклеиваем на торец двери. Получается примерно так.

IMG_0044

Хоть фотография была сделана днем, я потом проверил вечером: от фонарика блестят и контраст с машиной очень сильный. Что и требовалось получить. Одно НО: обратите внимание: в пакетике 2 наклейки, а не одна. Я взял 4 комплекта и теперь у меня мысли, куда бы еще наклеить оставшиеся 🙂

Про концевики даже писать нечего: отверткой выкрутил старый, перецепил фишку и на его место вкрутил новый концевик. Дело на 5 минут даже при отсутствии отвертки (ну нож-то должен быть в машине).

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

Машину на подъемник, пока висит, осматриваем на предмет “а как бы где чего?”.

IMG_0055

Начал течь сальник ступицы на правом заднем колесе. На замену!

Машину на подъемник, колодки и диски долой, все меняем, собираем и уезжаем, не забыв предварительно понажимать на тормоз, что бы колодки прижались. Казалось бы, все?

А фигу. Отъехав буквально на пять километров, при очередном торможении я услышал резко усиливающийся прерывистый и скрежещущий звук. Вот реально, была тишина (окна были открыты) и вдруг уши закладывает. Пока я анализировал звук, справа показался дымок, который набирал силу и хорошо так дымил. Первая мысль “горю, надо телефон взять, что бы видео как у Тулупова получилось!”. А вторая “вот перед соседями по дороге неудобно – Можайка в сторону центра и так забита, а тут я загоревшись, пару полос дополнительно перекрою …”. Хорошо, что и так был в правой полосе, врубил аварийку, сполз на повороте и побежал за огнетушителем в багажник. Пока бежал, пришла другая мысль “а чего это я бегу? Надо быть солидным, да и Дрынь застрахован сверху донизу ..”. В общем, к месту дыма я подошел уже не как вспугнутый воробей, а как “гордый орель”.

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

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

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

Вот видео.

http://youtu.be/zSfbrPLseLQ

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

IMG_0061

А вот и канавки, которые диск проточил …

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

Снятый диск на токарном станке обточили (биение было порядка 2х миллиметров) и собрали все назад. При сборке более опытный обратил внимание, что нам подсунули левые колодки.

Коробочка правильная

IMG_0059

А вот колодки – левые

IMG_0062

Слева – правильные, справа – неправильные. Когда держишь в руках разница ощутима. В общем, теперь у меня “пачти как бремба”, только синие. Покатались, потормозили “в пол”. Ничего. Значит, проблему решили … Кто бы мог подумать, что у УАЗа такие маленькие допуски в тормозах 🙂

А салонный фильтр я так и не поменял. Просто не смог понять как … Лазил “каком кверху”, фотографировал …

О зимней резине замолвлю я слово …

Внимание! Текст далее содержит много нелицеприятных высказываний в разные адреса.

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

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

И как-то раз я внезапно обнаружил, что пошел дождь. Сильный ливень. Нет, я не потерял управление, это было позже (смаил). Я обнаружил на стоянке большую лужу. Метров 50 длиной и несколькими сантиметрами глубиной. Так как мне было интересно, что происходит в реальности, когда машина влетает в лужу, то я начал старательно её разбрызгивать. Сначала потихоньку, потом все увеличивал и увеличивал скорость, постоянно отслеживая реакции машины. И где-то на 60-70 километрах в час я начал стабильно всплывать. Где-то на 90 километрах в час начали всплывать и задние колеса. Сказать, что это меня впечатлило, значит попросту соврать. Ощущение, которое возникает в тот момент, когда ты понимаешь, что машина едет по инерции и кручение рулем не оказывает практически никакого влияния на траекторию … В общем, рекомендую испытать, но только в контролируемой обстановке.

Ощущение заставило меня начать разбираться, в чем же причина. Зимняя резина, глубина протектора была миллиметров 8-10, должно хватать, а не хватает. Я попытался посчитать “почему”, но сломался на уравнениях. Просто не осилил кучу формул. Просто поставил себе условие “сильный дождь? скорость не больше 60 км/ч!”.

Все было хорошо в моей картине мира, пока я не купил новые покрышки BFG MT KM2. Первые километры я был как на вибростенде: своей пятой точкой я ощущал каждую шашечку на покрышке! Потом прикаталось – привык и я забыл о своих изысканиях на некоторое время. Потом опять прошел дождь и я снова увидел ту же самую лужу. У меня же новая резина, надо понять, когда всплывать начнет! Резина показала всю свою “сучность”: я тупо не смог разогнать машину до “всплывательных” скоростей, ибо мне не хватало места для разгона и остановки. Но до 120км/ч я разгонялся. Она не всплывала. Напрочь. Запомнив этот факт, я просто продолжил ездить дальше.

Наступила зима. Все вокруг буквально кричали: “ты чего, зимой на мудах? Идиот! Покупай зимнюю!”. А у меня снова денег не было и я продолжал ездить. Но опять включил “автобусный” режим, ведь муды не для зимы и все такое. И как-то внезапно обнаружил, что вообще-то машина на дороге чувствует себя значительно уверенней, чем ситроен на зимних липучках. То есть с одной стороны везде все говорили и писали, что грязевая резина зимой – практически верный трындец, а я ощущал и видел совершенно другое. Я просто и тупо ехал там, где другие джипы, кроссоверы и прочие пузатерки на “настоящей зимней резине” елозили и буксовали. А однажды, когда я поехал по нечищенной полосе (ну чего, всего сантиметров 20 снега, из них плотного, собранно с других полос, сантиметров 15) в обход пробки, то буквально спиной почувствовал “лучи добра”, отправляемые другими водителями в мой адрес.

И я снова стал разбираться, в чем-же разница и кто прав и виноват.

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

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

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

Screen Shot 2013-12-12 at 11.43.27

Думаю, смысл эксперимента понятен. Как и результаты: большинство ошибалось.

Последний вывод получился чуть попозже, но он уже был ожидаемым: нас разводят. Как обычных лохов. Сейчас объясню. И что бы не быть голословным, можете глянуть в любой шинный тест. В более-менее приличных еще и публикуют фотографии с тестов. Для примера я взял первую попавшуюся из журнала “зарублем”. Вот типичная картинка (За такие картинки надо прямо-таки спасибо сказать всяким маркетолухам и журнашлюшкам, которые считают, что так покрышка выглядит красивей и привлекательней)

Screen Shot 2013-12-12 at 12.02.41

А теперь типичная картинка с тестов грязевых шин зимой

OLYMPUS DIGITAL CAMERA

Ничего этакого не замечаете? Вот прямо-таки бросающегося в глаза?

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

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

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

Но почему же тогда все не ездят на грязевой резине, ведь она такая клевая?

По порядку:

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

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

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

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

Сначала мне казалось, что я один такой Д’Артаньян, а все вокруг дураки. Даже начал готовить шапочку из фольги и асбестовую прокладку на стул. Ведь все вокруг сравнивают поведение 5й хакии с 7й и обсуждают, что круче: континенталь или мишлен при езде на снегу.

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

Сначала проявился Maxxis, который штатно предусматривает ошиповку некоторых своих “грязевых шин”. МТ-754 и МТ-762 – готовые к ошиповке прямо с завода.

Screen Shot 2013-12-12 at 13.04.03

Потом проявился Kumho c Road Venture 834. И теперь я наблюдаю робкие попытки других производителей “расширить канавки” на зимних покрышках. У данлопа появились более-менее прилично смотрящиеся модели, еще кто-то мелькал …

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

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

Начинаем проектировать …

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

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

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

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

Так же у штатной магнитолы есть и дырка для компакт-дисков, но и ими я тоже давно не пользовался. Последние разы – еще в Д2, но там магнитола умела читать mp3 с DVD дисков … Умеет ли эта – фиг его знает. Но почему-то проверять нет желания.

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

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

Итак, начинаем сочинять список “хотелок” к .. ну назовем это медиасистеме.

1. Поддержка режима A2DP. Что бы смартфон/компьютер могли передавать музыку в машину.
1а. Наличие микрофона и системы подавления эха, что бы я мог разговаривать по телефону.
2. Наличие “крутилки” громкости и “трек вперед” (как минимум) в виде реальных, выпуклых, осязаемых кнопок. Никаких тачскринов и прочего для этого: не отрываясь от дороги, нащупал и сделал.
3. Наличие пары портов USB с током до 3А на каждый. Порты должны представляться “зарядками”, никаких синхронизаций и прочего.
4. Наличие радиоприемника, способного принимать диапазон 76-108МГц в WFM. Попросту, обычное FM радио с “нашим” и “буржуйским” диапазоном. Хоть и у меня куча музыки, но иногда охота послушать всякое …
5. Наличие радиостанции(-й), способных работать в диапазоне 27МГц и 433МГц. Или CB и “горох” с LPD и PMR. Привыкли-с … Диапазон 144МГц желателен, но не обязателен. 160+, 108+, 400+ как и остальные, желательны, но не критичны. Что на них? На 160+ и 400+ работает скорая, полиция и мчс. В свое время в Москве я слушал милицию, что бы знать, какие дороги будут перекрывать для членов. Очень помогало. Сейчас они на цифровую связь перешли, я не разбирался по отсутствию необходимости – теперь я езжу по другим дорогам. МЧС … лучше бы не понадобилось, но лучше во исполнение какой-то там статьи из конституции и вроде 66 статьи закона о связи иметь возможность. Если кратко, в случае БП/жопы и для спасения жизни я могу воспользоваться любым доступным мне каналом связи или любой частой. А так – склонностей к радиохулиганству не имею, а категорию не получил исключительно из-за лени. 108 или авиадиапазон интересен как высокоточный поставщик локальной погоды.
6. Наличие дисплейчика для отображения всякой разной информации (частоты радио, времени, температуры, еще чего). Дисплейчик должен быть достаточно большим, что бы одного взгляда хватало для получения информации.
7. Для оффроада надо иметь кренометр (клевая штука, хоть для экспедиционника почти всегда бесполезная, но все имеют, чем я хуже?). Пусть на дисплейчике и отображается по необходимости.
8. Обеспечение WiFi в машине (и интернет заодно). У меня семья продвинутая, усе с мобильниками и планшетами. Вот и пусть работает, заодно пробки всякие будет через что качать. Ну или для интернетика на стоянке.
8а. GSM/3G/LTE антенна внешняя. Иначе все грустно будет.

Кажется всё.

Наиболее нетерпеливые сразу увидят, что в отличии от “классических”, у меня ни слова не сказано про навигацию или про просмотр фильмов. Почему? Ну начнем с фильмов. Что, кто-то реально думает, что он будет смотреть в машине фильмы? Или семья? На 7″ … хорошо, на 8″ экранчике? С заднего сиденья? С переднего под углом в 45 градусов? Не смешите. Те, кто хочет смотреть фильмы, делает это с планшетов или ноутбуков. Это и дешевле и лучше (например, можно развернуть планшет так, что бы солнце не отсвечивало). Аналогично и с навигацией. Да, в магнитолу можно запихать WinCE или Android, поставить туда всякие “навигашки”, дать им интернет через что-нибудь (тут должно быть “через жопу”) … Но опять же, весь мой опыт говорит о том, что для смартфонов гораздо больше выбор и навигаций и выше частота обновления карт, чем для магнитольных версий. И моя реальность говорит, что практически всегда лучше взять навигатор из машины, что бы либо оценить окружающую местность, либо поискать точку. А нырять в машину и обратно, отыскивая соответствия карт и местности … И попробуйте обсудить маршрут хотя бы с 2-3 другими водителями, когда у вас навигатор “в магнитоле” и вы поймете всю несуразность ситуации.

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

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

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

Приемник FM – набор от мастеркита MP1090. 500 рублей
Переключатель каналов – MP1241A. 500 рублей.
Усилитель 4х40Вт – ВМ2032 – 1000 рублей.
Raspberry PI – 2000р
Bluetooth USB – 1000р
Wifi – 1000р
Модем 4G/3G/GSM – 1500р
SoundBlaster USB – 1000р
Микрофон, SD карточки, дисплейчик, провода и прочая мелочевка … ну размахнемся и положим 3000р.
Работа и прочее – бесценно. То есть бесплатно.

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

Остается больная тема – радиостанции. Счас и их подсчитаем.

СВ – это мегаджет 550 (нравятся они мне и на Д2 тоже она стояла) – 6000 рублей
140МГц и 430МГц … Тут ситуация сложная. С одной стороны, можно взять по станции на диапазон. Будет это примерно 10000 на каждую. Можно взять одну на оба. Скажем, FTM-350 умеет оба диапазона вдобавок и FM умеет. За 18000 тысяч рублей. К ним антенны по паре тысяч рублей. Итого 24-25 тысяч рублей на нормальную радиосвязь вынь да положь. Можно нормальные станции заменить портативкой, скажем VX-6R и вместо “крысинного хвоста” вытащить антенну наружу. Хоть у меня и есть 6R, но использовалась-то она как штурманская … еще одну?

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

Как вариант, взять и зацепить выход радиостанций через микшер на звуковую систему автомобиля. А вход тангеты – на вход гарнитуры. Ну и кнопочку PTT вывести куда-нибудь неподалеку от руля. А, чего, удобно: едешь, слушаешь дальнобоев на фоне музыки. Тебе позвонили, всё заткнулось. Поговорил, снова проявилось … Определенно, что-то этакое в этом есть.

Но у меня есть и еще одна “хотелка” – я давно хотел поставить себе в машину Yaesu 8×7 серии. Скажем, 817ND умеет работать на передачу во всех нужных мне диапазонах. В смысле одна радиостанция может заменить и СВ и 144 и 430 МГц станцию. Уже лучше. А если учесть, что станции этой серии умеют частично управляться с компьютера, то вообще хорошо. Правда, с приемом какие-то непонятки. В официальных бумагах пишут, что например автоадиапазон не принимается. А на форумах народ слушает и вроде без всяких “раскрытий”. Надо уточнять. Отсюда же вытекает очередной “плюс”: не нужно иметь много антенн, которые будут привлекать внимание. Хватит одной. А если взять крутую, типа ATAS-120, которая сама умеет подстраиваться, то вообще замечательно. Правда, цена уже давно выпрыгнула за разумные границы и скачками приближается к 50 тысячам рублей. Правда, жабу потихоньку пытается душить тот факт, что в пути с одной рацией будет гораздо удобней, чем с 2-3 … Но с другой стороны, надежность одной на три диапазона по определению меньше надежности трех.

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

Пока нахожусь в позиции буриданова осла. Может, кто-нибудь поделится фотографиями передних панелей своих радиофицированных автомобилей?

A7510 или мучения

Старый видеорегистратор ушел вместе с машиной, а значит у меня появилась необходимость в новом. Недолго думая, купил по ранее описанной методике StreetStorm CVR-A7510.

e8e982f69b80a34ae52ccfdf01d113eb

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

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

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

К небольшим плюсам регистратора можно отнести довольно часто обновляющиеся прошивки. Скорость обновления можете оценить сами

Screen Shot 2013-12-03 at 13.32.32

А теперь самое важное: те самые супер-фишки, которые маркетологи и рекламщики StreetStorm вытаскивают нам под нос:
– Формат SuperHD, Функция WDR для безупречной детальности при малых уровнях освещенности, Электронная стабилизация изображения, Активное шумоподавление, Auto ISO
Как бы сказать помягче … В общем, всё это разбивается о крайне низкое качество картинки, которое даже при ярком дневном освещении покрыто муаром. То есть картинка с офигенным разрешением, но вся расплывчатая. У меня очень большое подозрение, что внутри регистратор тупо увеличивает разрешение где-то с 1200х700, но миру печатать лень. На мой взгляд, качество картинки находится на уровне средненьких регистраторов, не выше. Мой старый снимал точно лучше. Что бы не быть голословным, вот видео, снятое в самых сложных для регистратора условиях.

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

Screen Shot 2013-12-03 at 13.45.22

Обратите внимание на размытие вокруг ровных границ. И это же место, при том же самом освещении и так далее, но снятое на Samsung Galaxy S4 Active.

20131203_134747

Думаю, разницу вы увидите сами … Остальные завлекалки на том же уровне. Особенно отличается LWDS – он пипикает когда угодно, но не когда я пересекаю сплошную полосу (каюсь, на съезде на заправку экперементировал)

Что еще осталось? Штука, которая втыкается в прикуриватель. Плюс: прямо на штуке есть usb порт для всяких смартфонов. Минус: эта штука постоянно вываливается из прикуривателя. Сначала я думал, что это особенность прикуривателя патриота (где-то когда-то читал, что наши прикуриватели от импортных отличаются. То ли глубиной, то ли еще чем). Купил разветвитель. Тоже самое. Вышел из положения подпиранием всяким валяющимся хламом.

И наконец что бы добавить пикантности получившейся неприглядной картинке: служба технической поддержки у StreetStorm тоже фикция. На телефоны не отвечают, на посланное в формочку с сайта тоже. Прошивка крайне сырая, постоянно что-то меняется (скажем, V5 вроде ничего, а V5.1 подключается к компу через USB только один раз, дальше надо искать что-нибудь тонкое и сбрасывать регистратор).

Вывод: в данный момент (3 декабря 2013) крайне НЕ рекомендую к покупке. CVR-A7510 совершенно не стоит своих денег.

Шишкин Лес

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

_MG_9783

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

Термос.

termosy_0.5l_v_chekhle(Картинку честно спер с сайта экспедиции)

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

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

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

Screen Shot 2013-11-24 at 10.32.34(фотка с алибабы, но у меня практически такой же)

Когда впереди идущий сел в лужице, я решил, что пришло время наконец-то “стравиться”. Довольный достал этот дефлятор … В общем, минут пять я пытался им что-либо сделать с ниппелем. Полный провал. Изредка были какие-то попшикивания, но логику их возникновения я не уловил. Пришлось идти на поклон к соседу по пробке в лесу и просить металлический колпачек. Выкручиваю ниппель, вынимаю, дожидаюсь свиста и закручиваю назад. Быстро, удобно, надежно.  Проверяю манометром: 0.75-0.8 во всех колесах с первой попытки. Непривычно только время от выкручивания до свиста: 29″ травятся быстрее, чем 32″.  Резюме: этот дефлятор – фуфло гламурное.

Ну и наконец, уазик.

_MG_9835

 

Я наконец-то его заправил под завязку по методу “залили в левый бак-покатались-залили до отстрела”.  Результат ниже 🙂

Screen Shot 2013-11-24 at 10.50.07

 

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

Пойдем по порядку. После стоянки заметил очень странный потек на переднем бампере.

20131123_092118

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

Где-то посредине покатушки обнаружил, что у меня из правого бака капает.

_MG_9802

 

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

Резина. “Штатная резина гавно! Каму выбрасывай сразу!” – примерно такие сообщения можно прочитать на любом уазиковском форуме.

_MG_9801

Скажу честно: не увидел я говна. Обычная всесезонная АТшка. Едет там же, где едет BFG AT, едет так же и садится там же. За всю покатушку я сел один раз и то исключительно из-за желания повыпендриваться (официально это было оформлено как познание возможностей техники): сел диагонально в колею. Как только выдернули с диагоналки, уехал дальше сам. Повторюсь, у меня проблемы были абсолютно теже самые, что и у машины на BFG AT. Ну или не было.

_MG_9803

На фотографии стравленное до 0.7 колесо. Плющится нормально, разбортировок не было (хотя я боялся, ибо крутил рулем довольно активно). Резюме: пока впечатления самые положительные.

Теперь возвращаемся к самому уазику.

Уплотнители у него нормальные (хор с мест “пока нормальные, скоро умрут”). Вот пример. _MG_9834Это я посидел жопой в грязи немного.

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

Про саму машину тоже ничего сказать нового не могу. Все едет, крутится, ничего не отвалились. Но (ох уже это НО. Но никак нельзя)! В список “исправить как только так сразу!” попало следующее:

– Что-то скрипит в руле. Поворачиваешь и такой легкий скрип. Если какое-нибудь уплотнение, то пофиг. А вот если провод какой упал …

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

– В деле музыки уазик меня разбаловал: его магнитола умеет работать hands-free для телефона. Музыка играет, треки переключаются. Ляпота. Но если позвонят .. надо или микрофон вытаскивать или магнитолу менять. Ни у кого в москве штатной магнитолы не завалялось для опытов? Куплю за небольшой прайс.

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

– Выкинуть нафиг завихритель. Лень, но звук меня иногда пугает.

И все. Уазик радует.

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

Упросил взять у АвтоВентури домкрат на тест. Взяли, привезли.

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

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

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

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

Как это происходило живьем:

Подумав, решил отнести к условно-полезным штукам. Условно – потому что надо еще зимой опробовать. Надо только модификацию “под компрессор”.

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

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

– Иметь вход для 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, распознать код ошибки или сходить в интернет – этими задачами пусть занимается компьютер.

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

 

Этим постом мастер начинает новую партию …

Этим постом начинаю новую серию, посвященную электронике.

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

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

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

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

Второй заморочкой стал спидометр. Вернее, его показания. Он все время врал. Причем врал неравномерно. Чем больше скорость, тем больше врал. Да, я в курсе, зачем так делают, но … раздражало. Лечился с помощью навигатора, он скорость с GPS показывал в уголке. Но стоило солнцу засветить экран … Раздражало!

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

Ну, а теперь у меня пока машины нет, но наверняка что-либо подобное будет и там. А оно мне надо? Правильно, оно мне не надо. Значит будем превентивно лечить.

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

При этом у меня нет миллионов. Как нет и желания работать паяльником, спаивая кучу микросхем в что-либо удобоваримое …