Posts Tagged ‘PHP’

Controlando a Arduino com PHP via porta serial

Posted in Arduino, Electronics, PHP on maio 1st, 2009 by Bruno Soares – 66 Comments

É isso mesmo, o PHP pode escrever ou ler dados da porta serial, e com isso podemos controlar a Arduino.

Você pode ligar o seu ar-condicionado, cafeteira, luz, etc… via Internet, e de uma forma bem simples.
Serialproxy também é uma ótima forma de se conectar a Arduino via Internet, utilizei no projeto Twitter Hardware, mas este post é sobre PHP, então vamos lá.

Arduino + PHP Diagram

Vou utilizar o exemplo descrito no post “Controlando Led RGB com Arduino e Processing” (trocando o Processing pelo PHP).

A função fopen do PHP da suporte a escrita na porta serial:

1
2
3
$port = fopen('COM2', 'w');
fwrite($port, '1');
fclose($port);

Linha 1) Abre a conexão com a COM2 (porta serial onde a minha Arduino está conectada).
Linha 2) Escreve na porta
Linha 3) Fecha a conexão

Código PHP do exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
/**
 * Arduino + PHP
 *
 * @author  Bruno Soares
 * @website www.bsoares.com.br
 */


$color = $_REQUEST['color'];

if (isset($color) && !empty($color)) {
    $color = hexdec($color);
    $message = '^' . $color . '$';

    // USB Serial Port (COM2)
    $portAddress = 'COM2';
   
    // Open connection on port
    $port = fopen($portAddress, 'w');
   
    // Necessary when the Arduino reset after the connection
    sleep(2);
   
    // Send chars
    fwrite($port, $message);
   
    // Close connection
    fclose($port);
}
?>

Linha 12) Converte a cor de hexadecimal para decimal.
Linha 13) Coloca os caracteres que indicam o inicio e fim da mensagem.
Linha 16) Define a variável com o endereço da porta (no meu caso COM2).
Linha 19) Abre a “conexão” com a porta serial.
Linha 22) Pausa o código por 2 segundo, pois a Arduino costuma reiniciar quando é feita uma conexão a ela.
Linha 25) Escreve a mensagem com a cor na porta serial.
Linha 28) Fecha a “conexão” com a porta serial.

Update 09/07/2009:
Lendo dados:
Tenho recebido diversos e-mails e até alguns comentários de pessoas que precisam ler dados de um sensor, potenciometro, ou qualquer coisa conectada a Arduino, e isso via PHP. Então vamos lá, preparei um código que faz isso de forma fácil.
Acredito que um problema que o pessoal tem tido com esta tarefa é: você deve se dar tempo para a mensagem chegar a Arduino (não que isso seja muito tempo), e também para que a Arduino consiga responder:

Código Arduino:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * Arduino + PHP
 *
 * @author  Bruno Soares
 * @website www.bsoares.com.br
 */


#define ANALOG_PIN 4

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available() > 0) {
    if (Serial.read() == '1')
      Serial.print(analogRead(ANALOG_PIN), DEC);
  }
}

Código PHP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
/**
 * Arduino + PHP
 *
 * @author  Bruno Soares
 * @website www.bsoares.com.br
 */


// Conecta na porta
$port = fopen('COM2', 'w+');

// Em alguns casos a Arduino pode reiniciar, por isso
// é bom esperar para enviar informação depois de conectar
sleep(2);

// Envia "1" para o programa na Arduino saber que deve responder
fwrite($port, '1');

// Espera para que o dado enviado pelo PHP chegue até a Arduino
sleep(1);

// Agora que a Arduino "Provavelmente já respondeu", pega
// o valor da resposta
echo fgets($port);

// Fecha a conexão com a porta
fclose($port);
?>

O que esse código faz?
A Arduino fica em loop esperando receber pela porta serial o numero 1, assim que recebido ela lê a voltagem do pino analógico 4 e escreve na porta serial.
O PHP abre a porta serial, escreve “1″, e espera para ler novamente, quando lê novamente encontra o valor do pino analógico 4, assim como a Arduino escreveu.
Bom, espero que este exemplo acabe com as dúvidas do pessoal que precise ler dados da Arduino :)

Observações:
Caso você precise fazer um projeto onde muitos usuário vão acessar o script que escreve na porta serial, você deve implementar uma fila, de forma a não ter um usuário escrevendo na porta ao mesmo tempo que outro, isto geraria um erro.
O código fonte escrito para a Arduino é o mesmo do post Controlando Led RGB com Arduino e Processing

Faça o download do código fonte aqui.

Conteúdo relacionado:
Arduino: http://www.arduino.cc/
Referência: http://www.arduinoprojects.com/?q=node/10
jQuery ColorPicker: http://www.eyecon.ro/colorpicker/

JPGEncoder (AS3) com AMFPHP

Posted in ActionScript 3.0, Flash, PHP, Remoting on abril 7th, 2009 by Bruno Soares – 3 Comments

Tenho notado pelo Google Analytics que pessoas chegam ao blog procurando por AMFPHP, encode de imagens criadas no flash, salvar imagem com Flash + AMFPHP e outros critérios de busca. E por isso me sinto na obrigação de escrever algo sobre isto.

Exemplo:

This movie requires Flash Player 9

Vou demonstrar exatamente o que o título do post propõe (Criar imagens no Flash com ActionScript 3, encodar essas imagens com a classe JPGEncoder presente na biblioteca as3corelib e salvar como um arquivo .jpg utilizando o AMFPHP). Já escrevi aqui como fazer isso em FluorineFx (ASP.NET Flash Remoting Gateway).

Suponho que quem esteja interessado em rodar o que está descrito neste tutorial tenha o Apache com PHP instalado, ou algum servidor com suporte. Caso você não tenha recomendo a instalação do XAMPP (é de fácil instalação e tem tudo que um programador precisa).

Configuração do AMFPHP:
A versão que utilizo neste tutorial é a 1.9 beta, mas versões posteriores devem funcionar perfeitamente.
• Baixe o AMFPHP do seguinte link: http://www.amfphp.org/
• Copie o conteúdo do ZIP para o diretório onde você está criando o projeto, recomendo a estrutura de diretórios como mostrada na imagem abaixo:
folders

• Para testar o funcionamento é só acessar o diretório browser do navegador (http://127.0.0.1/www/amf/browser/).

Fique entendido que a responsabilidade de gerar a imagem é do Flash, e o servidor deve apenas receber os binários para gravar em disco. Para gerarmos o código da imagem (binário), vamos utilizar a classe JPGEncoder.
Exemplo:

1
2
3
4
5
6
7
8
import flash.display.BitmapData;
import flash.utils.ByteArray;
import com.adobe.images.JPGEncoder;

var bmpData:BitmapData = new BitmapData(width, height);
bmpData.draw(MEU_MOVIECLIP);
var objJPGEncoder:JPGEncoder = new JPGEncoder(QUALIDADE);
var dadosEncode:ByteArray = objJPGEncoder.encode(bmpData);

Muito simples não? O método draw da classe BitmapData obtém a imagem atual do clip, criamos uma instância da JPGEncoder já passando a qualidade (0 à 100) e por fim “encodamos” o BitmapData utilizando o método encode da nossa instância da JPGEncoder, ele nos retorna um Array de Bytes (flash.utils.ByteArray).

Vamos a parte do actionscript que interessa:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private function encode():void
{
    lblMessage.text = "Codificando dados (JPGEncoder.encode)";
   
    var bmpData:BitmapData = new BitmapData(hit.width, hit.height);
    bmpData.draw(target);
    var objJPGEncoder:JPGEncoder = new JPGEncoder(sliderQuality.value);
    var dadosEncode:ByteArray = objJPGEncoder.encode(bmpData);
   
    sendToAmf(dadosEncode);
}

private function sendToAmf(data:ByteArray):void
{
    lblMessage.text = "Enviando dados para o AMF...";
   
    _objService = new NetConnection();
    _objResponder = new Responder(onResultEvent, onStatusEvent);
    _objService.connect(_amfGateway);
    _objService.call("br.com.bsoares.Image.saveDataToFile", _objResponder, data);
}

private function onResultEvent(result:Object):void
{
    lblMessage.text = "Abrindo imagem";
    navigateToURL(new URLRequest("http://blog.bsoares.com.br/articles/jpgencoder_amfphp/generated_images/image.jpg"), "_blank");
}

private function onStatusEvent(event:Event):void
{
    lblMessage.text = "Erro";
}

Agora a classe Image do PHP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
class Image
{
    var $imagePath;
   
    public function __construct ()
    {
        $this->imagePath = "../../../../../generated_images/image.jpg";
    }

    function saveDataToFile($byteArray)
    {
        file_put_contents($this->imagePath, $byteArray->data);
        return $this->imagePath;
    }
}
?>

O PHP só precisa pegar o ByteArray e salvar em um arquivo.

Dica: Para verificar os request usem o Charles Web Debugging Proxy.

É isso ai, qualquer dúvida só postar um comentário.

Conteúdo relacionado:
Código fonte do exemplo: http://blog.bsoares.com.br/articles/jpgencoder_amfphp/jpgencoder-amfphp.zip
AMFPHP: http://www.amfphp.org/
AS3CoreLib: http://code.google.com/p/as3corelib/
Charles: http://www.charlesproxy.com/

Enjoy

Convertendo PNG para SWF com PHP 5

Posted in Flash, PHP on abril 4th, 2009 by Bruno Soares – 1 Comment

Bom para quem não sabe o Adobe Flash consegue uma compressão incrível com arquivos do tipo PNG, mantendo a sua qualidade e transparência. Vou deixar um exemplo de código PHP para fazer essa conversão sem a ajuda de softwares como o png2swf.exe pois a realidade é que muitos servidores (hosts) não permitem que o script PHP rode softwares.

Classe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
/**
 * SwfConvertion
 *
 * @author Bruno Soares
 * @link   http://www.bsoares.com.br
 */

class SwfConvertion
{
    public function __construct () { }
   
    /**
     * image2swf
     *
     * @param  $imagePath String
     * @return void
     */

    public static function image2swf($imagePath, $outputPath = '')
    {
        if ($outputPath == '')
        {
            $outputPath = SwfConvertion::resolveOutputPath($imagePath);
        }
       
        $bitmap = new SWFBitmap(file_get_contents($imagePath));
       
        $shape = new SWFShape();
        $shape->setRightFill($shape->addFill($bitmap));
        $shape->drawLine($bitmap->getWidth(), 0);
        $shape->drawLine(0, $bitmap->getHeight());
        $shape->drawLine(-$bitmap->getWidth(), 0);
        $shape->drawLine(0, -$bitmap->getHeight());
       
        $movie = new SWFMovie();
        $movie->setDimension($bitmap->getWidth(), $bitmap->getHeight());
        $movie->add($shape);
        $movie->save($outputPath);
    }
   
    /**
     *
     *
     * @param $imagePath Object
     * @return String
     */

    private static function resolveOutputPath($imagePath)
    {
        return preg_replace('/^(.+)\.([A-Za-z]{3,4})$/i', '${1}.swf', $imagePath);
    }
}
?>

Exemplo de uso:

1
<?php SwfConvertion::image2swf('imagem_branco.png', 'imagem_branco_2.swf'); ?>

1º Teste:
PNG: imagem_branco.png 167KB
SWF: imagem_branco_2.swf 98KB
41,31% de compressão (menos 69KB)

2º Teste:
PNG: imagem_vermelho.png 309KB
SWF: imagem_vermelho_2.swf 264KB
14,56% de compressão (menos 45KB)

Obs.: É importante que você escolha bem as conversões que deseja fazer, pois em alguns casos o SWF pode ficar mais pesado que o PNG ou seja, se você vai utilizar este script para otimizar suas imagens compare os pesos antes de escolher a definitiva.

Conteúdo relacionado:
PHP Shockwave Flash: http://br2.php.net/manual/pt_BR/book.swf.php
Funções para SWF: http://br2.php.net/manual/pt_BR/ref.swf.php

Enjoy