Русский
Русский
English
Статистика
Реклама

Разработка на raspberry pi

Перевод Система удалённого мониторинга рабочих мест на базе 360-градусной камеры и Raspberry Pi

02.04.2021 12:23:26 | Автор: admin
Я создал прототип системы удалённого мониторинга рабочих мест. Эта система позволяет организациям, адаптирующимся к ограничениям, связанным с COVID-19, осуществлять наблюдение за сотрудниками и проводить виртуальные инспекции рабочих мест.

Система, о которой я хочу рассказать, представляет собой роботизированную панорамную камеру. Проект основан на Raspberry Pi. Здесь, ради простоты, используются панорамные фотографии, а не видеозаписи или потоковая передача сигнала. Опыт, полученный в ходе работы с сотнями компаний, использующих камеры с обзором в 360 градусов (эти компании, в целом, провели миллионы виртуальных проверок сотрудников), и анализ рынка, подсказывают мне, что сейчас, в начале 2021 года, чаще всего встречаются именно решения, основанные на панорамных фотографиях.



Я, исследуя ситуацию, пользовался материалами форума, посвящённого использованию API Ricoh Theta, и тем, что удалось узнать при личном общении с представителями бизнеса в ходе онлайн-встреч с ними.

Требования к проекту


Я остановился на следующих требованиях к проекту, касающихся его аппаратной составляющей и инфраструктуры:

  1. Гибкое позиционирование камеры с помощью робота.
  2. Использование одноплатного компьютера Raspberry Pi 4 с 4 Гб памяти для управления камерой и роботом.
  3. Ориентация системы на съёмку 360-градусных фотографий.
  4. Применение прозрачного корпуса камеры.
  5. Организация связи камеры с системой управления камерой по Wi-Fi.

Раскрою некоторые подробности, касающиеся вышеозначенных требований.

1. Гибкое позиционирование камеры


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

2. Raspberry Pi 4


На Raspberry Pi 4 можно установить, кроме прочих ОС, специализированную операционную систему Robot Operating System (ROS). Я решил использовать в проекте стандартную ОС Raspberry Pi. Благодаря этому он будет доступнее для заинтересовавшихся им разработчиков и организаций.

3. 360-градусные фотографии


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

4. Прозрачный корпус камеры


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

5. Wi-Fi-соединение между камерой и контроллером


Хотя надёжнее было бы организовать управление камерой по USB, используя Picture Transfer Protocol (PTP) и применяя библиотеку libptp, я решил выбрать API Google Open Spherical Camera (OSC) и связываться с камерой по Wi-Fi. API OSC, которое в документации Ricoh называется Web API, легче реализовать, что позволяет быстрее перейти к практическим испытаниям проекта.


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

Преимущества фотоснимков перед потоковой передачей видео


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

Компания fulldepth тестировала потоковую передачу видео с 360-градусной камеры, смонтированной на роботе, который предназначен для работы на глубине в 300 метров.


Продукция компании fulldepth

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

Изначально я хотел реализовать в описываемом тут проекте возможность потоковой передачи видео с Raspberry Pi на Windows 10-компьютер с применением RTP. Специалисты из fulldepth поделились со всеми желающими методологией потоковой передачи 360-градусного видео с Raspberry Pi. Используя их спецификации и программный код я, наверняка, смог бы реализовать нечто подобное и в своём проекте.

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

  • Разрешение фотоснимков больше, чем разрешение видео. Фотографии лучше выглядят с точки зрения людей, а системы искусственного интеллекта могут использовать их для определения параметров объектов.
  • При съёмке фотографий можно лучше контролировать параметры изображения такие, как выдержка (изображение можно делать светлее или темнее) и цветность.
  • Возможность создания HDR-изображений (High Dynamic Range, расширенный динамический диапазон), позволяющая корректировать неблагоприятные условия освещённости (нечто вроде слишком светлых фрагментов изображений, появление которых вызывает, например, яркий солнечный свет, проникающий в комнату через окно). При создании HDR-изображений делают несколько кадров одной и той же сцены, используя разную выдержку, после чего эти кадры объединяют, выбирая с каждого из них участки с наиболее удачной экспозицией.

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

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

Управление камерой


Для того чтобы упростить работу с камерой с робота, основанного на Raspberry Pi 4, я, на языке Dart, создал библиотеку и приложение, рассчитанное на работу в командной строке. Для написания библиотеки я выбрал именно Dart из-за того, что при таком подходе код библиотеки я мог бы многократно использовать во Flutter-приложениях, рассчитанных на Android и iOS. Dart-код компилируется в нативные бинарники, которые запускаются на Raspberry Pi без необходимости установки Dart SDK. Соответствующие инструменты командной строки, созданные для Raspberry Pi, можно использовать из bash-скриптов, что позволяет автоматизировать управление камерой.

Для того чтобы управлять камерой с Raspberry Pi, можно воспользоваться простым bash-скриптом. Ниже приведён пример такого скрипта, в котором выполняются следующие действия:

  1. Настройка различных параметров камеры (отключение автоматического перевода камеры в режим сна или автоматического выключения камеры).
  2. Деактивация встроенного таймера.
  3. Вывод параметров камеры в консоль для их проверки.
  4. Удаление из текущей директории, предназначенной для выгрузки изображений, всех старых изображений, снятых камерой Ricoh Theta, что приводит к тому, что в папке будут храниться только свежие изображения.
  5. Запуск процесса съёмки 500 фотографий.
  6. Передача изображений с камеры на Raspberry Pi с применением Wi-Fi-соединения.
  7. Загрузка изображений на удалённый облачный сервер. Просмотр этих изображений организован с помощью веб-сервера Apache.

#!/usr/bin/bash# отключение offDelay./theta offDelay --off# отключение sleepDelay./theta sleepDelay --off# выключение встроенного таймера./theta exposureDelay --seconds=0# уменьшение громкости звука срабатывания затвора./theta shutterVolume --low# подтверждение настроек./theta getOptionssleep 1s# ЭТА КОМАНДА УДАЛИТ ВСЕ ИЗОБРАЖЕНИЯ, ХРАНЯЩИЕСЯ В ПАПКЕ СКРИПТАrm R00*.JPGecho start timelapse photography loop testecho images will be viewable at http://45.xx.xx.xx/robot/# Пример цикла, в котором делается 500 снимков, позволяющих# наблюдать за развитием некоего процесса во времени.# Для того чтобы снять другое количество фотографий, нужно изменить# число, используемое ниже, например - так: {1..300}for counter in {1..500}do./theta takeAndDownloadecho that was picture $counter((counter++))# если снимки нужно делать с интервалом в 30 секунд# sleep 30secho 'waiting 10 seconds for the next shot'sleep 10s# если снимки нужно делать с интервалом в 5 минут# sleep 5mecho '*** Will Start Upload to Digital Ocean Hosting ***'scp -r *.JPG craig@45.xx.xx.xx:/home/craig/robot/`date +"%Y%m%d%H%M"`.JPGecho completed uploadecho deleting all RICOH THETA images from current directoryrm R001*.JPGdoneecho timelapse doneecho go to http://45.xx.xx.xx/robot/ to view images

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

Проблемы проекта, выявленные в ходе полевых экспериментов


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


Офисные эксперименты

Проблема электропитания автономного робота


Собственный источник питания робота слишком слаб для того чтобы эффективно обеспечивать энергией Raspberry Pi и всё сопутствующее оборудование. Подробности об энергопотреблении Raspberry Pi можно почитать в этом материале.

Обычно я тестировал систему, подключив её к настенной электрической розетке. Перевод робота на автономное питание вызвал у меня, так сказать, культурный шок. В результате я сделал вывод о том, что мне, когда робот питается от батарей, нужно внимательнее относиться к энергопотреблению дополнительного оборудования, вроде Wi-Fi-адаптера, подключённого к Raspberry Pi.


В полевых условиях на первый план выходят вопросы автономного питания устройства

Решение проблем мобильной связи


В офисе робот подключается к Wi-Fi-роутеру, а в поле к мобильному хот-споту, выводящему устройство в интернет через LTE-сеть. Наладка работы системы в таких условиях вызвала неожиданные сложности. В качестве хот-спота я использовал не специализированное устройство, а телефон Pixel 2. Для того чтобы узнать IP-адрес Raspberry Pi, мне, на Pixel 2, пришлось воспользоваться Termux и командой ip neigh. Потом я воспользовался ноутбуком для того чтобы подключиться к Raspberry Pi по SSH и настроить скрипты, ответственные за управление камерой. Если интересно вот моя статья о выполнении Linux-команд на Android-устройствах с использованием Termux.

Маршрутизация на Raspberry Pi


После загрузки Raspberry Pi с двумя Wi-Fi-интерфейсами автоматически были созданы два стандартных, конфликтующих друг с другом шлюза. Мне понадобилось вручную удалить стандартный маршрут к камере и перенаправить к камере трафик из подсети 192.168.1.0 Raspberry Pi.


Настройка двойного Wi-Fi-подключения на роботе без пользовательского интерфейса

Неожиданная польза, которую принёс этот проект моей компании


Робот, о котором я рассказываю, это экспериментальный проект, направленный на проверку различных идей. Я использую его в учебных целях. Отмечу, что не ожидал того, что работа над этим проектом хорошо отразится на оптимизации операций, которые в компании, где я работаю, выполняются вручную. Меня удивило то, что благодаря моему роботу ускорилась работа над проектами, которые даже с ним не связаны. Например, инструмент для тестирования API камеры, предназначенный для использования из командной строки на Raspberry Pi, стал широко применяться в компании для тестирования API камеры на Windows и Mac. Это стало возможным благодаря тому, что для разработки этого инструмента было решено использовать язык Dart (а так же благодаря существованию команды dart compile).

Ещё одной приятной неожиданностью стало то, что мы начали использовать при работе с этим инструментом bash-скрипты, направленные на проведение автоматизированных тестов API камеры. Это благотворно сказалось на наших мобильных разработчиках. API камеры это REST-подобное HTTP-API, в Dart-программах можно пользоваться JSON-данными. Это позволяет создавать тесты, которые подойдут тем разработчикам, которые пишут на Swift, Kotlin или Java. Я проверял робота, запуская тесты на Raspberry Pi. Однажды, отвечая на какой-то вопрос с форума, я просто показал свои результаты. В итоге оказалось, что то, что я сделал, заинтересовало разработчиков мобильного приложения. Теперь мы пользуемся WSL2 в Windows 10 для запуска bash-скриптов с соответствующих компьютеров.

Итоги


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

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

Хотите создать собственную 360-градусную камеру, смонтированную на каком-нибудь роботе?

Подробнее..

Перевод Практический взгляд на Raspberry Pi Pico с точки зрения STM32

19.06.2021 14:07:57 | Автор: admin
Сравнительно недавно Raspberry Pi Foundation выпустила плату Raspberry Pi Pico, основанную на микроконтроллере (Micro Controller Unit, MCU) RP2040. Эта плата привлекла большое внимание членов сообщества разработчиков различных электронных устройств. Появилось довольно много проектов, в которых используются программируемые модули ввода-вывода (Programmable I/O, PIO) Raspberry Pi Pico. Например, это проект PicoDVI, в котором конечные автоматы PIO используются для вывода DVI-сигнала.



Но с появлением Raspberry Pi Pico связано не только радостное возбуждение разработчиков электроники. Это событие заставило сообщество задаться важным вопросом о том, окажет ли появление платы какое-то ощутимое влияние на тех, кто пользуется STM32, SAM и другими микроконтроллерами, основанными на Cortex-M. Станет ли микроконтроллер RP2040 жизнеспособным выбором для некоторых из проектов, в которых используются похожие MCU? Учитывая то, что в состав RP2040 входит двухъядерный процессор ARM Cortex-M0+, кажется справедливой идея использования этого микроконтроллера там же, где применяются 32-битные MCU от ведущих производителей компонентов такого рода, в частности, от STMicroelectronics.

Сможет ли небольшой проект Raspberry Pi Foundation показать инженерам STM как надо делать микроконтроллеры, или создателям платы на RP2040 стоит пересмотреть некоторые из своих гипотез? Сложно ли будет портировать на RP2040 низкоуровневый код, рассчитанный на STM32?

Сложно ли перенести STM32-проект на RP2040?


Короче говоря, когда я обратила внимание на RP2040, мне подумалось, что будет интересно попытаться портировать на новый микроконтроллер мой C++-фреймворк для STM32. Правда, эта идея меня заинтересовала не из-за двухъядерного ARM Cortex-M0+. У меня есть двухъядерные микроконтроллеры STM32H7 (M4 и M7), которые, за счёт более совершенных характеристик, легко обойдут RP2040. Сильнее всего меня заинтриговали программируемые модули ввода-вывода RP2040, возникало такое ощущение, что они достойны того, чтобы познакомиться с ними поближе.


Плата Raspberry Pi Pico, основанная на RP2040 подключена к одноплатному компьютеру Raspberry Pi, играющему роль SWD-адаптера (оригинал)

Основываясь на опыте работы с STM32 я поняла, что смогу быстро портировать некоторые файлы, создав в репозитории проекта ветку RP, рассчитанную на другую архитектуру, и принявшись за дело. Ведь и в основном проекте, и в новой ветке код будет рассчитан на Cortex-M. Обычно работа с новым ARM-микроконтроллером заключается в том, чтобы найти даташит, справочное руководство и CMSIS-файлы для соответствующего устройства. А потом существующий низкоуровневый код можно легко адаптировать под новый подход к именованию периферийных устройств и под новую схему регистров, учитывая то, что фундаментальные компоненты нового и старого микроконтроллеров (SysTick, NVIC и так далее) ничем не отличаются.

Может, я поступила слишком опрометчиво, но я заказала плату Raspberry Pi Pico, даже не поинтересовавшись тем, есть ли для неё CMSIS-файлы, и даже не взглянув в справочное руководство по ней. Позже я, к своему удивлению, выяснила, что пока нет даже и речи о наличии CMSIS-файлов для Raspberry Pi Pico, или хотя бы о возможности взаимодействия RP2040 с другими устройствами из экосистемы Cortex-M. Но при этом SVD-файл для MCU RP2040 имеется в Pico SDK, а на основе этого файла можно создать заголовочный файл для устройства. Благодаря проекту cmsis-pi-pico в моём распоряжении, в итоге, оказалось рабочее решение.

Решение моей задачи можно было бы и упростить


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


Последовательность загрузки RP2040 (даташит RP2040, рисунок 15) (оригинал)

Есть ещё и скрипт компоновщика, который позволяет обеспечить нахождение в памяти всех необходимых битов по правильным смещениям. Всё это представляет собой достаточно скромный набор задач при работе с MCU, в котором выполняется загрузка образа прошивки, находящейся во Flash ROM по адресу, используемому по умолчанию.

Первая сложность, которую нужно было преодолеть для того чтобы научиться работать с RP2040, заключалась в понимании особенностей цепочечного процесса загрузки микроконтроллера. Тут всё очень похоже на то, как в прошлом, на обычных компьютерах, была организована загрузка с дискет, или то, как устроена загрузка с HDD/SSD. А именно внешняя QSPI Flash ROM рассматривается MCU лишь как устройство, которое, возможно, содержит загрузочные данные. Загрузчик первой фазы загрузки интегрирован в MCU и располагается в ROM по адресу 0x0000 0000. Он обращается к интерфейсу QSPI и пытается загрузить из него 256 байт данных. Потом будет проверен CRC32-хеш этих данных. Если проверка пройдёт успешно, они будут признаны загрузчиком второй фазы загрузки.

Загрузчик второй фазы может решать множество задач, при этом некоторые задачи он должен решать в обязательном порядке. Этот процесс, реализованный в RP2040, если сравнить его с аналогичным процессом в некоторых знаменитых клонах STM32, тоже имеющих SPI ROM (вроде отличных клонов компании GigaDevice), не так понятен, не так хорошо документирован, не так прозрачен, как мог бы быть. В нём много такого, в чём можно запутаться.

Говорят, что хорошие художники копируют


У меня ушло достаточно много времени на то, чтобы понять, как подход к управлению тактированием периферийных устройств, принятый в STM32, соотносится с системной архитектурой RP2040. Я внимательно читала даташит RP2040 и всех вокруг спрашивала об этом. Как оказалось, RP2040-версия системы управления тактированием периферии называется RESETS. Эта система является полной противоположностью той, что применяется в STM32. А именно, нужно установить условие сброса периферийного блока в 0 для того чтобы включить его тактирование. Так, чтобы включить тактирование GPIO, нужно переключить бит 8 в RESETS_RESET (PADS_BANK0).


Функциональная схема GPIO-пина RP2040 (оригинал)

Когда я это поняла, я посмотрела раздел документации по GPIO-периферии (раздел 2.19). И кое-что тут же бросилось мне в глаза. А именно, то, что я там увидела, совершенно не похоже на то, как устроена практически вся GPIO-периферия, с которой я когда-либо сталкивалась. В частности, речь идёт о периферии STM32, AVR и SAM.

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

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

Причуды загрузки


Как уже было сказано, загрузчик второй фазы загрузки должен быть расположен в начале образа прошивки. Я считала, что это должен быть какой-то достаточно стандартный код, поэтому просто взяла готовый ASM-код, который выдал официальный Pico SDK, и использовала его при сборке примера Blinky. Добавив этот код к RP2040-порту моего проекта Nodate, я смогла без проблем собрать Blinky.

Запись результирующего ELF-бинарника в RP2040 стала ещё одним приключением. Дело в том, что на плате Raspberry Pi Pico нет встроенного SWD-адаптера, чего-то в духе ST-Link. А микроконтроллеру на двухъядерном Cortex-M нужен могоканальный SWD-адаптер. Единственным подобным устройством, которое было у меня под рукой, оказался адаптер, интегрированный в плату Nucleo-STM32H7. Поэтому я решила использовать кастомный форк OpenOCD, созданный Raspberry Pi Foundation. Его я запустила на Raspberry Pi.

После столь основательной подготовки мне удалось успешно прошить RP2040, но ничего не заработало. Беглая проверка вызвала у меня такое ощущение, что в ходе загрузки мне не удалось выйти за пределы исходного загрузчика и добраться до прошивки, находящейся в SPI ROM. Сейчас мне сложно дать ответ о причинах происходящего. Это могла быть проблема с ASM-кодом второй фазы загрузки, это могла быть ошибка в экспериментальных CMSIS-файлах RP2040, которые создавала не я. Это могло быть и что-то совершенно иное.

Продолжение следует?



Raspberry Pi Pico (оригинал)

После того, как я потратила много часов на то, чтобы завести RP2040 с использованием CMSIS-файлов и файлов загрузчика второй фазы загрузки, мне кажется, что можно немного отстраниться от ситуации и переоценить происходящее. А именно, с того момента, когда начинала формироваться моя точка зрения на Raspberry Pi Pico, в запросе по поводу CMSIS-файлов появились сведения о том, что официальные CMSIS-файлы, возможно, появятся в Pico SDK 1.2.0. Это довольно-таки приятно.

Полагаю, любому, кто хочет поближе познакомиться с RP2040, пользуясь инструментами, ставшими индустриальным стандартом, имеет смысл дождаться этого релиза Pico SDK. А после того, как в моём распоряжении окажутся официальные CMSIS-файлы, я, вероятно, начну с переделывания примера Nodate Blinky, а потом попробую поработать с PIO. Перспектива создавать собственные интерфейсы кажется мне весьма привлекательной. И хотя возможности Raspberry Pi Pico не так мощны, как возможности CPLD или FPGA, они, всё равно, способны лечь в основу интереснейших проектов.

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

Полагаю, тех, кто захочет написать для Raspberry Pi Pico что-то своё, не особенно порадуют такие особенности платы, как запутанная работа с GPIO-периферией, сложный процесс загрузки, необходимость в загрузчике второй фазы загрузки, непрозрачность внешней ROM. В общем тому, кому интересна плата Raspberry Pi Pico, пока приходится ориентироваться на официальный SDK.

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

Пользовались ли вы Raspberry Pi Pico?


Подробнее..

Перевод Они взломали машину для мороженого в McDonalds ради права на ремонт и развязали холодную войну

17.05.2021 12:14:39 | Автор: admin

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




Джереми ОСалливан настаивает, что из всех загадок и странностей машины для мороженого от McDonald's в первую очередь нужно разобраться с её секретным паролем.

Как он поясняет, нужно нажать на экране цифровой машины для мороженого Taylor C602 на символ рожка для мороженого, потом нажать на кнопки со снежинкой и с молочным коктейлем, чтобы на экране появились цифры 5, потом 2, потом 3, потом 1. После этой последовательности из целых 16 нажатий на экране волшебным образом возникнет меню. Только при помощи этого чит-кода можно получить доступ к жизненно важным показателям машины ко всему, от настроек вязкости для таких ингредиентов, как молоко и сахар, до температуры гликоля в нагревательном элементе и смысла множества загадочных сообщений об ошибках.

Никто из компаний McDonald's или Taylor не объясняет, зачем там нужно тайное, скрытое меню, написал ОСалливан в одном из своих первых загадочных сообщений, которые я начал получать от него в этом году.

Как говорит ОСалливан, этого меню нет в ни в одной инструкции для покупателей цифровой машины для мороженого от Taylor, являющейся стандартным оборудованием для более чем 13 000 закусочных McDonald's в США и ещё десятков тысяч по всему миру. И эта непрозрачность и недружественность к пользователям далеко не единственная проблема с этими машинами. Они завоевали репутацию до абсурда ненадёжных и хрупких. Благодаря множеству спорных инженерных решений они так часто ломаются во всех ресторанах McDonald's по всему миру, что даже превратились в настоящий мем в соцсетях. Поищите в твиттере "broken McDonalds ice cream machine" и найдёте тысячи сообщений от раздосадованных людей.

Но после множества лет изучения этой сложной машины и множества вариантов её отказа, ОСалливана более всего раздражает то, что такой промышленный гигант, производящей пищевое оборудование, как Taylor, продаёт устройства для выдавливания McFlurry владельцам ресторанов McDonald's по $18 000 за штуку, и при этом не раскрывает им всех её внутренних секретов. Более того, Taylor поддерживает сеть из одобренных распространителей, ежегодно выставляющих открытым по франшизе ресторанам счета на тысячи долларов за дорогое обслуживание. За эти деньги техники компании, работающие по вызову, приходят в закусочные и вводят этот секретный пароль.

ОСалливан утверждает, что это секретное меню выдаёт наличие бизнес-модели, далеко выходящей за рамки простого понятия о праве на ремонт. По его словам, это просто молочно-коктейльное вымогательство [по-английски звучит красивее: milkshake shakedown / прим. пер.]. Схема простая: продайте закусочным сложную и капризную машину. Не давайте им понять, почему она постоянно ломается. Заберите себе часть их прибылей за обслуживание. Чрезвычайно прибыльно специально, намеренно ослеплять пользователя, чтобы он не мог вносить в оборудование, которым владеет, какие-либо фундаментальные изменения, говорит ОСалливан. А над всем этим стоит McDonald's, настаивающий на лояльном отношении к давнишнему поставщику. Возразишь монархии от McDonald's насчёт оборудования и корпорация отнимет у тебя франшизу.

Поэтому пару лет назад, после собственных странных и болезненных мучений с этими устройствами от Taylor, 34-летний ОСалливан и его партнёр, 33-летняя Мелисса Нельсон, начали продавать устройство размером с небольшую книгу под названием Kytch. Устанавливаете его в вашей машине для мороженого, подключаете к своему Wi-Fi, и оно взламывает ваше враждебное устройство, предоставляя доступ ко всем его запретным секретам. Kytch работает как жучок для прослушки, перехватывая все коммуникации между компонентами, и отправляя их на компьютер с более дружелюбным интерфейсом, чем у Taylor. Устройство не только показывает все внутренние данные машины, но и пишет их в журнал, и даже предлагает способы устранения проблем и всё это через web-интерфейс.


ОСалливан и Нельсон

В итоге, как только McDonald's и Taylor узнали о первых успехах Kytch, развязалась идущая уже два года Холодная война, сейчас перетекающая в горячую. В какой-то момент создатели Kytch даже решили, что Taylor наняла частных детективов, чтобы заполучить их устройства. Недавно Taylor показала собственный конкурирующий продукт, предлагающий мониторинг машин через интернет. McDonald's дошла до того, что разослала франшизам е-мейлы, предупреждая о том, что устройства Kytch осуществляют доступ к конфиденциальной информации Taylor и даже могут серьёзно поранить людей.

ОСалливан с партнёром, понаблюдав за попытками McDonald's и Taylor уничтожить их бизнес в течение пяти месяцев, прошедших с отправки тех самых емейлов, перешли в контрнаступление. Парочка, стоящая за Kytch, рассказала, что планирует подать в суд на те франшизы McDonald's, которые они подозревают в сговоре с Taylor в передаче компании устройств Kytch с целью реверс-инжиниринга. А это уже является нарушением договора с Kytch. В Taylor отрицают, что получили в своё распоряжение устройства, но не отрицают своего желания заполучить одно из них, или того, что дистрибьютор компании в итоге добрался до одного из устройств. Этот иск, вероятно, станет лишь первым залпом в намечающейся грязной юридической баталии против Taylor с McDonald's.

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

* * *

Стандартная машина для мороженого от Taylor, стоящая на кухне McDonald's, напоминает итальянский спортивный автомобиль, как сказал мне владелец одной франшизы, пишущий в твиттере под ником McD Truth.

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

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


Печально известные своим капризным характером и хрупкостью машины от Taylor используются практически всеми крупными сетями фастфуда, среди которых и более 13 000 ресторанов McDonald's в США, а также десятки тысяч этих заведений по всему миру

И хотя другие машины для мороженого нужно разбирать и чистить ежедневно, выбрасывая из них все остатки продуктов, в Taylor используется ежедневная тепловая обработка. Остатки еды нагреваются до 66 С, выдерживаются в таком виде 30 минут, а потом снова замораживаются в течение ночи. Получается современное чудо гигиены и экономии.

Однако в соответствии с аналогией с итальянской спортивной машиной эти агрегаты также капризные, хрупкие и чересчур сложные. Они отлично работают, когда всё идеально на 100%, пишет McD Truth. А если что-то не идеально, машина ломается. По договору франшизы McDonald's позволяет закусочным использовать другую, на этот раз реально итальянскую машину для мороженого производства Carpigiani из города Болонья. McD Truth пишет, что эта машина спроектирована гораздо лучше, но, учитывая, что запчасти из Италии могут идти для неё неделю, её покупает куда как меньше ресторанов.

Каждые две недели все высокоточные компоненты машины необходимо разбирать и обеззараживать. Некоторые её части надо тщательно смазывать. Среди её компонентов есть не менее двух десятков пластиковых и резиновых кольцевых прокладок различных размеров. Забудете хоть одну и насос откажет, или жидкие ингредиенты протекут. Техник одной из закусочных рассказал мне, что разбирал и собирал машину для мороженого от Taylor более сотни раз, и после сборки с первого раза они работали едва ли в десяти случаях. Они очень, очень, очень капризные, говорит он.


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

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

На этом можно сразу же недополучить сотни долларов. Особенно, как говорит ОСалливан, во время сезона трилистника, когда в McDonald's предлагаются зелёные мятные коктейли в честь дня св. Патрика, увеличивающие продажи коктейлей в десять раз. Сезон трилистника это, блин, очень серьёзно, подчёркивает ОСалливан.

И вот такие требовательные с технической точки зрения машины Taylor продаёт предприятиям, на которых за ними будет следить скучающий подросток, чья карьера в фастфуде ограничена несколькими неделями. Неудивительно, наверное, что во многих ресторанах McDonald's эти машины простаивают так же часто, как работают. Судя по статистике сайта McBroken.com, который автоматически пытается размещать в онлайне заказы на мороженое в каждом ресторане McDonald's в США раз в 20-30 минут, в любой момент за последние 2 месяца от 5 до 16% закусочных в США не могли продавать мороженое. В типичный неудачный день как, например, когда я размещал эту статью это означало, что мороженого не было в одном из пяти McDonald's в Лос-Анджелесе, Вашингтоне О.К. и Филадельфии, в одном из четырёх в Сан-Франциско, и в одном из десяти в Нью-Йорке.


Выборка статистики неработающих машин для мороженого в McDonald's США в произвольный момент времени

Многие компании боролись против предоставления прав собственным клиентам на ремонт приобретённого ими оборудования. Можно вспомнить попытки John Deere запретить фермерам доступ к ПО тракторов, и стремление Apple ограничить круг лиц, способных ремонтировать iPhone. Однако оборудование мало каких компаний приходится ремонтировать так часто по сравнению с машиной для мороженого в McDonald's. Когда WIRED обратилась в компанию McDonald's за комментариями, та даже и не подумала защищать беспорядочное поведение этих машин. Мы понимаем недовольство клиентов, пришедших в McDonald's за замороженной вкусняшкой, и обнаруживших сломанную машину для коктейлей. Мы стремимся улучшить эту ситуацию, написал представитель компании.

В соцсетях же машина для мороженого из McDonald's уже стала символом всех разочарований современными технологиями, капитализмом и условиями человеческого существования. Когда в 2017 году три женщины во Флориде напали на сотрудника McDonald's, узнав, что машина для мороженого сломана, значительная часть комментаторов в твиттере встала на сторону нападавших. Даже сама компания McDonald's писала в своём официальном аккаунте твиттера в прошлом году в августе, что у нас есть внутренняя шутка по поводу машины для мороженого, но мы беспокоимся, что она может не сработать.

Как-то вечером в марте я попытался подсчитать количество людей, написавших в твиттере вариацию шутки на тему о том, что они потратят $1400, полученные от правительства в качестве компенсации из-за пандемии, на починку машины для мороженого в местном McDonald's. После 200-го твита я сбился.

* * *

Ещё лет десять назад проблемы McDonald's с мороженым ещё не успели стать объектом критики в соцсетях. Поэтому когда в 2011 году ОСалливан и Нельсон впервые решили поставить на кон карьеры ради замороженных сладостей, им пришлось на себе ощутить все тонкости индустрии мягкого мороженого.

Познакомились они в Бакнеллском университете и начали встречаться в конце 2000-х, а потом начали свои карьеры в бухгалтерском деле Нельсон в Deloitte, а ОСалливан в Ernst & Young. Обоим это дело показалось невыносимо скучным. Спустя несколько лет они начали накидывать идеи по поводу собственного бизнеса, и остановились на увлечении замороженными йогуртами, из-за которого страну постепенно покрывали магазинчики Pinkberry и Red Mango.

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

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

На постройку первого прототипа Frobot у них ушло три года. Они купили машину Taylor на сайте-барахолке Craigslist и наняли инженеров. После первого ничем не примечательного испытания в кафе медицинской школы в Западной Виргинии Нельсон и ОСалливан поставили Frobot в коворкинге Вашингтона О.К. Большой белый шкаф продемонстрировал умеренный успех. Парочка решила испытать удачу, они уволились и переехали в Сан-Франциско, чтобы заниматься стартапом вплотную, и разместили Frobot следующего поколения в общественном клубе близ Дворца изящных искусств, где, по их словам, машина начала зарабатывать по $500 в день.

Но теперь, выпустив Frobot в большой мир, изобретатели столкнулись с проблемой. Они хотели, чтобы их машина стала полностью автономной, и с минимальным вмешательством конвертировала молочные вкусняшки в деньги. Правила национального санитарного фонда США требовали периодической проверки температуры продукта, чтобы машина не продавала испортившийся и повторно замороженный йогурт, переполненный не теми микроорганизмами. Данные по температуре хранились внутри машины Taylor, и доступа к ним у парочки не было. Однако их заинтересовал тот факт, что техник, которого они вызывали для обслуживания машины, мог вызвать нужные им цифры, вводя секретный код 5231, не упомянутый в инструкции владельца.

Примерно тогда ОСалливан связался с контактом в акселераторе железячных стартапов Hax из Шэньчжэня, пригласившим его поработать над Frobot в мастерской Hax. Им пообещали инвестиции в $100 000 и консультации советников, среди которых был Эндрю Хуанг по прозвищу зайка, легендарный гуру железа, первым взломавший Xbox 20 лет назад. ОСалливан и Нельсон сочли это предложение шансом преодолеть трудность с мониторингом температуры. Смогут ли Хуанг и его коллеги помочь им вытаскивать данные из машины и отправлять их в реальном времени на удалённый интерфейс?

ОСалливан и один из инженеров, работавших по контракту над Frobot, переехали в Шэньчжэнь в конце 2016 года. Они начали работать на складе Hax, расположенных над одним из знаменитых электронных рынков города, и пытались разобраться в машине для мороженого от Taylor, чтобы понять работу внутренних коммуникаций машины и научиться перехватывать данные. Хуанг вспоминает, что ОСалливан по духу был больше предпринимателем, чем технологом, однако был впечатлён тем, насколько подробно было проработано будущее машин Frobot. С самого начала было ясно, что у них есть своё видение, говорит Хуанг.

Также Хуанг вспоминает, как обратил внимание ОСалливан на тот факт, что машина от Taylor, использованная для создания Frobot, как и многие агрегаты пищевой индустрии, использует древние технологии, по сути не менявшиеся уже лет 50. Она не получила никаких преимуществ ни закона Мура, ни даже Web 2.0, вспоминает Хуанг свои слова. Эту еду все едят, а машина при этом вышла из тёмных веков.

И всё же ОСалливан со своим инженером активно шли вперёд, и к концу пребывания в Китае, через четыре месяца, они построили устройство, которое в дальнейшем превратится в Kytch хак, помогающий Frobot удовлетворять санитарным требованиям США.

ОСалливан с Нельсон отмечают, что всё это они проделали благодаря полученным у компании Taylor знаниям, а иногда и её активному участию. Один из руководителей компании был на вечеринке в Вашингтоне, посвящённой запуску прототипа их машины. Позднее компания предложила им поставить 10 машин для мороженого для их адаптации. Компания ради них даже отправила одну свою машину в Шэньчжэнь. Ведь Frobot не становился конкурентом Taylor он был новым многообещающим источником продаж, или даже новым автоматическим рынком.

В какой-то момент, будучи в Шэньчжэне, ОСалливан написал своему контакту в Taylor просьбу дать совет по одному из технических вопросов. Руководитель компании ответил ему, что если они хотят подключиться к управлению машиной или перехватывать пакеты с данным, это придётся делать без помощи Taylor из-за внутренней политики безопасности компании.

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

* * *

В 2017 году Frobot начали набирать популярность. Tesla установила два таких автомата в своём кафе. Стадион Levi's, домашний для команды по американскому футболу Сан-Франциско Форти Найнерс, установил себе шесть штук, а владельцы футбольной команды вложились в компанию Нельсон и ОСалливана. Тем временем отношение Taylor к Frobot оставалось достаточно дружеским для того, чтобы приглашать парочку на презентацию автоматов на торговых выставках.

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

В восьми автоматах Frobot, расположенных на территории залива Сан-Франциско начали появляться загадочные отказы и сообщения об ошибках, преследовавшие и других клиентов Taylor. Они получали от машин сообщения о слишком низкой температуре смеси для йогуртов. Или слишком высокой. Или о слишком большой вязкости. Вскоре они уже постоянно ездили на стадион Levi's, чтобы помогать сбитому с толку персоналу исправлять эти ошибки и пересобирать машины Taylor, находящиеся внутри их автоматов.


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

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

Вскоре стало ясно, что их бизнес стал чем-то противоположным автоматизации никто на стадионе или в Tesla не мог настроить или поддерживать Frobot без постоянной личной помощи основателей компании. И проблема заключалась в машине Taylor, находившейся внутри Frobot. Эти машины просто отстой, вспоминает свои мысли в тот момент ОСалливан.

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

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

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

Когда в апреле того года компания Kytch начала работу, Нельсон объездила всю территорию Залива в поисках ресторанов, использовавших машину от Taylor, рекламировала услуги владельцам франшиз в LinkedIn и предлагала шесть месяцев бесплатного пробного использования перед подпиской за $10/мес. Найдя несколько первых клиентов в Burger Kings и Super Duper Burgers, предприниматели, наконец, начали выходить на свой целевой рынок. Это были владельцы франшиз McDonald's, которые не только обладали крупнейшей коллекцией агрегатов от Taylor, но и использовали самую сложную и часто ломающуюся цифровую версию продукции компании.

Осенью 2019 года, начав проникать в причудливый внутренний мир работы закусочных McDonald's, ОСалливан и Нельсон были потрясены, узнав, что большинство владельцев закусочных никогда не получали доступ в сервисное меню, показывающие такие переменные, как температура воронок или гликоля, использовавшегося в капризном процессе пастеризации. Они даже не слышали об этом меню. И в этот момент у нас случилось просветление, говорит Нельсон. Почему настолько важные вещи скрыты за меню, о существовании которого большинство даже не подозревает?

Тем временем многие владельцы McDonald's ежемесячно выплачивали дистрибьюторам Taylor сотни долларов за обслуживание, и часто за услуги типа изменения простых настроек, спрятанных за эти меню. Тогда предприниматели добавили в свой Kytch функцию Kytch Assist, автоматически распознававшую некоторые из частых проблем машины и подстраивавшую эти скрытые переменные, предотвращая неприятности до того, как они произойдут.

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

После установки Kytch почти сразу стало ясно, что один чрезмерно усердный сотрудник заливал в один из приёмников машины слишком много смеси. Сегодня этот владелец просыпается в 5:30, берёт телефон, и убеждается в том, что все его машины прошли эту ненадёжную термообработку. Один техник по обслуживанию машин рассказал мне, что несмотря на то, что за последние два года Kytch почти удвоила стоимость своей приставки и добавила стоимость её активации в $250, она всё равно экономит владельцу франшизы как минимум тысячи долларов в месяц.

McD Truth по секрету сообщает, что Kytch всё равно редко удаётся предотвратить поломки машин для мороженого. Но без этих приставок работники ресторана всё равно в 9 из 10 случаев даже не сообщали владельцам о проблемах с этим агрегатом. Теперь, по крайней мере, последние получают предупреждение по емейл вместе с диагностикой проблемы. А это уже роскошь, пишет McD Truth. Kytch отличное устройство.


Устройство Kytch на базе Raspberry Pi, созданное для установки внутрь машины для мороженого от Taylor

Когда сарафанное радио франшиз McDonald's начало распространять информацию о Kytch, продажи компании начали удваиваться каждый квартал. ОСалливан и Нельсон наняли менеджера по продажам, ставшего у них третьим сотрудником, работающим полный день. К осени 2020 года во внутренности машины для мороженого от Taylor, расположенных по всему миру, проникло уже более 500 таких устройств. На основе статистики бесплатных испытаний компания прогнозировала, что к концу года они продадут ещё 500 штук. Однако империя мороженого, против которой они рискнули пойти, готовилась нанести ответный удар.

* * *

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

Через пару месяцев они заметили ещё один странный заказ, на этот раз поступивший от Бринкса Гилсона, представителя сторонней юридической фирмы, с которой работала Taylor. Узнав его имя, они отменили и этот заказ. В последовавшие месяцы подозрительные заказы продолжались. И если большинство владельцев франшиз заказывали Kytch для своих ресторанов, эти подозрительные клиенты просили доставить им устройства на домашний адрес.

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

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

В последовавшие месяцы, пока продажи Kytch набирали обороты, странные заказы прекратили поступать, и явных признаков враждебного отношения со стороны Taylor не наблюдалось. Нельсон и ОСалливан обрадовались пришедшему в феврале 2020 года письму от Тайлера Гэмбла, главы подразделения по работе с оборудованием в Национальном совете по управлению поставками группы из руководства франшиз McDonald's.

До Гэмбла дошло множество слухов по поводу Kytch, как писал он в своём письме, и он хотел опробовать это устройство в 10 собственных ресторанах. ОСалливан вспоминает, что при разговоре по телефону Гэмбл был настроен дружественно и интересовался Kytch, но при этом предупреждал, что возможность обойти секретное меню Taylor вещь рискованная, способная вызвать гнев компании. И всё же Нельсон и ОСалливан заворожила возможность того, что Гэмбл использует своё огромное влияние на другие франшизы с целью рекламы их собственного продукта. Они выдали ему четыре устройства для испытаний.

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

Затем он, по сути, целую минуту рассказывал о Kytch и рекламировал их аппарат. У меня была возможность опробовать их устройства в своих ресторанах в течение нескольких месяцев, рассказал Гэмбл собравшимся. Правду сказать, это оборудование не одобрено McDonald's, и поставщики пока ещё не полностью согласны с его использованием. Но моя задача рассказывать вам об оборудовании и о том, как оно влияет на индустрию, и я действительно считаю, что это устройство способно снизить сложность управления ресторанов, облегчить вашей команде жизнь и усилить денежный поток.

ОСалливан и Нельсон, смотревшие эту речь по интернету из своей стойки на выставке, были в восторге. Они почти не обратили внимания на замечания не одобрено McDonald's, и поставщики пока ещё не полностью согласны. Казалось, что им удастся продать Kytch практически всем McDonald's в Америке.


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

А затем 2 ноября грянул гром. Шокированный продавец Kytch переправил Нельсон и ОСалливан письмо, судя по всему, разосланное компанией McDonald's всем владельцам франшиз. В нём сначала предупреждалось, что установка Kytch нарушала условия гарантии на машины Taylor это знакомая угроза, исходящая от корпораций, борющихся против права на ремонт руками клиентов. Затем там заявлялось, что Kytch открывает доступ к контроллеру оборудования и конфиденциальным данным (то есть, данным, принадлежащим Taylor и McDonald's, а не владельцам ресторанов), создаёт потенциально большой риск безопасности для команды или техников, пытающихся почистить или починить машину, и что оно может привести к серьёзным травмам. Последним предупреждением в письме шло следующее: McDonald's настоятельно рекомендует удалить устройство Kytch из всех машин и перестать его использовать.

На следующий день McDonald's отправил другое сообщение всем владельцам франшиз, сообщая о выходе нового аппарата Taylor Shake Sundae Connectivity по сути, дублирующего многие функции Kytch. В письме повторялось предупреждение против использования Kytch.

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

Когда журнал WIRED связался с компаниями McDonald's и Taylor, компании повторили предупреждение о том, что Kytch представляет опасность для работников и техников. Обслуживание и работа со специальным оборудованием, разработанным Taylor, производящим мягкое мороженое и коктейли, может быть сложной, пишет представитель Taylor. Все проверки, встроенные в контроллер оборудования, предназначены для защиты оператора и техника, взаимодействующих с машиной.

Что касается подсоединённого к интернету аппарата от Taylor, похожего на Kytch, компания просто сообщила, что Taylor не имитировала устройство от Kytch и не имела такого желания. В компании утверждают, что разрабатывали такое устройство уже много лет, параллельно с другим кухонным устройством для интернета Open Kitchen, которое продаёт другое подразделение родительской компании Taylor, Middleby.

Никто из владельцев франшиз, общавшихся с редакцией, никогда не слышал об устройстве Open Kitchen, и не видел машину Taylor Shake Sundae Connectivity в работе. McDonald's говорит, что с октября это устройство испытывают всего несколько десятков ресторанов.

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

McD Truth утверждает, что емейлы из McDonald's, убившие Kytch, произрастают из цели Taylor создать собственную систему, похожую на Kytch, а также из долгосрочного сотрудничества McDonald's с Taylor. В конце концов, последняя производит не только машины для мороженого, но и грили, на которых жарятся главная продукция компании, бургеры. Возможно также, что McDonald's испугалась возможности устройства Kytch собирать проприетарные данные по продажам мороженого.

Ещё один владелец франшизы назвал этот разнос от McDonald's подозрительным и очень уж неуклюжим. Он сказал, что не видел ничего подобного за 25 лет владения закусочными.

* * *

После того, как McDonald's и Taylor разбомбили их стартап, Нельсон и ОСалливан стали подозревать, что две компании каким-то образом заполучили в свои руки устройство Kytch, чтобы если и не скопировать, то испытать его. Однако Kytch требовала от клиентов подписать контракт, запрещающий им отдавать своё устройство кому бы то ни было. Кто же его передал?

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

После краха их бизнеса ОСалливан и Нельсон начали изучать авторизации на веб-сайте Kytch, и увидели, что одна из учётных записей, связанная с той машиной Гэмбла, которую отправили в ремонт, была удалена через пару месяцев после рокового емейла от McDonald's в ноябре. Имя удалённого пользователя было Мэтт Уилсон. Был ли Уилсон одним из сотрудников Гэмбла? Они начали отслеживать его местонахождение на основе IP-адресов сетей, из которых он логинился, и нашли там IP из Арканзаса, Теннеси и Луизианы.

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

Нельсон и ОСалливан были в дружеских отношениях с директорами TFG, когда работали над Frobot. Они начали рыться в своих старых контактах, и нашли визитку Блэйна Мартина, одного из владельцев TFG, передавшего её им на выставке. И они были поражены, поняв, что его телефон использовали при создании учётной записи Мэтта Уилсона.

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

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

* * *

Теперь они надеются, что месть это блюдо, которое следует подавать посредством долгого и сложного юридического разбирательства. Планируемый ими иск основан на заявлениях о том, что Гэмбл, и, вероятно, другие пользователи Kytch, нарушили их контракты с компанией, позволив Taylor изучить устройства, заискивая таким образом перед McDonald's и их корпоративными союзниками.

Однако сооснователи Kytch не скрывают, что их юридические угрозы остановятся на этом. Они собираются идти до самого конца, вплоть до всей сети McDonald's. Мы уверены, что узнаем всё, что нам нужно, чтобы полностью расквитаться со всеми виновными, прогнозирует ОСалливан.

Taylor возражает, что не имеет и не имела в распоряжении устройства Kytch, и что ничего не знает о том, что кто-то логинился на веб-сайт компании. Однако отмечает, что наш дистрибьютор в Теннеси сообщил, что их техник удалил устройство Kytch, чтобы обслужить наше устройство. Дистрибьютор TFG никак не отреагировал на запросы на комментарии, а Тайлер Гэмбл не ответил на наши вопросы. Однако в ответе на наше письмо он назвал себя первейшим сторонником Kytch и утверждал, что поддерживал стартап публично и частным порядком. Странно, что они собираются судится с человеком, выступавшим за них и с их клиентом, писал Гэмбл, но правда выплывет наружу.

Вне зависимости от того, как будет разворачиваться юридический конфликт, бывший технический советник и инвестор стартапа, Хуанг, утверждает что попытки McDonald's и Taylor раздавить крохотный стартап являются формой признания его значимости. Когда крупные игроки приходят к тебе и начинают бить себя в грудь, они как бы признают тебя угрозой альфа-самцу, говорит Хуанг, у принадлежащего которому акселератора Hax до сих пор есть небольшая доля в компании. Это показывает, что на Kytch есть спрос, и что это устройство могло нарушить текущее положение вещей. Однако если большие парни не справляются, или хотят похитить идею, иногда им проще просто спрятать тело.

Что до Нельсон и ОСалливана, у них нет никаких иллюзий по поводу того, что их судебный процесс защитит Kytch от попыток McDonald's и Taylor уничтожить стартап. В одном из последних разговоров ОСалливан признал, что он считает эту статью чем-то вроде некролога его компании, после того, как её успешно уничтожили гиганты фастфуда.

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

Однако же иногда он описывает историю Kytch как борьбу Давида с Голиафом за право на ремонт, или даже ещё больше: как отважную попытку исправить не очень критичную, но очень распространённую часть мировой инфраструктуры. И эта попытка провалилась не из-за недостатков оборудования, но из-за людей, его контролирующих и для некоторых из них было бы лучше, если бы оно оставалось сломанным.

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

Камера против эвакуаторов, угонщиков, дачных гостей

17.05.2021 22:18:14 | Автор: admin


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

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

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

Алгоритм работы следующий. Камера после включения поднимает соединение через usb 3G модем, соединяется с VPN, мониторит картинку и, при появлении движения на ней, делает фото и, заодно, отправляет фото в телеграм-канал владельца. Из опций возможность записывать timelapse, видео и возможность покрутить головой удаленно, то есть поуправлять камерой и посмотреть что к чему. Нейросетей здесь нет, все достаточно просто.

Будет ли это работать?


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

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


оригинальная ссылка изображения

В качестве софта используется RPi-web-interface.

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

Отличия, дополнения следующие:

  • связь с telegram-каналом (отправка фото на канал),
  • 3g связь одновременно с наличием wi-fi,
  • обратная связь с камерой через vpn,
  • иные изменения в настройках.

Немного скучной предыстории


При разработке прототипа остро встали несколько вопросов:

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

Первая реализация камеры в части софта имела изобилие костылей.

Изначально все было собрано на raspberry pi 3b с неродной камерой (usb, не csi). В качестве обратной связи использовался skype. Для связи с камерой на нее надо было позвонить.
Через skype. В skype была функция автоответа, после снятия трубки устанавливался канал видеосвязи и можно было посмотреть то, что видела камера. Все просто.

И все просто жутко работало в плане скорости, звук был отвратительным и так далее. Потом skype перестала обновлять пакеты под raspberry. Была попытка продлить жизнь данного изделия с помощью exagear desktop, который эмулировал win и позволял установить такие приложения как icq, viber, teamspeak. Но все это работало крайне медленно и неэффективно. Потом exagear desktop, который был к тому же с платной лицензией (слава богу, единоразовый платеж) свернули и поддержку прекратили.



В плане питания все тоже было не совсем просто. Raspberry pi 3b любила и любит покушать, и powerbankи нужны были с достатком. Были попытки запитать от солнечный панелей, но сразу стало понятно, что этот вариант не подойдет.

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

Основа видеокамеры




В качестве базы, от который оттолкнемся при создании камеры будет та же raspberry pi, только модель zero w (c поддержкой wifi).

Наши комплектующие следующие:

  • raspberry pi zero w 1,8 к руб.;
  • камера со шлейфом 500 руб.
  • сервоприводы sg-90 2шт. 200 руб.
  • пластиковый подвес 100 руб.
  • блок питания 1000 руб.;
  • sd карта на 8, а лучше на 16Гб 1000 руб.;
  • 3g modem Huawei E171 2k руб.
  • sim карта с пакетом услуг интернет, например от мтс 500 руб.
  • переходник с mini-usb на usb для подключения usb 3g модема 200 руб.
  • коробка, в которой прислали raspberry pi-бесплатно.

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

Переходим к настройкам


Не будем далеко отходить от образа (image) с предустановленным Rpi-web-interface, servoblaster, приведенном в ранее опубликованной статье ссылка на образ. Его необходимо будет немного дополнить.

Первое, что настроим это 3g модем



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

Но в статье много лишних этапов, чтобы, так сказать, прочувствовать модем. Поэтому можно смело начинать настраивать с шага РЕКОННЕКТ ПРИ ДРОПЕ и не выполнять все предыдущие:

$ mkdir ~/3g$ cd ~/3g$ wget http://zool33.uni-graz.at/petz/umtskeeper/src/umtskeeper.tar.gz$ tar -xzvf umtskeeper.tar.gz$ chmod +x umtskeeper$ ./umtskeeper --sakisoperators "USBINTERFACE='0' OTHER='USBMODEM' USBMODEM='12d1:1506' APN='CUSTOM_APN' CUSTOM_APN='internet.mts.ru' APN_USER='mts' APN_PASS='mts'" --sakisswitches "--sudo --console" --devicename 'Huawei' --log --nat 'no'$ sudo nano /etc/rc.local/home/pi/3g/umtskeeper --sakisoperators "USBINTERFACE='0' OTHER='USBMODEM' USBMODEM='12d1:1506' APN='CUSTOM_APN' CUSTOM_APN='internet.mts.ru' APN_USER='mts' APN_PASS='mts'" --sakisswitches "--sudo --console" --devicename 'Huawei' --log --silent --nat 'no' &

*12d1:1506 изменить на свой, который можно узнать через lsusb.
**если модем не стартует, добавить sudo в начале команды.

После настройки модема и редактирования /etc/rc.local будет небольшой баг, так сказать. Несмотря на то, что rc.local запускает при загрузке все указанные в нем скрипты, umtskeeper запускается весьма неспешно. И на старт модема может уйти от 1 минуты до 3. Это может быть критично в некоторых ситуациях. Как с этим бороться, пока не ясно.

Теперь настроим отправку сообщений в telegram канал c raspberry pi



Нам понадобится следующая статья.

Здесь могут возникнуть сложности с настройкой botа в telegram, если нет опыта его создания через Godfather, а также получения токена и API, которые надо отразить в скрипте:

#Telegram detailstokenurl="http://personeltest.ru/aways/api.telegram.org/bot<your API key>"chatid="<your chat id>"

Однако, после настройки, функционал будет работать как часы:

картинка


Настройка параметров камеры



По умолчанию в Rpi-web-interface камера при включении мониторинга движения сначала делает снимок, а потом начинает писать потоковое видео. Об этом написано здесь. Вопрос Is it possible to record still images using the RPi Cam Web interface on motion detect?

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

Поэтому настройки камеры надо поменять следующим образом:





То вместо ca 1 и ca 0 написать только im in.
Теперь в telegram будут прилетать практически все фото.

Настройка VPN


ссылка на оригинал картинки

Здесь были размышления по поводу нескольких вариантов.

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

Второй вариант обратный ssh-, vpn- туннель. То есть создается туннель с raspberry pi на существующий собственный vpn сервер. При этом vpn сервер должен иметь белый ip, чтобы raspberry pi до него дотянулась. Неплохой вариант, но тут надо приобретать этот белый ip, пробрасывать порт на роутере, за которым сидит сервер, решать вопрос с падением vpn. Несложно, но хлопотно.

Третий (на нем было решено остановиться) услуга vpn, в частности vpnki.

На сайте предлагается бесплатный 14-дневный период, далее vpn-туннели блокируются, если не приобрести платный пакет услуг:



Сами тарифы не кусаются, а подробные инструкции помогут пройти несложный путь настройки туннелей. Их понадобится минимум два один для raspberry pi, второй для устройства, с которого будет доступ (допустим, телефон на android). В нашем случае для raspberry pi использовался этот вариант настройки.

И вот тут ждет еще один неприятный подводный камень, связанный опять же с rc.local.

Если коротко то модем и vpn конкурируют за соединение ppp0 и в итоге его занимает тот, кто быстрее запустится. Более подробно вопрос описан здесь.

Выход не запускать vpn пока не запустится модем (не установит соединение ppp). Далее вручную поднять vpn через команду

sudo pon vpnki updetach

Опять же здесь не решатся вопрос с падением vpn. *Свое соединение модем (umtskeeper) при падении восстанавливает и сообщения в телеграм приходить будут в любом случае, а вот vpn не оживает. Так что опция покрутить головой может немного хромать при плохой связи со стороны raspberry pi.

На этом все. Есть еще мысли добавить на web-интерфейс сведения о балансе mts и vpn.

Вопросы и предложения приветствуются.
Подробнее..

Перевод Дайте собачке погулять автоматическое открытие двери при помощи Raspberry Pi

06.04.2021 00:08:46 | Автор: admin

Работа дома хороший вариант для многих из нас. Можно больше времени проводить с семьей (хотя бы теоретически), включая питомцев. Мой офис находится на втором этаже, так что я не всегда замечаю, когда собака хочет погулять. Конечно, можно поставить звонок и научить ее звонить, чтобы понимать, когда выпускать животное наружу. Но зачем, если можно придумать over-engineered решение? Технологий никогда не бывает много.

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

Что нужно для старта


Raspberry Pi 4 или Raspberry Pi 3 с источником питания.
Карта памяти объемом в 8 ГБ или больше с Raspberry Pi OS.
Raspberry Pi камера и кабель для обнаружения объектов.
Модуль широкоугольного объектива для малинки. Ну или любой другой модуль камеры, который может вам понадобиться все зависит от того, на каком расстоянии от двери будет установлена эта камера.
Динамики с 3,5 мм штекером. Можно использовать и мегафон было бы желание.
Монитор и клавиатура (по желанию) с HDMI и набором кабелей.

Как определить, когда питомец хочет на улицу при помощи малинки


1. Настройте Raspberry Pi. Если не знаете как это сделать, вот туториал.
2. Подключите камеру к малинке.
3. Активируйте камеру при помощи raspi-config. Для этого необходимо зайти под администратором и перейти к Interface Options > P1 Camera.
4. Перезагрузка.



5. Тестируем фокус камеры при помощи команд, указанных ниже. Понятно, что картинка видна только если монитор подключен к ПК. Если используется headless версия rasbian, то нужно использовать scp для отправки изображения на компьютер.

raspistill -o /home/pi/focus.jpg

6. Ставим git. Для загрузки кода и скриптов из удаленного репозитория нужен git (мануал ну очень подробно разжеван, чтобы его могли использовать даже зеленые новички прим. Переводчика).

sudo apt-get update && sudo apt-get -y install git

7. Клонируем репозиторй с нужным кодом в собственную директорию.

cd ~/
git clone github.com/rydercalmdown/pet_detector


8. Устанавливаем зависимости, виртуальное окружение и python зависимости.

cd ~/pet_detector
make install


9. Загружаем заранее обученные модели. В проекте используется модель YOLOv3, обученная на дата-сете COCO. Модель умеет распознавать практически любые объекты в доме и квартире включая котов и собак.

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

say this is a test


11. Редактируем файл /etc/rc.local для запуска скрипта. Сначала нужно открыть файл при помощи команды sudo nano /etc/rc.local, а затем добавить вот эту строку.

source /home/pi/pet_detector/env/bin/activate && cd /home/pi/pet_detector/src && python app.py &

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


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

Подробнее..

Перевод Facebook отвлекает от работы? Блокируем его при помощи настенного выключателя

26.04.2021 20:23:29 | Автор: admin

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

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

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

Что нам понадобится для проекта


  • Raspberry Pi Zero W, SD Card, блок питания.
  • Два однополюсных выключателя.
  • Распределительная коробка.
  • Пластина с рычажками переключателей.
  • Провода.
  • Отвертки.

Начинаем работу с Raspberry Pi


1. Настраиваем Raspberry Pi Zero W и подключаемся удаленно.
2. Обновляем/устанавливаем git, если ранее это не было сделано:

sudo apt-get update && sudo apt-get install -y git

3. Копируем код из репозитория ниже. Он будет управлять инструментом dnsmasq, нашим локальным DNS:

git clone github.com/rydercalmdown/internet_kill_switch

4. Запускаем команду установки из клонированной директории. Этот шаг позволяет установить все зависимости, инструмент dnsmasq и убедиться, что все работает:

cd internet_kill_switchmake install

5. Убедиться в работоспособности кода просто. Если все хорошо, появится статус Running зеленым цветом:

sudo systemctl status dnsmasq# Use Ctrl + C to exit

6. Запускаем ПО для того, чтобы окончательно убедиться в правильной работе установленного софта:

make run# Use Ctrl + C to exit

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



8. Свободные концы проводов припаиваем к малинке. Порядок пинов не имеет значения. Главное, чтобы один конец был припаян к пину GPIO, второй к земле. По умолчанию нужны пины 18 и 24, но это можно настраивать.



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



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




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

12. Открываем файл src/toggle_switches.py для редактирования и добавляем необходимые адреса сайтов. Вы можете добавлять или удалять переключатели, изменяя список SWITCHES и добавляя новые объекты класса SwitchConfig. Допустимые параметры это номер пина BCM, за которым следует список сайтов, которые нужно заблокировать:

# Example: The switch connected to BCM pin 18 blocks social media, and the switch connected to BCM pin 24 blocks video websitesSWITCHES = [   SwitchConfig(18, ['facebook.com', 'instagram.com']),   SwitchConfig(24, ['netflix.com', 'youtube.com', 'vimeo.com']),]

13. Проверяем, как все работает. При запуске сервис показывает IP малинки:

cd ~/internet_kill_switchmake run# IP Address is 10.0.0.25

14. Конфигурируем DNS, используя полученный IP. Это можно сделать на уровне роутера или в конфигурации операционной системы.

15. Проверяем работу нашего выключателя. Если все окей, то тумблером можно блокировать или активировать сайт.


16. Теперь все подтверждаем, введя следующий код. Здесь вместо google.com вставляем ресурс, который хотим блокировать:

# When the switch is offdig +short google.com172.217.164.238# When the switch is ondig +short google.com127.0.0.1

17. Редактируем файл /etc/rc.local file. Он определяет поведение системы после перезагрузки малинки:

sudo nano /etc/rc.local# Add this line before the very last linecd /home/pi/internet_kill_switch/src && sudo ../env/bin/python app.py &

18. Устанавливаем выключатель в любом удобном месте и наслаждаемся его работой.


Проект очень простой, но фановый. Любому гику нечто подобное придется по душе. Систему можно менять/усложнять по своему вкусу. Если у вас есть идеи, как это сделать, поделитесь ими в комментариях, будет интересно!

Подробнее..

Самодельный стратостат

30.04.2021 12:16:20 | Автор: admin

result_lowres


Допустим, вы интересуетесь космосом, но космос для вас недоступен. Выше 10км не подняться, а посмотреть "что там?" очень хочется. По классификации NASA нижняя граница космоса начинается на 100км от поверхности Земли. Эта статья будет не совсем про космос, но про возможность создания своего стратосферного зонда с нуля. Я много видел примеров успешного запуска и несколько статей на Хабре, но почти все они это отчеты. Я же хочу оставить статью, которая сможет претендовать на "complete guide" для юных покорителей. Запаситесь терпением и безлимитным интернетом будет много текста, картинок и даже пару видео. Это был долгий путь для нас, но я намерен сделать его не таким изнурительным для всех желающих. Поехали?


Вступление


В этом проекте участвовало довольно много людей (навскидку ~10). Один бы я, разумеется, все это не потянул. Да и с друзьями интересней. У каждого была своя незаменимая роль в этом деле. А так как я организатор, вдохновитель и спонсор всего проекта, то мне выпала честь говорить от имени каждого участника.


Мое непосредственное участие касалось:


  • сборки электроники
  • программирования
  • финансирования
  • организационных моментов
  • подведения итогов

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


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


Давайте посмотрим на распределение времени по активностям:


project_length


Ожидание Ожидание служб доставки, ожидание ответа госслужб и, наконец, ожидание весны. Так как никто не хотел искать упавший зонд в ночи. А в регионе запуска (Северо-Запад) зимой темнеет очень рано. Ожидание съело 70% времени. Всегда закладывайте побольше времени в этот сегмент. Ну что я вам рассказываю? Все тут не первый день на IT женаты ;-)


Несмотря на довольно большую задержку нам удалось довести проект до успешного (!) завершения. И сейчас я расскажу вам как.


Список оборудования и компонентов


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


  1. Raspberry Pi 4 Model B
  2. SPOT Trace GPS Tracker
  3. Шар-зонд
  4. Фал (канат)
  5. Парашют
  6. Гелий
  7. GoPro 7 Black (+Micro SD card 128GB)
  8. Powerbank x2 (20000 mah)
  9. RPI Sense Hat
  10. LTE GPS HAT LTE / GPRS / GPS SIM7600E-H for Raspberry Waveshare 14952
  11. TEMPer Gold USB Temperature Sensor
  12. RPI Tall Case
  13. RPI Mounting Kit

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


Raspberry Pi 4 Model B


Резонный вопрос: почему не Arduino? Простой ответ потому что я не умею паять \()/


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


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


SPOT Trace GPS Tracker


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


В чем проблема большинства трекеров, которыми завален любой радиорынок? Давайте подумаем: GPS трекер получает свои координаты с помощь GPS спутников (ну еще компенсирует погрешность по наземным станциям) это замечательно, спутники покрывают всю поверхность Земли. Также очень замечательно, что наш трекер будет знать своё местоположение. Но нас то рядом с трекером не будет! Как он должен передать свои координаты в наш ЦУП? Самое массовое решение GSM сети. Иначе говоря покупаете симку, вставляете в трекер и он шлет вам смс-ки (ммс-ки, или стикеры в телегу, не важно). Я видел примеры успешных запусков с таким подходом. Но если честно, я пару раз выезжал за пределы КАД и готов вас уверить во многих местах сотовой связи нет совсем! Если наш зонд упадет в такой зоне провал операции, начинай сначала.


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


Так что еще раз отнеситесь к выбору поискового трекера максимально ответственно!


Шар-зонд


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


Фал (канат)


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


Парашют


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


Гелий


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


Количество стандартных баллонов по 40л которое нам понадобится мы считали так:


$B = V_s\div V_h$


Где $V_s$ объем шара в $м^3$, $V_h$ объем гелия при давлении 1атм в $м^3$


$V_s = 4\div3 * \pi * (D\div2)^3$


$V_h = V_b * P_b$


Где $D$ диаметр шара в метрах.


$V_b$ объем баллона в $м^3$. Мы взяли его равным $40\div1000$. Где 40 это известный объем баллона в литрах.


$P_b$ известное давление в баллоне в атмосферах.


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


Фух, надеюсь ничего не напутал пока переносил формулы из Excel.


RPI Sense Hat


Для любителей RPI это довольно известная вещь. Вкратце поясню это сенсорный мультитул для RPI. Имеет на борту следующее:


  • Датчик температуры (2 штуки)
  • Датчик давления
  • Датчик влажности
  • Гироскоп
  • Магнетометр
  • Компас
  • Акселерометр
  • LED дисплей

То что надо в одном флаконе.


LTE GPS HAT LTE / GPRS / GPS SIM7600E-H for Raspberry Waveshare 14952


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


А использовали мы ее только для показаний GPS (даже без GSM). Дело в том, что трекер то у нас есть (поисковый, не подключается к RPI), но хотелось бы еще к чему-то привязать телеметрию. И, желательно, привязать ее к координатам и времени. Из-за этого и появился еще 1 трекер, но уже подключенный к RPI. Показания с него (координаты, время, курс, скорость, высота) пишутся в лог и служат точкой синхронизации с показаниями всех сенсоров.


Его достоинство он имеет выносную антенну. А это очень важно, когда на борту 2 приемника GPS и 1 передатчик (поисковый трекер). Производители Spot Trace советуют размещать их трекер на расстоянии не меньше 30см от других GPS устройств, во избежание помех. Так что тут пригодилась выносная антенна, которую мы просто кинули за борт.


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


TEMPer Gold USB Temperature Sensor


Внешний градусник (для замера температуры внутри использовали Sense Hat).


Его достоинства: он подключается в порт USB, есть рабочий тулсет для проверки (под Win)


Его недостатки: нижний предел измерения $-40^oC$. Сразу скажу этого оказалось маловато; второй недостаток документация. Ее нет. Пришлось реанимировать проекты 5-летней давности под похожие модели и написанные на разных языках. В итоге поскрещивал ежа с ужом и немного поколдовал (тяжела и неказиста жизнь простого программиста). Но, в итоге, все работает надежно, как швейцарские часы. В разделе с кодом я поясню где был тонкий момент.


RPI Tall Case


Это крутая штука, которая доставляет мне эстетическое удовольствие.


Красивый, алюминиевый, высокий кейс для RPI 4. Разумеется, перед заказом и прикинул высоту RPI с обеими шапками (Sense + GPS) чуть-чуть не влезает при плотно закрытой крышке. Но, используя spacers (извините, не знаю русского названия), можно приподнять верхнюю крышку немного, для вентиляции.


Из проблем с ним было только одно один из разъемов GPS HAT сильно выпирал за границы платы и не влезал в кейс. Разъем пришлось нежно демонтировать кусачками.


Ну только посмотрите, как элитно стал выглядеть наш самописец:

tall_case_1
tall_case_2
tall_case_3


RPI Mounting Kit


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


Конструкция


Общая конструкция


Для начала рассмотрим общую конструкцию аппарата (масштаб не соблюден!):


general_scheme


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


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


Полезная нагрузка


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


  1. Предельная масса не более 2.5кг (для нашего объема шара)
  2. Защита от воды + плавучесть (облака, дождь, падение в озеро и т.п.)
  3. Хорошая терморегуляция (RPI не должна перегреться, а аккумуляторы не должны замерзнуть)

Посовещавшись с нашим конструкторским бюро, было решено делать куб со стороной 250мм из экструдированного пенополистирола (куплен в строительном магазине листами). Верхняя крышка двустворчатая из того же материала. В боковой стенке вырезано отверстие под объектив GoPro. Он легкий, имеет положительную плавучесть, достаточно прочный и не пропускает воду (швы, разумеется, проклеили):


payload_1
payload_2


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


payload_scheme


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

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


payload_5


Вент. отверстия также используются для крепления фала от парашюта:


payload_3
payload_4


Конфигурация Raspberry PI 4B


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


Скачать Raspberry PI Imager, выбрать нужную OS, свою SD карту и нажать WRITE:


Raspberry PI Imager


OS было решено взять максимально облегченную. Десктоп и рюшечки нам не нужны, только консоль, только хардкор. Выбор пал на Raspberry PI OS Lite 32-bit:


Raspberry PI Imager


SD карта для Raspberry PI


Хоть в официальной документации толком и не указан максимально допустимый объем карты памяти с которой RPI сможет загрузиться (но указан минимальный 16GB и, как-то намеками указана возможность загрузки с 256GB с определенного дистрибутива), быстрый гугл показал, что лучше взять 32GB. На этом и остановились. Класс карты не сильно критичен, но разница в цене между Class 4 и Class 10 мне показалась не критичной, так что почему бы не взять ту, что побыстрее? Тем более что это, в дальнейшем, открывает возможность скидывать поток видео с GoPro на карту. Но до этой реализации мы не дошли и, честно говоря, я пока не придумал зачем это надо. Карту взяли SanDisk Extreme 32GB типа такой


Подключаем RPI к компу


После того как OS записана на карту и карта вставлена в слот на RPI, можно включить RPI просто подав на него питание. Питается это чудо через порт USB-C, так что озаботьтесь проводом заранее (я использовал 1 из павербанков).


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


И что?

Да, операционку то мы поставили без десктопной оболочки, да и мониторы с клавиатурами мы подключать не планировали, и Wi-Fi там еще не настроен.
Так что я немного присел на стул на полчаса.


(


Честно говоря, бежать в магазин за проводом\переходником mini HDMI у меня не было никакого желания. Снова запускаем гугол и видим, что ситуация не безвыходная: можно подключить RPI к компу через USB и через него же наладить SSH. И, хотя тот же гугол говорит обратное, RPI при этом будет и питаться от компа и эмулировать сетевое соединение через один и тот же USB кабель. Нуштош, вытыкаем наш кабель из павербанка и подключаем его в USB компа. Снова замигали лампочки, RPI загрузился и, судя по статусу лампочек у него все отлично.


Но по SSH все еще не подключиться. Курим вот эту страницу. Нас интересует headless mode:


Enable SSH headless mode


Ага, надо поместить пустой файл с именем ssh в корень SD карты. Извлекаем карту из RPI и вставляем ее в комп (предварительно обесточив устройство). Делаем. Пробуем снова. Hostname, User, Password указаны там же, в подразделах для каждой OS. Но, честно говоря, информация там немного устаревшая. Например для Win10 указано, что надо использовать IP вместо имени хоста. Это не так. Забегая вперед, скажу, что и hostname: raspberrypi.local тоже заработал без приключений.


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

Итого. Что мы имеем по подключению по SSH:


Hostname: raspberrypi.local


User: pi


Password: raspberry


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


(


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


Итак, если вкратце, нам нужно будет поменять 2 файла на SD карте: config.txt && cmdline.txt (могут быть без расширений, я уже не помню). Вынимаем карту из RPI, подключаем к компу, находим первый файл и добавляем в конце строчку dtoverlay=dwc2:


dtoverlay


Теперь ищем второй файл (cmdline.txt).


По поводу второго файла небольшое отступление мне его менять не пришлось и так все было как надо. Но мало ли \_()/

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


cmdline.txt


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


ssh pi@rasberrypi.local

(да, кстати, озаботьтесь наличием SSH клиента на рабочем компе, если вдруг у вас его еще нет)


На этот раз все должно пройти как по маслу (извините, этого скрина тоже не сохранилось). Мы попадем в bash консоль на нашей Raspberry PI 4B по USB и теперь можем наворотить там дел ;-) А первое дело будет обеспечить себе максимально удобные условия работы, иначе говоря Wi-Fi!


Включаем Wi-Fi на RPI


Тут совсем все просто и без неожиданностей. В RPI OS входит утилита конфигурации через которую можно сделать все (или почти все) что может понадобиться в дальнейшем. Называется она raspi-config и ее использование, в частности в контексте настройки вафли неплохо описано в официальной документации тут.


Подключаемся по кабелю в SSH сессию нашего черного ящика, запускаем из консоли:


sudo raspi-config

Всего несколько клацаний кнопками и можно отсоединять наш USB кабель от компа и подключать его к павербанку (картинки из интернета):


raspi-config wi-fi setup


raspi-config wi-fi setup


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


Для удобства также советую добавить SSH ключи. Надеюсь не надо объяснять как это делать, но если вдруг, то вот отличный тутор от DigitalOcean

Сборка .NET Core проекта под RPI


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

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


wtf


А почему не питон??

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


Так что стереотипы прочь будем ваять простенький скрипт на шарпе (зря нам что ли кроссплатформу завозили)! Я буду показывать всё на примере своего проекта для логирования всех показателей. Кто захочет может использовать свой "hello world", кто не захочет вот исходники на гитхабе


Бытует мнение, что для того, чтобы завести что-то на dotnet, надо для начала этот самый dotnet установить. На самом деле это не так. Dotnet умеет паковать свой CLR в приложение для целевой платформы. Для этого у dotnet cli есть флаг --self-contained. Так же нам потребуется указать какой конкретно рантайм мы будем использовать при помощи параметра -r linux-arm. Ну и фреймворк укажем, чего уж там. Итого полная команда для сборки самодостаточного dotnet приложения (не требующего установки dotnet runtime на целевую машину) будет выглядеть так:


dotnet publish RpiProbeLogger\RpiProbeLogger.csproj --self-contained -r linux-arm -f netcoreapp3.1 -c Release

На выходе у нас получится исполняемый файл под linux arm со всеми зависимостями. Нам останется только скопировать все содержимое директории на Raspberry по SSH, сделать файл исполняемым (не обязательно) и, собственно, запустить (подробнее в разделе про CI/CD):


chmod +x /home/pi/RpiProbeLogger/RpiProbeLogger./home/pi/RpiProbeLogger/RpiProbeLogger

Если кто-то крутит носом от self-contained приложений ничего страшного, вариант с установкой рантайма и фреймворка (ну мало ли кто-то захочет еще и билдить на распберри) на RPI тоже допустим и прекрасно работает проверено! Вот статья которую я лично использовал (в ходе экспериментов).


CI/CD для Raspberry


Немного громкое название, но смысл тот-же приложения мы писать умеем, надо теперь их собирать под целевую платформу и как-то их туда доставлять. Тут нам поможет его величество PowerShell (linux-like товарищи легко заменять его на bash, sh, etc по вкусу. Это не принципиально).


Весь скрипт находится в корне репозитория и называется buildAndDeploy.ps1. Общий алгоритм такой:


  1. Подключиться к RPI по SSH для выполнения команд
  2. Установить SFTP сессию для работы с файлами
  3. Собрать наше приложение
  4. Скопировать билд на RPI
  5. Установить и включить сервис нашего приложения (чтобы запускался автоматически при загрузке RPI)

SSH


Поехали по очереди: с SSH/SFTP нам сильно поможет модуль для Powershell Posh-SSH. На мой взгляд с этим модулем все хорошо, кроме одного почему-то документацию по нему приходится искать по всему интернету и собирать по крупинкам. Может автор посчитал, что его API и ежу понятно, но вот мне было не очень понятно. Примеры использования с описаниями нашлись тут. Нас же сейчас интересует установка SSH сессии и делается она вот так:


$sshSession = New-SSHSession -Computer raspberrypi.local -Credential $credentials -KeyFile $rsaKeyFile

Сама сессия сохраняется в переменную $sshSession. Обратите внимание на 2 переменные: $credentials и $rsaKeyFile: мы же не хотим использовать привет из 90-х пароли? Мы будем использовать RSA ключи! И как это делать в случае Posh-SSH мне пришлось поискать. Сначала объясню немного про креденшиалс в Powershell есть такой командлет Get-Credential он занимается тем, что нативными средствами запрашивает пару логин-пароль у пользователя и возвращает их в качестве объекта:


$credentials = (Get-Credential pi)

В Win10 это выглядит так:


Get-Credential


Как вы уже догадались, первым параметром можно сделать пре-ввод логина pi. Нам это подходит. Теперь тонкий момент про Posh-SSH: он имеет параметр -KeyFile куда передается путь до приватного SSH ключа. НО! Приватный ключ может иметь passphrase а такого параметра Posh-SSH не имеет. Оказывается, и это пришлось поискать, Posh-SSH будет в качестве passphrase использовать пароль из объекта $credentials и это не слишком очевидное поведение, но именно из-за этого и затевалось использование Get-Credential. Что ж, этого вполне достаточно, чтобы подключиться по SSH к RPI. Полный скрипт находится в репозитории, а мы двигаемся дальше.


SFTP


Никаких откровений тут не скрыто, тот же Posh-SSH, те же Credentials, немного другое имя команды:


$sftpSession = New-SFTPSession -Computer raspberrypi.local -Credential $credentials -KeyFile $rsaKeyFile

Сразу укажу команду для копирования файлов (да, всего в одну строчку деплоим, без хитростей):


Set-SFTPFolder -SFTPSession $sftpSession -RemotePath '/home/pi/RpiProbeLogger' -LocalFolder "RpiProbeLogger\bin\$($c)\netcoreapp3.1\linux-arm\publish" -Overwrite

Да, называется она Set-SFTPFolder, не спрашивайте почему я не знаю. Можно догадаться, что копирует она содержимое исходной директории в целевую директорию, а параметр -Overwrite указывает что содержимое целевой директории будет перезаписано в случае совпадения имен файлов. Параметры -RemotePath и -LocalFolder ясны без пояснений. Единственное, что может привлечь внимание $($c) это передача параметра командной строки, который содержит тип сборки: Release или Debug. Он также используется в следующем пункте сборке приложения.


Сборка


Итак, как уже было описано в разделе про сборку .net под arm наша команда сборки будет выглядеть следующим образом:


dotnet publish RpiProbeLogger\RpiProbeLogger.csproj --self-contained -r linux-arm -f netcoreapp3.1 -c $c

Единственная разница тут это параметр $c который мы будем подставлять из параметров командной строки (Release, Debug, etc) на самом деле можно и не параметризовывать это, а захардкодить "Release" на любителя.


Включение\запуск сервисов


Все тот же Posh-SSH имеет еще одну полезную команду: Invoke-SSHCommand. С помощью нее мы выполним установку systemctl сервиса. Unix-like ребятам тут делать нечего, для остальных немного пролью свет что это.


systemctl это системная служба для управления службами (да-да). Она запускается автоматически и запускает, останавливает, управляет пользовательскими службами, основываясь на специальных файлах .service. Такой файл присутствует и у меня в репозитории в подпапке с проектом probelogger.service и вот его содержимое:


[Unit]Description=Probe Logger Service[Service]User=rootWorkingDirectory=/home/piExecStart=/home/pi/RpiProbeLogger/RpiProbeLoggerExecReload=/bin/kill -HUP $MAINPIDKillMode=processRestart=on-failureType=execStandardOutput=syslogStandardError=syslogSyslogIdentifier=RpiProbeLogger[Install]WantedBy=multi-user.target

Я не буду врать, говоря что мне тут понятно абсолютно все, но, в основном, это читается как-то так:


  1. запускать службу от пользователя root (да, секурность не секурность, я понимаю. но рут привелегии потребовались для чтения данных с порта USB. Об этом позже)
  2. рабочая директория такая-то
  3. запускать тот-то файл
  4. для перезапуска сервиса в случае катастрофы использовать команду kill
  5. перезапускать в случае падения
  6. логи сохранять в syslog

Далее пара команд Posh-SSH. Включение сервиса (означает что он будет запускаться автоматически при запуске RPI):


Invoke-SSHCommand -Command 'sudo systemctl enable /home/pi/RpiProbeLogger/probelogger.service' -SSHSession $sshSession

Немедленный запуск сервиса (не обязательно же перезапускать RPI для нашего логгера, мы же не драйвера пишем):


Invoke-SSHCommand -Command 'sudo systemctl start probelogger.service' -SSHSession $sshSession

Переменная $sshSession нам знакома из раздела про SSH сессию это именно та самая сессия. Файл probelogger.service в репозитории.


Что ж, на этом пожалуй все, что касается билда и доставки нашего самописца на RPI. Напоминаю, весь powershell-скрипт в корне репозитория (buildAndDeploy.ps1). Не совсем автоматизировано запускать нужно ручками, но вполне себе "continuous" билди хоть после каждого коммита. Можно было бы конечно поднять pipeline на основе этого на каком-нибудь Azure DevOps или кто что любит (благо выбор сейчас из десятка платформ присутствует), но я посчитал это оверкилом для таких задач. Побилдим руками, не сломаемся.


Команда билда и деплоя выглядит вот так:


.\buildAndDeploy.ps1 -enableService -runService

По умолчанию билдится Debug версия (нам же для разработки и отладки надо). Можно добавить параметр -c=Release если необходимо собрать финальную версию.


Отладка в Visual Studio


Это та часть, где время стерло бОльшую часть информации. Но поверьте тут все просто и прозрачно, а на MSDN есть даже статья по отладке кода на RPI для VSCode и Visual Studio VS Remote Debug.


Я опишу буквально в 2-х словах для своего случая (Visual Studio):


  1. Открываем окно удаленного дебага: Debug -> Attach to Process
  2. Выбираем Connection Type: SSH
  3. Вбиваем в поле Connection Target наш pi@rasberrypi.local
  4. Ищем в списке наш процесс dotnet (иногда может потребоваться включить Show processes from all users, зависит от вашей конфигурации)
  5. Жмем Attach и мы в деле!

Breakpoints, Watches, Locals, Immediate Window, Threads все работает.


Программирование


Сразу ссылка на репозиторий с исходниками GitHub


Я очень долго откладывал этот раздел для написания, т.к. софт был написан год назад и я почти забыл все те ужасы, которые мне пришлось побороть, сражаясь с китайскими комплектующими. Но попробуем хоть что-то наковырять. Сейчас я лишь заменил project reference на nuget package, т.к. зачем-то я скачивал исходники проекта нугет пакета (надеюсь просто так, сейчас солюшен билдится).


Как и в системе "театр-вешалка", dotnet приложение начинается с конфигурации. Конфигурации DI, логгеров и вот этого всего. В нашем случае в функции Main:


static async Task Main(string[] args)        {            var host = new HostBuilder()                .ConfigureServices((hostContext, services) => {                    services.AddHostedService<RpiProbeHostedService>();                    services.AddSingleton<SerialPort>((_) => {                         var serialPort = new SerialPort("/dev/ttyS0", 115200);                        serialPort.ReadTimeout = 500;                        serialPort.WriteTimeout = 500;                        serialPort.NewLine = "\r";                        serialPort.Open();                        return serialPort;                    });                    services.AddTransient<GpsModuleStatusCommand>();                    services.AddTransient<GpsModuleCoordinatesCommand>();                    services.AddSingleton<RTIMUSettings>((_) => RTIMUSettings.CreateDefault());                    services.AddSingleton<RTIMU>((provider) => {                        var muSettings = provider.GetService<RTIMUSettings>();                        return muSettings.CreateIMU();                    });                    services.AddSingleton<RTPressure>((provider) => {                        var muSettings = provider.GetService<RTIMUSettings>();                        return muSettings.CreatePressure();                    });                    services.AddSingleton<RTHumidity>((provider) => {                        var muSettings = provider.GetService<RTIMUSettings>();                        return muSettings.CreateHumidity();                    });                    services.AddTransient<SenseService>();                    services.AddTransient<ReportService>();                    services.AddSingleton<StatusReportService>();                    services.AddSingleton<TemperService>();                })                .ConfigureLogging(logConfig =>                {                    logConfig.SetMinimumLevel(LogLevel.Information);                    logConfig.AddConsole();                })                .Build();            await host.RunAsync();        }

Как видите, мы пошли путем использования IHostedService как основной крутилки нашего логгера, настроили SerialPort для доступа к GPS HAT (зачем-то я его инжектю в hosted service, вместо того чтобы использовать там GpsMuduleCommand, очевидно проглядел тогда), добавили наши сервисы для доступа к SenseHat в контейнер DI и настроили логирование в консоль. Тут все host.RunAsync()!


Не буду приводить тут содержимое каждого файла, кому надо посмотрят на гитхабе. Тут обрисую основную идею. Вся она описана в нашем хостед сервисе RpiProbeHostedService. Содержммое метода StartAsync:


public Task StartAsync(CancellationToken cancellationToken){    var gpsStatus = _gpsModuleStatusCommand.GetStatus();    if (gpsStatus?.Enabled == false)        _gpsModuleStatusCommand.SetStatus(                new GpsModuleStatusResponse                {                    Enabled = true,                    Mode = GpsModuleModes.Standalone                });    while (true)    {        if (cancellationToken.IsCancellationRequested)            return Task.CompletedTask;        var gpsData = _gpsModuleCoordinatesCommand.GetGpsData();        if (gpsData != null || _reportService.ReportFileCreated)        {            var senseData = _senseService.GetSensorsData();            var outsideTemperatureResponse = _temperService.ReadTemperature();            try            {                _reportService.WriteReport(senseData, gpsData, outsideTemperatureResponse?.OutsideTemperature);            }            catch (Exception ex)            {                _logger.LogError(ex, "Error writing report");            }        }        Thread.Sleep(1000);    }}

Итак, для начала нам нужно узнать в каком состоянии наш GPS HAT. Т.к. тот факт, что он включен еще не означает, что включен непосредственно GPS модуль. Если GPS выключен включаем его и идем дальше.


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


Затем собираем данные с SenseHat и внешнего градусника и записываем это все в файл-репорт. Вот и вся нехитрая логика.


С SenseHat проблем не было вообще никаких. А сейчас, при написании статьи, оказалось что с тех пор MS даже добавила его поддержку в свою iot library. Тут подробнее MSDN.


Проблемы, как вы догадались, были с внешним градусником. Я перепробовал с десяток разных проектов на разных языках (Python в их числе). Но ни один не заработал именно с этим градусником. Пару раз было очень близко, но видимо моя модель чуть-чуть отличалась и показания отрицательных температур были неверны. Это сейчас, с остывшей головой, я понимаю если проблема в месте, где присутствует минус надо смотреть на тип данных. И таки да, замена byte на sbyte сделала свое дело. Но тогда, год назад, я был на грани отчаяния. Метод ReadTemperature:


public OutsideTemperatureResponse ReadTemperature(){    if (!_controlDeviceOpen || !_bulkDeviceOpen)        OpenDevices();    var response = new OutsideTemperatureResponse();    try    {        _bulkStream.Write(_tempCommand);        var rawResult = _bulkStream.Read();        response.OutsideTemperature = ((rawResult[4] & 0xFF) + ((sbyte)rawResult[3] << 8)) * 0.01;        _statusReportService.DisplayStatus(response);        return response;    }    catch (Exception ex)    {        _logger.LogError("Error reading outside temperature", ex);        _statusReportService.DisplayStatus(response);    }    return null;}

Метод хоть и небольшой, но содержит парочку magic numbers. Знаете где вы найдете их объяснение? Нигде. Это все наковыряно и проверено (методом проб и ошибок) из разных проектов. Так что если у вас такой градусник поздравляю, ваши страдания окончены.


Не стоит забывать, что наш самописец не подключен к монитору и нам надо бы как-то понимать все ли на нем работает штатно. Для этих целей я использовал LED матрицу на SenseHat. Она небольшая, всего 8x8, так что выводить туда картинки не получится. Но получится мигать/светить лампочками. Более чем достаточно в столь аскетичном устройстве. Код метода DisplayStatus:


public bool DisplayStatus<T>(T status) where T : IResponse{    try    {        var currentStatus = _currentStatuses.FirstOrDefault(c => c.Cell.Row == status.StatusPosition.Row                                                            && c.Cell.Column == status.StatusPosition.Column);        _currentStatuses.Remove(currentStatus);        _currentStatuses.Add(new CellColor(status.StatusPosition, statusToColorMapping[status.Status]));        Show();        return true;    }    catch (Exception ex)    {        _logger.LogError(ex, "Error displaying status on LED");        return false;    }}

Видим, что я инкапсулировал координаты лампочки, которой надо посветить, в класс ответа от конкретной функции (GPS ответ, Sense ответ, ответ от внешнего градусника и т.п.). Все эти response реализуют интерфейс IResponse:


public interface IResponse{    public bool Status { get; }    public Cell StatusPosition { get; }}

Соответственно, обязаны предоставлять статус в формате "Успех\провал" и координаты ячейки LED куда его поместить, и делают это на свое усмотрение. Не буду говорить что это идеальный дизайн, но, как минимум год назад, мне он показался подходящим. Вот, например, как реализует свой статус ответ от SenseHat:


[Ignore]public bool Status => FusionPose.HasValue &&                        FusionQPose.HasValue &&                        Gyro.HasValue &&                        Accel.HasValue &&                        Compass.HasValue &&                        Pressure.HasValue &&                        PressureTemperature.HasValue &&                        Humidity.HasValue &&                        HumidityTemperature.HasValue;[Ignore]public Cell StatusPosition => new Cell(0,2);

Итого у нас есть 5 подсистем:


  1. GPS модуль: вкл\выкл
  2. GPS модуль: координаты получены и прочитаны
  3. SenseHat
  4. Внешний градусник: показания есть\нет
  5. Лог-файл: координаты имеются\нет

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


GPS HAT тоже не вызвал особых проблем, насколько я помню. За исключением новости (для меня), что для работы с SerialPort нужны привелегии root и его ответ пришлось немного попарсить:


private string[] ParseCoordinatesResponse(string rawResponse) =>    rawResponse        .Split(Environment.NewLine)        .FirstOrDefault(s => s.StartsWith("+CGNSSINFO:"))?        .Replace("\r", "")        .Replace("+CGNSSINFO:", "")        .Trim()        .Split(',');private GpsModuleResponse FormatResponse(string[] parsedResponse) =>    new GpsModuleResponse {        Latitude = $"{parsedResponse[5]}{double.Parse(parsedResponse[4]) / 100}",        Longitude = $"{parsedResponse[7]}{double.Parse(parsedResponse[6]) / 100}",        DateTimeUtc = DateTime.ParseExact($"{parsedResponse[8]} {parsedResponse[9]}", "ddMMyy HHmmss.f", null),        Altitude = double.Parse(parsedResponse[10]),        Speed = double.Parse(parsedResponse[11]),        Course = double.Parse(parsedResponse[12])};

Положение всех компонентов ответа указано в документации.


Еще 1 момент EventBased подход я решил не использовать, но он вроде работает и методы для него (DataReceived) остались в коде. Честно говоря, не помню почему я так решил, но думаю причины были.

Перейдем к финансам.


Бухгалтерия


Быстренько пробежимся по моей нелюбимой части сколько все это чудо стоит. В этот манускрипт не попали: стоимость камеры (она у меня уже на тот момент и так была), стоимость спасения и всякая мелочевка, типа клея и винтиков. Эти позиции сильно субъективны.


costs


Внизу 2 суммы: одна за все позиции, вторая (Minimum) это только если запускать одну камеру без RPI и всего с ней связанного. Как видите, поисковый трекер вместе с подпиской занимают ~30% цены всего аппарата. Так что если найдете вариант подешевле это хороший повод сэкономить.


Также, в процессе моих экспериментов, я накупил много лишнего это красная секция в табличке. Это то, что совсем не пригодилось. Желтая секция это то, без чего можно было бы обойтись. Эдакая ни вам, ни нам середина. Запуск только лишь зеленой секции означает запуск только камеры и RPI с Sense Hat. Мы запускали зеленую + желтую.


Конечно тут есть простор для оптимизации. Например, я считаю, что вместо GPS HAT можно было бы найти что-то подешевле, за парашют мы тоже явно переплатили, карту памяти для RPI можно смело брать 16Гб (а то и меньше), ну и так далее. Но это все было в первый раз, хотелось подстраховаться отсюда и цена соответствующая.


Подготовка к запуску


Прежде всего надо понять где запускать? Если вы житель мегаполиса, у меня для вас плохие новости нигде. Ладно шучу, не все так плохо =)


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


Для этого можно воспользоваться сервисом FPLN: включаем в настройках показ всего что нам нужно и ищем глазами свободное место. Вот чисто для примера такое (в зависимости от предполагаемой траектории):


launch_options


Откуда нам взять предполагаемую траекторию? Тоже есть сервис. CUSF Landing Predictor 2.5. Вбиваем наши варианты и параметры и смотрим что будет:


route_predicted


Совмещаем картинку с FPLN и смотрим подходит/не подходит? Если нет ищем новое место, если да поздравляю.


Для прогнозирования ветра можно использовать Windy. CUSF Landing Predictor так же учитывает направление и силу ветра на выбранное время и координаты. Как вспомогательное средство, можно использовать FlightRadar чтобы помониторить в реальном времени самолеты в предполагаемом районе запуска.

Ну что. Если вы дошли до этого этапа, значит бОльшая часть пути позади. Впереди запуск!


Запуск


Со слов участников: Выбрали точку, заправили тарантас, взяли пару баллонов гелия и двинули на место. Описывать тут особо нечего. Имейте только ввиду шар такого размера с гелием имеет неплохую подъемную силу! Так что придерживайте его пока будете надувать (а лучше привяжите временно).


В этой операции использовались:


  1. Клапан Голубева
  2. Переходник под него
  3. Шланг
  4. Переходник со шланга на баллон 3/4 дюйма

Просто вставлю пару фото, чтобы дать понять масштабы:

launch_2
launch_1


Убедитесь что GPS трекер включен! Без него вся эта затея будет провалена сразу после запуска. Далее подключаем питание к RPI и GoPro. Ждем успешный статус на RPI, включаем запись видео на камере, запаковываем короб, крепим к парашютному фалу, парашют к шару и Поехали!


Поиск и спасение


Ооооо, это был самый волнительный и насыщенный этап! Как только аппарат оторвался от земли (а точнее от рук) я, как оператор ЦУП, затаился в ожидании первых координат от поискового трекера.


operator


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


route_spot


Расстояние между конечными точками ~100км. Хотя расчетное было около 200км. Наш зонд немного не долетел. Но с этим разберемся в результатах.


Наивысшая точка (F) по этим показаниям 9800м. Дело в том, что у нашего поискового трекера предел измерения высоты 10км. Так что это еще не значит, что зонд выше не поднимался, нет. Просто после этой точки он пропал! Я, разумеется, ожидал этого и ждал, и ждал, и ждал. Ну сколько он может там летать над 10км? Ну час, ну максимум два. Учитывая, что расчетное время всего полета было 2ч 25мин. Но обратите внимание на дату и время в этой точке (верхняя часть):


f_point


А теперь взглянем на следующую точку G:


g_point


Где тебя носило больше суток ( )(._.`)?! Я все морги-больницы обзвонил все это время не спал и мониторил показания (да что уж там все мониторили). Но, видимо, условия для передачи сигнала были не благоприятные. Хорошо что запас автономности у этого трекера очень хороший он до сих пор передает координаты на тех же аккумах. Ок, в итоге нашелся, посмотрим где упал?


Упал он на краю лютого болота в 4-х километрах от ближайшей дороги. На фотках это не так видно, но поверьте ребята там были (дважды) болото непроходимое.


swamp_distance


Ближайшая дорога:


swamp_road


Край болота:


swamp_edge


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


Вертолет, как водится, не на каждом углу припаркован. Более реалистичный вариант вездеход! Начали шерстить интернеты, друзей и соцсети. Не скажу, что прям на каждом шагу раздают вездеходы в аренду в поисках мы провели несколько дней. Наконец вышли на одних ребят, Питерские производители вездеходов, которым нужен был, внезапно, демо-ролик их детища :3 И они согласились предоставить их вездеход с командой, если мы оплатим им сутки работы видеографа (так они его назвали). Что ж, из альтернатив был только другой вездеход, но почти вдвое дороже. Так что мы начали соглашаться. Ребята подготовили свой вездеход (все это время поисковый трекер передавал статусные сигналы раз в сутки, так что мы были вполне спокойны: его не украли медведи и он не утонул) и мы получили вот это:


awd


Согласитесь, выглядит, как то, что надо!


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


awd_result


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


Результаты


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


result_hires


Разумеется все кинулись проверять камеру. Это фото это один из последних кадров (я выбрал покрасивей) из заснятого видео. Вообще, по расчетам, запаса аккумулятора камеры должно было хватить еще и на приземление и на полежать немного. Но, как видите, не хватило она записала всего 25 минут видео (4k60fps), из которых 7 на земле перед запуском. Мы строили разные теории почему так произошло. В итоге, поковырявшись уже дома с оборудованием, выяснили: был сломан USB порт на павербанке для камеры. В какой момент он был сломан неизвестно. Но пока основная версия такова: подключили и включили камеру, как-то сломался порт, камера продолжала работать от внутреннего аккумулятора пока он не сел. Из-за внутреннего аккумулятора мы не смогли вовремя распознать поломку, а его запаса, по экспериментам, хватает примерно на 25-30 минут записи.


Когда все остыли, пришло время ковырять показания нашего самописца он отработал на все 100! И сейчас будет поток графиков, построенных по его показаниям. Так как RPI работал долгое время на земле (до и после запуска), я, для удобства анализа, обрезал куски данных с земли.


На шкале X всегда будет время в секундах с момента отрыва от поверхности. Поехали!


График набора высоты по показаниям GPS HAT:


alt_gps


Взглянув на него, мы видим: максимальная высота, которую он набрал на 2247-й секунде полета, составила 18993 метра над уровнем моря! Это выше чем Эверест, это выше чем летают любые пассажирские самолеты! Но прилично ниже расчетных 30км. Взглянув на то что осталось от, непосредственно, шара, мы предположили, что мы его просто перекачали и он взорвался раньше положенного. Была у меня еще версия что мы его недокачали. Но тогда бы он повисел на высоте, пока гелий не выйдет и опустился бы целым на землю. А от него ничего не осталось. Значит перекачали. Учтем на будущее.


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


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


alt_compare


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


Теперь, что же там с давлением?


pres_over_alt


Мы видим, как падало давление с набором высоты (эффект ожидаемый). Все в той же точке 2247 было зафиксировано минимальное значение 58 миллибар. Для сравнения на поверхности было 1050 миллибар. Т.е. всего 5.7% от давления на поверхности!


Как там работал наш кустарный охладитель? Температура внутри бокса:


inside_temp


Как видно скакнула до $38,5^oC$, но это очень далеко от предельной. Так что никто не перегрелся и никто не замерз. Да и в целом разброс всего 33-35 считаю очень хорошим результатом.


Что в этот момент происходило снаружи? Снова график 2-в-1, чтобы не захламлять картинками:


outside_temp_over_alt


Помните я сетовал на градусник? Вооот. Как видите провал ниже -40. Значит там было еще холоднее! И второй вывод, который тут можно сделать: самая холодная точка не самая высокая!


Насколько наш климатизатор страдал, можно оценить по графику разницы температур Inside vs Outside:


outside_inside_temp_diff


Как видите разность температур доходила почти до 80! Не сказать что хардкор, но прилично.


Ну и последний на сегодня показатель влажность:


humidity_over_alt


Там довольно сухо, да. Влажность падала до 3%. Ну а откуда ей там взяться?


Хватит графиков. Это, конечно же не все показания, которые записал наш RPI, но статья и так уже слишком разрослась. Так что я оставлю ссылку на полную телеметрию:



Видео


Использование вездехода по назначению:



Видео полета с бортовой камеры:



Выводы


Итак, несмотря на то, что расчетная высота достигнута не была: 19км против 30км все равно считаю, что проект завершился успешно. Тем более, это был первый опыт подобного рода для всех участников проекта. Давайте обозначим технические проблемы, возникшие в процессе этого мероприятия:


  • Камера не записала весь полет.
    • Возможная причина: поломка аккумулятора на запуске.
    • Возможное решение: заменить внешний аккумулятор, удалить внутренний аккумулятор перед запуском (позволит отследить проблему с внешним на ранних этапах)
  • Не была достигнута расчетная высота.
    • Возможная причина: перекачали шар. Закачали 1.5 баллона вместо расчетных 1.36
    • Возможное решение: закачать меньше гелия (1.36 баллона)
  • Порвался парашют. Не прям в хлам, пара мелких отверстий сбоку. Купол не пострадал и на полетные характеристики это не повлияло. Решение тут только одно заменить парашют на новый во избежание дальнейшего распространения повреждений.
  • Приземление в труднодоступной местности.
    • Причина: ранний взрыв шара
    • Возможное решение: закачать правильное количество гелия. 100% гарантии это не даст, но по итогу, расчетная траектория совпала с реальной, за исключением того, что нагрузка приземлилась раньше положенного времени.

На этом все, всем чистого неба над головой и удачи!

Подробнее..

Превращаем дисковый телефон в цифрового помощника с использованием Google Assistant и Raspberry Pi

03.05.2021 16:20:48 | Автор: admin

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

Речь идет о преобразовании телефона в цифрового секретаря, который всегда готов прийти на помощь. Для реализации проекта нужна плата Raspberry Pi Zero и подключение к Google Assistant. Ну а теперь подробнее о проекте.

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


Чуть подробнее о необходимых компонентах


Нам понадобится:
  • Raspberry Pi Zero с запаянными пинами, карта памяти с Raspberry Pi OS и адаптер питания.
  • Старый дисковый телефон с работающей трубкой (микрофоном и динамиком) и работающим рычажным переключателем, который придется кастомизировать.
  • Разного рода кабели, паяльник, отвертки и прочие мелочи.
  • 1 USB audio адаптер, совместимый с Linux.
  • 1 male-male 3.5 мм аудио кабель.
  • 1 Raspberry Pi Zero micro USB to USB A адаптер.

Как установить Google Assistant на старый телефон


Здесь несколько этапов работы:
  • Регистрация в Google (самое простое).
  • Аутентификация с Google (тоже несложно).
  • Кастомизация телефона.
  • Настройка помощника Google.

Регистрация в Google


Речь, конечно же, не о простой регистрации аккаунта в сервисах компании, а о регистрации с raspberry pi. Этот этап может быть немного сложным для тех, кто никогда не работал с Google Cloud Platform, так что лучше прочитать этот пункт, дабы не терять время. Если вы все знаете его можно и пропустить.

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

cd ~/
git clone https://github.com/rydercalmdown/google_assistant_telephone


Открываем console.actions.google.com в браузере. Здесь расположен центр управления Google Assistant Actions.

Выбираем новый проект и заполняем появлющиеся поля.


В новой вкладке подтверждаем имя проекта и выбираем Enable для включения API.


Далее на первой вкладке пролистываем страничку до конца и выбираем Are you looking for device registration? Click here


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


Выбираем Download OAuth 2.0 credentials для того, чтобы загрузить соответствующий файл, который малинка будет использовать для формирования запросов.


Переименовываем загруженный файл в oauth_config_credentials.json и передаем его на Raspberry Pi. Разместить его нужно в папку скопированного репозитория, загруженного в самом начале.

# Rename your downloaded file
cd ~/Downloads
mv your_unique_secret_file_name.json oauth_config_credentials.json
# Move the file into your repository
scp oauth_config_credentials.json pi@your_pis_ip_address:/home/pi/google_assistant_telephone


Возвращаемся к браузеру. После загрузки и переименования нажимаем Next и выбираем Save Traits, не изменяя настроек.


Аутентификация с Google


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

Открываем ссылку console.cloud.google.com/apis/credentials/consent и проверяем, чтобы имя проекта, заданное выше, совпадало с отображаемым по ссылке.

Выбираем External и нажимаем Create


Заполняем поле с названием, выбираем из выпадающего списка почту и добавляем этот e-mail в поле Developer contact information и сохраняем все.


На следующей странице выбираем Add or Remove Scopes и ищем в поисковой строке Google Assistant API. Выбираем /auth/assistant-sdk-prototype scope, обновляем путем нажатия на upfate и сохраняем все.


Затем выбираем OAuth Consent Screen и Add User, добавляя свою почту.


Теперь переходим в папку загруженного репозитория на Raspberry Pi и запускаем команду:

cd ~/google_assistant_telephone
make authenticate


Она завершает процесс аутентификации, после чего нужно скопировать полученный код в консоль. Если все хорошо, то появится сообщение credentials saved:

Эти данные требуются для перехода в текущую аудиторию.

# credentials saved: /Users/test/Library/Application Support/google-oauthlib-tool/credentials.json
mv /Users/test/Library/Application\ Support/google-oauthlib-tool/credentials.json /home/pi/google/assistant/telephone/credentials.json


Кастомизируем телефон


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

В любом случае телефон сначала нужно разобрать.


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


Провода нужно припаять к 18 пину и к земле.

Далее подключаем USB аудио адаптер к raspberry pi zero, после чего припаиваем к проводам трубки два разных 3,5мм провода. Они будут передавать сигнал от Raspberri Pi к трубке и обратно. Возможно, придется повозиться, определяя, где какой провод, но в целом здесь нет ничего сложного.


Заканчиваем кастомизацию телефона, подключая 3,5мм провода к адаптеру.


Остается лишь закрыть корпус телефона, не забыв вывести кабель питания малинки.


Настройка помощника


Осталось совсем немного настраиваем помощника и все. Здесь тоже несколько шагов.

Запускаем установочный скрипт. Это займет не один час, если вы используете Raspberry Pi Zero. Лучше всего запустить все вечером и оставить на ночь.

cd google_assistant_telephone
make install


Настраиваем USB-аудио. Для этого нужна всего одна команда.

make configure-audio

Теперь тестируем аудиоадаптер.

# Run, speak something into the microphone, and listen
make test

# Set volumes
alsamixer


Экспортируем ID проекта. Можно просто зайти вот по этой ссылке и выбрать
Project Settings

export PROJECT_ID=your-project-id

Экспортируем ID

export DEVICE_MODEL_ID=your-model-id-from-the-earlier-steps

Теперь выполняем команду

make run

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

Наконец, выполняем команду ниже для запуска помощника.

make configure-on-boot

Больше подробностей на страничке самого проекта.

Подробнее..

Превращаем одноплатник Cubietruck в Wi-Fi Hotspot с Captive portal, VPN-шлюзом и Ad block

25.05.2021 10:11:06 | Автор: admin
raspap

Для построения Wi-Fi сети обычно используют готовые маршрутизаторы, функционал которых всегда ограничен прошивкой. А если необходимо добавить блокировщик рекламы, VPN шлюз и красивый Captive portal, покупать новую железку? Стоимость устройства с таким функционалом будет уже весьма высока. Можно взять Linux с Hostapd и сделать точку доступа с Wi-Fi, но в отличие от готовых маршрутизаторов не будет наглядного Web-интерфейса. И для решения этой задачи был создан проект RaspAP, который на базе устройств с ОС Debian создает Wi-Fi Hotspot с Captive portal, VPN-шлюзом, Ad block. Для RaspAP в отличие от OpenWrt не требуется непосредственная поддержка устройства, достаточно поддержки последней версии Debian. RaspAP работает поверх уже установленных ОС: Raspberry Pi OS, Armbian, Debian, Ubuntu. Как сделать Wi-Fi Hotspot на RaspAP прошу под кат.

RaspAP open-source проект создания беспроводного маршрутизатора из многих популярных устройств работающих на ОС Debian, включая Raspberry Pi. Содержит удобный Web-интерфейс для настройки, блокировщик рекламы, осуществляет шлюзование сетевого трафика через OpenVPN или WireGuard.

Используя RaspAP можно быстро развернуть Hotspot с доступом в сеть Интернет, где угодно: в магазине или торговом центре, заправке, кафе и ресторане, библиотеке, больнице, аэропорте и вокзале, а также в совершенно непривычных, уединенных местах, например на вершине горы. Благодаря наличию Captive portal, посетители подключаясь к Сети, обязательно увидят информацию, которую владелец Wi-Fi желает довести до пользователей. Это может быть информация о соглашение использования публичного hotspot, и т.д.

Поддерживаемые устройства и ОС


Для устройств на ARM-архитектуре заявлена официальная поддержка, устройства на x86 процессорах в настоящее время находится в стадии Beta.

raspap

Поддерживаемые ОС и архитектуры RaspAP

Базовой платформой работы RaspAP является устройство Raspberry Pi. Но благодаря поддержки Armbian на основе Debian, список поддерживаемых устройств становится весьма широким.

Wi-Fi Hotspot на RaspAP будет развернут на одноплатном компьютере Cubietruck, процессор AllWinner A20 (ARM32), с ОС Armbian (на базе Debian). Для задач маршрутизации сетевого трафика для нескольких клиентов процессора AllWinner A20 с двумя ядрами Cortex-A7 будет недостаточно, но вы можете взять гораздо более мощное устройства из каталога поддерживаемых проектом Armbian.

RaspAP


raspap

Под капотом RaspAP использует hostapd, dnsmasq, iptables, веб-интерфейс работает на lighttpd с php-скриптами. С точки зрения использования новых функций применяется политика спонсорства. Если оформить ежемесячное спонсорство, то ваш аккаунт на GitHub будет добавлен в группу Insiders, которые первыми получают возможность протестировать новые функции. Функции доступные на данный момент только спонсорам будут помечены Insiders Edition.

raspap

Веб-интерфейс RaspAP

Возможности RaspAP:

  • Графический интерфейс для настройки и отображения графиков активности клиентских устройств;
  • Поддержка сертификатов SSL;
  • Интеграция с Captive portal;
  • Управление DHCP-сервером;
  • Поддержка адаптеров 802.11ac 5 ГГц;
  • Автоопределение внешних беспроводных адаптеров.

Пройдемся коротко по основным функциям RaspAP.

Точка доступа


По умолчанию создается точка доступа со следующими параметрами:

  • Interface: wlan0
  • SSID: raspi-webgui
  • Wireless Mode: 802.11n 2.4GHz
  • Channel: 1
  • Security Type: WPA2
  • Encryption Type: CCMP
  • Passphrase: ChangeMe

К AP можно подключаться по ключевой паре SSID + пароль или по QR-коду. В случае бездействия клиента, AP может его отключить (требуется поддержка в драйверах). В Insiders Edition доступна возможность изменять мощность в dBm. Для обеспечения гарантированной работы можно задать ограниченное количество подключаемых клиентов.

Для Raspberry Pi Zero W доступен режим виртуализации беспроводного устройства. Единственное на борту Wi-Fi устройство будет работать в режиме клиента и точки доступа. Режим виртуализации сетевых интерфейсов работает и на других адаптерах USB Wi-Fi таких как RTL8188.

Блокировщик рекламы (Ad blocking)


Блокирует ads, трекеры и узлы из черного списка. В качестве источника черного списка выступает проект notracking, список обновляется автоматически. Блокируются следующие типы узлов: tracking, поставщики рекламы, сбор аналитики, фишинговые и мошенические сайты, содержащие вредоносные программы, веб-майнеры.

Captive portal


raspap

Captive portal

Из коробки интегрирован nodogsplash. nodogsplash легкое и простое решения создания кастомизируемых порталов. Поддерживает различные политики работы клиентов.

Поддержка дисплея для вывода состояния работы


Статистическую работу можно выводить на TFT-экран Adafruit Mini PiTFT контроллер ST7789. Скрипт вывода информации написан на Python, поэтому программный код можно легко адаптировать и для другого дисплея, например для ILI9341.

raspap

Вывод информации о работе AP

Поддержка различных сетевых устройств в качестве WAN-интерфейса (Insiders Edition)


В качестве доступа к сети Интернет, RaspAP поддерживает несколько различных типов сетевых устройств, такие как:

  • Ethernet interface (eth);
  • Wireless adapter (wlan);
  • Mobile data modem (ppp);
  • Mobile data adapter with built-in router;
  • USB connected smartphone (USB tethering);

Это особенно удобно когда вы путешествуете или работает в полевых условиях.

OpenVPN


raspap

Сетевой трафик можно туннелировать используя клиента OpenVPN. В Insiders Edition доступна возможность хранения нескольких профилей OpenVPN с функцией быстрого переключения между ними.

WireGuard (Insiders Edition)


raspap

WireGuard быстрый и современный VPN, в котором используется самая современная криптография. Он более производителен, чем OpenVPN, и обычно считается наиболее безопасным, простым в использовании и самым простым решением VPN для современных дистрибутивов Linux. Благодаря низкому overhead, если устройство работает от батареи, то время работы при использование WireGuard будет больше, чем при использование OpenVPN.

Доступ к Web-интересу настроек через SSL


raspap

Для защиты сетевого трафика от перехвата, доступно шифрование по SSL в пределах локальной сети. Проект mkcert позволяет в несколько простых шагов развернуть корневой центр сертификации и генерировать сертификаты, подписанные вашим собственным частным ЦС.

Постановка задачи


Установка RaspAP будет произведена из публичного репозитория, на Cubietruck установлена последняя версия Armbian (на основе Debian): Armbian 21.02.3 Buster, Linux 5.10.21-sunxi. На борту имеется встроенный адаптер wlan0, будет выступать в качестве клиентского доступа к сети Интернет (WAN-интерфейс). Для Hotspot подключим RTL8188 USB WiFi dongle wlan1.

  • IP конфигурация для wlan0: address 192.168.43.12 netmask 255.255.255.0 gateway 92.168.43.1.
  • IP конфигурация для wlan1: address 10.3.141.1 netmask 255.255.255.0 gateway 10.3.141.1.

Конфигурация DHCP-сервера:

  • Диапазон выдаваемых IP-адресов 10.3.141.50 10.3.141.254;
  • Шлюз/DNS-сервер: 10.3.141.1.

Для шлюзования сетевого трафика через OpenVPN установим на VPS сервер SoftEther VPN Server. SoftEther VPN Server мультипротокольный VPN-сервер, который может поднимать L2TP/IPsec, OpenVPN, MS-SSTP, L2TPv3, EtherIP-серверы, а также имеет свой собственный протокол SSL-VPN, который неотличим от обычного HTTPS-трафика (чего не скажешь про OpenVPN handshake, например), может работать не только через TCP/UDP, но и через ICMP (подобно pingtunnel, hanstunnel) и DNS (подобно iodine), работает быстрее (по заверению разработчиков) текущих имплементаций, строит L2 и L3 туннели, имеет встроенный DHCP-сервер, поддерживает как kernel-mode, так и user-mode NAT, IPv6, шейпинг, QoS, кластеризацию, load balancing и fault tolerance, может быть запущен под Windows, Linux, Mac OS, FreeBSD и Solaris и является Open-Source проектом под GPLv2.

Для VPS сервера выберем тариф на vdsina.ru за 330 р./месяц, в который включена квота на 32 ТБ трафика, чего более чем достаточно. SoftEther VPN Server будет развернут в Docker контейнере, поэтому выбор ОС CentOS/Debian/Ubuntu не принципиально важен.

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

raspap

VPS сервер на vdsina.ru

Сервер был развернут в Московской локации, IP-адрес 94.103.85.152, dns-имя: v636096.hosted-by-vdsina.ru. Подключение к серверу будет по DNS имени.

raspap

Итоговая схема сети

Как будет выглядеть Web-интерфейс RaspAP и подключение к Hotspot


Подключение к AP SSID: raspi-webgui


Подключение к AP raspi-webgui

Конфигурационные файлы RaspAP


Для установки RaspAP есть Quick installer, но он выполняется без задания параметров и wlan0 настроен как Hotspot, что нам не подходит. Поэтому воспользуемся Manual installation, с некоторыми изменениями т.к. руководство содержит некоторые ошибки и сам RaspAP работает с некоторыми некритичными багами, из-за этого пришлось немного больше потратить время на установку. О багах будет в ходе установки.

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

Список конфигурационных файлов (GitHub):

  • hostapd.conf служба hostapd
  • default_hostapd служба hostapd
  • 090_raspap.conf служба dnsmasq.d
  • 090_wlan1.conf служба dnsmasq.d
  • defaults.json служба raspap
  • dhcpcd.conf служба raspap
  • config.php портал конфигурации RaspAP

hostapd.conf служба hostapd

Содержит настройки AP по умолчанию такие как: ssid, channel, password и т.д.

hostapd.conf
driver=nl80211ctrl_interface=/var/run/hostapdctrl_interface_group=0beacon_int=100auth_algs=1wpa_key_mgmt=WPA-PSKssid=raspi-webguichannel=1hw_mode=gwpa_passphrase=ChangeMeinterface=wlan1wpa=2wpa_pairwise=CCMPcountry_code=RU## Rapberry Pi 3 specific to on board WLAN/WiFi#ieee80211n=1 # 802.11n support (Raspberry Pi 3)#wmm_enabled=1 # QoS support (Raspberry Pi 3)#ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40] # (Raspberry Pi 3)## RaspAP wireless client AP mode#interface=uap0## RaspAP bridge AP mode (disabled by default)#bridge=br0



default_hostapd служба hostapd

Настройка службы hostapd, параметр DAEMON_CONF определяет путь к настройкам.

default_hostapd
# Location of hostapd configuration fileDAEMON_CONF="/etc/hostapd/hostapd.conf"



090_raspap.conf служба dnsmasq.d

Настройка службы dnsmasq, параметр conf-dir определяет путь к настройкам.

090_raspap.conf
# RaspAP default configlog-facility=/tmp/dnsmasq.logconf-dir=/etc/dnsmasq.d


090_wlan1.conf служба dnsmasq.d

Настройка dnsmasq для сетевого интерфейса wlan1. Содержит диапазон выдаваемых IP-адресов, и другие сетевые настройки. Необходимо обратить внимание на название файла по маске 090_[ИДЕНТИФИКАТОР_ИНТЕРФЕЙСА_HOTSPOT].conf. Если у вас сетевой интерфейс для hostspot будет назваться например wlan2, то следует задать название файла 090_wlan2.conf.

090_wlan1.conf
# RaspAP wlan0 configuration for wired (ethernet) AP modeinterface=wlan1domain-neededdhcp-range=10.3.141.50,10.3.141.255,255.255.255.0,12hdhcp-option=6,10.3.141.1


defaults.json служба raspap

Настройка DHCP серверов для интерфейсов wlan0 и wlan1.

defaults.json
{  "dhcp": {    "wlan1": {       "static ip_address": [ "10.3.141.1/24" ],      "static routers": [ "10.3.141.1" ],      "static domain_name_server": [ "10.3.141.1" ],      "subnetmask": [ "255.255.255.0" ]    },    "wlan0": {      "static ip_address": [ "192.168.43.12/24" ],      "static routers": [ "192.168.43.1" ],      "static domain_name_server": [ "1.1.1.1 8.8.8.8" ],      "subnetmask": [ "255.255.255.0" ]    },    "options": {      "# RaspAP default configuration": null,      "hostname": null,      "clientid": null,      "persistent": null,      "option rapid_commit": null,      "option domain_name_servers, domain_name, domain_search, host_name": null,      "option classless_static_routes": null,      "option ntp_servers": null,      "require dhcp_server_identifier": null,      "slaac private": null,      "nohook lookup-hostname": null    }  },  "dnsmasq": {    "wlan1": {      "dhcp-range": [ "10.3.141.50,10.3.141.255,255.255.255.0,12h" ]    },    "wlan0": {      "dhcp-range": [ "192.168.43.50,192.168.50.150,12h" ]    }  }}


dhcpcd.conf служба raspap

Настройка для сетевого интерфейса wlan0, который выходит в сеть Интернет.

dhcpcd.conf
# RaspAP default configurationhostnameclientidpersistentoption rapid_commitoption domain_name_servers, domain_name, domain_search, host_nameoption classless_static_routesoption ntp_serversrequire dhcp_server_identifierslaac privatenohook lookup-hostname# RaspAP wlan0 configurationinterface wlan0static ip_address=192.168.43.12/24static routers=192.168.43.1static domain_name_server=1.1.1.1 8.8.8.8


config.php портал конфигурации RaspAP

Файл настроек графического Web-интерфейса. Содержит переменные влияющие на отображение настроек. Самый главный параметр define('RASPI_WIFI_AP_INTERFACE', 'wlan1');. В качестве значения указать сетевой интерфейс hotspot wlan1.

config.php
...define('RASPI_WIFI_AP_INTERFACE', 'wlan1');...define('RASPI_ADBLOCK_ENABLED', true);define('RASPI_OPENVPN_ENABLED', false);...


Пошаговая установкаRaspAP


Руководство установки доступно в разделе Manual installation.

Шаг 1 Подключение адаптера USB WiFi RTL8188


Подключаем адаптер в любой доступный USB порт. В Armbian драйвера уже есть, поэтому проверим подключение командой lsusb:

root@bananapim64:~# lsusbBus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hubBus 003 Device 004: ID 0bda:c811 Realtek Semiconductor Corp.Bus 003 Device 002: ID 1a40:0101 Terminus Technology Inc. HubBus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hubBus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubroot@bananapim64:~#

В списке присутствует Realtek Semiconductor Corp., значит адаптер успешно распознался. Если вывести название интерфейса для подключенного адаптера, то его имя будет wlxe81e0584796d, что несколько далеко от привычного именования вида wlanX. Для задания названия для адаптера wlan1, необходимо выполнить следующие действия (более подробнее почитать про именование сетевых интерфейсов по ссылке1,ссылке2):

$ sudo ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules$ sudo reboot

После перезагрузки в системе будет два беспроводных адаптера: wlan0 и wlan1.

Шаг 2 Настройка сетевых интерфейсов


Настроим сетевые интерфейсы в конфигурационном файле: /etc/network/interfaces.

# Network is managed by Network managerauto loiface lo inet loopback# WANauto wlan0allow-hotplug wlan0iface wlan0 inet dhcp# Wi-Fi APauto wlan1iface wlan1 inet static    address 10.3.141.1    netmask 255.255.255.0    gateway 10.3.141.1

Шаг 3 Установка RaspAP


Теперь приступаем к установке RaspAP.
Обновление системы:

sudo apt-get updatesudo apt-get full-upgrade

Установка зависимостей для не RPi OS:

sudo apt-get install software-properties-common sudo add-apt-repository ppa:ondrej/phpsudo apt-get install dhcpcd5

Установка пакетов:

sudo apt-get install -y lighttpd git hostapd dnsmasq iptables-persistent vnstat qrencode php7.3-cgi

PHP:

sudo lighttpd-enable-mod fastcgi-php    sudo service lighttpd force-reloadsudo systemctl restart lighttpd.service

Создание Web-портала:

sudo rm -rf /var/www/htmlsudo git clone https://github.com/RaspAP/raspap-webgui /var/www/htmlWEBROOT="/var/www/html"CONFSRC="$WEBROOT/config/50-raspap-router.conf"LTROOT=$(grep "server.document-root" /etc/lighttpd/lighttpd.conf | awk -F '=' '{print $2}' | tr -d " \"")HTROOT=${WEBROOT/$LTROOT}HTROOT=$(echo "$HTROOT" | sed -e 's/\/$//')awk "{gsub(\"/REPLACE_ME\",\"$HTROOT\")}1" $CONFSRC > /tmp/50-raspap-router.confsudo cp /tmp/50-raspap-router.conf /etc/lighttpd/conf-available/sudo ln -s /etc/lighttpd/conf-available/50-raspap-router.conf /etc/lighttpd/conf-enabled/50-raspap-router.confsudo systemctl restart lighttpd.servicecd /var/www/htmlsudo cp installers/raspap.sudoers /etc/sudoers.d/090_raspap

Создание конфигурации:

sudo mkdir /etc/raspap/sudo mkdir /etc/raspap/backupssudo mkdir /etc/raspap/networkingsudo mkdir /etc/raspap/hostapdsudo mkdir /etc/raspap/lighttpdsudo cp raspap.php /etc/raspap 

Установка разрешения:

sudo chown -R www-data:www-data /var/www/htmlsudo chown -R www-data:www-data /etc/raspap

Настройка контролирующих скриптов:

sudo mv installers/*log.sh /etc/raspap/hostapd sudo mv installers/service*.sh /etc/raspap/hostapdsudo chown -c root:www-data /etc/raspap/hostapd/*.sh sudo chmod 750 /etc/raspap/hostapd/*.sh sudo cp installers/configport.sh /etc/raspap/lighttpdsudo chown -c root:www-data /etc/raspap/lighttpd/*.shsudo mv installers/raspapd.service /lib/systemd/systemsudo systemctl daemon-reloadsudo systemctl enable raspapd.service

Установка стартовых настроек, настройки в каталоге ~/temp, при необходимости заменить на свои:

sudo apt-get install -y curl unzipmkdir -p ~/tempcurl -SL --output ~/temp/config_ct.zip https://github.com/devdotnetorg/Site/raw/master/Uploads/files/config_ct.zipunzip ~/temp/config_ct.zip -d ~/temprm ~/temp/config_ct.zipесли есть: sudo mv /etc/default/hostapd ~/default_hostapd.oldесли есть: sudo cp /etc/hostapd/hostapd.conf ~/hostapd.conf.oldsudo cp ~/temp/default_hostapd /etc/default/hostapdsudo cp ~/temp/hostapd.conf /etc/hostapd/hostapd.confsudo cp config/090_raspap.conf /etc/dnsmasq.d/090_raspap.confsudo cp ~/temp/090_wlan1.conf /etc/dnsmasq.d/090_wlan1.confsudo cp ~/temp/dhcpcd.conf /etc/dhcpcd.confsudo cp ~/temp/config.php /var/www/html/includes/sudo cp ~/temp/defaults.json /etc/raspap/networking/sudo systemctl stop systemd-networkdsudo systemctl disable systemd-networkdsudo cp config/raspap-bridge-br0.netdev /etc/systemd/network/raspap-bridge-br0.netdevsudo cp config/raspap-br0-member-eth0.network /etc/systemd/network/raspap-br0-member-eth0.network 

Оптимизация PHP:

sudo sed -i -E 's/^session\.cookie_httponly\s*=\s*(0|([O|o]ff)|([F|f]alse)|([N|n]o))\s*$/session.cookie_httponly = 1/' /etc/php/7.3/cgi/php.inisudo sed -i -E 's/^;?opcache\.enable\s*=\s*(0|([O|o]ff)|([F|f]alse)|([N|n]o))\s*$/opcache.enable = 1/' /etc/php/7.3/cgi/php.inisudo phpenmod opcache

Настройка маршрутизации:

echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/90_raspap.conf > /dev/nullsudo sysctl -p /etc/sysctl.d/90_raspap.confsudo /etc/init.d/procps restartsudo iptables -t nat -A POSTROUTING -j MASQUERADEsudo iptables -t nat -A POSTROUTING -s 192.168.43.0/24 ! -d 192.168.43.0/24 -j MASQUERADEsudo iptables-save | sudo tee /etc/iptables/rules.v4

Включение hostapd:

sudo systemctl unmask hostapd.servicesudo systemctl enable hostapd.service

OpenVPN:

sudo apt-get install openvpnsudo sed -i "s/\('RASPI_OPENVPN_ENABLED', \)false/\1true/g" /var/www/html/includes/config.phpsudo systemctl enable openvpn-client@clientsudo mkdir /etc/raspap/openvpn/sudo cp installers/configauth.sh /etc/raspap/openvpn/sudo chown -c root:www-data /etc/raspap/openvpn/*.sh sudo chmod 750 /etc/raspap/openvpn/*.sh

Ad blocking:

sudo mkdir /etc/raspap/adblockwget https://raw.githubusercontent.com/notracking/hosts-blocklists/master/hostnames.txt -O /tmp/hostnames.txtwget https://raw.githubusercontent.com/notracking/hosts-blocklists/master/domains.txt -O /tmp/domains.txtsudo cp /tmp/hostnames.txt /etc/raspap/adblocksudo cp /tmp/domains.txt /etc/raspap/adblock sudo cp installers/update_blocklist.sh /etc/raspap/adblock/sudo chown -c root:www-data /etc/raspap/adblock/*.*sudo chmod 750 /etc/raspap/adblock/*.shsudo touch /etc/dnsmasq.d/090_adblock.confecho "conf-file=/etc/raspap/adblock/domains.txt" | sudo tee -a /etc/dnsmasq.d/090_adblock.conf > /dev/null echo "addn-hosts=/etc/raspap/adblock/hostnames.txt" | sudo tee -a /etc/dnsmasq.d/090_adblock.conf > /dev/nullsudo sed -i '/dhcp-option=6/d' /etc/dnsmasq.d/090_raspap.confsudo sed -i "s/\('RASPI_ADBLOCK_ENABLED', \)false/\1true/g" includes/config.php

При конфигурирование через Web-интерфейс столкнулся с багом, который при изменение настроек DHCP сервера на интерфейсе wlan1 удаляет файл конфигурации 090_wlan1.conf и не создает его заново. В результате DHCP сервер не выдает IP-конфигурацию новым клиентам. Временное решение этой проблемы заключается в блокировке файла на удаление, необходимо выполнить следующую команду (по блокировке файлов почитать по ссылке):

sudo chattr +i /etc/dnsmasq.d/090_wlan1.conf

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

sudo reboot now

После перезагрузке появится Wi-Fi точка доступа с SSID raspi-webgui и паролем ChangeMe. Портал будет доступен по адресу: http://10.3.141.1.

Установка SoftEther VPN Server на VPS сервер


На сервер v636096.hosted-by-vdsina.ru установим Docker по официальному руководству Install Docker Engine on Ubuntu.

Создание сети для Docker контейнеров


Для подсети в которой будет контейнер с SoftEther VPN Server определим следующие параметры:

  • Название сети: vpnnetwork;
  • Subnet: 172.22.0.0/24;
  • Driver: bridge;
  • Range: 172.22.0.0/25;
  • gateway: 172.22.0.127;
  • HostMin: 172.22.0.1;
  • HostMax: 172.22.0.126;
  • Hosts/Net: 126.

Для создание внутренней сети Docker выполним команду:

$ docker network create --driver bridge --subnet 172.22.0.0/24 --ip-range=172.22.0.0/25 --gateway 172.22.0.127 vpnnetwork

Для проверки доступности сети выполнить команду: ping 172.22.0.127.

Создание контейнера с SoftEther VPN Server


Для создание контейнера будем использовать образ siomiz/softethervpn. До запуска основного контейнера необходимо создать конфигурацию, в которой указать пароль для управления сервером параметр SPW и пароль для управления хабом параметр HPW. Файл конфигурации будет располагаться по пути /usr/vpnserver/vpn_server.config. Выполнить следующие команды:

$ mkdir -p /usr/vpnserver$ docker run --name vpnconf -e "SPW={PASSWORD}" -e "HPW={PASSWORD}" siomiz/softethervpn echo$ docker cp vpnconf:/usr/vpnserver/vpn_server.config /usr/vpnserver/vpn_server.config$ docker rm vpnconf

Для уменьшения размера контейнера возьмем образ на основе Alpine, все журналы log в null. Выполнить следующие команды для создание контейнера:

$ docker run --name vps-server-softethervpn -d --cap-add NET_ADMIN --restart always --net vpnnetwork --ip 172.22.0.2 -p 443:443/tcp -p 992:992/tcp \-p 1194:1194/udp -p 5555:5555/tcp -v /usr/vpnserver/vpn_server.config:/usr/vpnserver/vpn_server.config \-v /dev/null:/usr/vpnserver/server_log -v /dev/null:/usr/vpnserver/packet_log -v /dev/null:/usr/vpnserver/security_log siomiz/softethervpn:alpine

Если контейнер запустился, то переходим к следующему шагу.

Настройка SoftEther VPN Server


Для настройки SoftEther VPN Server лучше использовать графическую утилиту для ОС Windows. Для загрузки необходимо перейти на страницу SoftEther Download Center. В списке Select Component, выбрать SoftEther VPN Server Manager for Windows, далее Select Platform windows. Можно выбрать пакет .zip без необходимости установки. Пакет softether-vpn_admin_tools-v4.34-9745-rtm-2020.04.05-win32.zip распаковать и запустить vpnsmgr.exe.

Создаем новый профиль кнопка New Setting, указываем следующие настройка:

  • Setting Name: VDSina_ru_main_server
  • Host Name: v636096.hosted-by-vdsina.ru
  • Port Number: 443
  • Password: пароль который был указан в переменной SPW при создание конфигурационного файла vpn_server.config

Затем подключаемся к серверу кнопка Connect.

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

Для настройки алгоритма шифрования нажать на кнопку Encryption and Network. По умолчанию включен алгоритм DHE-RSA-AES256-SHA. Из списка выбрать другие более стойкие комбинации шифрования, но нужно помнить чем сильнее алгоритм, тем больше нагрузка на CPU сервера и на конечное маршрутизирующее устройство.

По умолчанию будет доступен хаб DEFAULT, удаляем его.

Создаем новый хаб кнопка Create a Virtual Hub. Укажем Virtual Hub Name: VPNROOT. Открываем настройки хаба кнопка Manage Virtual Hub.

Создадим пользователя подключения, кнопка Manage Users, затем кнопка New. Аутентификация будет по паре логин/пароль, укажем имя: officeuser1.

Для отделение подсети клиентов VPN сервера и подсети Docker контейнеров включим NAT, кнопка Virtual NAT and Virtual DHCP Server (SecureNAT), далее кнопка Enable SecureNAT. Изменим подсеть VPN клиентов на: 192.168.30.x, закроем окно, кнопка Exit.

На этом настройка сервера закончена.


Последовательность действий по настройке SoftEther VPN Server

Получение файлов конфигурации *.ovpn


Для подключения OpenVPN клиента необходимо получить файлы конфигурации *.ovpn, для этого переходим на главный экран настроек SoftEther VPN Server и нажимаем на кнопку OpenVPN / MS-SSTP Settings. Далее, в следующем окне генерируем файлы конфигурации, кнопка Generate a Sample Configuration File for OpenVPN Clients. Сохраняем архив OpenVPN_Sample_Config_v636096.hosted-by-vdsina.ru_20210519_150311.zip, для дальнейшего подключения потребуется файл f1167ecd086e_openvpn_remote_access_l3.ovpn.


Последовательность действий по получению файлов конфигурации *.ovpn

Настройка OpenVPN на RaspAP


Создание маршрутов
Теперь переходим в консоль Cubietruck и добавляем маршруты:

sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADEsudo iptables -A FORWARD -i tun0 -o wlan1 -m state --state RELATED,ESTABLISHED -j ACCEPTsudo iptables -A FORWARD -i wlan1 -o tun0 -j ACCEPT

Делаем копию существующих маршрутов и сохраняем новые

cp /etc/iptables/rules.v4 /etc/iptables/rules.v4.baksudo iptables-save | sudo tee /etc/iptables/rules.v4

Настройка профиля OpenVPN

Переходим на портал по адресу 192.168.43.12/openvpn_conf и указываем данные для подключения:

  • Username: officeuser1
  • Password: указанный для officeuser1 в SoftEther VPN Server
  • Для конфигурационного файла выбираем файл f1167ecd086e_openvpn_remote_access_l3.ovpn.

Сохраняем настройки и перезапускаем OpenVPN. Если подключение удалось, но в поле IPV4 ADDRESS будет публичный IP-адрес VPN сервера: 94.103.85.152 (v636096.hosted-by-vdsina.ru).

raspap
Страница настроек OpenVPN в RaspAP

Настройка Captive portal


Установка Captive portal в руководстве Captive portal setup.

Для установки выполним следующие действия:

sudo apt-get updatesudo apt-get install -y libmicrohttpd-devcd ~/git clone https://github.com/nodogsplash/nodogsplash.gitcd nodogsplashmakesudo make install

Далее необходимо внести изменения в конфигурационный файл /etc/nodogsplash/nodogsplash.conf. Указать следующие параметры:

...GatewayInterface wlan1...GatewayAddress 10.3.141.1...

Регистрация службы и запуск:

sudo cp ~/nodogsplash/debian/nodogsplash.service /lib/systemd/system/sudo systemctl enable nodogsplash.servicesudo systemctl start nodogsplash.service sudo systemctl status nodogsplash.service

Страницы html для изменение дизайна страниц располагаются по пути: /etc/nodogsplash/htdocs/. Теперь выполним подключение к AP SSID: raspi-webgui.

Устранение проблем


Первым делом необходимо проверить IP-конфигурацию сетевых интерфейсов, командами: ifconfig или ip a.

Проверить занятость портов, командами:

netstat -ntlp | grep LISTENlsof -i | grep LISTENlsof -nP -i | grep LISTEN

Если установка RaspAP выполняется на Ubuntu, то вы можете столкнуться с конфликтом использования 53 порта, который занят службой systemd-resolved. Для отключения данной службы, воспользоваться материалом How to disable systemd-resolved in Ubuntu.

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

sudo systemctl status hostapd.servicesudo systemctl status dnsmasq.servicesudo systemctl status lighttpd.servicesudo systemctl status openvpn-client@clientsudo systemctl status nodogsplash.servicesudo systemctl status raspapd.service


Что дальше?


Для проверки совместимости необходимо RaspAP развернуть на Banana Pi BPI-M64 (Armbian 21.02.1 на основе Ubuntu 18.04.5 LTS). Далее, развернуть на x86 с другим более новым адаптером, например USB Realtek 8811CU Wireless LAN 802.11ac. На GitHub размещен репозиторий raspap-docker, который оборачивает RaspAP в контейнер, но по факту запускает скрипт автоматической установки, что несколько неудобно и неправильно. Поэтому для более широкого распространения RaspAP необходимо его правильно обернуть в Docker контейнер для ARM и x86 архитектур.

Итог


Проект RaspAP безусловно заслуживает внимания, основные функции работают отлично. Это единственный проект связанный с Wi-Fi сетями, работающий поверх существующей ОС, у которого работает Web-интерфейс (пока есть небольшие баги). Для личного использования, теста, стоит попробовать. Но для продакшен в бизнесе пока лучше не использовать, необходимо более детально просмотреть исходный код и конфигурацию на предмет безопасности. В любом случае, проект добавил себе в закладки, надеюсь баги исправят в скором времени.



На правах рекламы


VDSina предлагает виртуальные серверы на Linux и Windows выбирайте одну из предустановленных ОС, либо устанавливайте из своего образа.

Присоединяйтесь к нашему чату в Telegram.

Подробнее..

Перевод Pimoroni Pico Wireless добавляем беспроводную связь к Raspberry Pi Pico

26.05.2021 20:08:54 | Автор: admin

Raspberry Pi Pico отличная плата, хотя и с урезанными возможностями. В целом, ей не хватает двух ключевых функций. Первая это кнопка reset, которую, впрочем, можно без проблем добавить самостоятельно. Вторая, более важная беспроводная связь.

Исправить вторую проблему сложнее, но все равно можно. Сейчас появилась совместимая плата, Pimoroni Pico Wireless, которая подключается к малинке и обеспечивает работу с беспроводными сетями пока что только WiFi, о Bluetooth расскажем ниже. Подключается она через SPI-интерфейс.

В целом, добавление беспроводной связи к Pico совсем не сложная задача, компания Adafruit доказала это при помощи AirLift FeatherWing с ESP32. Работает система как с Pico, так и с Feather RP2040. Есть еще Maker Pi Pico, плата, которая поддерживает и ESP8266. Но портативных систем, добавляющих беспроводную связь, для Pico не так много. И Pimoroni Pico Wireless один из отличных вариантов.

Что собой представляет Pimoroni Pico Wireless и как использовать плату?



Pico Wireless по GPIO-интерфейсу. Здесь и достоинство и недостаток системы. Достоинство простота подключения. Недостаток плата закрывает доступ ко всем пинам. Модуль идеально подходит к Pico, размеры у него такие же, как и у малинки.

ESP32-WROOM-32E мощный микроконтроллер, который, правда, в Pico Wireless используется в качестве сопроцессора так же, как и в AirLift FeatherWing от Adafruit. В обычной ситуации контроллер поддерживает работу как с WiFi, так и с Bluetooth, но в этой модели работает лишь WIFi. С другой стороны, при внимательном изучении платы наверняка откроется возможность активировать и Bluetooth, поскольку аппаратно все это поддерживается.


Есть и возможность все же задействовать пины GPIO, но для этого потребуется дополнительная система например, Pico Omnibus. При этом нужно будет убедиться в отсутствии конфликтующих контактов на подключенных устройствах. Питание Pico Wireless обеспечивает GPIO Raspberry Pi Pico, так что дополнительно подключать ничего не нужно.


Железо ничто без программного обеспечения. Pico Wireless поддерживает С++ и собственную версию MicroPython, которая включает picowireless модуль, разработанный для использования с платой. Эта функция отлично работает, ее уже протестировали при помощи скриптов. Проблем не было, единственное пользователь должен понимать, как работает беспроводная сеть, чтобы работать с ПО.

Если желания возиться самостоятельно нет, то лучший вариант Adafruit CircuitPython. Здесь нужно всего лишь изменить несколько строк для того, чтобы Pico увидел подключенный модуль. Кроме того, нужно еще и скопировать несколько библиотек в Pico. После того, как это было сделано, удалось без проблем подключиться к сети и получить погодные данные через API.

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

Светодиод RGB подключен к ESP32 через три контакта (красный = 25, зеленый = 26, синий = 27), и для его использования нам нужно использовать esp.set_analog_write (). Например, вот код для установки красного светодиода.

esp.set_analog_write(25, 0)
esp.set_analog_write(26, 1)
esp.set_analog_write(27, 1)


Здесь можно изменять значения между 0 и 1, что дает возможность настраивать цвет самого светодиода.

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

Характеристики:

  • Модуль ESP32-WROOM-32E (даташит).
  • 1 сенсорная кнопка.
  • Светодиод RGB.
  • Слот для карты памяти Micro-SD.
  • Предварительно припаянные пины для подключения к Raspberry Pi Pico.
  • Размер 53mm x 25mm x 11mm.
  • Библиотеки C++ и MicroPython.

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



Где можно использовать Pimoroni Pico Wireless


В целом, беспроводная связь для Pico открывает перед разработчиком ряд новых возможностей, включая работу с приложениями IoT. Pico Wireless дает возможность взаимодействовать малинке с другими устройствами, используя как стандартные протоколы связи, так и не самые обычные, включая MQTT. Библиотека CircuitPython добавляет еще и поддержку базового HTTP. В ходе теста был проверен мы HTTP-ответ от API с передачей значения в REPL, что полезно для отладки проблем с подключением.

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

В сухом остатке


Как и говорилось выше, Pico Wiereless можно в считанные секунды подключить к малинке, потеряв при этом доступ к GPIO. Соответственно, не будет возможности использовать пины. Проблема решается при помощи Pico Omibus, что увеличивает размеры платы. Также можно самостоятельно припаять систему, придумав что-либо для подключения к пинам.

Подробнее..

Перевод Лучшие одноплатники на базе чипа RP2040 в 2021 году. Часть 1

11.06.2021 02:20:41 | Автор: admin

С момента выхода Raspberry Pi Pico мы опубликовали несколько статей о системах на базе чипа RP2040 от обзора возможностей одноплатника самой компании до более продвинутых систем других производителей. Сейчас их выпущено уже столько, что публиковать обзор всех подобных плат просто нет смысла. Зато можно разместить подборку лучших систем.

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

Немного о критериях выбора плат с RP2040


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

Нужна ли беспроводная связь? С полноценным модулем Wi-Fi и Bluetooth поставляется лишь Arduino Nano RP2040 Connect. Но помимо нее производители предлагают дополнения к Pico вроде Adafruit Airlift board или Pimoroni Pico Wireless Pack.

Экосистема. Понятно, что Raspberry Pi Pico совместима со всей экосистемой продукции Raspberry Pi Foundation. Есть и другие платы, вроде Adafruit Feather RP2040, которые совместимы с представителями продуктовой линейки FeatherWing. Возможности таких плат отличаются от возможностей оригинальной системы.

Наличие дополнительных коннекторов. Это, в первую очередь, Stemma QT, Qwiic и Grove, которые идеально подходят как для простых, так и сложных проектов. У Pico нет дополнительных коннекторов, зато они есть у плат других производителей.

Выбираем лучшие платы с RP2040 чипом


Raspberry Pi Pico


  • Плюсы: низкая цена, всего $4, небольшой размер, простота в использовании, встроенный ADC.
  • Минусы: нет USB-C, только три ADC-пина.

Первый в мире и самый дешевый одноплатник (вернее, микроконтроллер) на базе RP2040 стоит всего 4 доллара США. У него полноценный 40-пиновый GPIO. Поскольку де-факто это стандарт, некоторые сторонние платы совместимы с распиновкой Pico, включая Kitronik Robotics Board или Pimoroni. Они добавляют к функциональности Pico беспроводную связь, несколько светодиодов или другие элементы.

Конечно, покупая самую недорогую модель, вам придется идти на компромиссы. Во-первых, у Pico всего три analog-to-digital пина, тогда как у некоторых сторонних плат четыре или больше. Кроме того, у Pico всего 2 МБ памяти, что весьма немного, хотя и достаточно для решения многих задач.

Плюс ко всему, у Pico micro-USB коннектор, разработчики (вероятно с целью удешевления) решили не устанавливать USB-C. Тем не менее, учитывая обширную экосистему, Pico можно считать must have микроконтроллером для разработчика.

Adafruit Feather RP2040


  • Плюсы: удачный форм-фактор, STEMMA QT, FeatherWing, возможность подключения и зарядки аккумулятора, разметка пинов на обеих сторонах платы.
  • Минусы: нет подтягивающих резисторов на пинах I2C и нет мониторинга батареи.

Adafruit, партнер Raspberry Pi по чипу RP2040, выпустила несколько отличных плат RP2040 за короткий промежуток времени. У компании есть собственный набор форм-факторов. Самая большая плата, Feather, как раз и получила чип RP2040. У Feather RP2040, совместимого с экосистемой FeatherWings, меньше контактов, чем у Raspberry Pi Pico. Но все же разрабочтики выбрали оптимальный минимум.

Потери в пинах GPIO компенсируются возможностью подключения LiPo / Li-Ion батареи, отличной разметкой контактов и наличием Stemma QT, плюс разъема Adafruit, который выбирают для компонентов, которые подключаются посредством I2C. Благодаря Stemma QT у нас нет проблем с подключением и полярностью, что позволяет нам сосредоточиться на проекте, а не на поиске нужных пинов.

Если вы ищете самую универсальную плату RP2040 на рынке, вы ее нашли. Конечно, стоит она дороже, чем Raspberry Pi Pico, но Adafruit Feather RP2040 отличный продукт, который можно использовать в вашем следующем проекте.

Сytron Maker Pi Pico


  • Плюсы: низкая стоимость, простота использования, дополнительные фичи, дополнительные светодиоды и коннекторы.
  • Минусы: с ESP-01 придется повозиться

Raspberry Pi Pico это увлекательный и недорогой способ заняться программированием и электроникой. Правда, во многих случаях к Pico придется докупать компоненты, чтобы расширить сферу его применения. Maker Pi Pico это большое количество дополнительных функций с небольшим размером. При этом стоимость устройства менее 10 долларов, включая предварительно распаянный Raspberry Pi Pico.

За 10 долларов вы получаете просто потрясающее количество функций: кардридер micro SD, зуммер / аудиоразъем 3,6 мм, NeoPixel, контакты GPIO свободны для использования, плюс шесть разъемов Grove для работы с совместимыми компонентами. У каждого из контактов GPIO есть полезный, который можно использовать для быстрой отладки. Включенный в комплект ESP-01 обеспечивает базовый доступ к Wi-Fi. А еще компания Cytron выпустила обновленное руководство о том, как подключить Maker Pi Pico к беспроводной сети. За 10 долларов сложно найти что-то получше.

Adafruit QT Py RP2040


  • Плюсы: небольшой размер, порт Stemma QT, USB-C.
  • Минусы: ограниченное количество GPIO пинов.

QT Py RP2040 от Adafruit похож на Pimoroni Tiny 2040. У платы тоже небольшой размер, плюс тщательно подобранный выбор контактов GPIO для проектов. QTPy RP2040 от Adafruit можно без проблем распаять на плате большего размера. Плюс у системы есть разъем Stemma QT / Qwiic, который обеспечивает дополнительное соединение I2C для работы с совместимыми компонентами. Отличное решение для прототипирования.

Низкая стоимость и простота использования QTPy RP2040 не единственные преимущества платы. Здесь есть еще форк Adafruit MicroPython, CircuitPython, со множеством библиотек для работы с компонентами Stemma QT / Qwiic. Даже если у вас уже есть Raspberry Pi Pico, QTPy RP2040 все равно должен быть частью вашего проекта.

Pimoroni Tiny 2040


  • Плюсы: небольшой размер, больше ADC-пинов, чем у Pico, есть кнопка Reset.
  • Минусы: плата несовместима с add-on системами для Pico, сложности с распайкой, высокая цена.

Размер этой платы составляет всего лишь треть от и так небольшого Raspberry Pi Pico. Разработчики позаботились о сохранении всех функций Pico с добавлением новых. Есть, например, дополнительный аналоговый вход. Из-за небольшого размера платы она стала дороже, причем ровно в три раза, чем Pico. Стоимость Pimoroni Tiny 2040 составляет $12.

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

Подробнее..

Перевод Быстрое обнаружение Covid-19 на рентгеновских снимках с помощью Raspberry Pi

14.06.2021 18:13:31 | Автор: admin

Системы обнаружения Covid-19 на рентгеновских снимках выдают быстрые результаты, в частности информацию о том, насколько серьёзно лёгкие поражены вирусом Covid-19. Традиционные системы обнаружения Covid-19 обладают тем недостатком, что для формирования отчётов им требуется довольно длительное время, в то время как инфицированный человек нуждается в немедленной помощи. Кроме того, после каждого использования всех подобных систем обнаружения вируса часть деталей приходится утилизировать, что в некоторых случаях может приводить к их дефициту.К старту курса о машинном и глубоком обучении мы перевели статью о том, как эта проблема решается при помощи Raspberry Pi, кроме того, материал знакомит читателей с онлайн-платформой EDGE Impulse.


Наша система обнаружения Covid-19 на рентгеновских снимках требует лишь однократной установки и связки с рентгеновским аппаратом, после чего может работать сколько угодно времени. Она способна определять состояние инфицирования лёгких значительно быстрее традиционных систем. Такого результата можно достичь двумя способами: с помощью библиотеки Python или посредством создания и тренировки ML-модели. В этой статье мы расскажем, как создать и обучить модель. В скором времени мы опубликуем статьи о других методах, в которых используется предварительно обученная модель.

Что для этого нужно

Решение задачи начнём с подбора компонентов.

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

Предварительные требования

На Raspberry Pi должна быть установлена последняя версия ОС Raspbian. Также необходимо подготовить наборы данных для рентгеновских снимков лёгких, инфицированных и не инфицированных Covid-19. Такие снимки можно получить на сайте kaggle онлайн-ресурсе, где размещены рентгеновские снимки инфицированных пациентов, предоставленные сообществом экспертов и врачей. Аналогичные данные приведены на портале GitHub. Загрузим наборы данных рентгеновских снимков здоровых лёгких и лёгких, инфицированных Covid-19.

Теперь выберем платформу для создания ML-модели и обучим её обнаруживать на рентгеновских снимках инфицированные вирусом лёгкие. Здесь у нас есть разные варианты, например TensorFlow, PyTorch или онлайн-платформы: SensiML, Apache Spark, EDGE Impulse и так далее. Я выбрал EDGE Impulse.

В интерфейсе Edge Impulse переходим в меню создания проекта. Система спросит, как мы намереваемся использовать проект. Поскольку мы будем работать с проектом для создания ML-модели обработки изображений, выберем вариант, связанный с работой с изображениями.

Затем система спросит, как нужно классифицировать изображение (классификация одного или многих объектов). Здесь можно выбрать любой вариант. Я выбрал классификацию одного объекта (рис. 2). Щелчком мыши выберем только что созданный проект. Здесь система предложит указать, как его необходимо использовать. Выберем пункт Connect a development board (Подключение макетной платы). Через эту плату данные будут загружаться в проект (рис. 3).

1. Создание проекта1. Создание проекта2. Выбор типа для классификации2. Выбор типа для классификации3. Подключение макетной платы3. Подключение макетной платы

Установка на Raspberry Pi

Откроем окно терминала и с помощью приведённых ниже команд установим на Raspberry Pi зависимость для EDGE_Impulse:

curl -sL https://deb.nodesource.com/setup_12.x | sudo bash -sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-appsnpm config set user root && sudo npm install edge-impulse-linux -g --unsafe-perm

После установки запускаем Edge_Impulse командой edge-impulse-linux. Нам будет предложено ввести адрес электронной почты и пароль для EDGE Impulse. Вводим требуемые данные и входим в систему (рис. 4).

4. Вход в систему с помощью адреса электронной почты и пароля4. Вход в систему с помощью адреса электронной почты и пароля

Система попросит выбрать проект, к которому должно быть подключено устройство. Указываем название проекта (в моём случае это COVID-19 Detector) (рис. 5).

5. Выбор проекта5. Выбор проекта

Подготовка набора данных

Система выдаст URL-адрес для загрузки набора данных. Есть два варианта загрузки наборов данных рентгеновских снимков: либо через камеру Raspberry Pi (поместив рентгеновские снимки в кадр камеры), либо загрузив файлы фотографий средствами ПК/Raspberry Pi (рис. 6). Я рекомендую второй вариант.

Чтобы вручную загрузить с ПК наборы данных, то есть изображения рентгеновских снимков, выберем эти наборы в качестве тестовых и тренировочных изображений. Выбрав наборы, загрузим их для обучения и установим метки [в оригинале level, крайне вероятна сложная опечатка label, о пороге принятия решений речь идёт далее] для классификации изображений. Здесь я устанавливаю метку Covid-19 infected (Covid-инфицированные лёгкие) и Normal Lungs (Здоровые лёгкие) (рис. 8). Далее загружаем рентгеновские снимки здоровых лёгких и лёгких, инфицированных Covid-19.

6. Получение URL-адреса для создания модели6. Получение URL-адреса для создания модели7. Загрузка набора данных с использованием камеры Raspberry Pi для модели7. Загрузка набора данных с использованием камеры Raspberry Pi для модели8. Загрузка данных из файла изображения8. Загрузка данных из файла изображения

Если вы не успели загрузить изображения в соответствующие категории, с помощью функции Edit (Редактирование) можно позже добавить и/или обозначить их как "Инфицированное лёгкое" или "Здоровое лёгкое". Размечая набор данных, пожалуйста, будьте осторожны. Если пометить рентгеновские снимки здоровых лёгких как Covid-инфицированные, модель будет обучена неправильно, и её точность будет снижена. Перед первоначальной загрузкой наборов данных (с веб-сайта) необходимо создать две отдельные папки: одну для тренировочных, другую для тестовых наборов данных. В обеих папках создадим ещё две папки с названиями Infected lung X-ray (Рентген инфицированных лёгких) и Normal lung X-ray (Рентген здоровых лёгких) соответственно. Загрузим отдельно изображения из обеих папок и после загрузки распределим их по соответствующим категориям (рис. 9).

9. Установка уровня для рентгеновского снимка наборов данных для тренировки модели9. Установка уровня для рентгеновского снимка наборов данных для тренировки модели

Повторим те же шаги, загружая рентгеновские изображения инфицированных и здоровых лёгких для тестовых наборов данных. Опция загрузки изображений для тестовых наборов данных находится рядом с опцией тренировки (рис. 10).

10. Вкладка тренировочных данных10. Вкладка тренировочных данных

Тренируем модель

После загрузки рентгеновских снимков инфицированных и неинфицированных наборов данных модель готова к тренировке. Переходим на вкладку Impulse design, выбираем пункт Create Impulse и жмём кнопку Create Impulse (см. рис. 11). Затем добавляем блок обработки и блок обучения (рис. 12, 13).

11. Создание Impulse11. Создание Impulse12. Выбор блока обработки12. Выбор блока обработки13. Блок обучения.13. Блок обучения.

После добавления блоков обработки и обучения необходимо определить параметры [в оригинале the parameter в единственном числе опечатка]. Для этого нужно получить характеристики рентгеновского снимка и сохранить их (рис. 14, 15). Затем переходим к новой опции тренировки ML-модели. Для этого в экспертном или обычном режиме Keras выбираем тренировку создаваемой ML-модели. В нашем случае выбираем обычный режим. В этом режиме можно задать количество циклов обучения. При увеличении количества циклов обучения точность работы модели увеличится, так как она пройдёт через различные циклы обучения, но при этом также увеличится время, необходимое для обучения ML-модели. Здесь можно задать такие параметры, как порог принятия решений и скорость обучения, значения которых влияют на точность и время работы модели.

15. 3D-визуализация признаков модели15. 3D-визуализация признаков модели16. Генерация параметра16. Генерация параметра17. Настройка и создание Ml-модели17. Настройка и создание Ml-модели

В оригинале надпись к рисунку 15 Feathers graph for ML model., вероятнее всего Features graph for ML model, то есть визуализация пространства признаков модели в трёхмерном пространстве.

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

Теперь натренированная модель готова к тестированию. Протестировать модель мы можем с уже загруженным рентгеновским снимком, на котором модель попытается обнаружить инфекцию Covid-19 в лёгких.

18. Обнаружение инфекции по рентгеновскому снимку во время тестирования18. Обнаружение инфекции по рентгеновскому снимку во время тестирования19. Классификация снимка для проверки точности модели19. Классификация снимка для проверки точности модели

Развёртывание модели

Теперь наша ML-модель готова к развёртыванию. Развернуть созданную ML-модель для обнаружения инфекции вируса Covid-19 на рентгеновском снимке лёгкого можно многими способами и на разном оборудовании. Поскольку мы используем Linux, выбираем Linux. Затем открываем окно терминала и запускаем программу.

edge-impulse-runner-linux

После этого Raspberry Pi начнёт загрузку ML-модели и запустит её. Получаем URL-адрес, по которому можно наблюдать видео с камеры Raspberry Pi в реальном времени. Помещаем рентгеновский снимок лёгкого перед камерой (снимок должен быть хорошо освещён). Модель определяет инфицированное лёгкое и через несколько секунд выдает результаты Covid-теста.

Развёртывание ML-модели обнаружения Covid может быть осуществлено и другими способами. Используя SDK, можно обнаруживать Covid, развёртывая ML-модели на Python. Кроме того, можно загрузить рентгеновский снимок непосредственно в набор тестовых данных, а затем запустить ML-модель в режиме живой классификации она сработает за считанные секунды.

20. Выбор платы для развёртывания20. Выбор платы для развёртывания21. Развёртывание ML-модели в Raspberry Pi21. Развёртывание ML-модели в Raspberry Pi22. Обнаружение инфицированного лёгкого по рентгеновскому изображению22. Обнаружение инфицированного лёгкого по рентгеновскому изображению24. Вывод результатов24. Вывод результатов23. Обнаружение инфекции по рентгеновскому снимку23. Обнаружение инфекции по рентгеновскому снимку24. Здоровые лёгкие идентифицируются как здоровые24. Здоровые лёгкие идентифицируются как здоровые25. Обнаружение вирусной инфекции внутри лёгкого на рентгеновском снимке25. Обнаружение вирусной инфекции внутри лёгкого на рентгеновском снимке

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

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

Узнайте, как прокачаться и в других специальностях или освоить их с нуля:

Другие профессии и курсы

ПРОФЕССИИ

КУРС

Подробнее..

История про Гену, Чебурашку и тестирование производительности реактивного приложения, работающего на Raspberry Pi

24.04.2021 10:05:15 | Автор: admin

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

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

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

(Чебурашка быстро нарисовал на доске следующую диаграмму для Гены)

Архитектура системы управления апельсиновой плантациейАрхитектура системы управления апельсиновой плантацией

- Ты смеешься надо мной, Чебурашка?! Я же на английском ничего не понимаю!

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

- Чебурашка, я тебе вопрос о производительности задал! Я не просил пересказывать отрывок из презентации для инвесторов... Давай ближе к теме!

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

  1. Какой максимальный размер апельсиновой плантации, управление которой наша система поддерживает?

  2. Как продолжительно система может работать на плантации данного размера?

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

Прежде чем перейти к решению данных вопросов, давайте разберем виды тестов производительности:

Throughput
Тесты скорости системы

Load
Нагрузочные тесты

Peak/Stress/Endurance
Стресс тесты

Goal
Цель

How much data per second can the system handle?
(Пропускная способность системы)

How the system behaves under real-life load during the time?
(Как система ведет себя при продолжительной нормальной нагрузке?)

What is the limit for the system?
(Как ведет себя система на пределе и где этот предел?)

Issues to find
Помогает найти проблемы

Bottlenecks
(Узкие места)

Memory leaks
(Утечки памяти)

Concurrency issues
(Проблемы конкурентной работы с данными)

High CPU / RAM / Disk / Network of individual component
(Избыточное потребление ресурсов)

Hardware issues, for example overheating
(Технические проблемы, например перегрев)

Data corruption
(Повреждение данных)

Hardware corruption
(Физические повреждения системы)

Recovery issues
(Проблемы восстановления после сбоев)

- Вот, Чебурашка, можешь ведь изъясняться и на русском, когда захочешь!

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

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

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

- Отлично, так и сделаем! Я согласую это с заказчиками прямо сегодня!

- Геннадий, давай я тебе расскажу об отдельном приложении, которое я разработал специально для проведения всех названных выше типов тестов производительности. Это приложение отвечает за запуск сценариев тестов, управление эмуляторами, сбор данных потребления ресурсов (CPU, Memory, Disk I/O, DIsk space usage, Network I/O) всей системой, так и отдельными компонентами, количество ошибок в логах, пропускную способность системы и целостность данных.

- Почему ты не использовал какое-либо готовое решение? Я слышал про такие инструменты для нагрузочного тестирования, как Gatling или Tank от Яндекса?

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

Архитектура системы тестов производительностиАрхитектура системы тестов производительности

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

Через пару месяцев...

- Добрый день, Чебурашка! Какие результаты нагрузочных тестов?

- Добрый день, Геннадий! При помощи нашей системы тестов производительности мы смогли обнаружить и исправить множество дефектов и узких мест, также мы внедрили нагрузочные тесты в CI/CD Pipeline и мы запускаем их регулярно.

Мы можем сказать, что:

  1. Один экземпляр системы способен работать на плантации площадью до 5 гектаров с количеством деревьев до 1250 штук (Далее: "стандартные условия").

  2. Система с хранилищем в 128 Гб в стандартных условиях способна непрерывно работать более 1 месяца.

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

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

- Обсудим. Но это уже другая история...

Подробнее..

Создание терминала для СКУД и УРВ

21.06.2021 12:17:59 | Автор: admin

Вступление

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

Историю можно начать с того, что наша компания очень долгое время сотрудничает со всемирно известной сетью фастфудов - KFC (на территории Беларуси и Украины). Головной болью такой сферы, как HoReCa, был и будет учет рабочего времени сотрудников. Учитывая огромную текучку кадров, в том числе и обычных студентов, которые пришли подработать на непродолжительное время, становится сложно проконтролировать, сколько часов отработано тем или иным сотрудником. Плюс немаловажным моментом стало то, что сотрудники часто перемещаются с ресторана на ресторан, а это требует дополнительного контроля. Как же быть?

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

Поэтому был придумал предельно простой и быстрый сценарий действий на терминале:

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

  2. Выбрать на тачскрине Работа, после чего отправиться на свое рабочее место и приступить к работе

  3. При необходимости перерыва подойти к терминалу, пройти идентификацию, выбрать Перерыв

  4. При возвращении на рабочее место - подойти к терминалу, пройти идентификацию, выбрать Работа

  5. По окончанию рабочей смены подойти к терминалу, пройти идентификацию и выбрать Завершить работу.

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

Разработка

Имея на руках техническое задание, была разработана структурная и функциональная схема. Далее пошло самое интересное: мы начали рассматривать различные варианты одноплатных компьютеров, которые бы смогли обеспечить нужный функционал терминала. Среди вариантов были следующие компьютеры: Banana Pi M4, Orange Pi PC+, ODROID-C4, NanoPi M4 и Raspberry PI Computer Module 3+. Произведем небольшое сравнение данных моделей.

Banana Pi M4

Orange Pi PC+

ODROID-C4

NanoPi M4

Raspberry PI CM3+

Память

Слот MicroSD с поддержкой расширения до 256 ГБ и флэш-память eMMC 8 ГБ с поддержкой до 64 ГБ

TF-карта (макс. 32ГБ) / слот для карты eMMC

8 ГБ флэш-память EMMC

1x разъем EMMC (доступно 8/16/32/64 ГБ)

1 слот Micro SD

нет встроенной eMMC, но есть разъем eMMC,
1 слот для MicroSD до 128 GB

8 GB eMMc + поддержка 1 слота microSD

RAM

1 GB DDR4 (опционально 2 GB)

1GB DDR3

4GB DDR4

Двухканальный 2GB DDR3-1866

1GB LPDDR2 SDRAM

CPU

Realtek RTD1395 ARM Cortex-A53 Quad-Core 64 Bit 1.8 GHz

H3 Quad-coreCortex-A71.2 GHz

Amlogic S905X3 Quad-Core Cortex-A55 ARMv8.2-A 64-bit 1.5GHz

RK3399- Cortex-A72 + Quad Core Cortex-A531.8 GHz

Broadcom BCM2837B0 с четырьмя ядрами Cortex A53 1.2 GHz

GPU

Mali 470 MP4 GPU OpenGL ES 1.1/2.0

Mali400MP2 GPU 600MHz
с поддержкой OpenGL ES 2.0

Mali-G31, поддержка OpenGL ES 3.2 и API Vulkan последнего поколения

Mali-T864поддержка OpenGL ES1.1/2.0/3.0/3.1, OpenCL, DX11 и AFBC

Broadcom VideoCore IV

Сеть

Ethernet 10/100/1000 Мбит / с
Опциональный USB-ключ Wi-Fi. Поддержка PoE

10/100 Ethernet RJ45

RJ45 Ethernet порт (10/100/1000)

Порт Gbps Ethernet

10/100 для подключения маршрутизатора или коммутатора с функцией PoE

После детального изучения и анализа цены (все модели находились в примерно одном ценовом диапазоне на момент их анализа - 2019 год), мы все же пришли к выводу, что лучше всего подойдет Raspberry PI Computer Module 3+. Почему Raspberry ? Да, некоторые характеристики уступают конкурентам, однако главным преимуществом стало то, что по Raspberry банально больше поддерживаемых библиотек и лучше техническая поддержка, т.к Raspberry на рынке с 2012 года и вокруг него сформировалось активное комьюнити.

Решение со встроенной памятью eMMC, предусмотренное в CM3, позволяет не использовать флеш-карту в качестве носителя ОС. Большое количество циклов перезаписи eMMC повышает надежность и срок службы памяти по сравнению с флеш-картами. При этом мы зарезервировали разъем для SD карт. Сразу можно сказать, что заявленной памяти для терминала хватает с лихвой, ибо сохраняемые события весят от силы пару килобайт. Что касается хранения фотографий, то здесь все сложнее: программно мы поставили ограничение в 5000 фото, но так как у нас зарезервирована флеш-карта, то данный лимит можно расширить до приемлемого значения.

Разработку управляющей платы мы начали с организации необходимых питающих напряжений. На нашей плате нам необходимо было обеспечить 3 значения напряжений: 5.0В, 3.3В и 1.8В. Внешний источник питания у нас 12В 3А. Для получения 5В и 3.3В мы использовали схему на основе широтной импульсной модуляции. Для источника питания 1.8В мы задействовали линейный понижающий преобразователь. Это выглядит, примерно, следующим образом.

Схема питания терминалаСхема питания терминала

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

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

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

То есть если закоротить питание, считыватель уйдет в защиту (питание считывателя отключится), а терминал продолжит работу. Номиналы резисторов R51 и R52 задают выходной ток. Изменяя номинал резистора R51 можно менять ток ограничения в значительных пределах (у нас стоят заданные на схеме номиналы исходя из рассчитанной нами нагрузки).

Питание мы организовали, самое время перейти к периферии.

К слову, Raspberry поддерживает UART-интерфейс и 2 USB версии 2.0. Через один из доступных USB мы решили организовать доступ к Ethernet с помощью микросхемы LAN9514 . Второй USB используется для подключения периферии, например индикатор алкоголя. Также задействовав GPIO для подключения кнопок, электромагнитных замков, защёлок, алкостестера в дискретном режиме работы и картаприемников.

Схема реализации Ethernet и USBСхема реализации Ethernet и USB

У CM3 на борту всего 2 UART. Один нам пригодится для организации интерфейса RS-485, а второй - debug. Поэтому мы использовали микросхему FT4232HL, для увеличения количества интерфейсов. У нее есть входной интерфейс USB, который поддерживает связь с LAN9514, он же в свою очередь коннектится с CM3.

Схема расширения количества UART-овСхема расширения количества UART-ов

Вот теперь у нас стало больше на целых 4 UARTa (задействуем всего 2). Один используется для подключения биометрического модуля отпечатков пальцев от южнокорейского производителя Suprema-SFM6020-OP6-8M/16M (8M - 5К отпечатков, 16М- 25К отпечатков).

Второй для подключения карточного модуля 7941D (поддерживает 2 частоты Emarine (125 кГц) и Mifare (13,56 МГц).

Suprema-SFM6020-OP6-8MSuprema-SFM6020-OP6-8M

Один из выделенных UART, как и планировали, мы задействовали под RS-485, позволяющий подключать внешние карточные или биометрические считыватели, а также передавать информацию во внешние системы при необходимости интеграции. Схема 485-го представлена ниже.

RS-485RS-485

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

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

Входной WiegandВходной WiegandВыходной WiegandВыходной Wiegand

Немаловажным моментом будет, что терминал имеет 2 реле для управления замком, турникетом или шлагбаумом. Рассмотрим данный момент на примере подключения турникета (стандартная ситуация для СКУД). Есть два режима управления турникетом, потенциальный режим и импульсный. При потенциальном режиме управления для разблокировки турникета в направлении А срабатывает выход L1 OUT (в направлении В выход L2 OUT). При окончании данного времени или при совершении прохода выходной сигнал возвращается в исходное состояние.

В импульсном режиме для разблокировки выхода L1 OUT и L2 OUT срабатывают кратковременно, посылая управляющий импульс на турникет (обычно 0,2-0,3 секунды). При получении импульса турникет разблокируется в соответствующем направлении на время 5 секунд либо пока не будет совершен проход в данном направлении.

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

Например, для работы с турникетами PERCo в контроллере должен быть установлен импульсный режим управления. Для этого время срабатывания сигналов L1 OUT и L2 OUT должно быть установлено в пределах от 0,2 до 1 секунды.

Подключение турникета PERCoПодключение турникета PERCo

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

  1. RPi D - 72.4 градуса обзор, 5 mpx, размер камеры 25x24 мм (старое исполнение).

  2. RPi G - 160 градусов обзор, 5 mpx, размер камеры 25x24 мм (теперь используем только этот вариант).

Схема организации интерфейсов DSI и CSIСхема организации интерфейсов DSI и CSI

Выбирая дисплей, выбор снова пал на знакомый бренд - 7-ми дюймовый touch-screen от Raspberry с разрешением 800x480 и DSI интерфейсом.

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

Корпус терминалаКорпус терминала

Собрав все воедино мы получили терминал данного вида.

Знакомьтесь, терминал D1!Знакомьтесь, терминал D1!

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

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

Подробнее..

Перевод Запуск домашнего веб-сервера без статического IP с помощью Python

13.05.2021 08:09:48 | Автор: admin


Приветствую жителей Хабра!


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


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




Недавно я решил установить веб-сервер на Rasberry Pi, работающий за моим домашним маршрутизатором. У меня есть опыт настройки веб-серверов на виртуальных машинах Linux со статическими IP-адресами, поэтому в настройке сервера apache2 на Pi нет ничего особенного, и в Интернете есть сотни руководств. Проблема только в том, что при изменении внешнего IP вашего роутера сайт сломается! Один из способов решить эту проблему заплатить своему интернет-провайдеру за статический IP-адрес но тогда в чём веселье?!


Во многих своих последних проектах я использовал Google Domains для покупки доменного имени и обычно запускал сайты без собственных гугловских серверов имен на отдельном VPS/облачном сервере. Но для моего домашнего сервера я решил использовать невероятно простую в настройке функцию переадресации IP-адресов поддоменов, чтобы перенаправить базовый домен (@.example.com) на IP-адрес моего маршрутизатора (а затем настроить мой маршрутизатор на перенаправление с http портов на https порты на Pi). Тогда мне пришлось бы вручную проверять, работает ли сайт, и менять IP при необходимости. Очевидно, это не идеальный план, поэтому я решил написать скрипт для автоматизации этого процесса.


На заметку, вы можете найти полный скрипт на гитхабе или импортировать пакет Python с помощью pip install domains-api

Есть много способов проверить ваш внешний IP-адрес, и один из самых простых, которые я нашел, был через ipify API (api.ipify.org), который просто возвращает ваш общедоступный IP-адрес. При использовании Python библиотеки requests запрос выглядит следующим образом:


IP = requests.get('https://api.ipify.org').text

Вот и все, это ваш внешний IP. Легко, правда? Есть много других подобных способов получить внешний IP-адрес, но я считаю, что это самый простой.


Итак, что еще нам нужно для нашего скрипта? Нам нужно где-то хранить IP-адрес, чтобы проверять будущие запросы. Изначально я решил сохранить его в простом текстовом файле. Нам также нужен способ либо уведомить пользователя, либо обновить domain.google.com, либо и то, и другое. Первый вариант довольно легко реализовать с помощью библиотеки электронной почты для Python, поэтому я настроил её для работы с моей учетной записью Gmail следующим образом (вам нужно будет разрешить менее безопасные приложения (less secure apps) в своей учетной записи Google):


from email.message import EmailMessagedef send_notification(new_ip):    msg = EmailMessage()    msg.set_content(f'IP has changed!\nNew IP: {new_ip}')    msg['Subject'] = 'IP CHANGED!'    msg['From'] = GMAIL_USER    msg['To'] = GMAIL_USER    try:        server = smtplib.SMTP_SSL('smtp.gmail.com', 465)        server.ehlo()        server.login(GMAIL_USER, GMAIL_PASSWORD)        server.send_message(msg)        server.close()        log_msg = 'Email notification sent to %s' % GMAIL_USER)        logging.info(log_msg)    except (MessageError, ConnectionError) as e:        log_msg = 'Something went wrong: %s' % e        logging.warning(log_msg)

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


def enc_pwd():    pwd = base64.b64encode(getpass("What's your email password?: ").encode("utf-8"))    with open('cred.txt', 'wb') as f:        f.write(pwd)def read_pwd():    if os.path.isfile(f"{CWD}/cred.txt"):        with open(f'{CWD}/cred.txt', 'r') as f:            if f.read():                password = base64.b64decode(pwd).decode('utf-8')                logging.info('Password read successfully')                return password            else:                    enc_pwd()                read_pwd()    else:        enc_pwd()        read_pwd()

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


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


def check_ip():    if os.path.isfile('ip.txt'):        # Снова проверим предыдущий IP        with open('ip.txt', 'r') as rf:            line = rf.readlines()            if not line:                first_run = True            elif line[0] == IP:                first_run = False                change = False            else:                first_run = False                change = True    else:        first_run = Trueif first_run or change:        # Запишем новый IP в файл        with open('ip.txt', 'w') as wf:            if first_run:                wf.write(IP)            elif change:                wf.write(IP)                # Уведомим пользователя:                send_notification(IP)    time.sleep(21600)       # в окончательной версии на моем боевом веб-сервере я удалил это 6-часовое ожидание и рекурсивный вызов в конце и просто добавил скрипт в crontab для запуска один раз в час. Мне также пришлось сделать все пути к файлам абсолютными, поскольку по умолчанию для crontab рабочий каталог - '/'.    check_ip()

Бум! Это была первая реализация моей идеи. Когда я получаю уведомление по электронной почте, я могу просто изменить правила переадресации на сайте domains.google.com


Стоп, что? Мне все еще нужно это делать самому? Конечно нет, есть способ проще!


Что ж, оказывается, есть два способа автоматизировать это один значительно менее эффективный, но бесконечно более захватывающий, а другой довольно скучный, но бесконечно более эффективный! Я начну, как и сделал, с захватывающего и сложного способа: слышали когда-нибудь о Selenium для автоматизации тестирования веб-сайтов? Я решил написать сценарий, который будет физически входить в домены Google и перемещаться по сайту, чтобы изменить правила для меня, если и когда изменится IP. Однако это приводило к следующим проблемам:


Прежде всего, Google Domains (и другие сервисы Google, такие как Gmail) довольно хорошо обнаруживают автоматизацию браузера и просто не позволяют вам войти в систему через веб-драйвер Selenium. Мне посчастливилось найти этот ответ (есть и другие решения) в Stack Overflow, который предлагал войти в сам Stack Overflow с вашей учетной записью Google, прежде чем переключаться на желаемую службу Google, что действительно работало, пока я не брал под контроль браузер и при необходимости не вводил капчу. Со скриптом, запущенным на моем ноутбуке или десктопе, это замечательно тем более, что после первоначальной проверки Captcha StackOverflow, похоже, больше не проверял тот же компьютер, поэтому после этого веб-драйвер можно было запустить в автономном режиме, но это не подходит для веб-сервера! Хотя я мог заставить веб-драйвер нормально работать с помощью PyVirtualDisplay и Geckodriver (веб-драйвер для Firefox), ему удавалось только один раз попасть на желаемую страницу Мои домены, а в других случаях вообще не мог войти в систему из-за Captcha.



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


Так уж получилось, что у Google Domains есть API именно для той цели, которая мне нужна. Я изначально отклонил APi, когда не смог заставить его работать с правилами переадресации поддоменов, которые я использовал, не понимая, что API предназначен для изменения правил динамического DNS эта документация стала намного более понятной после того, как я настроил запись динамического DNS вместо стандартного правила Переадресация поддоменов (спасибо Джереми Гейлу за его отличный урок о том, как сделать что-то подобное с помощью простого сценария bash, который помог мне победить эту проблему!)


Раздел Synthetic records на странице конфигурации DNS Google Domains должен выглядеть следующим образом:


Вот как должна выглядеть ваша запись


Выберите Dynamic DNS вместо Subdomain forward.


Затем вы получите автоматически сгенерированные учетные данные, необходимые для аутентификации с помощью API:


Просто нажмите Просмотреть учетные данные, скопируйте и вставьте их в свой запрос API.


Теперь, зная этот метод, я смог значительно уменьшить длину и нагрузку на скрипт! TTL динамического DNS также очень низок, по умолчанию: 1 мин, что сокращает возможное время простоя ещё один дополнительный бонус. Всё, что мне было нужно, это включить вызов API в мою функцию check_ip(), и он сделает все за меня! И эта единственная строка кода (2 с вызовом логирования) выглядит так:


req = requests.post(f'https://<auto_generated_username>:<auto_generated_password>@domains.google.com/nic/update?hostname=@.example.com&myip={IP}')logging.info(req.content)

Я заключил всё в блок try / except, чтобы перехватить любые исключения, и таким образом этот довольно простой, но удивительно полезный скрипт был почти готов. Теперь осталось только добавить его в crontab на моем веб-сервере и дать ему работать, и (теоретически) мне больше не придется беспокоиться о смене IP!


Стоп! Время рефакторинга:


Так, вот, о чем я позаботился! Чтобы сделать этот скрипт универсально доступным, я реорганизовал всё, чтобы использовать более объектно-ориентированный подход, основанный на классах, с классами User и IpChanger. Класс User содержит все учетные данные для входа в smtp и вызова API domains.google, а первый созданный экземпляр вместе с атрибутом previous_ip, для проверки, сохраняется в одном pickle файле (аналогично сериализации в JavaScript); в будущих экземплярах класса User() пользовательский экземпляр создается из pickle, если не указано иное. Класс User также содержит метод уведомления пользователя по электронной почте, который теперь включает условие ошибки на случай сбоя вызова API. Затем класс IpChanger вызывает класс User() каждый раз, когда он создается, а также выполняет все различные проверки и запросы, поэтому вы просто инициализируете класс IpChanger() и всё; он работает! Я также добавил несколько различных вариантов для уведомлений по электронной почте, более конкретную обработку ошибок/логирование, некоторые аргументы/параметры командной строки для управления профилем пользователя, а также смог избавиться от неуклюжей обработки файла ip.txt, сохранив всё в одном пользовательском экземпляре.


Готовый, практически уникальный (!) результат можно увидеть ниже во всей его полноте, а также его можно форкнуть/клонировать с моего GitHub (включая README.md с инструкциями по установке). Я также выпустил его как пакет Python на pypi.org, который вы можете просмотреть здесь или установить обычным способом с помощью: pip install domains-api


Любые вопросы, отзывы или предложения пишите!




Какие ещё методы стабильной работы веб-сервера без статического адреса вы знаете? И как можно доработать это решение?


Полный скрипт (без file_handlers.py):
import osimport sysimport getoptimport base64import smtplibfrom email.message import EmailMessagefrom getpass import getpassfrom itertools import cyclefrom requests import get, postfrom requests.exceptions import ConnectionError as ReqConErrorfrom domains_api.file_handlers import FileHandlersfh = FileHandlers()def get_ip_only():    """Gets current external IP from ipify.org"""    current_ip = get('https://api.ipify.org').text    return current_ipclass User:    BASE_URL = '@domains.google.com/nic/update?hostname='    def __init__(self):        """Create user instance and save it for future changes to API and for email notifications."""        self.domain, self.dns_username, self.dns_password, self.req_url = self.set_credentials()        self.notifications, self.gmail_address, self.gmail_password = self.set_email()        self.outbox = []    def set_credentials(self):        """Set/return attributes for Google Domains credentials"""        self.domain = input("What's your domain? (example.com / subdomain.example.com): ")        self.dns_username = input("What's your autogenerated dns username?: ")        self.dns_password = getpass("What's your autogenerated dns password?: ")        self.req_url = f'https://{self.dns_username}:{self.dns_password}{self.BASE_URL}{self.domain}'        return self.domain, self.dns_username, self.dns_password, self.req_url    def set_email(self):        """Set/return attributes for Gmail credentials if user enables notifications"""        self.notifications = input("Enable email notifications? [Y]all(default); [e]errors only; [n]no: ").lower()        if self.notifications != 'n':            self.gmail_address = input("What's your email address?: ")            self.gmail_password = base64.b64encode(getpass("What's your email password?: ").encode("utf-8"))            if self.notifications != 'e':                self.notifications = 'Y'            return self.notifications, self.gmail_address, self.gmail_password        else:            return 'n', None, None    def send_notification(self, ip=None, msg_type='success', error=None, outbox_msg=None):        """Notify user via email if IP change is made successfully or if API call fails."""        if self.notifications != 'n':            msg = EmailMessage()            msg['From'] = self.gmail_address            msg['To'] = self.gmail_address            if ip and msg_type == 'success' and self.notifications not in {'n', 'e'}:                msg.set_content(f'IP for {self.domain} has changed! New IP: {ip}')                msg['Subject'] = 'IP CHANGED!'            elif msg_type == 'error' and self.notifications != 'n':                msg.set_content(f"Error with {self.domain}'s IPChanger: ({error})!")                msg['Subject'] = 'IPCHANGER ERROR!'            elif outbox_msg:                msg = outbox_msg            try:                server = smtplib.SMTP_SSL('smtp.gmail.com', 465)                server.ehlo()                server.login(self.gmail_address, base64.b64decode(self.gmail_password).decode('utf-8'))                server.send_message(msg)                server.close()                return True            except Exception as e:                log_msg = 'Email notification not sent: %s' % e                fh.log(log_msg, 'warning')                self.outbox.append(msg)                fh.save_user(self)                sys.exit(1)class IPChanger:    ARG_STRING = 'cdehinu:'    ARG_LIST = ['credentials',                'delete_user',                'email',                'help',                'ip',                'notifications',                'user_load=']    def __init__(self, argv=None):        """Check for command line arguments, load/create User instance,        check previous IP address against current external IP, and change via the API if different."""        # Load old user, or create new one:        if os.path.isfile(fh.user_file):            self.user = fh.load_user(fh.user_file)            fh.log('User loaded from pickle', 'debug')        else:            self.user = User()            fh.log('New user created.\n(See `python -m domains_api --help` for help changing/removing the user)', 'info')        self.current_ip = self.get_set_ip()        # Parse command line options:        try:            opts, _args = getopt.getopt(argv, self.ARG_STRING, self.ARG_LIST)        except getopt.GetoptError:            print('''Usage:python/python3 -m domains_api --help''')            sys.exit(2)        if opts:            self.arg_parse(opts)        # Check IPs:        try:            if self.user.previous_ip == self.current_ip:                log_msg = 'Current IP: %s (no change)' % self.user.previous_ip            else:                self.user.previous_ip = self.current_ip                fh.save_user(self.user)                self.domains_api_call()                log_msg = 'Newly recorded IP: %s' % self.user.previous_ip            fh.log(log_msg, 'info')        except AttributeError:            setattr(self.user, 'previous_ip', self.current_ip)            fh.save_user(self.user)            self.domains_api_call()        finally:            if fh.op_sys == 'pos' and os.geteuid() == 0:                fh.set_permissions(fh.user_file)            # Send outbox emails:            if self.user.outbox:                for i in range(len(self.user.outbox)):                    self.user.send_notification(outbox_msg=self.user.outbox.pop(i))                    fh.log('Outbox message sent', 'info')                fh.save_user(self.user)            fh.clear_logs()    def get_set_ip(self):        """Gets current external IP from api.ipify.org and sets self.current_ip"""        try:            return get_ip_only()        except (ReqConError, ConnectionError) as e:            fh.log('Connection Error. Could not reach api.ipify.org', 'warning')            self.user.send_notification(msg_type='error', error=e)    def domains_api_call(self):        """Attempt to change the Dynamic DNS rules via the Google Domains API and handle response codes"""        try:            req = post(f'{self.user.req_url}&myip={self.current_ip}')            response = req.text            log_msg = 'Google Domains API response: %s' % response            fh.log(log_msg, 'info')            # Successful request:            _response = response.split(' ')            if 'good' in _response or 'nochg' in _response:                self.user.send_notification(self.current_ip)            # Unsuccessful requests:            elif response in {'nohost', 'notfqdn'}:                msg = "The hostname does not exist, is not a fully qualified domain" \                      " or does not have Dynamic DNS enabled. The script will not be " \                      "able to run until you fix this. See https://support.google.com/domains/answer/6147083?hl=en-CA" \                      " for API documentation"                fh.log(msg, 'warning')                if input("Recreate the API profile? (Y/n):").lower() != 'n':                    self.user.set_credentials()                    self.domains_api_call()                else:                    self.user.send_notification(self.current_ip, 'error', msg)            else:                fh.log("Could not authenticate with these credentials", 'warning')                if input("Recreate the API profile? (Y/n):").lower() != 'n':                    self.user.set_credentials()                    self.domains_api_call()                else:                    fh.delete_user()                    fh.log('API authentication failed, user profile deleted', 'warning')                    sys.exit(1)        # Local connection related errors        except (ConnectionError, ReqConError) as e:            log_msg = 'Connection Error: %s' % e            fh.log(log_msg, 'warning')            self.user.send_notification(msg_type='error', error=e)    def arg_parse(self, opts):        """Parses command line options: e.g. "python -m domains_api --help" """        for opt, arg in opts:            if opt in {'-i', '--ip'}:                print('''            [Domains API] Current external IP: %s                ''' % get_ip_only())            elif opt in {'-h', '--help'}:                print(                    """        domains-api help manual (command line options):

    You will need your autogenerated Dynamic DNS keys from    https://domains.google.com/registrar/example.com/dns    to create a user profile.    python -m domains_api                    || -run the script normally without arguments    python -m domains_api -h --help          || -show this help manual    python -m domains_api -i --ip            || -show current external IP address    python -m domains_api -c --credentials   || -change API credentials    python -m domains_api -e --email         || -email set up wizard > use to delete email credentials (choose 'n')    python -m domains_api -n --notifications || -toggle email notification settings > will not delete email address    python -m domains_api -u user.file       || (or "--user_load path/to/user.file") -load user from pickle file    python -m domains_api -d --delete_user   || -delete current user profile                                             || User files are stored in "/var/www/domains_api/domains.user""""            )        elif opt in {'-c', '--credentials'}:            self.user.set_credentials(update=True)            self.domains_api_call()            fh.save_user(self.user)            fh.log('API credentials changed', 'info')        elif opt in {'-d', '--delete'}:            fh.delete_user()            fh.log('User deleted', 'info')            print('>>>Run the script without options to create a new user, or '                  '"python3 -m domains_api -u path/to/pickle" to load one from file')        elif opt in {'-e', '--email'}:            self.user.set_email()            fh.save_user(self.user)            fh.log('Notification settings changed', 'info')        elif opt in {'-n', '--notifications'}:            n_options = {'Y': '[all changes]', 'e': '[errors only]', 'n': '[none]'}            options_iter = cycle(n_options.keys())            for option in options_iter:                if self.user.notifications == option:                    break            self.user.notifications = next(options_iter)            fh.save_user(self.user)            log_msg = 'Notification settings changed to %s' % n_options[self.user.notifications]            fh.log(log_msg, 'info')            if self.user.notifications in {'Y', 'e'} and not self.user.gmail_address:                fh.log('No email user set, running email set up wizard...', 'info')                self.user.set_email()                fh.save_user(self.user)        elif opt in {'-u', '--user_load'}:            try:                self.user = fh.load_user(arg)                fh.save_user(self.user)                fh.log('User loaded', 'info')            except FileNotFoundError as e:                fh.log(e, 'warning')                sys.exit(2)        sys.exit()

if name == "main":
IPChanger(sys.argv[1:])


<!--</spoiler>-->
Подробнее..

MirkoPC док-станция для Raspberry Pi 4, превращающая малинку в полноценный ПК

20.04.2021 14:21:11 | Автор: admin

Raspberry Pi 4 Model B отличный одноплатник, который можно использовать для решения обширного спектра задач. Все бы хорошо, но у платы, в силу ее небольшого размера, ограниченное число портов и коннекторов. Потенциально плата поддерживает гораздо большее их количество, чем реализовали разработчики.

Вот бы добавить HDMI, несколько USB, Ethernet! И это уже можно сделать, причем почти без усилий. Разработчик из Польши по имени Mirek предложил собственное решение своеобразную док-станцию для малинки, которая превращает ее в полноценный Linux-ПК. На этой плате есть несколько выходов для дисплеев, USB-порты, разъем для подключения PCIe NVMe и кое-что еще.

Стоит напомнить, что сама малинка четвертой модели базируется на четырехъядерном ARM Cortex-A72. Есть Wi-Fi 6 и Bluetooth 5.0. Плата MirkoPC добавляет к этому:

  • 1 x M.2 2242/2280 M-key сокет (PCIe x1 Gen 2);
  • 1 x microSD слот;
  • 1 x Gigabit Ethernet порт;
  • 2 x HDMI-порта (1 обычный, 1 micro);
  • 4 x USB 2.0;
  • 1 x 28-pin GPIO header;
  • 2 x MIPI CSI-2 интерфейса камеры;
  • 2 x MIPI DSI интерфейсы дисплея;
  • 1 x 3.5mm;
  • 1 x USB-C порт питания (5V/3A).

Кроме того, у платы есть DAC-конвертер (вплоть до 32-bit/384 kHz) и усилитель наушников, плюс модуль часов реального времени с батарейкой, а также инфракрасный порт для использования в качестве пульта управления. Еще разъем для подключения кулера и светодиоды.

Несмотря на то, что малинка не самая мощная плата в своем классе (она уступает, например, Intel NUC), одноплатник оснащен флагманским для Raspberry Pi чипом Broadcom BCM2711. При необходимости можно приобрести Compute Modules с 8 ГБ ОЗУ LPDDR4-3200 и 32 ГБ внутренней памяти.

Новая разработка дает возможность установить microSD или даже NVMe SSD любого объема.


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

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

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


Здесь тоже куча портов и коннекторов:

  • Gigabit Ethernet;
  • M.2 2242 сокет;
  • HDMI-порт;
  • 3 x USB Type-A;
  • 1 x USB Type-C OTG;
  • microSD слот;
  • 40-pin Raspberry Pi GPIO header;
  • коннекторы для экранов и камеры;
  • 2 x power inputs (2.1 мм и 3.5 мм).

Стоимость TOFU около $110. Скорее всего, и плата от польского разработчика будет стоить примерно столько же.

Подробнее..

Перевод SparkFun Pro Micro RP2040 функциональная плата с чипом от Raspberry ценой в 10

05.05.2021 00:09:59 | Автор: admin

Прошло совсем немного после анонса собственного чипа от Raspberry Foundation, а плат с этой микросхемой вышло немало. Есть относительно дорогие, есть не очень. Одна из наименее дорогих плат SparkFun Pro Micro RP2040. Ее цена составляет $10.

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

Коротко о главном


У SparkFun целый модельный ряд плат RP2040. Но система, которая здесь описана наиболее типичный представитель линейки. Она недорогая, это узнаваемый форм-фактор, плюс сравнимые с конкурентами характеристики. Кстати, она похожа на Adafruit Feather RP2040, плату, которую мы уже описывали, но у новой модели есть 16 МБ флеш-памяти.

Характеристики:
  • SoC: ARM Cortex M0+ c 133 МГц.
  • SRAM: 264 КБ
  • Внутренняя память: 16 МБ
  • GPIO: 20 GPIO пинов следующей конфигурации 10 x PWM, 10 x Digital I/O, 4 x Analog 12-bit ADC, 1 x I2C (Qwiic), SPI, 2 x UART, программируемый IO, 1 x WS2812 / NeoPixel.
  • USB: USB C

Дизайн SparkFun Pro Micro RP2040



Будучи почти такого же размера, как ItsyBitsy RP2040 от Adafruit, SparkFun Pro Micro RP2040 имеет узнаваемый дизайн, идеальной подходящий для использования в макетной плате. Но система прекрасно подходит и для работы над домашними проектами ее без проблем можно распаять или подключить к чему угодно (ну, почти).

Ярко-красный цвет платы выделяет ее из обилия плат черного и зеленого цветов. Выводы GPIO помечены при помощи шелкографии причем на обеих сторонах платы, так что запутаться не получится. Питание можно подавать как через USB-C порт, так и через RAW / + и GND. Правда, нельзя превышать характеристики в 5В и 600 мА. На противоположном конце платы располагается разъем Qwiic.

Разъемы такого типа совместимы с форматом Adafruit Stemma QT, благодаря чему к плате можно подключать широкий спектр моделей других плат, датчиков, сенсоров и дисплеев. Есть и переходники, которые еще больше расширяют возможности подключения дополнительных систем. Ну а доступ к UART, контактам SPI осуществляется через GPIO.

Использование SparkFun Pro Micro RP2040



Тесты проводились с последними версиями MicroPython и CircuitPython. Для CircuitPython тестировалась базовая GPIO функциональность с использованием светодиода и кнопки. Все это работало без проблем. Второй тест заключался в подключении WS2812 / NeoPixel, установке библиотеки neopixel CircuitPython. Все это заняло несколько минут, после чего все заработало, как и требовалось.

Третий тест подключение емкостного тач-сенсора при помощи кабеля Qwiic / Stemma QT. С MicroPython удалось протестировать использование I2C устройств посредством Qwiic-коннектора. Первым таким устройством стал OLED-экран, который был запрограммирован на вывод серии графических образов и анимаций. Четвертый тест подключение четырехзначного семисегментного дисплея с питанием от TM1637. Здесь уже потребовался переходник. В общем-то, и в этом случае проблем никаких не было. Использовался генератор случайных четырехзначных чисел и прокрутка текста.

Pro Micro RP2040 от SparkFun объединяет в себе лучшие возможности двух плат Adafruit RP2040: ItsyBitsy RP2040 и QT Py RP2040. Как и ItsyBitsy RP2040 от Adafruit, Pro Micro RP2030 от SparkFun предлагает большой выбор контактов GPIO, а также разъем Qwiic / Stemma QT и USB-C, как и QT Py.

Юзкейсы для платы


Как и говорилось выше, она отлично подходит для любых проектов. Можно сделать, например, робота. Разъем Qwiic и 16 МБ флеш-памяти позволяют использовать Pro Micro RP2040 в проектах по сбору данных.


При цене в $10, как у ItsyBitsy RP2040, эта плата обладает дополнительными возможностями, включая большое количество GPIO-пинов и Qwiic / Stemma QT коннектор. При этом размеры платы очень небольшие.

Если вам нужна хорошая плата среднего размера с неплохим выбором функций, то SparkFun Pro Micro RP2040 лучший выбор.

Подробнее..

Перевод Одноплатник Pimoroni Pico LiPo как микроконтроллер от Raspberry, только лучше

02.06.2021 20:09:34 | Автор: admin

После того, как Raspberry Pi Foundation разработала и анонсировала свой процессор RP2040, на рынке появилось несколько одноплатников на его основе, включая собственную разработку Raspberry. Среди наиболее заметных RP2040-проектов стоит отметить Adafruit Py RP2040 и Pimoroni Tiny 2040. Есть еще и Adafruit Feather RP2040 с Cytron Maker Pi Pico.

Напомним, что сам по себе проект Raspberry Pi Pico это, по сути, микроконтроллер с GPIO и возможностью программирования. Плату можно применять для эмуляции самых разных типов интерфейсов, включая ретро-системы. У Pico от Raspberry относительно небольшой набор функций, но своих денег плата стоит. Сейчас появился новый девайс, который называется Pimoroni Pico LiPo. Это как бы Pico на стероидах.

Его стоимость $17, то есть в 4 с немногим раз больше, чем у оригинального Pico. Но и возможности шире, так что девайс может пригодиться тем разработчикам, кому не хватало возможностей микроконтроллера от Raspberry. Так, здесь есть функция заряда аккумулятора, USB-C порт, 16 МБ флеш-памяти и коннектор Stemma QT / Qwiic.

Подробнее о характеристиках



Система на чипе RP2040
Двухьядерный Arm Cortex M0+, частота 133 МГц.
264KB SRAM, и 4 / 16MB Flash памяти
GPIO 26 мультифункциональных 3.3V GPIO пинов
2 SPI, 2 I2C, 2 UART, 3 12-bit ADC, 16 PWM каналов
1 x User LED (GPIO 25)
8 Programmable I/O (PIO) state machines for custom peripheral support.
Stemma QT / Qwiic коннектор
SWD debug breakout
Модуль можно распаивать на платах
Power USB C для данных и питания
2 pin JST коннектор для LiPo / Li lon аккумуляторов. Мониторинг батарей + LED для отображения режима работы батареи.

Дизайн и использование Pimoroni Pico LiPo



Pico LiPo идеально работает с MycroPython. Для того, чтобы получить максимальную отдачу от платы, нужно использовать CircuitPython, в особенности при работе с компонентами Stemma QT / Qwiic. Если по какой-то причине вам необходимо работать с MicroPython и при этом взаимодействовать с устройствами Stemma QT / Qwiic, то стоит попробовать последний проект от Adafruit. Вот здесь можно загрузить все необходимое, работает с Pico LiPo весьма гладко.

Как и говорилось выше, Pico LiPo это Raspberry Pi Pico на стероидах. При таком же размере и аналогичной GPIO распиновке у девайса есть функция зарядки батарей, Stemma QT / Qwiic и кнопка включения. Наиболее важная возможность таки зарядка аккумуляторов. Режим зарядки контролируется чипом MCP73831. Ток небольшой 215 мА, но в ходе теста LiPo батарея была заряжена полностью.


Есть защита аккумулятора XB6096I2S, что предотвращает возможное превышение параметров заряда. Выделенного MicroPython или CircuitPython модуля для мониторинга заряда нет. Для определения факта заряда используется 24-й пин. А для мониторинга 29-й. Всего у девайса три аналоговых входа столько же, сколько и у малинки, но меньше, чем у Adafruits Feather RP2040. Да, на один пин меньше, но если учитывать, что его используют для контроля заряда батареи, то с потерей смириться проще.

Положительный момент в этом возможность использования аккумулятора в качестве базового бесперебойника питания. Так, проект можно запитать от USB-C, но если питание отключится, в дело вступает батарея. Распиновка у Pico LiPo такая же, как и у малинки. Плюс есть коннектор Stemma QT, благодаря которому подключение внешнего устройства становится очень простой задачей.

Наличие этого коннектора реальный прорыв для I2C-девайсов. Дело в том, что у ряда производителей есть множество совместимых компонентов, включая датчики температуры, емкостные входы, экраны и т.п. Используя емкостный сенсорный датчик MPR121 и последнюю версию CircuitPython 7 для Pico LiPo, мы создали демонстрационную модель системы с применением Stemma QT-коннектора.


Система заработала сразу и без проблем. Кроме того, мы видим множество проектов с применением Stemma QT / Qwiic. Рядом с этим коннектором есть трехпиновой коннектор JST-SH это отладка. Контакты используются для получения данных из работающего RP2040 без использования UART. Используя эти контакты и другой Pi Pico в качестве дебаг-хоста мы можем работать с процессором, SRAM, отображенной памяти I/O в выбранной среде разработки. Если вы разрабатываете критически важные RP2040-приложения, то это ключевая особенность. Ну а для большинства из нас просто интересная функция.

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

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

Как и упоминалось выше, распиновка у платы такая же, как у малинки, так что использовать ее можно точно там же и точно так же, где применяется Raspberry Pi Pico. При желании этот микроконтроллер можно заменить на LiPo в уже готовом проекте и получить больше функций. Мы проверили это утверждение, заменив микроконтроллер от Raspberry на новую плату вот в этом проекте. После замены все заработало без танцев с бубном.

Юзкейсы для Pimoroni Pico LiPo



У LiPo есть все, что дает Raspberry Pi Pico, плюс дополнительные функции. Даже одна лишь возможность подключения батареи стоит тех $17, которые просят разработчики за свой микроконтроллер. Его можно применять в самых разных проектах, от световых мечей на базе NeoPixel до интернета вещей. Pico LiPo можно применять в разных роботехнических проектах, но для сервоприводов, двигателей и т.п. понадобится собственный источник питания GPIO платы не даст ток больше 600 мА.

Подробнее..

Перевод Raspberry Pi Foundation 5 устройств менее чем за год. Что дальше?

31.05.2021 22:09:30 | Автор: admin

Менее чем за год Raspberry Pi Foundation выпустила целую серию новых продуктов. Четыре гаджета вышло в 2020 году и один в 2021. Все это невзирая на проблемы с логистикой из-за пандемии. Успех частично объясняется ростом спроса на ПК, включая миниатюрные системы, после массового перехода на удаленку.

Компания постаралась удовлетворить спрос: сначала она выпустила хорошую камеру, в апреле 2020, через месяц Raspberry Pi 4 c 8 ГБ ОЗУ. Потом Compute Module 4, Raspberry Pi 400 и, совсем недавно, Raspberry Pi Pico за $4. Даже пандемия COVID-19 не повлияла на эффективность работы и цепочку поставок. Будет ли компания отдыхать? Вряд ли.

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

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


Год бюджетных ПК


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

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

Но в любом случае множество пользователей по всему миру оценили достоинства системы ценой менее $50, которую можно использовать в качестве десктопного ПК. Спрос резко увеличился, и уже в марте 2020 года компания продала 640 000 девайсов, что стало вторым по объему продаж месяцем в истории компании. По данным TechRepublic общий объем разных устройств за 2020 год превысил 7,1 млн штук.

В 2020 году появился новый продукт в линейке Pi 400. Компания взяла свой флагман, Pi 4, и поместила его в клавиатуру, в результате чего получился эдакий десктопный ПК с базовыми функциями. Он предназначен, в основном, для семей с ограниченным бюджетом и не занимает много места на рабочем столе. Идея создания такого устройства появилась не вдруг команда вынашивала ее более четырех лет.


Команда, кстати, думала, что пандемия быстро закончится, возможно, даже к тому моменту, как будет выпушен Pi 400. Но, как все мы знаем, это оказалось ошибкой. Согласно данным продаж, компания продала в марте от 300 до 400 тыс. этих устройств. У Raspberry Pi Foundation не было проблем с продажами скорее, проблемы возникли с необходимостью удовлетворять постоянно растущий спрос.

Но все оказалось не так сложно, как могло бы быть. Команде удалось отладить процессы так, что участие в процессе производства кого-либо из членов команды почти не требовалось. Нужно было поддерживать процесс, мониторить выполнение задач, но не более. С Pi 400 возникли некоторые сложности, поскольку требовалась ручная сборка некоторых элементов. Но в итоге все получилось.

Как Raspberry Pi помогла пациентам, студентам и их родителям


Компания участвовала и в большом количестве социальных и благотворительных инициатив. В частности, команда предоставляла свои устройства учащимся, кто не мог позволит приобрести технику. В феврале Raspberry Pi Foundation предоставила 5000-й комплект в рамках кампании Bloomfield Trust.

Также Raspberry Pi Foundation продавала свои наборы напрямую школам, без посредников и наценок. Более того, образовательным учреждениям устройства предлагались по оптовым ценам. По словам представителей компании, Raspberry Pi c 2 ГБ ОЗУ, мышью, клавиатурой и базовым дисплеем лучший выбор, чем бюджетные ноутбуки, которые предлагаются школьникам в рамках государственных инициатив в Великобритании.

За 40 фунтов стерлингов вы получаете нечто гораздо более крутое, чем самый дешевый Chromebook. Да и недорогие Хромбуки это мусор, рассказал представитель компании.


Бездонная бочка


Речь идет о еще одном устройстве компании микроконтроллере Pico. Это первая такая система в продуктовой линейке Raspberry Pi, как и первое устройство с собственным процессором.

Pico чрезвычайно востребованный продукт. В марте 2021 года компания отрузила 200 000 устройств при общем количестве заказов в 900 000. Затем было отгружено еще 100 000 устройств, но покупатели заказали дополнительно 200 000.

Это попытка наполнить бездонную бочку. Некоторые покупатели, видя цену в $4, вероятно, заказывали десятки микроконтроллеров, заявил Аптон.

Raspberry Pi Pico позиционируется как девайс для обучения, хотя, конечно, устройство массово покупают и любители DIY. В любом случае, микроконтроллеры полностью новый рынок для компании. Этот девайс расширяет и без того объемную экосистему продуктов.


Программное обеспечение новый фокус компании в 2021 году


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

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

Raspberry Pi планирует к середине года перевести платформу на Debian 11, что позволит обновить многие элементы системы, включая оптимизацию стека Mesa 3D. Также Аптон надеется увидеть, как повлияет обновленный Chromium на Raspberry Pi. Одно из преимуществ Chromium мультимедийные возможности, включая видеоконференции, что крайне актуально в нынешнюю эпоху удаленки.

Сейчас мы используем Chromium 88, так что находимся на переднем краю современных технологий. Это очень важно, поскольку многие платформы видеоконференцсвязи задействуют самые новые возможности браузеров. И если мы говорим о том, что Raspberry Pi отличная платформа для работы из дома, нужно поддерживать видеоконференцсвязь, говорит Аптон.

Если 2020 год был годом нового железа Raspberry Pi, то 2021 может стать годом, где во главу угла ставится разработка ПО. Усилий для этого нужно не меньше, чем в ходе разработки аппаратного обеспечения, поскольку команда Raspberry Pi одновременно работает с ядром, с Debian и Chromium.

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

Подробнее..

DLang, Vibe.d и кросс-компиляция для RPi4

18.06.2021 10:22:12 | Автор: admin

Добрый вечер!

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

Недавно я написал сервер на DLang с использованием библиотеки Vibe.d. Для него я пишу кросс-платформенный клиент. Основной моей системой является Arch, и мне этого более чем достаточно, но для тестирования некоторых платформозависимых вещей я перезагружаюсь в Windows 10.

Отсутствие в Windows пакетного менджера и тому подобных вещей отпугнуло меня от того, чтобы собирать сервер для нее, хотя это и возможно. Поэтому мне в голову пришло очень логичное решение - запустить сервер на моем Raspberry Pi 4. Сейчас я использую его для удаленного доступа к принтеру и сканеру.

Попытка 1. Компиляция на микрокомпьютере

Первое, что пришло мне в голову - скинуть исходники на целевое устройство, скачать туда компилятор, систему сборки (в моем случае DUB) и собрать все там. Я предполагал, что это будет немного дольше, но я всегда мог оставить этот процесс выполняться на ночь, но не тут-то было...

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

На целевом устройстве стоит основанный на Debian Raspbian 10 Buster. Для поиска пакетов придется использовать apt... По сравнению с pacman он гораздо менее удобный, выдает кучу лишнего мусора (ИМХО).

Эталонным компилятором для D является dmd, но поиск по пакетам не выдал ничего полезного. Как оказалось : первое - dmd нет в стандартном репозитории Debian и Ubuntu, второе - он не поддерживает arm.

Чтож... Ничего страшного, ведь для D есть еще минимум 2 полноценных компилятора. Один из них, GDC, является частью GNU-Compiler-Collection и, вероятно, найдется везде, где есть Linux. Второй же, ldc, использует LLVM для генерации кода, поэтому его вы можете найти практически везде (Можно даже скачать его на Android через Termux).

Именно эти два компилятора оказались доступны для загрузки на микрокомпьютер :

sudo apt install ldc2 gdc

Оставался только DUB - de facto система сборки и менджер пакетов для D. Он есть в стандартном репозитории, но он не работает... Проекты не инициализируются, при загрузке зависимостей не может установить соединение с сервером. Сплошное расстройство!

В одной из статей про сборку D для arm было указано про проблемы с DUB. В качестве решения там предлагалось собрать его самостоятельно из исходников. Почему нет? Спускаемя к исходникам : https://github.com/dlang/dub

Для сборки в репозитории есть скрипт build.d (Код на D может быть запущен как скрипт при помощи специального интерпретатора - rdmd для dmd, ldmd для ldc, gdmd для gdc). gdmd не установился вместе с gdc, так что будем использовать ldmd. Собираем :

ldmd -run build.d

Собрать-то собрали, но лучше от этого не стало. dub работает, но очень медленно. Загрузить все зависимости для Vibe.d ему так и не удалось...

Попытка 2. Кросс-компиляция через GDC

Первая статья, которая была про компиляцию D кода под arm предлагала использовать кросс версию gdc. Почему нет?

Идем на официальный сайт и скачиваем последнюю доступную версию : https://gdcproject.org/old/downloads . Первоначально меня смутила дата сборки компилятора, но что же поделать.

После загрузки и распаковки нужно было проверить работоспособность компилятора. Для этого я написал обычный для всех Hello world :

import std.stdio;int main(string [] args) {  writeln("Hello, World!");  return 0;}

Теперь нужно это откомпилить и проверить на целевой платформе. С тулчейном это делается достаточно просто (только вместо arm-linux-gnueabihf-gdc нужно указывать полный путь) :

arm-linux-gnueabihf-gdc app.d

Получается исполняемый файл. Скидываем его на Raspberry, выдаем разрешение на исполнение и... Работает!

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

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

Статья, которую я использовал для этого пункта.

Попытка 3. LDC и мутки с библиотеками

Остался только один компилятор, способный откомпилить нужную мне программу для arm - ldc. Он установлен у меня на основном компьютере при помощи pacman. Какие-то дополнительные действия не нужны.

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

ldc-build-runtime --ninja --dFlags="-w;-mtriple=arm-linux-gnueabihf"

Появиться папка ldc-build-runtime.tmp/lib в которой храниться уже откомпилированная стандартная библиотека для arm. Для того чтобы скормить ее компилятору указываем следующий флаг : -L=-Lldc-build-runtime.tmp/lib
Пробуем собрать Hello World - ошибка линковки (не может найти точку входа). "Приехали", - подумал я. Собрал для начала объектный файл и решил попробовать слинковать его уже на raspberry - ld послал меня куда подальше.

Подумав и погадав, я решил скачать кросс-компилятор для C, взять линковщик оттуда и собрать все на основной машине. В Ubuntu и Debian arm-linux-gnueabihf есть в стандартном репозитории, а в Arch его можно было или собрать из AUR, или скачать уже собранный.

Раз уже делать, так делать - собираем из AUR. Процесс долгий, но интересный. Компиляция происходит в 3 этапа, постепенно собирая binutils, glibc и тп.

Спустя пару часов компилятор все же собрался. Я установил путь до него и собрал тестовую программу. Заработало!

Пробуем таким же образом слинковать другие библиотеки для проекта с Vibe.d... Не получилось. Линковщик стал таскать абсолютно все библиотеки из файловой системы raspberry и потерял половину ссылок. Undefined reference на malloc я еще не видел. До этого момента.

Не будем расстраиваться. Раз без включения библиотек от Raspberry все работает, просто локально соберем OpenSSL и ZLib (так же нужен), а потом прилинкуем их.

ZLib собрался довольно просто и быстро. Прилинковать его при помощи -L=-Lzlib/lib тоже не составило труда. Но вот OpenSSL отказался собираться от слова совсем. То ему компилятор не нравиться, то ему просто я не нравлюсь.

Из решений я нашел только одно - собрать OpenSSL на малине, скачать оттуда собранную и прилинковать на основной машине. На микрокомпьютере OpenSSL собрать было нетрудно. Я скачал его и добавил флаг -L=-Lopenssl/lib.

При компиляции я увидел всего 2 ошибки : неопределенная ссылка на SSL_get_peer_certificate и на ERR_put_error. Это меня доконало, я решил оставить это дело и лечь спать. Если бы я знал, как я был близок к победе на этом моменте.

Попытка 4. Toolchain и скрипты

На следующий день я решил попробовать все сначала, учесть все предыдущие ошибки и сделать что-то наподобие toolchainа для сборки D кода под ARM.

Начать я решил с кросс-компилятора для C. Загуглив что-то наподобие "arm-linux-gnueabihf gcc" я нашел вот этот вот сайт.

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

Для проверки работоспособности компилятора я решил запустить Hello World, но уже на C :

#include <stdio.h>int main(int argc, char ** argv) {  printf("Hello, World!\n");  return 0;}

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

#!/bin/bashgcc_arm/bin/arm-linux-gnueabihf-gcc main.c -o app.o

К счастью, все заработало с первого раза. Теперь я решил приступить к настройке компилятора для D. Как самый успешный, был выбран ldc. Я скачал последний релиз с GitHub (http://personeltest.ru/aways/github.com/ldc-developers/ldc) и также поместил рядом с C-компилятором.

Теперь было необходимо собрать стандартную библиотеку D для arm. Так появился build_ldc_runtime.sh :

#!/bin/bashexport CURRENT_DIR=$(pwd)export LDC_PATH=$CURRENT_DIR/"ldc2/bin"export GCC_PATH=$CURRENT_DIR/"gcc_arm/bin"export CC=$GCC_PATH/"arm-linux-gnueabihf-gcc"$LDC_PATH/ldc-build-runtime --ninja --dFlags="-w;-mtriple=arm-linux-gnueabihf"

Сборка прошла успешно, и я перешел к тестированию HelloWorld. Также откомпилил его и запустил на Raspberry, но получил слегка неожиданную ошибку. Исполняемый файл требовал GLIBC не ниже, чем 2.29. Погуглив, как посмотреть версию GLIBC, я понял, что на малине стоит всего-лишь 2.28...

Так как, по моему мнению, clang и llvm, а следовательно и ldc, не пропагандируют GLIBC и вроде как даже могут обходиться без нее, был сделан вывод о том, что проблема в gcc.

Я решил скачать Toolchain с той же версией gcc, что и на целевом устройстве, то есть 8.3.0. К счастью, на том же сайте был найден подходящий компилятор. Я удалил старый, распаковал новый, пересобрал ldc_runtime и все заработало.

Чудесно. Оставалось присобачить сюда ZLib и OpenSSL. Начал я, конечно, с ZLib, так как с ним меньше проблем :

#!/bin/bashexport CURRENT_DIR=$(pwd)export GCC_PATH=$CURRENT_DIR/"gcc_arm/bin"export CC=$GCC_PATH/"arm-linux-gnueabihf-gcc"mkdir tmp_zlibcd tmp_zlibgit clone https://github.com/madler/zlib.gitcd zlib./configure --prefix=$CURRENT_DIR/zlibmakemake installcd ../..rm -rf tmp_zlib

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

Не имею никакого желания с этим разбираться, я решил отказаться от OpenSSL и использовать Botan (Vibe.d имеет такую возможность). К слову, все собралось и слинковалось с первого раза :

#!/bin/bashexport CURRENT_DIR=$(pwd)export GCC_PATH=$CURRENT_DIR/"gcc_arm/bin"export CCX=$GCC_PATH/"arm-linux-gnueabihf-g++"mkdir tmp_botancd tmp_botangit clone https://github.com/randombit/botan.gitcd botanpython configure.py --cpu=arm --cc-bin=${CCX} --prefix=${CURRENT_DIR}/botanmake && make installcd ../..rm -rf tmp_botan

Приложение с Vibe.d И Botan успешно откомпилилось и ДАЖЕ ЗАПУСТИЛОСЬ на raspberry. Просто замечательно. Но есть одно "но" - OpenSSL. Мы так и не разобрались с ним. Проблема оказалась достаточно глупой и легко решаемой.

Поискав SSL_get_peer_certificate и ERR_put_error в репозитории OpenSSL я понял, что в последних alpha версиях они были объявлены deprecated и удалены. Vibe.d официально поддерживает OpenSSL версии 1.1, а я скачал alpha 3.x, где этих функций просто не было.

Необходимо было просто скачать более старую, стабильную версию исходников и собрать их :

#!/bin/bashexport CURRENT_DIR=$(pwd)mkdir tmp_opensslcd tmp_opensslgit clone https://github.com/openssl/openssl -b OpenSSL_1_1_1-stablecd openssl./Configure linux-generic32 shared \    --prefix=$CURRENT_DIR/openssl --openssldir=$CURRENT_DIR/tmp_openssl/openssl \    --cross-compile-prefix=$CURRENT_DIR/gcc_arm/bin/arm-linux-gnueabihf-make && make installcd ../..rm -rf tmp_openssl

И вот наконец, все это заработало. Я написал небольшой скрипт, который сразу запускает компилятор с нужными флагами :

#!/bin/bashexport CURRENT_DIR=/home/test_user/Projects/rpi4_d_toolchainexport LDC_PATH=$CURRENT_DIR/ldc2/binexport GCC_PATH=$CURRENT_DIR/gcc_arm/binexport LDC_RUNTIME_PATH=$CURRENT_DIR/ldc-build-runtime.tmp/libexport OPENSSL_PATH=$CURRENT_DIR/openssl/libexport ZLIB_PATH=$CURRENT_DIR/zlib/libexport BOTAN_PATH=$CURRENT_DIR/botan/libexport CC=$GCC_PATH/"arm-linux-gnueabihf-gcc"$LDC_PATH/ldc2 -mtriple=arm-linux-gnueabihf -gcc=$CC -L=-L${LDC_RUNTIME_PATH} -L=-L${OPENSSL_PATH} -L=-L${ZLIB_PATH} -L=-L${BOTAN_PATH} $@

Теперь все проекты легко и просто собираются следующей командой :

dub build --compiler=~/ldc_rpi

Прототипом и основным источником информации послужил вот этот GitHub репозиторий.

Заключение

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

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

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

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

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

А если вы когда-нибудь соберетесь собирать что-то для raspberry pi 4, то можно скачать отсюда тот Toolchain, который в итоге у меня получился (тут все компиляторы и библиотеки).

Только в файле ldc_rpi, поменяйте значение CURRENT_DIR на путь до папки с toolchainом.

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

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru