LEDs on/off com PHP, Python e RPi

Opa. Nova experiência fresquinha.
Da última vez que trabalhei com LEDs, usei apenas um e o fiz piscar algumas vezes. Ok, é o início, mas não dá pra parar por aí.
Problema: usar "alguma coisa não física" para controlar o estado (ligado / desligado) de vários LEDs.
Pra resolver isso vamos precisar de:
- Raspberry Pi B;
- 3 LEDs coloridos;
- 3 resistores (270 ohms aproximadamente);
- Fios.
Determinei que essa "alguma coisa não física" seria uma página HTML, já que o RPi é o meu servidor web.

Um pouco de eletrônica

Já que estamos nos acostumando com eles, não custa nada saber que:

LED: Light Emiting Diodo, ou diodo emissor de luz.
Diodo: Válvula eletrônica. No caso do LED, a corrente é transformada em luz visível, mas essa não é a única aplicação de um diodo.
Resistor: é basicamente um limitador. Ele oferece uma resistência à passagem de elétrons (a corrente elétrica), o que reduz a tensão.

Em algum momento no futuro me aprofundarei em cada um desses elementos, e outros.

Um pouco de HTML

Pra mim é muito natural usar o HTML para desenvolver alguma coisa, afinal, todos os elementos que eu preciso já estão prontos (caixas de seleção, botões de rádio, campos, formulários, tabelas, etc.). Para esse projeto usarei os seguintes elementos:
input: esse elemento é bem versátil. Usaremos o tipo 'checkbox', uma caixa de seleção múltipla, e o tipo 'submit', o botão de envio.
p: parágrafo.
label: etiquetas para os campos do formulário
form: o formulário

Um pouquinho de PHP

O papel do PHP aqui é receber os dados do formulário e enviar ao Python. Usarei acesso à variáveis, laço de repetição foreach() e teste de condição com if..else

E um pouco de Python

A grande estrela da coisa é o Python e a biblioteca RPi.GPIO. Usarei os seguintes métodos da biblioteca:
setmode(): para determinar a tabela de códigos das portas GIPO
setwarnings(): para inibir os avisos
setup(): para inicializar as portas
output(): para enviar os sinais True e False para as portas
E testes de condição com if..elif

Primeiro...

Vamos construir a página que lidará com a ativação dos LEDs. Eis o conteúdo do arquivo index.php:
<!DOCTYPE html>
<html>
    <head>
        <title>LED's on/off</title>
        <meta charset = 'utf-8'>
        <style>
            form { width: 100%; }
            label { padding: 8px; float: left; }
            p { display: table; clear: both; text-align: center; }
        </style>
    </head>
    <body>
        <?php
            $cores = array('amarelo' => 'Amarelo', 'verde' => 'Verde', 'vermelho' => 'Vermelho');
            $on = array();
            $lig = array();
            foreach($cores as $cor => $tag) {
                if(in_array($cor, $_POST['cor'])) {
                    $lig[] = "sudo python3 on.py {$cor}";
                    $on[] = $cor;
                } else {
                    $lig[] = "sudo python3 off.py {$cor}";
                }
            }
            exec(implode(' & ', $lig));
        ?>
        <form method = 'post'>
            <?php
                $check = "<label><input type = 'checkbox' name = 'cor[]' value = '#VALOR#' #CHECKED#>#NOME#</label>";
                foreach($cores as $cor => $tag) {
                    $foo = str_replace('#VALOR#', $cor, str_replace('#NOME#', $tag, $check));
                    if(in_array($cor, $on)) {
                        $foo = str_replace('#CHECKED#', 'checked', $foo);
                    } else {
                        $foo = str_replace('#CHECKED#', '', $foo);
                    }
                    echo $foo;
                }
            ?>
            <p>
                <input type = 'submit' value = 'Enviar'>
            </p>
        </form>
    </body>
</html>


Depois...

Precisamos construir dois arquivos, o on.py e o off.py. Eles serão os responsáveis por ligar e desligar os LEDs. Existem diversas outras maneiras de chegar nesse mesmo objetivo, mas achei mais didático dessa maneira:
#on.py
import sys                    #bibliotecas do sistema
import RPi.GPIO as GPIO        #bibliotecas GPIO

GPIO.setmode(GPIO.BOARD)    #usa a mesma numerção da placa
GPIO.setwarnings(False)        #evita os avisos

cor = sys.argv[1]            #recupera o primeiro argumento (prompt)

GPIO.setup(7, GPIO.OUT)        #configura o pino 7
GPIO.setup(13, GPIO.OUT)    #configura o pino 13
GPIO.setup(15, GPIO.OUT)    #configura o pino 15

if(cor == 'amarelo'):        #se 'amarelo'
    GPIO.output(7, True)    #liga o amarelo
elif(cor == 'verde'):        #se 'verde'
    GPIO.output(13, True)    #liga o verde
elif(cor == 'vermelho'):    #se 'vermelho'
    GPIO.output(15, True)    #liga o vermelho

#off.py

import sys                    #bibliotecas do sistema
import RPi.GPIO as GPIO        #bibliotecas GPIO

GPIO.setmode(GPIO.BOARD)    #usa a mesma numerção da placa
GPIO.setwarnings(False)        #evita os avisos

cor = sys.argv[1]            #recupera o primeiro argumento (prompt)

GPIO.setup(7, GPIO.OUT)        #configura o pino 7
GPIO.setup(13, GPIO.OUT)    #configura o pino 13
GPIO.setup(15, GPIO.OUT)    #configura o pino 15

if(cor == 'amarelo'):        #se 'amarelo'
    GPIO.output(7, False)    #desliga o amarelo
elif(cor == 'verde'):        #se 'verde'
    GPIO.output(13, False)    #desliga o verde
elif(cor == 'vermelho'):    #se 'vermelho'
    GPIO.output(15, False)    #desliga o vermelho


Nossa, mas quanto código repetido, você diria. Sim, foi de propósito, para, como eu disse antes, ser didático.

Os dois arquivos farão as mesmas coisas, mas em sentido oposto: identificarão a cor que deve ser acessa/apagada, que será informada na linha de comando no formato "sudo on[off].py cor", e executará a ação.

Salvei os 3 arquivos na pasta /var/www/leds. Agora falta uma última coisa aqui: o www-data, que é o usuário padrão quando fazemos navegação através da web, não pode executar o "sudo", então precisamos resolver isso. Vamos fazer o seguinte:

sudo nano /etc/sudoers

Esse arquivo contém as configurações do sudo. A última linha nos interessa. Adicione o seguinte código ao arquivo:

www-data ALL=(root) NOPASSWD:ALL

Isso irá habilitar o www-data a dar um "sudo". Esse acesso é necessário pois só o super usuário pode acessar as portas GPIO.

Quase tudo pronto. Vamos abrir nosso navegador preferido no endereço http://192.168.0.10/leds e dar uma boa olhada na página. Não se esqueça que esse IP aí de cima é o do meu RPi. Troque pelo endereço do seu.

Por fim, o circuito!

Seguiremos a mesma ideia do post anterior, onde colocamos o positivo na porta que vamos usar, o negativo no resistor de baixa resistência e, por último, todas as pontas restantes dos resistores ligadas ao terra. Usei os seguintes pinos:
- Terra: 9
- LED amarelo: 7
- LED verde: 13
- LED vermelho: 15

A hora da verdade

No navegador, escolha as cores que quer ativar e clique em "Enviar". Se tudo deu certo, os LEDs se acenderão, e a nossa primeira integração entre PHP e Python funciona.

Divirta-se! Por hoje é só.

Comentários

Postagens mais visitadas deste blog

Tá na hora de piscar LEDs de maneira melhorada

PagSeguro e PHP - Usando a tela do PagSeguro (checkout redirect)