Данная статья является частью цикла:
» Organillo Magia v2.0. Вперед, за новыми приключениями!
» Organillo Magia v2.0. Программная часть
» Organillo Magia v2.0. Аппаратная часть
» Organillo Magia v2.0. Каркас.
» Organillo Magia v2.0. Корпус.

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

* * *

Итак. Вот она, эта, Raspberry Pi 3B:

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

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

Все, что нужно для того, чтобы ее запустить – подать питание (5 вольт в miniUSB от обычной “телефонной зарядки”) и подключить к монитору/телевизору. Мышь/клава – по вкусу: USB или беспроводной свисток. Операционка селится на microSD-карточку и запихивается в слот на плате. Запустится автоматически при подаче питания. Может быть, что угодно: от винды и линукса, до самостоятельных экзерсизов на тему. Можно самому сборку с операционкой делать, можно тупо скачать готовую из интернета, залить ее на карточку, воткнуть в raspberry и наслаждаться. Обычно в комплекте уже идет карточка с версией Debian на ядре Linux и иксами – т.е. при включении вы получаете операционку с привычным оконным интерфейсом. Все! Дальше, что хотите делайте. Ну, если совсем просто, вот, вы купили комп в магазине, принесли домой, поставили на стол, включили, он запустился. Делаете, что хотите. Тут – то же самое.

* * *

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

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

Для raspberry есть две сборки (проигрыватель + операционка) на выбор: на базе OSMC (Open Source Media Center) и на базе OpenELEC (Open Embedded Linux Entertainment Center). Не, ну, их, само-собой, хреново-немерено разных. Но эти две – наиболее популярны. И то и другое – на базе Linux.

Лично я попробовал и то, и другое. Там, в интернетиках, есть полно обзоров и баталий на тему сравнения, что лучше. Я разницы не нашел никакой. Разве, что OpenELEC почму-то не захотела сходу опознавать мой USB-шный DVD-привод. Но оно, как-то само и починилось. Пару раз воткнул-вытокнул – опознало. Пес его знает что там ему не понравилось. Он у меня, старенький, конечно… По итогам оставил сборку OSMC – она мой антиквариат схавала без приключений…

Что это все значит на уровне “для самых маленьких”:
– Скачать сборку: тут (OSMC) или тут (OpenELEC). И там, и там, выбирать файл-образ для raspberry
– Полученный файл записать на microSD-карточку. Любую от 8 гигов емкости и выше. “Записать” имеется в виду, не тупо скопировать через кард-ридер какой, а при помощи программы для записи “образов”. Я пользуюсь Win32 Disk Imager – он бесплатный. Но подойдет и Nero, и что угодно другое, что может это делать. Чем вы, там, дивидишечки с софтом пиратите с торрентиков? Вот оно и подойдет. Лишь бы умело файл-образ формата .img развернуть на выбранный носитель.
– Запихиваем записанную карточку в raspberry
– Подключаем мышку или клавиатуру (USB или беспроводную). Можно, что-то одно. Там дальше и мышки хватит по кнопочками интерфейса тюкать.
– Подключаем монитор или телевизор к HDMI-выходу на raspberry. Только имейте в виду, что она по HDMI и звук гнать будет. В принципе, почти все телевизоры сейчас умеют его так принимать. Мониторы – не все. Если нужен звук, а монитор не умеет его получать через HDMI, то там, на raspberry, рядом с HDMI есть дырочка легко узнаваемой формы. Угадайте, что в нее надо воткнуть, чтобы звук пошел… Правда, она только аналоговое стерео гонит. А через HDMI вы можете получить полновесную цифру с 7.1 канальным звуком.
– Подключаем raspberry к блоку питания. Обычная зарядка от телефона с подходящим штекером (miniUSB) – подойдет.

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

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

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

Даже не хочу начинать все это подробно описывать – смысла нет. Главная мысль, которую хочу донести: даже без всех этих настроек и дополнений – вы уже сделали работающий медиаплеер. Затащите в него хоть CD/DVD/BlueRAY с внешнего USB-привода, хоть авишку с флеш-драйва – все! Оно играет и показывает.

* * *

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

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

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

Вернемся к нашей raspberry. Видите, вон там у нее длинная такая шина с шпиньками:

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

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

В OSMC, там уже есть нужная библиотека. Но она немного странная и с ней не очень удобно работать. Но оно же, в сущности Линукс там унутрях, помните? Значит и проблем никаких нет. Делаем так, чтобы нам было удобно. И, прежде всего, ставим нужную библиотеку со всеми ништяками, блэкджеком и всеми остальными.

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

Для консольного подключения ко всяким внешним серверам я на своем большом настольном компе с виндами использую PuTTY. На каком адресе там повисла raspberry у моего домашнего роутера? В моем случае на 192.168.0.123. У вас – будет другой адрес. Смотреть на маршрутизаторе или в настройках сети raspberry, хоть в том же Kodi, который продолжает благополучно крутиться на девайсине.

SSHмся к устройству через PuTTY на адрес подключенного устройства.

В OSMC пользователь по умолчанию, не поверите: osmc. И пароль у него в точности такой же.

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

sudo apt-get update
sudo apt-get install -y python-dev
sudo apt-get install -y python-pip
sudo easy_install -b /home/osmc -U distribute
sudo apt-get install build-essential

Далее, собственно, саму библиотеку для управления шпыньками шины:

export ARCH=arm
export CROSS_COMPILE=/usr/bin/
sudo pip install rpi.gpio

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

Далее, создаем себе какую-нибудь удобную папку в файловой системе, где-нибудь в /usr/local/bin:

sudo mkdir /usr/local/bin/Scripts
cd /usr/local/bin/Scripts

Создаем там файл с каким-нибудь удобным именем и начинаем в нем ваять:

sudo touch control.py
sudo nano control.py

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

* * *

Поиграв недельку с выводами, устаканил систему интерфейса/индикации на двух кнопках и пяти светодиодах:

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

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

  • Светодиод “работает интерфейс
    На самом деле, он мне нужен был только на стадии отладки. Настроен так, чтобы взмыргивать при каждом рабочем цикле управляющей программы. Если мыргает, значит все в порядке – скрипт запустился и работеат фоном, считывая параметры и зажигая/гася светодиоды. Он забавный – решил оставить его и в финальной версии.
  • Светодиод “активность
    Это “родной” светодиод raspberry – ACT. Он, там, много чего показывает, но по внешним признакам его поведение похоже на светодиод HDD в настольном писюке. В принципе, он и без того есть на плате, намертво впаянный возле разъема питания. Но в корпусе ж его не видно! Поэтому я его программно перенаправлю на один из шпыньков, выведя с него своим собственным светодиодом на мордочку корпуса.
  • Светодиод “стало жарко, я включил себе вентилятор
    Еще один “тестовый” светодиод. Нужен был на стадии подключения и отладки вентилятора. Собственно, он, в какой-то момент времени этот вентилятор собою заменял. Типа, светится = вентилятор крутится. Погас = вентилятор остановился. Тоже решил оставить в финишном исполнении. Вентилятор внутри корпуса, маленький, тихий и так сходу не поймешь, крутится он там в утробе или нет.
  • Светодиод “я подключился к интернету
    Думаю, понятно его назначение. Если горит, значит устройство не просто подключилось вайфаем к домашнему роутеру, но и видит внешние ресурсы. Идет проверка пингом чего-нибудь снаружи. Гугля, например. Пингуется – связь есть, зажигаем лампочку. Не пингуется – связи нет, лампочка не горит, мы варимся в собственном соку без доступа к интернетам.

Ну и, для управления этим зоопарком, я написал вот такой код на питоне:

#!/usr/bin/python

# подключаем нужные для работы скрипта библиотеки:
import RPi.GPIO as GPIO
import time
import os
import subprocess

# назначаем переменные с номерами шпыньков на шине
# по схеме Broadcom SOC channel (на картинке-схеме выше, это
# все, вон, те многочисленные GPIO с циферками).
# проще их один раз расставить по переменным и потом уже
# использовать в коде по именам, а не пытаться вспомнить на 
# какой номер чего повешено
pioONOFF = 3
pioREBOOT = 4
pioREADY = 20
pioACT = 21
pioFANc = 26
pioFANl = 16
pioCONNECT = 19

# назначаем переменные с предельными температурами
# для вкыла/выкла вентилятора
# их надо две, чтобы вентилятор не дергало каждую
# секунду на пороге срабатывания
# дельты в 5-10 градусов - достаточно для стабильной
# равномерной работы
tempMAX = 60
tempMIN = 50

# интервал паузы в цикле, чтобы каждую микросекунду
# не дергать все подряд. Раз в 5 сек. - вполне достаточно
cycleSEC = 5

# назначаем переменную с адресом чего-нибудь внешнего
# чтобы по состоянию доступности оного судить о том
# подключена ли наша фигня к интернету, или нет
# можно и локальный адрес роутера, типа 192.168.0.1
# но доступность роутера не всегда означает доступность
# интернета - тут сами выбирайте, что вам интереснее
pingHOST = "8.8.8.8"

# будем обращаться к шпинькам по номерам
# Broadcom SOC channel (опять см. схему выше):
GPIO.setmode(GPIO.BCM)

# и пусть не парит мозг сообщениями об ошибках:
GPIO.setwarnings(False)

# шпинек номер pioONOFF будет кнопкой:
GPIO.setup(pioONOFF, GPIO.IN, pull_up_down = GPIO.PUD_UP)

# шпинек номер pioREBOOT будет кнопкой:
GPIO.setup(pioREBOOT, GPIO.IN, pull_up_down = GPIO.PUD_UP)

# эти шпинки будут выводами (светодиодами, вентиляторами и т.п.):
GPIO.setup(pioREADY, GPIO.OUT)
GPIO.setup(pioFANc, GPIO.OUT)
GPIO.setup(pioFANl, GPIO.OUT)
GPIO.setup(pioCONNECT, GPIO.OUT)

# эта функция выполнится при нажании кнопки вкл/выкл:
def Shutdown(channel):
    GPIO.output (pioREADY, GPIO.HIGH) # засветить светодиод "работает интерфейс"
    time.sleep(3)                     # пауза 3 сек, для осознания факта человеком
    os.system("sudo shutdown -h now") # выполнить системную команду софтового выкла

# эта функция выполнится при нажатии кнопки сброса:
def Restart(channel):
    GPIO.output (pioREADY, GPIO.HIGH) # засветить светодиод "работает интерфейс"
    time.sleep(3)                     # пауза 3 сек, для осознания факта человеком
    os.system("sudo reboot -h now")   # выполнить системную команду софтового перезапуска

# начать пасти факт нажатия кнопок и, в зависимости от нажатого,
# выполнить ту или иную функцию описанную выше
GPIO.add_event_detect(pioONOFF, GPIO.FALLING, callback = Shutdown, bouncetime = 5000)
GPIO.add_event_detect(pioREBOOT, GPIO.FALLING, callback = Restart, bouncetime = 5000)

# начать бесконечный цикл до морковкина зоговения:
while True:
    GPIO.output (pioREADY, GPIO.HIGH) # засветить светодиод "работает интерфейс"
    
    # пингануть внешний ресурс: 
    HOSTresp = os.system("ping -c 1 -s 1 -W 3 " + pingHOST + " > /dev/null")
    if HOSTresp == 0:
       GPIO.output (pioCONNECT, GPIO.HIGH) # если пингуется, то включить светодиод "я подключился к интернету"
    else:
       GPIO.output (pioCONNECT, GPIO.LOW)  # если не пингуется, то выключить светодиод "я подключился к интернету"
 
    # получить данные о температуре CPU:
    tFile = open('/sys/class/thermal/thermal_zone0/temp')
    tempCPU = float(tFile.read())
    tempCPU = round(tempCPU/1000)
    if (tempCPU > tempMAX):
       GPIO.output (pioFANc, GPIO.HIGH) # если выше максимальной, то включить светодиод "мне жарко"
       GPIO.output (pioFANl, GPIO.HIGH) # и вентилятор включить тоже
    if (tempCPU < tempMIN):
       GPIO.output (pioFANc, GPIO.LOW) # если ниже минимальной, то выключить светодиод "мне жарко"
       GPIO.output (pioFANl, GPIO.LOW) # и вентилятор выключить тоже
 
    # сделать паузу
    # собственно, это и обеспечивает мыргание светодиода "работает интерфейс"
    # иначе цикл будет пробегать так быстро, что время свечения светодиода будет мизерным
    # и почти незаметным глазу:
    time.sleep(0.25)
    GPIO.output (pioREADY, GPIO.LOW) # теперь его можно выключить
 
    # повторить весь цикл через заданное количество сек:
    time.sleep(cycleSEC)

Как-то, вот так оно все…

Теперь надо перенаправить сигнал лампочки ACT со светодиода на плате к своему светодиоду на шпыньке.  Залезаем в файл конфига:

sudo nano /boot/config.txt

… и добавляем в нем строку:

dtoverlay=pi3-act-led,gpio=25

Теперь, вместо светодиода на плате, будет мигать тот, который мы повесим на шпиньку GPIO25 (см. схему выше)

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

sudo nano /etc/rc.local

… добавить там строку:

sudo python /usr/local/bin/Scripts/control.py &

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

Продолжение читайте тут

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

Комментарии:

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

  • Erraen

    > чего сейчас модно пинговать внешнего на предмет определения живости
    Гугловские DNS сервера – 8.8.8.8 и 8.8.4.4

  • А зачем тебе рутовый пользователь, если sudo работает?

    • Jim

      Уже не помню, если честно :-)
      Оно ж, это вот так в посте сразу – бряк – и, типа, статья. Писал то я ее параллельно измывательствам над системой, походу редактируя. Что-то там было, чего без рута не сделать… Потом “рецепт” выхолостился и, согласен, в таком виде рут уже не нужен, ты прав… Исправлено…

      А! Вспомнил. Я в какой-то момент не знал про автозапуск из rc.local и вкорячил хрон не долго думая. И зачем-то хотел, чтобы он крутился от рута… Короче, не актуально уже :-)

  • >    if (tempCPU > tempMAX) or (tempGPU > tempMAX):
    ...
    >    if (tempCPU < tempMIN) or (tempGPU < tempMIN):
    ...
    

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

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

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

    - Случай с == максимуму тоже никак не рассмотрен.

    По логике это должно выглядеть как-то так:

        overheat = tempCPU > tempMAX or tempGPU > tempMAX
        signal = GPIO.HIGH if overheat else GPIO.LOW
        GPIO.output(pioFANc, signal)
        GPIO.output(pioFANl, signal)
    

    или даже так:

        overheat = any(t > tempMAX for t in [tempGPU, tempCPU])
        for pin in [pioFANc, pioFANl]:
            GPIO.output(pin, GPIO.HIGH if overheat else GPIO.LOW)
    

    Я сдался пытаться отредактировать код в Вордпрессе, поэтому вот: https://gist.github.com/isagalaev/5da186caaa83db59b1e34a6e7937874b

    • Jim

      Странно… В комментариях тэг code не работает. А pre – работает… Надо будет стили прочесать.

      С условием по температуре – ты отчасти прав.

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

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

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

    • Jim

      В принципе, можно все оставить, как у меня, но выкинуть мониторинг GPU. Тогда все по логике станет, как надо. Брать оба параметра – блаж без особого смысла. Платка, как я сказал – слишком маленькая, чтобы в двух ее узлах возникала существенная разница температур… Исправлено.

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

Оставить комментарий:

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