Pitágoras e Base Jumping

Com 2 sensores de toque (é o que tenho neste momento) e um motor ocorreu-me um elevador automático, capaz de desligar ou reverter o motor cada vez que a cabina atinja um dos extremos do percurso:

pitagoras-elevator

O elevador em si não é muito diferente do de elevador de Linda Hamilton e a ideia da sua utilização com um Raspberry Pi e um PiFace Digital também não é original (Reinoud de Lange recorreu a microswitches em vez de sensores LEGO).

O código (um loop infinito que desloca a cabina para cima e para baixo)

#!/usr/bin/python3

import sys
from time import sleep
import pifacedigitalio

pifacedigital = pifacedigitalio.PiFaceDigital()
led7=pifacedigital.leds[7]
led6=pifacedigital.leds[6]
led7.turn_off()
led6.turn_off()
in0=pifacedigital.input_pins[0]
in1=pifacedigital.input_pins[1]

subir=True

sleep(2.0)

while(True):
 if(in1.value != 0):
   print("EM BAIXO!")
   led6.turn_on()
   sleep(0.025)
   led6.turn_off()
   subir=True

 if(in0.value != 0):
  print("NO ALTO!")
  led7.turn_on()
  sleep(0.025)
  led7.turn_off()
  subir=False

 if((in0.value ==0) and (in1.value ==0)):
   if (subir):
     print("PARA CIMA!")
     led6.turn_on()
     sleep(0.025)
     led6.turn_off()
   else:
     print("PARA BAIXO!")
     led7.turn_on()
     sleep(0.025)
     led7.turn_off()

Alguns pormenores da montagem:

elevator-bottom-sensor
O sensor no fundo do «poço» do elevador
elevator-winch
O mecanismo que puxa o elevador
elevator-top-sensor
O sensor no topo do «poço» do elevador
elevator-cabin-basejumper
A cabina do elevador levando um assustado base jumper

Pitagoras e a Esfinge

Faltava ainda um tipo qualquer de sensor para ter um sistema verdadeiramente autónomo por isso liguei um sensor de toque LEGO Mindstorms (ainda estilo RCX) a uma das entradas digitais PiFace.

O PiFace tem 8 entradas digitais com pull-ups internos (li algures que se podem desligar, deixando as entradas «flutuantes»). Como o sensor de toque RCX é um mero interruptor basta ligar um dos cabos a uma das entradas e o outro à massa. Com o sensor em repouso (interruptor aberto) a entrada do PiFace vai ler um “1” e quando ocorrer contacto (interruptor fechado) a entrada vai ficar ligada à massa e é lido um “0”.

bricklink.com: Lego Touch Sensor (879)

É muito fácil acompanhar o estado do sensor, basta ler continuamente o estado da entrada. No script abixo usei a entrada #0 e acrescentei um atraso de 200 ms entre cada leitura para não inundar o terminal com mensagens “ON!” ou “OFF!”

#!/usr/bin/python3

import sys
from time import sleep
import pifacedigitalio

pifacedigital = pifacedigitalio.PiFaceDigital()
led7=pifacedigital.leds[7]
led6=pifacedigital.leds[6]
led7.turn_off()
led6.turn_off()
in0=pifacedigital.input_pins[0]

while(True):
 if(in0.value != 0):
   print("ON!")
 else:
   print("OFF!)
 sleep(0.2)

E se quisermos usar o sensor para controlar o leão basta juntar tudo:

#!/usr/bin/python3

import sys
from time import sleep
import pifacedigitalio

DELAY_UP = 0.17
DELAY_DOWN = 0.14
DELAY_WAIT = 0.75

pifacedigital = pifacedigitalio.PiFaceDigital()
led7=pifacedigital.leds[7]
led6=pifacedigital.leds[6]
led7.turn_off()
led6.turn_off()
in0=pifacedigital.input_pins[0]

while(True):
 if(in0.value != 0):
   print("Para cima!")
   led7.turn_on()
   sleep(DELAY_UP)
   led7.turn_off()
   print("Espera!")
   sleep(DELAY_WAIT)
   print("Para baixo!")
   led6.turn_on()
   sleep(DELAY_DOWN)
   led6.turn_off()

Para ligar o sensor à entrada #0 do Piface Digital cortei um cabo RCX a meio:

rcx-cableO diagrama abaixo ilustra a configuração final, no que diz respeito às ligações eléctricas:

pitagoras-e-a-esfinge

Raspberry Pi como alternativa LEGO WeDo

Para a primeira aplicação prática montei o Roaring Lion do conjunto LEGO WeDo (as instruções de montagem deste e outros modelos simples estão disponiveis no site LEGO Education).

raspberrypi-lego-roaring-lionO leão é muito simples: fazendo rodar o motor num sentido ele levanta-se nas patas dianteiras, no outro sentido volta a deitar-se (como não há sensor de posição é necessário afinar os tempos à mão)

lego-roaring-lionNuma primeira fase testei comandar o leão remotamente a partir de uma sessão SSH, criando para isso um script (lion.py) em python:

#!/usr/bin/python3

import sys
from time import sleep
import pifacedigitalio

DELAY_UP = 0.17       # o leão custa um pouco mais a subir
DELAY_DOWN = 0.14     # do que a descer

pifacedigital = pifacedigitalio.PiFaceDigital()
led7=pifacedigital.leds[7]
led6=pifacedigital.leds[6]
led7.turn_off()
led6.turn_off()

comando='.'

while(comando!="s"):
 comando=input("Comando: ")
 if (comando=="c"):
   print("Para cima!")
   led7.turn_on()
   sleep(DELAY_UP)
   led7.turn_off()
 elif (comando=="b"):
   print("Para baixo!")
   led6.turn_on()
   sleep(DELAY_DOWN)
   led6.turn_off()
 elif (comando=="s"):
   print("Tchau!")
 else:
   print("?") # comando desconhecido

É necessário dar permissões de execução ao script:

sudo chmod u+x lion.py

Para correr, basta invocar directamente o script:

./lion.py

Os comandos são simples:

  • c – para cima
  • b – para baixo
  • s – para sair

Funciona bem mas seria bem melhor se o leão estivesse sempre à espera de um comando e pudessemos usar o rato em vez do teclado, por exemplo a partir de um browser.

Para isso precisamos de um servidor (daemon) http – poderia ter ido para o apache mas preferi ir à procura de um servidor http mais leve e encontrei o Monkey (no passado tive boas experiências com o lighttpd e existe também o nginx):

Começamos por adicionar o repositório para usar a versão directamente mais recente em vez da que vem do mundo Debian:

sudo nano /etc/apt/sources.list

e adicionar a linha

deb http://packages.monkey-project.com/primates_pi primates_pi main

depois actualizar a cache:

sudo apt-get update

e instalar todos os componentes:

sudo apt-get install monkey          
                  monkey-liana       
                  monkey-logger      
                  monkey-dirlisting  
                  monkey-cgi         
                  monkey-fastcgi     
                  monkey-mandril     
                  monkey-cheetah     
                  monkey-auth

(embora só seja, mesmo necessários o monkey e os módulos liana e cgi )

Para testar basta aceder por browser na porta 2001:

http://192.168.1.123:2001/

(o conteúdo desta página está ficamente em /usr/share/monkey/)

Para poder invocar scripts de python a partir de páginas html é necessário recorrer a CGI (penso que seria possível fastcgi mas esta não é de todo a minha especialidade).

Criei uma pasta só para armazenar os scripts que vão ser acedidos por browser:

sudo mkdir /usr/share/monkey/cgi-bin

É necessário configurar o monkey para carregar o módulo CGI:

sudo nano /etc/monkey/plugins.load

basta descomentar a linha (mentendo os espaços em branco):

Load /usr/lib/monkey/monkey-cgi.so

além disso é necessário mudar a conta com que o monkey corre para poder utilizar as libraries do PiFace:

sudo nano /etc/monkey/monkey.conf

(basta mudar de www-data para root)
E finalmente reiniciar o monkey:

sudo service monkey restart

Para testar, colocar na pasta /usr/share/monkey/cgi-bin o ficheiro hello.cgi:

#!/usr/bin/python3
print("Content-Type: text/html")     # HTML is following
print()                              # blank line, end of headers
print("<TITLE>CGI script output</TITLE>")
print("<H1>This is my first CGI script</H1>")
print("Hello, world!")

(eventualmente dar-lhe permissões de execução – sudo chmod u+x)

E aceder por browser: http://192.168.1.123:2001/cgi-bin/hello.cgi

Confirmado o funcionamento, criar 2 scripts para controlo do leão:

E uma página que se limita a disponibilizar dois links para os dois scripts:

<html><head>
<title>Pitagoras</title>
</head><body>
<p><a href="cgi-bin/cima.cgi">Para cima!</a></p>
<p><a href="cgi-bin/baixo.cgi">Para baixo!</a></p>
</body></html>

E…

funciona!

É pena que o CGI obrigue a que cada vez que é dado um comando seja reinicializado o python e recarregados os módulos – cada comando demora por isso demora 2 ou 3 segundos. Os melhoramentos ficam para outra altura.

Raspberry Pi – headless + wireless

Objectivo: utilizar um Raspbery Pi sem teclado nem monitor nem cabo de rede em momento algum.

Nota: as instruções são para quem usa Ubuntu e deverão servir para a generalidade dos Linuxes mas não para Windows.

Download do Raspbian (neste momento a versão mais recente é a ‘2014-01-07-wheezy-raspbian.zip’) e extrair a imagem (‘2014-01-07-wheezy-raspbian.img’).

Inserir um SD card com pelo menos 4 GB e lançar a aplicação “Disks” (gnome-disks). Seleccionar o SD Card, no meu caso o SD Card é visto como “8 GB Block Device (/dev/mmcblk0)” e carregar em “More Options” (o botão no canto superior direito) e escolher  “Restore Disk Image…”

Escolher o ficheiro com a imagem Raspbian (2014-01-07-wheezy-raspbian.img) e esperar alguns minutos que a operação termine. Ficam 2 partições no SD Card:

  • BOOT
  • 2.9 GB Volume

A segunda partição será utilizada como “/” pelo Raspbian e tem uma estrutura semelhante à do Ubuntu (ambos são baseados em Debian).

Basta editar 3 ficheiros:

  • […]/etc/hostname
  • […]/etc/network/interfaces
  • […]/etc/wpa_supplicant/wpa_supplicant.conf
$sudo nano [...]/etc/hostname

A ideia é ter um nome distinto e reconhecível para podermos depois encontrar o nosso dispositivo no router wireless. Substituí o ‘raspberrypi’ que vem de origem por ‘pitagoras’.

$sudo nano [...]/etc/network/interfaces

Aqui bastou acrescentar uma linha (post-up…) para desactivar a ligação por cabo quando a ligação wi-fi estiver funcional:

auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
    wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
    post-up ifdown eth0
iface default inet dhcp

Assume-se IP dinâmico tanto para ligação por cabo como wireless mas pode-se determinar um endereço IP estático (não o fiz ainda por pura preguiça).

$sudo nano [...]/etc/wpa_supplicant/wpa_supplicant.conf

Neste ficheiro apenas estavam presentes as duas primerias linhas, o resto foi acrescentado.

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="ID da rede Wi-Fi"
    psk="Preshared Key da rede Wi-Fi"
    id_str="Descritivo opcional"
}

Com um Wi-Pi para a ligação wireless funcionou à primeira (não testei ainda outros dispositivos mas pelo menos o D-Link DWA-131 deverá funcionar, está a funcionar noutro projecto). Para saber o endereço IP bastou ir ao router ver os devices ligados:

00:0f:13:38:1e:38    192.168.1.123    0 dia 0 hora 01 minuto    pitagoras

Para aceder remotamente por ssh:

ssh pi@192.168.1.123

E pronto (no Raspbian a password de origem de ‘pi’ é ‘raspberry’)

pi@pitagoras ~ $

Controlo de motores Lego

Quero utilizar o Raspberry Pi para controlar directamente construções em Lego, um pouco à maneiro do Lego Education WeDo Robotics.

Encomenda à PTRobotics:

Já tinha:

  • Lego Power Functions Rechargeable Battery Box (8878) ou AA Battery Box (8881)
  • Lego Power Functions XL Motor (8882)
  • fio eléctrico
  • carregador com ficha micro-USB
  • SD Card 4 GB com Raspbian instalado e pré-configurado para wi-fi para evitar ter de usar um teclado e um monitor
  • 2 resistências entre 220 Ω e 2.2 KΩ (usei duas de 1 KΩ)

A montagem do PiFace é simples: encaixar o módulo sobre o Raspberry Pi, inserir o SD Card e o Wi-Pi e fornecer energia através do cabo micro-USB.

O PiFace faz uso da interface SPI pelo que é necessário activá-la:

$sudo raspi-config

Escolher no menu “8 Advanced Options” e depois “A5 SPI”, responder “yes” e finalmente “finish”. Não é necessário reboot.

É também necessário instalar o módulo python para o PiFace, que já faz parte do repositório do Raspbian:

$sudo apt-get install python3-pifacedigitalio

Para testar, basta correr o script que vem com o módulo:

$python3 /usr/share/doc/python3-pifacedigitalio/examples/blink.py

O LED #7 acende e apaga segundo a segundo, tudo OK podemos passar ao controlo do motor.

As saídas do PiFace são Open Collector pelo que é necessário um pull up (ligar aos +5 V através de um resistência) para obter algo compatível com as entradas da bridge.

A bridge é alimentada pela bateria Lego Power Functions (usei um cabo Power Functions cortado a meio, aproveitando apenas os 2 condutores exteriores – um para GND e o outro para PWR).

powerfunctions-hbridge-powerUtilizei um voltímetro para confirmar qual o positivo e qual o negativo – no caso do modelo 8878 da foto acima o selector de velocidade ficou rodado até ao extremo no sentido dos ponteiros do relógio; no modelo 8881 é necessário deslocar o selector no sentido da ficha.

O motor é ligado à H-bridge com a outra metade do cabo anterior, desta vez utilizando apenas os 2 condutores interiores.

O script blinky.py anterior serve para testar mas para controlo manual a partir da shell do python optei por usar estes comandos:

$python3
>>>import pifacedigitalio
>>>pifacedigital = pifacedigitalio.PiFaceDigital()
>>>led7=pifacedigital.leds[7]
>>>led6=pifacedigital.leds[6]
>>>led7.turn_off()
>>>led6.turn_off()

Para acender apenas o LED #7 e fazer o motor rodar num sentido:

>>>led7.turn_off()
>>>led6.turn_on()

Para acender apenas o LED #6 e fazer o motor rodar no sentido oposto:

>>>led7.turn_on()
>>>led6.turn_off()

Se acender ambos os LED o motor permanece parado:

>>>led7.turn_on()
>>>led6.turn_on(

E para sair da shell de python:

>>>exit()

Montagem do Rover

Para montar o Rover resta agora:

  • ligar os blocos maiores entre si (o conjunto bateria + Raspberry PI e o Mindstorms NXT) tendo o cuidado de não dificultar a troca de pilhas do NXT nem o acesso aos vários botões e fichas do conjunto:

IMG_2531-2IMG_2535-2IMG_2537-2IMG_2539-2IMG_2540-2IMG_2543-2IMG_2544-2IMG_2546-2

  • depois ligar os dois motores e as três rodas (uma roda por motor e uma terceira roda livre que serve apenas para sustentar o Rover e facilitar as curvas à esquerda ou à direita):

IMG_2547-2

  • e finalmente os cabos, o cartão SD e o adaptador WiFi USB:

IMG_2558-2IMG_2559-2

Esta foi a primeira versão, serviu para o primeiro video de demonstração mas o comportamento deixava muito a desejar (sobretudo devido ao centro de gravidade muito alto e à roda livre instável. Mais à frente mostrarei versões melhoradas, inclusive com sensores (um Rover para poder ser um robot autónomo precisa de algum tipo de sensor para entender o mundo à sua volta).

Legoficação de um Raspberry Pi

Material necessário (aconselho consultar a wiki RPi VerifiedPeripherals):

  • 1 Raspberry Pi (à venda na PTRobotics e na Portugal-Didáctico)
  • 1 Cartão SD 4GB (à venda em todo o lado)
  • 1 bateria com ficha USB (PNY PowerPack 5200mAh, à venda na FNAC)
  • 1 cabo USB-MicroUSB (vem com a bateria)
  • 1 adaptador WiFi USB, preferencialmente mini (D-Link DWA-131 à venda na FNAC)
  • 1 cabo USB A-B o mais curto possível (arranjei um cabo «prolongador» USB extremamente curto numa loja chinesa e juntei um adaptador A-B mas há cabos à venda no eBay)

Poderá ser conveniente, mas não indispensável:

  • 1 hub USB 2.0* (à venda na Worten)
  • 1 teclado USB (à venda em todo o lado, na Mediamarkt há uns muito pequenos)
  • 1 rato USB (à venda em todo o lado)
  • 1 monitor/TV com ligação HDMI ou DVI (neste caso é também necessário um adaptador HDMI-DVI)
  • 1 caixa para Raspberry Pi

* infelizmente nem todos servem, há alguns como o Targus ACH114EV que não seguem devidamente as normas e apesar de funcionarem num PC normal não funcionam no Raspberry Pi. Os modelos KUNFT H-088 e Mitsai H-092 funcionam (este último tem inclusive uma ficha para alimentação externa que poderá dar jeito se quisermos ligar dispositivos USB que consumam mais corrente do que o Raspberry Pi consegue fornecer)

É necessário ligar as duas peças mais volumosas (o Raspberry Pi e a bateria) às restantes peças Lego de um modo prático mas sólido. Optei por colar duas vigas Technic a cada uma de modo a poder tratá-las como se fossem blocos Lego normais.

Raspberry Pi + Bateria USB
Raspberry Pi + Bateria USB antes de serem legoficados

Usei uma cola de contacto própria para plásticos ABS tendo apenas o cuidado adicional de espaçar as vigas a colar com outras peças lego de modo a assegurar que a distância entre as duas respeita os padrões Lego.

Para a bateria usei duas vigas 1×9 (40490):

IMG_2519-2 IMG_2520-2

Para o Raspberry Pi (com caixa) usei duas vigas 1×11 (32525):

IMG_2521-2 IMG_2512-2

Como o espaço entre as vigas da bateria é duas unidades inferior ao espaço entre as vigas do Raspberry Pi podemos ligar os dois num só módulo:

IMG_2527-2

Crónicas do Engenheiro Maluco por Tartes de Framboesa e Lego: Introdução

Objectivo:

Disponibilizar uma plataforma para que crianças de todas as idades se divertam enquanto desenvolvem aptidões nas áreas da Ciência e Engenharia (sobretudo Robótica).

Os blocos Lego não são apenas um brinquedo, são excelentes ferramentas pedagógicas. E além dos blocos básicos, com os quais já se pode construir quase tudo que vier à imaginação, os conjuntos Technic, Power Functions e Mindstorms permitem-nos acrescentar movimento e autonomia às nossas criações.

Nos Estados Unidos (e não só) existem várias organizações que pretendem incutir nas crianças e adolescentes o gosto pelas ciências (STEM – science, technology, engineering and mathematics). Muitas delas fazem-no justamente com Lego:

Dentro do mesmo espírito mas limitado apenas ao ramo das ciências da computação, dois projectos captaram muito recentemente a minha atenção:

A Raspberry Pi Foundation surgiu da preocupação de quatro docentes do Computer Laboratory na University of Cambridge com a falta de preparação dos candidatos a cursos de ciências da computação no Reino Unido. Decidiram por isso difundir entre o público juvenil a versão moderna dos micro-computadores baratos e fáceis de programar que abundaram nos anos 80/90 (a ideia parece-me pertinente já que eu tive um ZX Spectrum 128 aos 14 anos e vejam no que deu).

Tal como no Spectrum havia uma ligação muito directa à linguagem Basic, a Raspberry Pi Foundation decidiu apostar na linguagem Python (daí o Pi que surge no nome) e ainda na linguagem Scratch desenvolvida no Lifelong Kindergarten Group do Media Lab (MIT, Massachussets Institute of Technology) especificamente para estudantes dos 8 aos 16. Esta última é uma linguagem visual que permite desenvolver programas ou animações sem ser necessário escrever código, bastando apenas juntar blocos (como no Lego) e ajustá-los às nossas necessidades.

Como o Media Lab autoriza e até incentiva o desenvolvimento de extensões ao Scratch surgiram muitos outros projectos dele derivados, incluindo alguns que permitem interagir com blocos Lego Mindstorms como o Enchanting do Southern Alberta Robotics Enthusiasts e o Snap! (anteriormente chamado BYOB – Bring Your Own Blocks) da University of California em Berkeley.

Juntando tudo (Snap! + Raspberry Pi + algumas peças Lego Technic e Mindstorms) podemos criar pequenos robots relativamente fáceis de programar, sem o preço nem o peso de um computador portátil nem a complexidade de um microcontrolador dedicado (como um PIC ou um ARM, apesar de neste campo projectos como o Arduíno terem permitido diminuir significativamente a componente complexidade).

Depois é só dar asas à criativade e ao engenho dos engenheiros e cientistas de todas as idades que possam pegar nisto.

Missa digital

Nesta paróquia da Diocese de Leiria onde viemos passar o fim de semana a igreja tem 2 televisores LCD que na missa vespertina passam as letras dos cânticos em formato karaoke. Além disso os próprios cânticos são em playback e em vez do regente do coro há um segundo ambão com mesa de som.

Aos Domingos as leituras passam também nos ecrans.

Dizem-me que este software litúrgico está à venda, com algum sucesso. Imagino que daqui a uns anos saia um upgrade com um pregador a assegurar as homílias. Se houver a opção «10 minutos, sem devaneios nem fugas ao tema» e a opção de download de vários avatares 3D à escolha então sim, as vendas serão colossais!

Grandiosa Engenhoca de Berlindes 0.3

This post is part 3 of 3 of  Grandiosa Engenhoca de Berlindes 1

Já que tive de desmontar a Engenhoca para melhorar alguns dos pontos identificados na versão anterior aproveito para documentar melhor o projecto.

Numa nora verdadeira, a água é levada por uns recipientes (alcatruzes) montados nas extremidades dos braços da nora. Apesar de existirem versões Lego muito engenhosas que mantêm a ideia dos alcatruzes, não tenho experiência nem variedade de peças à disposição para me aventurar por aí, preferi empurrar os berlindes ao longo de uma superfície.

O trajecto dos alcatruzes forma uma circunferência mas em Lego há poucas peças grandes e curvas que possam ser usadas (há umas secções de rampa de skate mas não tenho nenhuma) e não consegui aproximações suficientemente boas com as peças-rampa (telhas) tradicionais (o berlinde ou ficava encravado entre a rampa e o braço da nora ou escorregava por entre ambos).

Optei então por uma superficie ajustável, à custa de uma corrente:

GBC1-corrente
Os berlindes deslizam ao longo desta corrente, disposta como um quarto de circunferência.

A corrente tem 33 unidades de comprimento, à custa de 11 «elos» cinzentos interligados com outros10 elos brancos, todos eles «vigas» (beams) de comprimento 3, do tipo 32523. A ideia é suspender a corrente de modo a formar um quarto de uma circunferência (não muito exacta mas se for flexível o suficiente acaba por autoajustar-se com o próprio deslizar do berlinde).

Os pontos de fixação dos extremos da corrente podem ser calculados sabendo o raio da circunferência:

quart-circ

Como a corrente tem o comprimento de apenas um quarto de circunferência,  o perímetro total será 33×4=132 a que corresponde um raio de 21 unidades:

P=2πR

Na verdade a nora tem um raio ligeiramente menor, cerca de 20 unidades (é difícil obter-se exactamente o comprimento pretendido com a combinação de peças utilizada) mas como o percurso da corrente também não segue uma circunferência perfeita acaba tudo por se ajustar.

GBC1-v03-nora
A nora utiliza uma roda com 8 braços com pequenos alcatruzes nas extermidades.

Finalmente um pormenor da corrente depois de montada:

GBC1-corrente-montada
Consegue-se ver os extremos dos braços a roçarem a corrente: após 1 ou 2 rotações completas da nora a corrente ficou ajustada.