Uber для автомехаников

Вот приходит мне иногда спам — мол, хватит кормить автосервисы, купите у нас чудесный диагностический адаптер (банальный китайский ELM327) и не заморачивайтесь с ремонтом авто! Как человек, знающий, чем ДМРВ отличается от BDSM, я в это все сразу не верю. Даже если зайти на сайт продавцов чудодейственного устройства — то он буквально кричит «не покупайте это говно!». Признаки лохотрона, разумеется, элементарные. Если вас хотят надурить — то попадете вы на классическую страничку-лендинг, сделанную прямо по учебнику «Landing page for dummies».

Впрочем, «товарный бизнес», заключающийся в перепродаже лохам китайского дерьма с алиэкспресса — это ерунда. Вот некие чуваки придумали аж целый стартап на основе примерно той же идеи — в разъем OBD-II, присутствующий во всех более-менее современных автомобилях, втыкается чудо-коробочка, «считывает ошибки», и через мобильное приложение записывает в ближайший автосервис, предложивший наименьшую стоимость ремонта. Вам уже смешно? Но идея настолько поразила отечественного блоггера [info]gorynych1, что он написал длинный текст с многозначительными выводами о том, что наконец-то паразитам из автосервисов придется поумерить аппетит:

https://gorynych1.livejournal.com/207768.html

В комменты пришел настоящий автомеханик [info]ploughlike_elk и немного покритиковал идею, заодно, правда, немного перейдя на личность автора поста:

https://gorynych1.livejournal.com/207768.html?thread=1910168#t1910168

Если хочется больше подробностей — то вот тот же [info]ploughlike_elk расписывает, как соотносятся «ошибка», прочитанная диагностическим сканером, и возможная стоимость устранения неисправности (спойлер: никак):

https://ploughlike-elk.livejournal.com/356963.html

Горыныч немного бомбанул и расписался аж четырьмя записями, где прогнозировал счастье человечества и кабздец нехорошим автомеханикам, в особенности лж-юзеру [info]ploughlike_elk:

https://gorynych1.livejournal.com/208825.html
https://gorynych1.livejournal.com/208945.html
https://gorynych1.livejournal.com/209339.html
https://gorynych1.livejournal.com/209820.html

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

PS Особенно хороши, конечно, измышления Горыныча про Wrench — службу «выездных автомехаников». Сервис, хочу заметить, не первый, и даже не единственный — но и как все аналоги, отнюдь не совершивший революции в деле авторемонта.

Забавное про «полупроводниковую» экономику

Делаю сейчас одно устройство, в котором используется так называемая K-линия — немного напоминающий UART автомобильный диагностический интерфейс (он же ISO 9141). Преобразователей из K-линии в UART и подобные интерфейсы (тот же RS232) придумано довольно много, мне лично нравится вариант на логической микросхеме. Из обвязки нужно всего лишь два резистора, диод и транзистор, а стоимость деталей в чип-и-диповской рознице — менее 50 рублей (особенно, если не гнаться за какими-нибудь низковольтными вариантами логики), а «оптом» — думаю, упадет рублей до 10-15.

Для состоятельных парней выпускаются специализированные микросхемы — всякие MC33199, MC33290, L9637, или более актуальная (то есть еще встречающаяся в продаже) Si9243 — внутри там примерно то же самое, только в корпусе SOIC-8. В розницу эта микросхема стоит около 70 рублей, оптовая цена опускается до 40.

А теперь следите за руками — специализированная микросхема оказывается выгоднее, если к стоимости компонентов добавить стоимость монтажа. В случае с решением «на логике» мы имеем 22 точки пайки, а на специализированной микросхеме — всего 8. Стоимость ручного (точнее, «полуавтоматического») монтажа — что-то порядка 2-3 рублей за точку пайки — и 14 «лишних» точек съедят всю экономию.

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

PS А заодно можно сделать вывод, что «узкоспециализированная» микросхема более выгодна и для производителя, чем «универсальная» стандартная логика — себестоимость их производства одинакова, а вот продать первую можно значительно дороже.

Про беспилотные автомобили

[info]vitus_wagner подкинул ссылку на MIT-овскую статью по модной теме беспилотных автомобилей. Анонс — «В MIT разработали систему, которая позволяет беспилотным автомобилям ездить по сельским дорогам без точной карты» — не очень точно отражает суть работы. Системы типа nVidia DAVE2, довольно простые в реализации (у меня есть даже подборочка материалов по теме) точно так же могут вертеть рулем в нужном направлении, и для своей работы требуют только видеокамеру, смотрящую вперед — данные от GPS и карта там необязательны.

Что отличает эту систему от «нейросетевого» подхода — даже не детерминированность, пусть даже она и приятна (есть несколько публикаций, показывающих, что нейросеть по образцу сделанной в nVidia «сходит с ума» при некоторых манипуляциях с картинкой — вплоть до того, что пытается повернуть совсем в другую сторону, если изменить в картинке на входе всего один пиксель). Внимательно попробуйте осознать описание DAVE2 — эта система определяет угол поворота руля, исходя из картинки, которую видит перед собой «водитель». Но… Посмотрите на эту схему, в том или ином виде присутствующую в любом вводном материале про спортивное или «экстремальное» вождение:

apeks

Три траектории, изображенные здесь — это три разных способа прохождения одного и того же поворота, в той или иной степени «хорошие» (в зависимости, конечно, от прочих факторов). Для наглядности изображена «шпилька» — поворот на 180°, но вся та же теория остается верной и в том случае, если угол будет другим. «Осознанное» управление автомобилем предполагает, что водитель, подъезжая к повороту (из левого нижнего угла картинки), определит точку поворота руля и точку апекса — и, соответственно, траекторию в повороте. Но обратите внимание, что видимая картинка при приближении к повороту во всех трех случаях одинакова — так что система, полагающаяся в своем принятии решений только на текущий видеокадр, очевидно будет неспособна «выбирать» траекторию. Обратите внимание на то, как в ролике nVidia нейросеть «крутит» руль, дергая его туда-сюда (примерно на 7:32):

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

Так вот, важнейшее, на мой взгляд, новшество в подходе MIT — это определение траектории, исходя из конфигурации дороги. Границы дорожного полотна их система определяет с помощью лидара, сканирующего пространство вокруг автомобиля с частотой 5 раз в секунду. Затем строится «локальная» траектория (довольно примитивным, правда, образом — ровно посередине между левой и правой обочинами «вписывается» сплайн, то есть достаточно гладкая кривая), и до очередного обновления автомобиль движется по этой траектории. Никто, в общем, не мешает «вписывать» траекторию и более «правильным» образом — скажем, между правой обочиной и серединой дороги, как предписывают ПДД.

Заметьте, насколько это отличается от подхода «авось нейросеть научится» :)

Orfeus

Открыл для себя творчество группы Orfeus. Венгры играют весьма бодрый power metal и поют на своем инопланетном языке аж с 1988 года. От выступления на венгерском телевидении в 1993 году пустил слезу — но несмотря на колхозный вид, уже тогда играли здорово:

Группа существует и сейчас, изредка записывает альбомы (Metal Archives знает о трех), и в целом выглядит достойно.

Ну и покороче

А то в предыдущей записи слишком многа букв :)

Столкнулся с небольшим багом в примерах к микроконтролеру CC3200 (ARM Cortex-M4 + WiFi). Если в многозадачной системе поменять настройки WiFi (они пишутся в подключенную к микроконтролеру флешку), а затем перезапустить сопроцессор WiFi (для применения новых настроек) способом, указанным во всех примерах, можно получить полностью неработоспособный WiFi — настройки не успевают записаться (ну вот так мне показалось — особо в подробности не вдавался). Решение очевидное — небольшая пауза при перезапуске. Я озвучил его на форуме техподдержки коллеге по несчастью 26 апреля в 1:25 PM по форумному времени — а ровно через три с половиной часа сотрудник техподдержки предложил то же самое в соседней теме.

Закон парных случаев?

База данных за один вечер и три бутылки пива

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

CREATE TABLE measurements (
    measurementID int NOT NULL AUTO_INCREMENT,
    sensorID int NOT NULL,
    time datetime NOT NULL,
    value double NOT NULL,
    PRIMARY KEY (measurementID)
)

Это очевидно неправильно — имел удовольствие несколько лет подряд наблюдать за эволюцией небольшой SCADA-системы, где хранение данных организовали примерно так. Пока датчиков было немного — оно работало, но примерно на сотне-другой обновляющихся примерно раз в 5-10 секунд датчиков потребовало для работы некоторых костылей. Для начала — в БД перестали записывать «небольшие» изменения данных — скажем, меньше 5% (величина была выбрана довольно произвольно — не надо спрашивать, соответствует ли такой подход требованиям технического задания :) ) от предыдущего сохраненного значения. Затем — по мере накопления данных соорудили чудовищную систему из триггеров и хранимых процедур, которая автоматически создавала «архивные» таблицы сравнительно небольшого размера. Впоследствии, конечно же, выяснилось, что эта система временами глючит и иногда новую таблицу для архива надо создавать вручную.

Наконец, на одном из объектов в дополнение к привычным «медленным» газоанализаторам поставили два десятка акселерометров — и тут все повалилось уже серьезно. Во-первых… нет, для начала в нулевых. Не надо говорить мне, что datetime в SQL неспособен хранить данные с «разрешением» меньше секунды, а опрашиваемый раз в секунду акселерометр бесполезен — тут речь шла уже о том, чтобы записать в базу хоть что-то. А теперь во-первых — показания акселерометров меняются сравнительно быстро и под фильтр «небольших» изменений данных не подпадают, и во-вторых — отказы БД стали чуть ли не ежесуточными. Считайте сами — в сутках 86400 секунд, и при двух десятках пишущих что-то датчиков мы влегкую получаем 1,7 миллиона записей в сутки. Да, часть из них отфильтруется — но и миллиона строк хватит, чтобы популярные СУБД с SQL хорошо и надежно «легли».

Признаться, я списывал многое из этих проблем на невысокую квалификацию разработчиков этой системы, но после доклада Сергея Аксенова “Антипаттерны разработки программных комплексов для интернета вещей” на Inothings++ понял, насколько героические люди используют SQL для хранения такого рода данных. Про выбор СУБД в видео — с 4:28:

Идея понятна — реляционные СУБД расчитаны на количество строк порядка миллионов (десятков миллионов — если у вас поблизости есть грамотный администратор баз данных), а как легко посчитать — это всего лишь суточный архив сравнительно небольшой системы. Впрочем, случай «Стрижа» еще более-менее прост — частота опроса каких-нибудь ЖКХшных счетчиков относительно небольшая, всего несколько раз в сутки. А что делать, если хочется хранить, скажем, данные по 16 каналам АЦП с небольшой в общем-то частотой дискретизации в 16 тысяч выборок в секунду? Нет, я прекрасно представляю, как это сделать «на файлах», и это совсем не сложно — простенький формат хранения данных можно полностью реализовать за неделю неспешной работы (собственно, что-то наподобие edflib, но работающее на микроконтролере с сотней килобайт памяти я написал в прошлом году где-то за несколько дней):

Implementing EDF takes a week. EDF+ takes a few weeks but is better and more powerfull. If you still decide to start with EDF, it is wise to adopt the 12 simple additional EDF+ specs.

Не смотрите, что он предназначен для записи всяких физиологических данных — я в таком виде пробовал всякие обороты двигателя, расход воздуха и прочее время впрыска записывать, они в этот формат прекрасно вписываются :)

Еще из полезного чтения — статья Luca Deri о системе, названной им tsdb — построенной поверх Berkeley DB системе, обеспечивающей хранение миллионов (!) временнЫх рядов (time series — собственно, это общее название для такого рода данных). Решение не совсем подходящее для моего случая — но опять же содержащее несколько полезных идей.

Для начала — система, многократно превосходящая по производительности решения на основе SQL, реализована всего лишь в 1000 или около того строк кода на Си. Именно это и вдохновило меня на написание собственного решения — 1000 строк это совсем немного, а следовательно, должно быть довольно просто. Второе — данные желательно каким-либо образом объединять — если в tsdb это сделано довольно произвольным образом (в базе много редко обновляемых временных рядов), то в моем случае я просто решил писать «секундные» (или соответствующие какой-то доле секунды) записи, как в EDF.

В общем, осознав эти «три источника и три составные части», я взял пивка и засел за Visual Studio — и примерно за вечер написал прототип базы данных, оптимизированной под мои требования — десятки-сотни одновременно записываемых временных рядов с частотой дискретизации от единиц до тысяч Гц. Собственно, по факту получился тот же EDF, только записанный в Berkeley DB. Выбор довольно произвольный (прежде всего — ее используют в tsdb) — но эта, так сказать, «встраиваемая СУБД» поразила меня своей простотой. Немного не радует лицензия — хотя при желании могу выложить код на какой-нибудь гитхаб для очистки совести.

Что могу сказать? Не прилагая никаких усилий в части оптимизации, на собственном ноутбуке я «из коробки» получил скорость записи в базу данных около 40-50 Мбит/с (похоже, упираясь в производительность жесткого диска) — причем, судя по всему, падения производительности с ростом числа записей в БД не происходит. Например, в БД размером около 11,5 Гб — это чуть меньше 1,5 миллионов записей по 8 килобайт (в каждой из записей — по 4000 «точек», каждая из которых — двухбайтовое целое) никакого снижения скорости записи или чтения я не наблюдал (дальше просто стало жалко жесткий диск). Что забавно — тесты «на чтение» демонстрируют полезность кеширования — сначала 10 000 записей читаются за долгие 8 секунд, а затем, если повторить тот же тест «не отходя от кассы» — за 0,22 секунды. Не видел бы — не поверил.

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

PS А если вам все же нравится SQL — почитайте, как правильно организовывать хранение time series в реляционной БД:

https://blog.timescale.com/time-series-data-why-and-how-to-use-a-relational-database-instead-of-nosql-d0cd6975e87c

И все-таки хочу напомнить, что решение «на коленке» практически не уступает приведенному в статье по ссылке в плане производительности (и да, надо бы проверить его с четырехгигабайтным кешем :) ).

Схема вместо картинок

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

fritzing-breadboard

Эксперты, где вы?

Выложили фотографии остатков американских «Томагавков». В мятых железках я не особо понимаю, а вот что касается электроники — интересно, куда делись многочисленные эксперты, которые ставили диагноз по фотографиям «черного ящика» Су-24?

tomahawk-parts-1

tomahawk-parts-2

Арифметика, бессердечная ты сука

По на водке Биссо Атанасова — заходим на сайт «Таманской винной компании» (страна должна знать своих героев!), прокручиваем страничку донизу и видим сделанные безвестным веб-дизайнером «счетчики», сообщающие нам, что с 480 га виноградников «компания» умудряется получить 82 984 320 литров вина в год и разлить их в 55 000 000 бутылок.

Делим одно на другое — хрен с ними, с бутылками по полтора литра (объем стандартной винной бутылки вдвое меньше, если что) — но вот урожайность в 1729 гектолитров с гектара, на порядок больше «нормальной» заслуживала бы нобелевской премии по биологии.

Вывод из этого довольно простой — «Таманская винная компания» в основном занимается розливом привозного «виноматериала» не самого высокого качества. Заходим на том же сайте в раздел «Каталог» и запоминаем — это так называемое «вино» брать не стоит.

Великая битва слона с китом

Как известно, в своем крестовом походе против Телеграма Роскомнадзор придерживается тактики РВСН — «точность попадания компенсируется мощностью заряда». Телеграм, говорят, пока не накрыли, а вот подсеть, через которую работает гугловская баннерокрутилка, заблокировали надежно.

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

Пайка в печке

Хочу поделиться впечатлениями от сборки и использования контролера печки для пайки оплавлением по мотивам описанного Олегом Артамоновым — собственно, это будет большой и развернутый комментарий к статье по ссылке:

http://olegart.ru/wordpress/reflow-soldering/

Собственно, такой девайс понадобился мне для сборки относительно «серийных» изделий — но что значит «серийных»? Скажем, «серые коробочки» для любительского и ретро-ралли разошлись уже тиражом в несколько десятков штук — правда, в процессе проектирования находится более продвинутый вариант. Пайка вручную даже пяти AtMega, пусть даже в «человеческом» корпусе с шагом выводов 0,8 мм — занятие малоинтересное по определению. В общем, запаивая к новому сезону очередную «партию» коробочек, я задумался — а нельзя ли как-то упростить это дело?

Вариант с заказом производства в том же «Резоните» я не расмматривал — во-первых, стыдно заказывать изготовление штучных партий устройств, где всех деталей — AtMega, пара резисторов и оптопара, во-вторых — это получалось относительно дорого (в частности, стоимость «подготовки производства» в 3000 рублей, даже будучи «размазанной» на партию в десяток изделий, все равно оказывалась в числе значимых статей расходов). Наверное, 3000 можно потратить как-то иначе — например, вот на такую печку.

В принципе, вариантов переделки электродуховки в печку для пайки довольно много, но иностранцы почему-то не склонны к экономии в такого рода проектах. Например, зачем-то они используют твердотельные реле — да, это стильно, модно и молодежно, но одновременно — довольно дорого (раза в два дороже «дискретных» тиристора и оптопары). Зачастую используют готовые контролеры типа Controleo — да, с ним вся переделка печки сводится к правильному подключению проводов, но сам контролер стоит совершенно неприличных денег (да, силовой части в нем нет, придется городить несколько твердотельных реле и блок питания, а это дополнительные расходы). Короче говоря, контролер за авторством Олега Артамонова показался мне более приближенным к российским реалиям — с легкодоставаемыми компонентами (все есть в Чип-и-Дипе и Терраэлектронике) и в целом доступный для повторения.

Сама электродуховка «для опытов» досталась мне бесплатно, будучи вытащенной из лежащего на балконе хлама. Подходящие дешевые печки стоят «в магазине» что-то около 2000-3000 рублей, б/у можно найти либо в собственном хламовнике (бесплатно), либо на каком-нибудь авито (недорого).

Плату устройства я немного переделал — во-первых, заменил SMD-шные резисторы и конденсаторы на выводные (просто их у меня много, да и паять вручную кучу SMD совсем неинтересно), во-вторых, сделал ее односторонней с несколькими перемычками на верхнем слое — для изготовления по «лазерно-утюговой» технологии (кстати, переход с SMD на выводные детали это дело значительно упрощает). Заодно выкинул «лишнее» — например, USB-порт и реле. Избавившись от USB, можно было бы попробовать и заменить микроконтролер на более дешевый — как выясняется, прошивка с ампутированным обменом по USB прекрасно влезет и в AtMega8, но я понадеялся, что получится использовать готовую прошивку без доработок. Забегая вперед, скажу — они понадобились, в первую очередь из-за того, что в выкидывании всякого ненужного барахла я немного поторопился и избавился от термодатчика TMP37.

Заодно я поменял габариты платы, рассчитывая вписать ее в корпус Gainta G767 (я придерживаюсь той точки зрения, что проектируя печатную плату — надо сразу задуматься, в какой корпус ее поставить) — но с этим облажался по-крупному. Конечно, надо было сначала купить этот корпус и промерить его «по месту» — но я понадеялся на чертеж и лоханулся с размерами. Вот какое там расстояние между крепежными отверстиями для платы? Я подумал, что в чертеже ошибка — но нет, кто-то додумался указать расстояние именно между этими двумя точками. Интересно, каким инструментом его можно замерить? Добавлю еще, что вычислить расстояние между крепежными отверстиями возможно лишь в том случае, если известны диаметры стоек.

Еще из моей лажи — я не сразу заметил, что несмотря на то, что дисплеи Winstar WH1602A (самый дешевый в продаже) и WH1602J (а этот использован в схеме) имеют очень похожие разъемы, назначение выводов в этих разъемах совсем разное — и после того, как я просто припаял дисплей к плате на «гребенке» и долго выяснял, почему он не работает, мне все равно пришлось сидеть и долго запаивать проводочки :)

Довольно важный вопрос, почему-то обойденный стороной в описании на сайте Олега — калибровка датчика температуры. Судя по всему, в ранних прошивках она была жестко зашита в контролер — а в выложенной на сайте версии прошивки появилась возможность немного варьировать параметры. К сожалению, описания этого процесса либо нет, либо оно погибло вместе с сайтом fclab.ru — так что кратенько прокомментирую, что нужно сделать. Используемая в устройстве термопара типа K (как в мультиметрах) имеет практически линейную характеристику в интересующем нас диапазоне от +25 до +250 °С — поэтому в EEPROM микроконтролера прошиваются два 16-битных числа, первое из которых для термопары равно 31 (расчет этого коэффициента можно увидеть в файле thcouple.c в исходниках прошивки) — и без особой необходимости менять его не надо. Второе число задает сдвиг шкалы — в единицах, равных 1/4 °С. Например, значение -100 увеличит показания температуры на 25 °C, а 100 — напротив, уменьшит их на ту же величину. Так как я выкинул термодатчик, показания которого принимались за температуру холодного спая термопары, пришлось записать в эту ячейку памяти -100 — приняв «комнатную температуру» за 25 °C. Конечно, можно было бы сделать и лучше — но, как показала практика, и так нормально. Показания прибора, когда термопара засунута в чайник с кипящей водой — около 96-97 °С, что можно считать более-менее приемлемым. Так как я выкинул дополнительный термодатчик, пришлось все-таки поставить WinAVR и добавить в прошивку обнуление показаний канала АЦП, к которому тот был подключен — иначе «градусник» начинал безбожно врать.

Да, еще один волнующий многих вопрос по поводу прошивки — какие использовать значения fuse. В принципе, все написано и в тексте — но чтобы не вдумываться в фразы типа «в конфигурации отключены DIV8, JTAGEN и HWBEN» — приведу здесь значения, которые мне подсказал «AVR fuses calculator» — L=0xDE, H=0xDD, E=0xCF.

Больше, наверное, никаких проблем и не возникло — ну разве что внезапно выяснилось, что в Москве проблематично недорого купить термопару — имеющаяся у меня термопара от мультиметра в металлическом корпусе оказалась довольно инерционной в показаниях, а провод явно пованивал при нагреве до 250 °C. Да, в некоторых магазинах (Промэлектроника, например) термопары типа K можно купить рублей за 100 — но только не в том случае, если такое желание внезапно возникло в пятницу в конце рабочего дня. В общем, проще и дешевле всего оказалось купить в Юлмарте самый дешманский мультиметр модели 838 (кстати, сравнив его со своим десятилетней давности Mastech 830, я просто офигел, насколько деградировали дешманские мультиметры). Заодно мне достались два разъема-«банана» — термопару я подключил проводками к клеммной колодке.

С учетом покупки мультиметра бюджет проекта составил примерно те самые 3000 рублей, которые жаба не позволила тратить на «подготовку производства» в Резоните — и надо сказать, что я в целом остался доволен — даже нанося паяльную пасту (я взял на пробу Multicore CR36) вручную из шприца (медицинского, с обрезанной толстой иглой), удалось добиться вполне приемлемого количества брака (прежде всего слипшихся ножек на микросхемах с малым шагом — это исправляется с помощью паяльника и «оплетки для выпайки»). Но главное — это скорость монтажа, нанести пасту, расставить детали и сунуть несколько плат в печку получается намного быстрее, чем в случае, когда все надо запаивать вручную. Надо бы попробовать нанести паяльную пасту через трафарет — я, конечно, попробовал вырезать какое-то подобие трафарета из прозрачной пленки, но ножом это делать неудобно, и те же ножки микроконтролера я объединил в одну широкую прорезь — замыканий получается меньше, чем при ручном нанесении, но все равно они иногда случаются.

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

А что случилось с Чип-и-Дипом?

Смотрю цены на разные микроконтролеры — и неожиданно ЧиД оказывается одним из наиболее выгодных вариантов.

Atmega8A — 75 рублей в розницу в ЧиДе, и 74,51 — оптом в Терраэлектронике или Электронщике (я так понимаю, что он ищет, в частности, и в Терре) (UPD Терра=Компэл=Электронщик).

STM32F103RBT6 — 190 в розницу в ЧиД, и 212 — в Терре (правда, начиная от 40 штук — Терра выгоднее).

LPC1768FBD100.551 — 350 в ЧиД — и опять же, Терра может что-то противопоставить только при партии от 40 штук.

Кто-то в лесу сдох?

Внезапное открытие про дизайн ThinkPad

«Классическая» легенда про дизайн IBMовских ноутбуков утверждает, что дизайнеры первых ThinkPad сделали их черными и угловатыми, потому что вдохновлялись формой японской коробочки для еды — бэнто (или, в вольном переводе на русский, тормозка). Смею утверждать, что это все чушь, а на самом деле они фанатели от в равной мере нестареющего дизайна «Волги» модели 3102 :)

gaz-3102-gon

PS Нет, папа точно не «Мазерати»:

thinkpad-maserati

Reflow soldering

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

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

Операционная система из говна и палок

На «Гиктаймсе» опубликовали конспект первой лекции курса Олега Артамонова по программированию микроконтролеров. Курс, конечно, немного экзотический в сравнении с любым интернетовским руководством по тем же STM32 — в нем рассматривается программирование с использованием операционной системы RIOT. Никакого вам CubeMX, никакой FreeRTOS — но в целом материал не особо привязан к конкретной ОС и «железу» и ориентирован скорее на то, чтобы продемонстрировать подходы к программированию для микроконтролеров «вообще».

Для тех, кому проще воспринимать видео — на Youtube выкладываются и видеозаписи лекций:

https://www.youtube.com/playlist?list=PLJEYfuHbcEIApuZR4L5tRiBCwTZCYeTNY

Но при всех заявленных и видимых достоинствах этих лекций, хвалить их целиком пока рано — поэтому перейду к всякой ерунде. Как водится, половина удовольствия от чтения «околоэлектронных» материалов на «Хабре» и «Гиктаймсе» — это комментарии, где обычно ссаными тряпками гоняют ардуинщиков. В этот раз к «гонимым» добавились также те, кто не осилил ничего, кроме всевозможных HAL и StdPeriphLib от производителя, и те, кто почему-то считает микроконтролером Raspberry Pi. Но все это не заслуживало бы упоминания — если бы не один комментарий:

…например, в Contiki — там многозадачность с инвалидностью третьей группы, там надо в треде либо без switch-case, либо без сообщений жить. Этому в университете всех учить не надо, кому в жизни не посчастливится — сами научатся.

https://geektimes.ru/company/samsung/blog/299187/#comment_10699171

Полез смотреть, что же за альтернативный подход к многозадачности исповедуют авторы операционной системы Contiki — и обнаружил там совершенно замечательную штуку. Оказывается, тамошнее подобие «потоков» обычной RTOS реализовано довольно необычно, исключительно средствами языка C.

Для начала — вот такой хитрый пример кода, который обычно называется Duff’s device — «Прием Даффа», в честь Тома Даффа, обратившего внимание на то, что метки в конструкции switch языка C позволяют нарушать «блочную» структуру программы — например, перейти сразу внутрь цикла:

switch (count % 8) {
    case 0:    do { *to = *from++;
    case 7:         *to = *from++;
    case 6:         *to = *from++;
    case 5:         *to = *from++;
    case 4:         *to = *from++;
    case 3:         *to = *from++;
    case 2:         *to = *from++;
    case 1:         *to = *from++;
               } while ((count -= 8) > 0);
}

Кстати говоря, Duff’s Device упомянут [info]sharpc в известном «Теоретическом минимуме для программиста«. Конструкция довольно дикая, мало чем отличающаяся от GOTO — и хочу заметить, что особых преимуществ по скорости (в оригинале она использовалась для того, чтобы развернуть цикл в memcpy) на современных процессорах она не дает. Знать о ней, наверное, надо, а вот применять — только по необходимости.

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

volatile int counter;

int example( int *lc ) {
    switch ( *lc ) { case 0:

    printf( "First run!\n" );
    while ( 1 ) {
        *lc = 9; case 9: if ( !(counter > 10) ) return 0;
        printf( "Threshold reached\n" );
        counter = 0;
    }

    } *lc = 0; return 2;
}

Будем вызывать эту функцию примерно таким образом:

int main( void ) {
    int lc = 0;

    while ( 1 ) {
        example( &lc );
        printf( "Back in main, counter = %d\n", counter );
        counter++;
    }

    return 0;
}

Обратите внимание, что строчка First run! напечатается только один раз, несмотря на то, что функция вызывается многократно. Фактически, таким нехитрым приемом реализован механизм ожидания событий — нетрудно догадаться, что в промежутках между вызовами нашей функции counter может изменяться как угодно (на это я намекаю, объявив его volatile). А теперь определим несколько макросов:

struct pt {
    int lc;
};
#define PT_BEGIN(pt)          switch((pt)->lc) { case 0:
#define PT_WAIT_UNTIL(pt, c)  pt->lc = __LINE__; case __LINE__: if(!(c)) return 0
#define PT_END(pt)            } (pt)->lc = 0; return 2
#define PT_INIT(pt)           (pt)->lc = 0

И перепишем пример, используя их:

volatile int counter;

int example( struct pt *pt ) {
    PT_BEGIN( pt );

    printf( "First run!\n" );
    while ( 1 ) {
        PT_WAIT_UNTIL( pt, counter > 10 );
        printf( "Threshold reached\n" );
        counter = 0;
    }

    PT_END( pt );
}

int main( void ) {
    struct pt example_pt;
    PT_INIT( &example_pt );

    while ( 1 ) {
        example( &example_pt );
        printf( "Back in main, counter = %d\n", counter );
        counter++;
    }

    return 0;
}

Хочу добавить, что в компиляторе из Microsoft Visual Studio этот пример не работает, если при компиляции указан параметр /ZI (он по умолчанию установлен для конфигурации Debug) — можно заменить его на /Zi.

Оцените, что получилось — исключительно средствами языка C реализован простенький, из говна и палок, механизм кооперативной многозадачности. Если добавить к нему планировщик и, скажем, какой-нибудь таймер, то получится та самая операционная система Contiki — названная в честь построенной из тех же говна и палок лодки Тура Хейердала. Теоретически, в Contiki есть и механизм вытесняющей многозадачности — но реализован он не для всех архитектур, в отличие от кооперативной, для которой достаточно лишь компилятора C. Это позволяет «портировать» ядро Contiki куда угодно.

Какие же у этого подхода недостатки? Начну с очевидного — использовать одновременно и protothreads, и конструкцию switch нельзя. Другая нехорошая штука — при переходе потока в состояние ожидания и выходе в планировщик теряются значения всех локальных переменных внутри функции этого потока. Это довольно неприятно, так как требует постоянно держать в голове «нестандартное» поведение программы. Бороться с этим можно либо объявляя локальные переменные потока, как static, либо используя глобальные переменные. Наконец, ждать событий можно только в основной функции потока, что резко ограничивает «полет фантазии» в реализации какой-то нетривиальной логики.

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

Internet of Cunts

Решил я на днях погуглить про чипы CC2541 — благо парочка модулей на них с, простите, алиэкспресса досталась мне совершенно бесплатно. Кроме того, надо было прикинуть возможность реализации прошлогоднего «кошмара техинспекции» — так что я искал реально «вглубь», настолько, что даже наткнулся на вот такое объявление на Freelansim:

Мы французская компания, специализирующаяся в разработке IOT дивайсов.
На данный момент мы разработали нашу прошивку сами. Эта прошивка в рабочем состоянии и уже используется в серийной продукции.
Однако теперь нам нужно очистить код, и добавить новые функции. Для этого мы ищем талантливого разработчика с опытом работы с IAR 8051 и встроенным программированием.

https://freelansim.ru/tasks/194715

Слово perifit в нике автора объявления легко выводит на страничку «французской компании» — она так и называется, Perifit, и делает вагинальные тренажеры с Bluetooth.

perifit

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

Про авиабезопасность и кодовые замки

Присматривал на алиекспрессе рюкзачок какой-нибудь и наткнулся на вот такую модель:

https://ru.aliexpress.com/item//32838255479.html

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

tsa-lock

Вот такой красивый логотип в виде ромбика на кодовом замке — это не эмблема производителя, а обозначение того, что замок соответствует требованиям американской Transportation Security Administration — Администрации транспортной безопасности. Оказывается, что для облегчения досмотра багажа в аэропортах эти товарищи в 2003 году не придумали ничего лучше, чем обязать производителей встроить в багажные замки возможность открыть их одним из семи «мастер-ключей».

tsa-keys

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

tsa-lolkey

Скачивайте модельки с гитхаба и изготавливайте ключики:

https://github.com/Xyl2k/TSA-Travel-Sentry-master-keys