В следующих частях про GPIO что планируется?
uart,i2c,spi?
Сообщения pi
-
RE: GPIO для чайников (часть 1)
-
RE: GPIO для чайников (часть 1)
Отлично расписано.
Для ленивых тоже есть способ зажечь светодиод )echo 1 > /sys/class/gpio/gpioN/direction echo 1 > /sys/class/gpio/gpioN/value
-
Удаленное управление. Поймаем кнопку за событие.
И снова вечер и снова делать нечего.
А вот например GPIO. Тут один товарищ описал что такое GPIO в серии статей GPIO для чайников. Из них мы знаем, что GPIO может работать как на вход, так и на выход. Грубо говоря, если я замкну 2 пина, один из которых будет IN, а второй OUT и поменяю значение второго, то значение первого так же изменится. Думаю, схему подобного приводить не стоит, потому что, фактически, это просто соединение прямым проводом двух пинов.
Теперь мысль дальше. Вместо прямого провода мы можем соединить 2 пина кнопкой. Нажимаем кнопку - пины замыкаются, значение IN меняется, отпускаем...ну и так далее. Я соединил кнопкой 2 пина: GPIO3 и GPIO4. Получилась вот такая вот схемка.
Другой, более удобной кнопки у меня, к сожалению нет. Ну да ладно. Осталось только понять когда кнопка нажата, а когда наоборот.
Теперь обратимся к ferro-remote, программке, которую я описывал тут. Можно, например, для нее написать скрипт, который покажет текущее состояние пина 4:
g = fr.client.gpio.export(4, "in") print(g:get( ))
Все. Данный скрипт запросит состояние пина и выведет его в консоль.
Малинка висит на 192.168.1.11:12345
сохраним файл как gpio.lua. Запускаем:
$ ./lua_client -s 192.168.1.11:12345 -e gpio.lua 0
Кнопка отжата. Нажимаем, и запускаем снова
$ ./lua_client -s 192.168.1.11:12345 -e gpio.lua 1
Ура! Работает!
Но как-то странно все это. Для того, чтоб понять, что сейчас в значении у GPIO4 я вынужден делать удаленный вызов (sick!) с довольно приличной частотой (sick! sick!), чтоб хоть как-то адекватно среагировать на событие. А если клиентов штук 50?
Но, у нас же есть система Linux на raspberry, которая ЗНАЕТ, когда изменилось состояние пина. У GPIO есть такое свойство, имя которому
EDGE.
EDGE может принимать 4 значения:- none: не реагировать на изменения
- rising: реагировать только на "подъем" пина
- falling: реагировать только на "сброс" пина
- both: реагировать на оба события
Тут стоит сделать примечание, что не все пины поддерживают данное свойство. Пишу к тому, что у меня есть аналог малинки, на котором из 30 GPIO edge поддерживают только 7.
В lua_client есть возможность подписаться на данное событие. В контексте самого клиента оно называется on_changed.
подписка происходит методом subscribe объекта gpio. Например:
gpio = fr.client.gpio -- алиас для удобства function value_changed( data ) -- функция-обработчик события print( "Value 3 -> 4 has changed to", data.value ) -- текущее состояние выведем end function main( ) local gin, erri = gpio.export( 4, "in" ) -- получим 4 для ввода local gout, erro = gpio.export( 3, "out" ) -- получим 3 для вывода if gin and gout then fr.run( ) -- специальная функция, которая говорит клиенту -- не завершать работу после функции main, а ждать событий assert(gout:set(0)) -- установим значение пина 3 на 0 assert(gin:set( "edge", "both" )) -- установим значение edge пина 4 на both assert(gin:subscribe("on_changed", value_changed, gin )) -- подпишемся, -- "запомним" gin, чтоб он не был прибит GC else print( erri, erro ) -- что-то пошло не так, просто выведем ошибки end end
Сохраним, выполним:
$ ./lua_client -s 192.168.1.11:12345 -e gpio.lua Value 3 -> 4 has changed to 0 Value 3 -> 4 has changed to 1 Value 3 -> 4 has changed to 1 Value 3 -> 4 has changed to 1 Value 3 -> 4 has changed to 0 Value 3 -> 4 has changed to 0
Ну прям песня! Теперь я не закидываю малинку запросами с вопросом о состоянии, система сама генерирует событие и присылает мне новое! Процессор на 0, трафик на 0. События.
Кстати, если посмотреть внимательно, то можно заметить, что подряд идут одинаковые значения. Я точно не помню как подобный эффект называется, но суть его в том, что пока я нажимаю на кнопку, она в реальности успевает несколько раз законтачиться и расконтачиться. Система на это все реагирует генерацией события. Чем качественнее кнопка, тем меньше таких вот косяков. У меня - очень некачественная.
Теперь, чтоб было еще интереснее, повесим на GPIO2 диод, как было описано в GPIO для чайников (часть 1) и переделаем немного скрипт, чтоб он устанавливал пину 2 состоние пина 4, когда то изменится.
Итого. Тот же самый скрипт, только добавил открытие GPIO2 и изменение его состояние по изменению GPIO4
gpio = fr.client.gpio function value_changed( data, diod ) print( "Value 3 -> 4 has changed to", data.value, data.interval ) diod:set( data.value ) -- установим состояние диода. end function main( ) local gin, erri = gpio.export( 4, "in" ) local gout, erro = gpio.export( 3, "out" ) local diod, errd = gpio.export( 2, "out" ) -- откроем диод if gin and gout and diod then fr.run( ) assert(gout:set(0)) assert(gin:set( "edge", "both" )) assert(gin:subscribe("on_changed", value_changed, diod, gin )) else print( erri, erro, errd ) end end
Теперь скрипт включает и выключает диод, когда я нажимаю или отжимаю кнопку.
PS: Где-то у меня инкрементный енкодер валялся. Думаю, если я его найду, то добавлю пример работы с ним.
-
Удаленное управление. События. Энкодер инкрементальный.
И снова здравствуйте!
Отрыл сегодня инкрементальный енкодер на полке. Попытаюсь описать как с ним работать и как снимать направление вращения.
Что такое этот энкодер, думаю, смысла говорить нет. Это легко гуглится. Выглядит эта штука вот так:
У него есть 3 пина и если посмотреть на железку сверху, то по часовой стрелке можно эти пины обозначить как A, O, B.
Пин O - пин, работающий на выход, пины A и B работают на вход, то есть "читают" состояние пина O.
Теперь ситуация:
Поворачиваем енкодер по часовой стрелке и ...
Сначала меняется состояние пина A
потом B
потом меняется состояние пина A обратно
затем снова B возвращает свое первоначальное значение. Картина, в общем такая:
(Картинка не моя; взял с интернета)
Можно заметить, что в один момент времени пины принимают одинаковое значение, НО при этом имеют разный расклад на предыдущем шаге. Таким образом мы можем понять в какую сторону крутится ручка енкодера.
Покажу на примере ferro-remote как можно это обработать и сделать простейший счетчик, который при повороте по часовой стрелке увеличивает значение, а против - уменьшает.
Тут я описывал как можно ловить события (сигналы, прерывания ... называть можно как угодно) с пинов GPIO, работающих в режиме IN. Думаю повторить тоже самое для данного примера.
Возьмем 3 пина на RPi: GPIO 2, 3, 4.
2 будет A
3 будет O
4 будет BДля начала простой скрипт, который их откроет и расставит им верное направление
-- gpio-encoder.lua gpio = fr.client.gpio -- алиас current = 0 -- сам счетчик. Просто глобальная переменная function main( argv ) fr.run( ) -- нужно ждать события, скажем не завершать исполнение после main -- откроем 3 пина 2, 4 - IN 3 - OUT local A = assert(gpio.export( 2, "in" )) local O = assert(gpio.export( 3, "out" )) local B = assert(gpio.export( 4, "in" )) -- для пинов A и B установим edge в значение both assert(A:set( "edge", "both" )) assert(B:set( "edge", "both" )) end
Если такой скрипт исполднить lua_client'ом, то делать он не будет ничего, кроме того, что получит объекты для работы с пинами, а потом прибьет их сборщиком мусора.
Добавлю-ка я ему обработку события. Тут сделаю так (я видел в интернетах, что у народа довольно большие проблемы с энкодерами и логикой работы с ними. Хотя ничего страшного и сложного нет):
Оба события будет обрабатывать один и тот же обработчик. Можно сделать ДВА разных обработчика, но получится длинее и не уверен, что проще. В параметры обработчику будет передаваться признак того, какой именно пин сработал. false - сработал пин A, true - пин B. Мысль дальше: Чтобы понять как вращается ручка, в момент установки пина на 1, нужно уметь получить состояние другого пина, если оно установлено в 1, значит мы должны увеличить или уменьшить счетчик.
Если мы в обработчике пина B и пин A изменен, то мы вращаем по часовой стрелке и нужно прибавить и наоборот. добавим это в код:
- pin - false(А) или true(B)
- states - таблица, которая изначально имеет такой вид: {[false] = 0, [true] = 0}
- то есть оба состояние выставлены на 0
function change_handler( data, pin, states ) -- directions это просто вспомогательная таблица -- суть ее в том, что в случае вращения по часовй стрелке -- к счетчику будет прибавляться 1, а против -- -1 local directions = { [false] = -1, [true] = 1 } states[pin] = data.value -- установит состояние текущего пина в текущее значение -- states[not pin] - состояние соседнего пина -- если текущий пин установлен и соседний тоже установлен if data.value == 1 and states[not pin] == 1 then current = current + directions[pin] -- прибавим или отнимем print( current ) end end и того полный скрипт выглядит так: -- gpio-encoder.lua gpio = fr.client.gpio current = 0 function change_handler( data, pin, states ) local directions = { [false] = -1, [true] = 1 } states[pin] = data.value if data.value == 1 and states[not pin] == 1 then current = current + directions[direct] print( current ) end end function main( argv ) fr.run( ) local states = {[true] = 0, [false] = 0} local A = assert(gpio.export( 2, "in" )) local O = assert(gpio.export( 3, "out" )) local B = assert(gpio.export( 4, "in" )) assert(A:set( "edge", "both" )) assert(B:set( "edge", "both" )) -- подпишемся на события от GPIO assert(A:subscribe( "on_changed", change_handler, false, states, A )) -- пин А false assert(B:subscribe( "on_changed", change_handler, true, states, B )) -- пин B true end
Теперь код можно сохранить (например как gpio-encoder.lua) и выполнить lua_client'ом. 192.168.1.11:12345 - адрес и порт малины. Если при открытии не вылетело никаких ошибок, то можно покрутить ручку после запуска.
$ lua_client -s 192.168.1.11:12345 -e gpio-encoder.lua 1 2 3 4 5 4 3 2 1 0 -1 -2 -3 -4 -3 -2 -1 0 1 2 1 0 -1
Работает! Можно использовать.
PS: а нет никакого PS.
-
Пытаемся смотреть IPTV на Raspbian.
Я решил закончить свои эксперименты по поводу просмотра IPTV на Raspberry Pi.
Представляю полученные результаты.
И так, имеем в наличии:
- -Raspberry Pi с установленной ОС Raspbian сборки от 16.08.2012;
- -подключенная лицензия на кодеки MPEG2 и VC1;
- -штатный медиаплеер OMXplayer;
- -установленные медиаплееры XINE-UI и VLC-player;
- -провайдерская мультикаст-трансляция каналов IPTV (простые и FULL-HD каналы).
Хотя видеопоток успешно подхватывался всеми перечисленными медиаплейерами, XINE и VLC оказались на данный момент абсолютно непригодные для этой задачи в виду того, что пока их сборки не используют GPU. Трансляция велась со скоростью не более 1-5 кадров в секунду при 100% загрузке процессора. Даже если эти плееры запускать не из LXDE.
Консольный OMXplayer гораздо лучше справился с этой задачей. Благо его научили работать с GPU.
Но всё равно, его работу можно назвать удовлетворительной лишь с натяжкой.
Первая проблема- у меня неполучилось скормить ему плейлист. Пришлось каждый канал запускать в ручную. Но это в принципе не так критично. Гораздо более критичным оказался недостаток памяти в Raspberry Pi.
Каналы в формате FULL-HD, транслирующиеся в формате h.264, оказались ему не по зубам.
Картинка возникает на 1-2 секунды (правда картинкой её назвать сложно- более половины экрана разбито на кубики), после этого плеер вылетает с пожеланиями "всего хорошего".
С обычными каналами, транслирующимися в формате MPEG2, плеер в общем-то справляется более-менее. Но опять же, относительно чистой картинки получилось добиться лишь на каналах, которые транслируются с уменьшенным разрешением. На каналах, транслирующихся в обычном разрешении (720 точек), по экрану периодически пробегают квадратики. Т.е. Raspberry не успевает уверенно декодировать этот поток налету.
Увеличение частоты процессора до 800МГц абсолютно никак не влияет на качество картинки. HD-каналы так-же вылетают, а простые- всё так же квадратятся.
Играться с оверклокингом GPU и памяти я не стал. Ибо сильно сомневаюсь, что прирост производительности в 10% исправит ситуацию.
На этом я свои эксперименты завершил. На данный момент Raspberry Pi невозможно использовать для нормального просмотра IPTV используя штатные средства ОС Raspbian. Остаётся надеяться на то, что кто-нибудь напишет специализированный плагин для просмотра IPTV под XBMC, или создаст оптимизированную сборку, выделив максимум ресурсов IPTV-плееру.
Для тех, кто хочет попробовать посмотреть IPTV на своей "Малинке" дам пару советов.
-
Перераспределите память в пользу GPU, через raspi-config.
-
OMXplayer запускайте из терминала, не запуская LXDE.
-
Чтобы плеер увидел мультикаст-поток, адреса нужно изменять.
Например, в плейлисте моего провайдера адреса каналов представлены в таком виде:
rtp://@239.1.1.24:1234
Для плеера этот адрес должен выглядеть так:
udp://239.1.1.24:1234
Т.е. чтобы посмотреть этот канал, я ввожу следующую команду:
omxplayer udp://239.1.1.24:1234
Далее плеер задумывается на 5-10 секунд, потом выводит информацию о найденном потоке и его характеристиках и ещё секунд через 5 начинается трансляция.
Выйти из трансляции можно нажатием клавиши Q
Вот в общем то и всё, что я хотел сказать.
Попробуйте сами, может вы добъётесь более положительных результатов.
-
радио ТЕХНО-ДИЗАЙН по радиолюбительски
В итоге дискуссий по теме "GPIO для чайников (часть 5-продолжение)" получился вот такой интернет-приемничек, с дизайном без претензий на международную выставку.
-
Новая жизнь старого кассетника
Завалялся у меня старый проигрыватель дисков, кассет и т.д. – старый стал, лазер подсел, даже на максимальном токе диски уже не читал. Да и морально устарел – ни тебе MP3, ни USB. Но сделан был добротно, посему и выкинуть жалко было. Валялся в подвале, место занимал. Но благодаря гениально-простому применению ARM-а английскими инженерами, наличию свободного времени в связи с отсутсвием загрузки в проектах, решил я вдохнуть жизнь с железяку, безмолвно просившую меня открытой крышкой дископриемника.
Да в принципе, я уже давно задумывался об устройстве, позволяющем мне слушать радио на русском/украинском языках, ввиду отсутсвия наличия эфирного радио на оных.
Проигрыватель был успешно принесен из подвала и разобран для идентификации нужных входов/выходов. А нужно мне было не много – 5В и вход стерео на усилитель мощности. В принципе, это заняло найбольшую часть времени, потраченного на конструирование – без осцилографа при помощи одного только мультиметра ... Но, метод научного тыка доказал свою эффективность и необходимые входы были найдены. Правда вместо необходимых 5 В нашел только 13В, посему пришлось ставить КРЕН на 5В/1А, соответственно лишние 4..8Вт пришлось рассеивать, благо под рукой оказался радиатор из старого блока питания. Ну, зато дёшево
Дополнительно поставил релюшку – 13 вольт брались непосредственно с блока питания и в стендбае не отключались. Итак, привод диска – на выкинштейн. Плату управления – туда-же. Освобождаем место под радиатор. Закрепляем «малинку» винтами к корпусу. Между делом паяем блок управления и индикации (во как), состоящее из одного светодиода и двух кнопок, подтягиваем к +3.3В, чтобы противостоять наводкам от ВиФи (в «GPIO для чайников» все подробно описано).
За основу программногообеспечения берем примерчик из 5го урока и модифицируем следующим образом:
А) список каналов держим в отдельном файле – в этом случае можно просто обновлять файл без перекомпиляции программы. Думаю, нет смысла приводить код, стандартные файловыеоперации
Б) добавляем обработку второй кнопки (одна кнопка щелкает каналы вперед, другая – назад)
int do_parent (int fd, pid_t p, int n) { signed char key_pressed =0; while(!key_pressed) { if (bcm2835_gpio_lev(KEY_UP)) key_pressed = INCREASE_STATION; if (bcm2835_gpio_lev(KEY_DN)) key_pressed = DECREASE_STATION; if (key_pressed) printf("Key : %d\n", key_pressed); }
В) Когда переключаемся на другой канал – гасим светодиод . В случае успешного захвата канала – зажигаем светодиод. Достаточно тривиально.
Г) для автостарта пришлось вводить искусственную задержку в пару секунд – я подозреваю, что вайфаю нужно пару секунд, чтобы законектиться. Если в это время стартует плеер, программа подвисает.
-
Обновление форума
Форум обновился.
Старые сообщения удалось перенести, но информация об авторах сообщений утеряна.
Поэтому у всех старых сообщений один и тот же автор -
RE: Не запускается raspberry pi 3B Ver1.2
Но что видно на экране?
Уточняю. Вы это сделали:
- Подключили телевизор к HDMI разъёму малинки
- Подключили клаву к одному USB порту
- Подключили мышку к другому USB
И что видно на экране? Если с питанием всё нормально, а разноцветный квадрат НЕ появляется, то (скорее всего) у вас SD-карточка не загрузочная. Достаньте где нибудь заведомо нормальную карточку и попытайтесь загрузиться с неё.
-
RE: Не запускается raspberry pi 3B Ver1.2
Может образ ОС не тот записал на карту?
Образы для 4ки не будут работать на тройке -
RE: MAX6675
К SPI видимо
SCK - GPIO 11
CS - CE0/CE1
SO - GPIO9
Vcc - к питанию (первый или второй пин, в зависимости от того, сколько нужно 5 или 3.3В)
Gnd- Gnd -
RE: не устанавливается ПО
Весь этот огромный лог состоит из повторяющихся участков, в которых пишется:
Internal Server Error 500 # На сервере, к которому Вы обращаетесь, возникла ошибка. [IP: 93.126.105.202 80] # Вот IP этого сервера Error reading from server. # Ошибка возникла при чтении файла Failed to fetch # На сервере нет вот этого файла http://fastmirror.pp.ua/raspbian/raspbian/pool/main/libx/libxss/libxss1_1.2.3-1_armhf.deb Remote end closed connection # После этого сервер закрывает соединение.
Можно сделать два предположения:
- Ваш инсталлятор не адекватен репозитарию
- Сервер грохнулся.
Что из них истина - это надо разбираться.
@sokol#6866 fastmirror.pp.ua
Но этот URL наводит на грустные размышления.
-
RE: не устанавливается ПО
@sv-lary#6865
Ок, это мой первый опыт с малинкой.по этапно что я делаю:
записываю на флешку образ 2022-01-28-raspios-bullseye-armhf-liteзакидываю на флешку файл ssh и файл wpa_supplicant.conf, в котором прописанно:
country=UA ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="логин" psk="пароль" key_mgmt=WPA-PSK }
логин и пароль естественно подставленны от сети ви-фи.
далее захажу через PuTTY в командную строку распберри, делаю три команды по очереди:sudo apt-get update sudo apt-get upgrade sudo apt-get install fluidsynth
и вот что получаю:
pi@raspberrypi:~ $ sudo apt-get update Get:1 http://raspbian.raspberrypi.org/raspbian bullseye InRelease [15.0 kB] Get:2 http://archive.raspberrypi.org/debian bullseye InRelease [23.5 kB] Get:3 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf Packages [13.2 MB] Get:4 http://archive.raspberrypi.org/debian bullseye/main armhf Packages [250 kB] Fetched 13.5 MB in 11s (1,264 kB/s) Reading package lists... Done pi@raspberrypi:~ $ sudo apt-get upgrade Reading package lists... Done Building dependency tree... Done Reading state information... Done Calculating upgrade... Done The following packages will be upgraded: libcamera-apps-lite libcamera0 libcryptsetup12 libexpat1 libwbclient0 raspi-config rpi-eeprom 7 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Need to get 2,935 kB of archives. After this operation, 1,599 kB of additional disk space will be used. Do you want to continue? [Y/n] y Get:1 http://archive.raspberrypi.org/debian bullseye/main armhf libcamera0 armhf 0~git20220201+e96d0201-1 [547 kB] Get:4 http://archive.raspberrypi.org/debian bullseye/main armhf libcamera-apps-lite armhf 0~git20220131+7ac5197-1 [239 kB] Get:2 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf libwbclient0 armhf 2:4.13.13+dfsg-1~deb11u3 [294 kB] Get:6 http://archive.raspberrypi.org/debian bullseye/main armhf raspi-config all 20220126 [30.2 kB] Get:7 http://archive.raspberrypi.org/debian bullseye/main armhf rpi-eeprom armhf 13.8-1 [1,529 kB] Get:3 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf libcryptsetup12 armhf 2:2.3.7-1+deb11u1 [222 kB]
-
RE: не устанавливается ПО
- Большая просьба - никогда не формируйте свои вопросы с использованием скриншотов. Только текстовые копии. Скриншот невозможно загрузить в текстовый редактор, процитировать что-то из него и что-то искать.
- "При попытке установки" - Вы не написали самое главное - как Вы пытались выполнить установку? Какой же Вы ждёте ответ?!
- Разглядывая картинку (!) можно увидеть, что выдаётся сообщение "internal server error" (это я набирал вручную, глядя на картинку) которое говорит о том, что проблемы не у Вас, а на сервере, к которому Вы обращаетесь. Я не знаю, что это за сервер и зачем Вы к нему обращаетесь. Но проблема - там.
Кстати говоря, на моей "малинке" этот синтезатор установлен по умолчанию. Я его вручную не устанавливал. Но, если у Вас его почему-то нет, то может быть "как все - по камушкам":
- В главном мею выбираем "Настройки"
- Add / Remove software
- В строке поиска пишем fluidsynth
- В строке с найденной программой взводим галку
- Нажимаем "Ок"
Ну если у Вас не устновлена никакая графическая оболочка, то в командной строке введите
sudo apt-get install fluidsynth
И всех делов...
-
RE: Отключение ИК подсветки на камере
Честно говоря, я подробности не вникал, но мне кажется, что такая конфигурация, как у Вас - это просто механическая комбинация камеры OV5647 и двух IR светильников. Вот таких:
Каждый светильник имеет свой датчик освещённости и, при снижении освещённости ниже порога, включает подсветку. Автоматически. А с платой камеры он связан всего двумя проводниками - питанием. Так что, если Вы хотите просто отключить подсветку - выкиньте нафиг эти фонарики и всё. Они 300 р стоят. А если Вы хотите их включать и выключать по командам из малинки, то тогда (мне кажется) надо оторвать плюсовую ногу светильника от питания камеры и завести её на любую ножку GPIO.
-
RE: Отключение ИК подсветки на камере
-
"чебурашка с ушами ИК прожектори и объективом сразу из платы"
Вот это ?
-