Sozinho em casa com os miúdos, usei o SBrick para um micro rover telecomandado:
É uma montagem frágil mas estou certo que é possível fazer ainda mais pequeno e ainda assim mais robusto, é uma questão de tempo e engenho.
[actualizado no dia seguinte]
Uma versão ligeiramente melhor em que a ligação das rodas aos micro-motores não gera tanto atrito e onde experimentei utilizar 3 pilhas de lítio CR2430 para fornecer os 9 Volt. As pilhas portaram-se melhor do que eu esperava.
Assim quase do nada tenho aqui um robot de mesa bastante interessante para experiências com o Snap!
[nova actualização]
O consumo do robot com 3 pilhas CR2430 novas varia entre 60 mA (movendo-se para a frente) e 90 mA (rodando sobre si próprio).
Descobri que é muito fácil usar um wiimote em Linux por isso na sequência de ‘SBrick – controlo remoto com um gamepad‘ segue agora como controlar o SBrick com um wiimote (na verdade um clone barato, um N-Play Remote Plus, comprado fora de horas numa Worten – infelizmente não havia a versão com Motion Plus).
O wiimote usa Bluetooth, apesar de não seguir estritamente as normas. Se tivermos bluetooth no nosso PC podemos confirmar que estamos em condições de utilizar o wiimote carregando em simultâneo nos botões ‘1’ e ‘2’ do wiimote para que este fique visível durante uns segundos:
$ hcitool -i hci0 scan
Scanning ...
04:02:16:01:1C:E7 Nintendo RVL-CNT-01
Como não segue as normas não é possível emparelhar com ele mas existem ferramentas para isso como o cwiid. Como vou usar pyhton fui buscar a library correspondente:
$ sudo apt-get install python-cwiid
existem vários exemplos básicos que não vou apresentar aqui, sigo directamente para o resultado final:
O script utilizado no video acima:
# apt-get install python-cwiid
import cwiid
from time import sleep
from subprocess import call
from math import log10
# macros for the SBrick
DRIVE_A="gatttool -b 00:07:80:7F:28:E1 -i hci0 --char-write --handle=0x0025 --value=0102"
DRIVE_B="gatttool -b 00:07:80:7F:28:E1 -i hci0 --char-write --handle=0x0025 --value=0103"
COAST_A="gatttool -b 00:07:80:7F:28:E1 -i hci0 --char-write --handle=0x0025 --value=01020000"
COAST_B="gatttool -b 00:07:80:7F:28:E1 -i hci0 --char-write --handle=0x0025 --value=01030000"
BREAK_A="gatttool -b 00:07:80:7F:28:E1 -i hci0 --char-write --handle=0x0025 --value=0002"
BREAK_B="gatttool -b 00:07:80:7F:28:E1 -i hci0 --char-write --handle=0x0025 --value=0003"
# connecting to the wiimote. This allows several attempts
# as first few often fail.
print 'Press 1+2 on your Wiimote now...'
wm = None
i=1
while not wm:
try:
wm=cwiid.Wiimote()
except RuntimeError:
if (i>5):
print("cannot create connection")
quit()
print "Error opening wiimote connection"
print "attempt " + str(i)
i +=1
#set wiimote to report button presses and accelerometer state
wm.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC
#turn on all led and ruble to show connected
wm.led=15
wm.rumble=True
sleep(0.5)
wm.rumble=False
wm.led=0
sleep(1.5)
# roll = accelerometer[0], standby ~125
# pitch = accelerometer[1], standby ~125
while True:
buttons = wm.state['buttons']
#only pay attention when button '1' pressed
if (buttons & cwiid.BTN_1):
roll=(wm.state['acc'][0]-125)
pitch=(wm.state['acc'][1]-125)
if (roll<0):
if (roll<-4):
if (roll<-25):
roll=-100
else:
roll=-50*log10(-4*roll)
else:
roll=0
if (roll>0):
if (roll>4):
if (roll>25):
roll=100
else:
roll=50*log10(4*roll)
else:
roll=0
if (pitch>0):
if (pitch>4):
if (pitch>25):
pitch=100
else:
pitch=50*log10(4*pitch)
else:
pitch=0
if (pitch<0):
if (pitch<-4):
if(pitch<-25):
pitch=-100
else:
pitch=-50*log10(-4*pitch)
else:
pitch=0
if ((pitch<>0)or(roll<>0)):
roll=2.5*roll
pitch=2.5*pitch
if(pitch<>0):
if(roll>0):
# turn right
motor_L=pitch
motor_R=-pitch-roll/2
else:
# turn left
motor_R=-pitch
motor_L=pitch+roll/2
elif(roll<>0):
#just rotate
motor_R=motor_L=roll;
else:
# does nothing
motor_R=motor_L=0
if((motor_R<>0)or(motor_L<>0)):
if(motor_R<0):
duty=str(hex(int(-motor_R)))
command_A=DRIVE_A+"00"+duty[2:]
else:
duty=str(hex(int(motor_R)))
command_A=DRIVE_A+"01"+duty[2:]
if(motor_L<0):
duty=str(hex(int(-motor_L)))
command_B=DRIVE_B+"00"+duty[2:]
else:
duty=str(hex(int(motor_L)))
command_B=DRIVE_B+"01"+duty[2:]
#send motors commands to SBrick
call(command_A, shell=True);
call(command_B, shell=True);
sleep(0.1)
#send COAST commands to SBrick
call(COAST_A, shell=True);
call(COAST_B, shell=True);
else:
# inactive
sleep(0.01)
E agora um primeira experiência com múltiplos DS2413 numa mesma microLAN…
Cada dispositivo 1-wire tem um ID distinto gravado em fábrica:
$sudo ls /mnt/1wire/
3A.4C2B13000000 81.086D33000000 settings structure uncached
3A.B0E216000000 bus.1 statistics system
Vemos que temos 3 dispositivos de 2 classes diferentes. A classe 81 é a do Master Controller (o adaptador USB DS9490R) e a classe 3A é a do DS2413. Temos portanto dois dispositivos DS2413 na rede, cada um com o seu ID:
4C2B13000000
B0E216000000
Na forma como o owfs lida com 1-wire o par “Classe.ID” funciona como um endereço. É possível definir alias mas funcionam apenas localmente (isto é: se movermos a microLAN do meu Ubuntu para o LEGO ev3dev tẽm de ser redefinidos) e na minha primeira experiência com alias perdi o acesso aos dispositivos por isso deixo para outra altura.
Sendo da mesma classe, estes dois dispositivos partilham os mesmos atributos (PIO.A, PIO.B e PIO.ALL por exemplo). Se tiver um LED em cada PIO destes devices podemos por exemplo acender todos os LEDs percorrendo todos os dispositivos da classe 3A e escrevendo “1,1” na subpasta PIO.ALL.
O programa abaixo acende cada LED em sequência, primeiro num sentido depois no outro:
E o programa abaixo acende as luzes aleatoriamente, mais próprio para um concerto ou uma discoteca (com tempo hei-de estudar a forma de usar as rotinas PyAudio para medir a intensidade de uma música e controlar as luzes ao ritmo desta embora duvide que o EV3 tenha CPU para tal).
import sys, traceback
from time import sleep
from subprocess import call
from random import randrange
# B0E216000000/PIO.A = primeiro LED
# B0E216000000/PIO.B = segundo LED
# 4C2B13000000/PIO.A = terceiro LED
# 4C2B13000000/PIO.B = quarto LED
def main():
try:
# apagar tudo ao comecar
call("echo 0,0 > /mnt/1wire/3A.B0E216000000/PIO.ALL", shell=True);
call("echo 0,0 > /mnt/1wire/3A.4C2B13000000/PIO.ALL", shell=True);
while True:
# apaga tudo
call("echo 0,0 > /mnt/1wire/3A.B0E216000000/PIO.ALL", shell=True);
call("echo 0,0 > /mnt/1wire/3A.4C2B13000000/PIO.ALL", shell=True);
if (randrange(2) == 1):
call("echo 1 > /mnt/1wire/3A.B0E216000000/PIO.A", shell=True); # LED1
if (randrange(2) == 1):
call("echo 1 > /mnt/1wire/3A.B0E216000000/PIO.B", shell=True); # LED2
if (randrange(2) == 1):
call("echo 1 > /mnt/1wire/3A.4C2B13000000/PIO.A", shell=True); # LED3
if (randrange(2) == 1):
call("echo 1 > /mnt/1wire/3A.4C2B13000000/PIO.B", shell=True); # LED4
sleep(0.25);
except (KeyboardInterrupt, SystemExit):
print "Exiting...";
except Exception:
traceback.print_exc(file=sys.stdout);
# apagar tudo antes de sair
call("echo 0,0 > /mnt/1wire/3A.B0E216000000/PIO.ALL", shell=True);
call("echo 0,0 > /mnt/1wire/3A.4C2B13000000/PIO.ALL", shell=True);
sys.exit(0);
if __name__ == "__main__":
main()
Estou a reproduzir em LEGO um concerto dos Xutos&Pontapés. A posição dos elementos da banda em palco vai ser controlada por um controlador (ainda não decidi se um Raspberry Pi ou um LEGO EV3) e quero poder controlar também as luzes dos projectores:
Se as luzes acendessem todas em simultâneo as ligações eléctricas seriam simples e seriam necessários passar apenas 2 cabos (positivo e negativo, comuns a todos os LEDs) pela estrutura por cima do palco. Mas eu quero um controlo individual dos projectores e pelo menos 10 deles. Isso significa pelo menos 11 cabos (10 positivos e 1 negativo comum) e apesar de ser possível (consigo passar 4 ou 5 cabos de jumper por entre um furo Technic por isso bem arrumados os cabos até nem dariam muito nas vistas) obriga-me a ter pelo menos 10 portas digitais para o controlo (o que também é possível com circuitos adicionais mas não me cativa). E se quiser aumentar o número de projectores a coisa começa a complicar-se.
Comecei logo a pensar num bus de controlo e pendurar micro-circuitos de controlo ao longo do bus. O ideal mesmo seriam LEDs I2C mas não encontrei nada suficientemente pequeno ou funcional por isso optei por uma microLAN 1-wire.
O termo “1-wire” é enganador: são necessários pelo menos 2 cabos num bus 1-wire (dados e massa) e na maioria das aplicações práticas será necessário um terceiro para alimentar os dispositivos (a norma prevê um modo “parasita” em que os dispositivos retiram alimentação da ligação prevista para dados mas isso apenas se aplica a dispositivos de muito baixo consumo como sensores de temperatura). Mesmo assim 3 cabos é muito bom para controlar quantos LEDs quiser (se decidir mais 2 ou 3 projectores não preciso passar mais 2 ou 3 cabos nem desencantar mais 2 ou 3 portas digitais no controlador).
A Maxim fabrica o DS2413, um circuito extremamente reduzido que implementa 2 portas digitais bidireccionais. É um chip SMD mas a Adafruit fornece um kit com o chip já montado numa placa de circuito impresso sendo só necessário soldar 4 headers e eventualmente uma resistência (tudo fornecido com o kit) para podermos utilizar na nossa microLAN.
Uhmmm… qual microLAN?
É possível implementar uma microLAN com o Raspberry Pi como master utilizando uma porta GPIO e uma resistência de pull-up. Mas é algo específico para o Raspberry, prefiro algo que possa replicar no meu PC ou no LEGO EV3. Por isso encomendei à RS Online um Maxim DS9490R que é um dispositivo USB que funciona como master controller numa microLAN e é suportado pelo Linux.
No meu portátil (Ubuntu 14.04) foi só ligar:
$ dmesg
(...)
[18011.890734] usb 2-1.3: new full-speed USB device number 7 using ehci-pci
[18011.983566] usb 2-1.3: New USB device found, idVendor=04fa, idProduct=2490
[18011.983576] usb 2-1.3: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[18012.021996] Driver for 1-wire Dallas network protocol.
[18012.026144] usbcore: registered new interface driver DS9490R
Não fui ver que módulos foram carregados na altura mas penso que foram ‘ds2490’ e ‘wire’ (existe também um módulo ‘ds9490r’ mas não está presente no meu Ubuntu).
Após detectar uma microLAN o kernel cria uma pasta ‘/sys/bus/w1’ para dispositivos 1-wire:
$ ls /sys/bus/w1/devices
81-000000336d08 w1_bus_master1
“81-” identifica o DS9490
A ligação do DS2413 à microLAN é muito simples: o DS9490R tem uma ficha RJ12, idêntica às RJ11 dos telefones mas com 6 contactos. Felizmente dos 6 contactos apenas os 2 centrais são necessários pelo que podemos usar um cabo normal de telefone só com dois condutores:
3 – OW (OW 1-Wire Data)
4 – GND_OW (1-Wire Return)
Wire D
Apesar da datasheet da MAXIM indicar o pinout achei esta foto menos dada a confusões:
A Sheepwalk Electronics vende alguns produtos 1-wire (inclusive o DS9490R) e publica no seu site alguma informação útil relacionada com 1-wire.
Depois de soldar o header à placa da Adafruit foi só fazer as ligações (com cabos de jumper ou crocodilos, o que houver à mão):
Com 3 baterias AA NiMH (cerca de 3.8V) e um LED branco de alto brilho (cerca de 3.2V) temos 0.6V na resistência por isso se esta for de 1KΩ o consumo do LED será de 0.6 mA de corrente, bastante abaixo dos 20 mA tolerados por cada porta e suficiente para um teste (no palco LEGO irei puxar mais por cada LED, pelo menos 10 mA cada e alimentação será de outro tipo).
NOTA: com o kit da Adafruit vem uma resistência de 4.7KΩ para pull-up da linha ‘1-Wire Data’. Deveria ligar esta resistência ao pino 1 da ficha RJ12 (+5V vindos do bus USB do host onde estiver ligado o controlador, neste caso o PC) mas não me agradou muito a ideia e como suspeito que internamente o controlador já preveja isso optei deliberadamente por não usar o pull-up… aparentemente sem consequências.
Pouco depois de ligar o cabo telefónico ao controlador USB o nosso circuito é imediatamente reconhecido:
Infelizmente diz que a famíla 3A não está registrada – o suporte nativo do kernel a dispositivos 1-wire não se extende [ainda?] ao DS2413. É pena, assim não temos nada útil dentro de ‘/sys/bus/w1/devices/3a-00000012fdf4’. Mas tudo bem, já esperava isso, existe o projecto owfs dedicado especificamente ao 1-wire:
sudo apt-get install owfs
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libow-2.8-15 owfs-common owfs-fuse owftpd owhttpd owserver
Suggested packages:
owfs-doc
The following NEW packages will be installed:
libow-2.8-15 owfs owfs-common owfs-fuse owftpd owhttpd owserver
0 upgraded, 7 newly installed, 0 to remove and 0 not upgraded.
Need to get 296 kB of archives.
After this operation, 1,364 kB of additional disk space will be used.
Do you want to continue? [Y/n]
Após a instalação descobrimos que temos 3 serviços a correr:
owserver
owhttpd
owftpd
Embora não me pareçam necessários, nesta fase vou deixá-los a correr. Descobrimos também que o owfs impede o kernel de carregar os drivers que referi acima de modo a não ocorrerem conflitos:
Para aceder à microLAN usamos o comando ‘owfs’ mas primeiro é necessário definir um mountpoint onde o owfs vai criar uma estrutura de pastas virtuais que mapeiam cada dispositivo (escolhi ‘/mnt/1wire’):
sudo mkdir /mnt/1wire
sudo owfs -u -m /mnt/1wire
Para confirmar que funciona:
$ sudo ls /mnt/1wire
81.086D33000000 bus.1 settings statistics structure system uncached
temos 1 dispositivo na microLAN (o master controller DS9490R). Vamos agora ligar o DS2413 à microLAN – passadas algumas dezenas de segundos temos:
$ sudo ls /mnt/1wire
3A.F4FD12000000 bus.1 statistics system
81.086D33000000 settings structure uncached
agora já temos algo útil dentro do device ‘3A.F4FD12000000’:
$ sudo ls /mnt/1wire/3A.F4FD12000000
address family PIO.A PIO.BYTE r_locator sensed.B
alias id PIO.ALL r_address sensed.A sensed.BYTE
crc8 locator PIO.B r_id sensed.ALL type
Ligando um LED a PIO.A podemos acendê-lo:
$ sudo sh -c "echo 1 > /mnt/1wire/3A.F4FD12000000/PIO.A"
e voltar a apagá-lo:
$ sudo sh -c "echo 0 > /mnt/1wire/3A.F4FD12000000/PIO.A"
(os comandos são muito feios porque o owfs tem de correr com previlégios de root e eu não sou root no meu Ubuntu; em Raspberry Pi ou ev3dev bastaria:
Com a webcam a funcionar e com tanta coisa em comum com a comunidade Raspberry Pi ocorreu-me experimentar o OpenCV e testar as capacidades do EV3 no campo da Computer Vision.
Em vez de instalar o opencv todo, instalei apenas o módulo para python:
root@ev3dev:~# apt-get install python-opencv
Depois foi só criar o script ‘teste-opencv.py’:
import numpy as np
import cv2
imagePath = "/root/teste-face.jpg"
cascPath = "/root/haarcascade_frontalface_default.xml"
resultPath ="/root/resultado.jpg"
faceCascade = cv2.CascadeClassifier(cascPath)
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags = cv2.cv.CV_HAAR_SCALE_IMAGE
)
print "Found {0} faces!".format(len(faces))
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imwrite(resultPath,image)
Como não instalei o opencv não tenho os ficheiros xml com regras de classificação. Para este exemplo o autor do artigo referido disponibiliza também o ficheiro ‘haarcascade_frontalface_default.xml‘.
Para esta foto ‘teste-face.jpg’:
O resultado do script, ao fim de 3 a 5 minutos de CPU a 80% foi este:
Ter o LEGO Mindstorms EV3 a correr uma versão quase standard de Debian Linux começa agora a revelar as suas vantagens: podemos atirar-lhe com quase tudo o que tivermos na nossa gaveta de sucata… como por exemplo um teclado numérico USB:
O sistema operativo reconhece-o como um teclado convencional:
root@ev3dev:~# dmesg
usb 1-1.4.1: new low-speed USB device number 7 using ohci
input: USB-compliant keyboard as /devices/platform/ohci.0/usb1/1-1/1-1.4/1-1.4.1/1-1.4.1:1.0/0003:0B38:0003.0001/input/input2
hid-generic 0003:0B38:0003.0001: input: USB HID v1.10 Keyboard [USB-compliant keyboard] on usb-ohci.0-1.4.1/input0
input: USB-compliant keyboard as /devices/platform/ohci.0/usb1/1-1/1-1.4/1-1.4.1/1-1.4.1:1.1/0003:0B38:0003.0002/input/input3
hid-generic 0003:0B38:0003.0002: input: USB HID v1.10 Mouse [USB-compliant keyboard] on usb-ohci.0-1.4.1/input1
root@ev3dev:~# lsusb
Bus 001 Device 007: ID 0b38:0003 Gear Head Keyboard
Bus 001 Device 006: ID 058f:9254 Alcor Micro Corp. Hub
(o teclado tem embutido um hub USB de 2 portas daí o segundo device USB reportado)
O sistema operativo cria entradas do tipo ‘event#’ em ‘/dev/input’ assim como apontadores com descritivos mais legíveis:
ls /dev/input/by-id/ -la
lrwxrwxrwx 1 root root 10 Aug 13 23:38 usb-0b38_USB-compliant_keyboard-event-if01 -> ../event2
lrwxrwxrwx 1 root root 10 Aug 13 23:38 usb-0b38_USB-compliant_keyboard-event-kbd -> ../event1
De modo que o teclado pode ser referido por um destes dois ficheiros:
Felizmente isto só é necessário se quisermos ler directamente o teclado. Em situações normais, quando os nossos programas estão a correr, o próprio sistema operativo pode fazer esse trabalho por nós. No caso do ev3dev podemos ler uma única tecla a partir da consola com o seguinte comando bash:
read -s -n 1 Tecla < /dev/tty1
O parâmetro ‘-s’ serve para correr em modo silencioso (i.e. a tecla não é simultâneamente escrita na consola) e o parâmetro ‘-n 1’ força a leitura de um único caracter (quanto ao pipe ‘< /dev/tty1’ descobri entretanto que tanto faz referir /dev/tty0 como /dev/tty1 portanto a partir daqui refiro a consola do ev3dev como /dev/tty1… porque sim)
O script abaixo junta esta informação com a obtida anterior a respeito dos motores e permite controlar a rotação do motor com as teclas ‘4’ (LEFT) e ‘6’ (RIGHT), terminado com a tecla ‘ENTER’.
A utilização básica do LEGO Mindstorms EV3 com ev3dev fica completa com a utilização de motores.
Ligando um motor (45503 EV3 Medium Servo Motor) na ficha A, o sistema operativo acusa o evento:
root@ev3dev:~# dmesg
(...)
tacho-motor tacho-motor0: Tacho motor registered.
ev3-tacho-motor outA:motor: A Tacho Motor connected to port outA gpio 91 irq 192
Uma vez mais é necessário consultar a wiki do projecto ev3dev para entender como aceder aos motores. Estes também são mapeados pelo sistema operativo, desta vez em “/sys/bus/legoev3/devices/” e em ” /sys/class/tacho-motor/”:
Usando o ev3dev há duas formas de aceder ao LCD do LEGO Mindstorms EV3:
modo de texto: terminal via /dev/tty0
modo gráfico: framebuffer via /dev/fb0
Ambos os modos estão ainda a sofrer desenvolvimentos mas o segundo modo é seguramente o mais complexo pelo que fico-me por enquanto só pelo modo de texto.
Assim para escrever qualquer coisa basta por exemplo redireccionar o comando echo para /dev/tty0:
echo "Hello world!" > /dev/tty0
Já é qualquer coisa mas para limpar o ecran sem ter de enviar vários “echo” existem formas melhores. Sendo um terminal tty convencional, a maioria dos comandos para terminal devem funcionar (inclusive algumas sequencias de escape). Experimentei o tput:
Para limpar o ecran:
tput clear > /dev/tty0
Para posicionar o cursor:
tput cup linha coluna > /dev/tty0
(tput cup 0 0 envia para o canto superior esquerdo e já agora com tput cols ficamos a saber que o LCD tem 44 colunas)
Para escrever branco sobre negro:
tput smso > /dev/tty0
Para voltar ao negro sobre branco:
tput rmso > /dev/tty0
Muito bem, já escrevo o que quiser em qualquer lado do ecran… mas a fonte é tão pequena que só com uma lupa é que se lê. Como aumentar o texto?
A primeira hipótese que me ocorreu foi instalar o figlet que usa caracteres ASCII para fingir fontes maiores:
mas é uma forma um bocado coxa. O melhor mesmo é poder trocar o tamanho dos caracteres e para isso existe o comando “setfont” que felizmente já existe no ev3dev e disponibiliza umas quantas fontes em “/usr/share/consolefonts/”, vejamos só quantas há na variante Lat15 (que serve à maioria das linguas ocidentais incluindo a nossa):
Depois de ter Wi-Fi decidi testar mais alguns dispositivos USB que uso com o Raspberry Pi.
Para começar, uma vez que o EV3 apenas tem uma porta USB, imprescindível um hub, de preferência pequeno:
Hub KUNFT 4 Portas USB 2.0 H-088 (na Worten por €6,99)
Com o EV3 ainda desligado liguei-o e a ele o dongle Wi-Fi (ThePiHut).
Da primeira vez não obteve rede, não sei se não esperei tempo suficiente. Retirei o hub, liguei novamente (sem o dongle Wi-Fi) esperei um pouco e depois liguei o dongle e desta vez obtive rede. E a partir daqui cada boot/reboot com tudo ligado funcionou sempre bem.
root@ev3dev:~# lsusb
(...)
Bus 001 Device 002: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Agora o audio:
[Nota: o EV3 já tem uma placa de audio interna, suportada pelo ALSA, e um altifalante interno também. Mas tanto quanto percebi funciona de modo semelhante ao jack audio do Raspberry Pi, por PWM, consumindo CPU… além de ser mono e não permitir ligação externa a um amplificador]
DIY USB to Audio Module for Raspberry PI / Arduino / MAC / PC + More – Green (SKU 315287 na DX – DealExtreme, US$10.88)
root@ev3dev:~# dmesg
(...)
input: Burr-Brown from TI USB Audio DAC as /devices/platform/ohci.0/usb1/1-1/1-1.4/1-1.4:1.2/0003:08BB:2704.0001/input/input2
hid-generic 0003:08BB:2704.0001: input: USB HID v1.00 Device [Burr-Brown from TI USB Audio DAC ] on usb-ohci.0-1.4/input2
(...)
root@ev3dev:~# lsusb
(...)
Bus 001 Device 004: ID 08bb:2704 Texas Instruments Audio Codec
(...)
E para tocar um ficheiro mp3 (previamente trasnferido por ssh):
root@ev3dev:~# apt-get install mpg321
root@ev3dev:~# mpg321 -a hw:1,0 Thunderstruck.mp3
Rock’n Roll!!!
Durante a execução o mpg321 consome entre 22 a 25% de CPU. É um bocado alto (quando se utiliza a rede em simultâneo, por exemplo um update, ocorrem soluços) e como dizem que o SoX consome menos CPU…
Durante a execução o play consome 20 a 22% de CPU, apenas marginalmente melhor.
Mas como SoX permite vários formatos (wav, ogg…) permite o redireccionamento (pipe) de outros comandos como o espeak:
ieee80211 phy1: rt2x00_set_rt: Info - RT chipset 5390, rev 0502 detected
ieee80211 phy1: rt2x00_set_rf: Info - RF chipset 5370 detected
ieee80211 phy1: Selected rate control algorithm 'minstrel_ht'
ieee80211 phy1: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2870.bin'
ieee80211 phy1: rt2x00lib_request_firmware: Info - Firmware detected - version: 0.29
E para a ligação wireless, à semelhança do Raspbian no Pi, editei o ficheiro ‘interfaces’:
root@ev3dev:~#nano /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d
### acrescentar as linhas abaixo ###
auto lo
iface lo inet loopback
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid "WI-Fi SID"
wpa-psk "Wi-Fi Password"
iface default inet dhcp