Search
Write a publication
Pull to refresh

Онлайн радио с энкодером

Всегда хотел купить себе роутер MR-3020, чтобы поиграться. Ведь на хабре столько всякого интересного из него делали!!! Вообще планирую его поставить на самодельного робота для управления им по WI-FI. Но делать робота сразу накладно, да и сложно. Сначала надо бы разобраться как вообще с ним работать.

Итак, начнем.

Шаг первый. Прошивка.


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

Шаг второй. Установка звуковой карты.


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

Установлены необходимые модули для работы со звуком, как уже упоминалось на хабре.
Всегда, проверяя какие-то девайсы, работающие со звуком, я ни них проигрываю песню группы Технология «Нажми на кнопку». Качаем ее wget-ом, проигрываем с помощью madplay, и получаем результат!
Но слушать скачанную музыку не очень интересно. Потому что ее надо качать перед этим. Я решил, что буду слушать радио. Для этого был создан небольшой скрипт, который только то и делал, что запускал радио и сворачивался, чтобы не мешать работать дальше в консоли с роутером:
#!/bin/ash
wget -q -O - http://online-radioroks.tavrmedia.ua/RadioROKS | madplay - -Q --no-tty-control &

Радио работает. Но чего-то не хватает. Хотелось громкость регулировать. Но не резистором, а софтово )

Шаг третий. Скрипт для управления громкостью.


Вычитал где-то, что уровень громкости можно посмотреть вот так: amixer -c 0 sget Speaker Playback Volume
И собственно устанавливать любой другой уровень громкости вот так:
amixer -c 0 sset Speaker Playback Volume xx%
Я сделал небольшой скрипт, который позволяет кнопками < > соответственно увеличивать или уменьшать громкость на 10 процентов.
Спойлер
#!/bin/ash
get_volume()
{
string=$(amixer -c 0 sget Speaker Playback Volume | grep 'Front Left:')
IFS='['
n=0
for i in $string
do
let "n++"
if [ "$n" == "2" ]
then
value_volume=$i
fi
done
value_volume=$(echo $value_volume | sed 's/.$//')
value_volume=$(echo $value_volume | sed 's/.$//')
value_volume=$(echo $value_volume | sed 's/.$//')
echo $value_volume
}
down=','
up='.'
keyreturn=0
out=0
readkey()
{
	read -s -n 1 KEY
	keyreturn=0
	if [ $KEY == $down  ];
	then
   	 keyreturn=1
   	let "out = $value_volume - 10"
   	amixer -c 0 sset Speaker Playback Volume $out% > /dev/null
	fi

	if [ $KEY == $up ];
	then
   	let "out = $value_volume + 10"
   	amixer -c 0 sset Speaker Playback Volume $out% > /dev/null
	    keyreturn=2
	fi
}
get_volume
readkey

while ( [ "$keyreturn" != 0 ] ) do
get_volume
readkey
done



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

Шаг четвертый. Железная реализация.


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

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

$regfile = «m64def.dat»
$crystal = 16000000
$hwstack = 512
$swstack = 512
$framesize = 128
$baud = 9600

Dim A As Byte, B As Integer

Portd.6 = 1
Portd.7 = 1

Config Portc.0 = Output
Portc.0 = 0

B = 100

Do
A = Encoder(pind.6, Pind.7, P, L, 1)
Waitms 10
If B = 102 Then
Print «u»
B = 100
End If
If B = 98 Then
Print «d»
B = 100
End If
Loop

End

L:
Portc.0 = 1
Incr B
Return

P:
Portc.0 = 0
Decr B
Return
End

Tx и землю микроконтроллера я поключил к преобразователю uart-usb и подключил его через последний порт юсб хаба к роутеру. Осталось написать прогу для роутера, которая будет ждать байты на уарте и крутить громкость, куда контроллер укажет. Я не был уверен, что смогу сделать все на шелле, потому что не знал, как там корректно принимать входящие по уарту данные, и поэтому решил сделать адский комбайн из Python + shell. Я создал три скрипта: один повышает громкость на 10, второй уменьшает, а третий, на питоне, ждет байты от микроконтроллера и запускает тот или иной скрипт.
Скрипт на питоне:
import serial
import subprocess
PIPE = subprocess.PIPE
up = './up_volume.sh'
down = './down_volume.sh'
#p = subprocess.Popen(cmd, shell = True)
#p.wait()
ser = serial.Serial('/dev/ttyUSB0', 9600)
while True:
    buff = ser.read()
    print(buff)
    if (buff == 'u'):
        p = subprocess.Popen(up, shell = True)
        p.wait()
       # print('up')
        
    if (buff == 'd'):
        p = subprocess.Popen(down, shell = True)
        p.wait()
       # print('down')
    if (buff == 'e'):
        ser.close()
        exit
ser.close()


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

Буду рад, если кто-то подскажет, как сделать все правильнее.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.