sábado, 14 de setembro de 2013

Let there be light - vamos fazer uma lanterna

Neste post vamos fazer um pequeno programa que permite utilizar o telefone Android como se de uma lanterna se tratasse.

O projeto é muito simples, vamos inserir um botão na interface para ligar e desligar a luz do flash que vamos utilizar para a iluminação.


Primeiro a interface, o código:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/relativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <Button
        android:id="@+id/buttonFlashlight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:text="Luz" />

</RelativeLayout>

Muito simples, só um botão, optei por inserir o texto diretamente na propriedade do botão uma vez que não vou reutilizar o texto nem pretendo traduzir a interface para outra língua.

Agora as permissões, para podermos ligar e desligar a luz do flash do telefone precisamos de autorização. Para isso adicionamos a seguinte linha ao manifesto da aplicação:

    <uses-permission android:name="android.permission.CAMERA" />

Para além disso devemos indicar que a aplicação requer a camera com a seguinte linha:

 <uses-feature android:name="android.hardware.camera" />

O manifesto completo fica assim:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="edu.pjcferreira.flashlight"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />

    <application
        android:debuggable="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name="edu.pjcferreira.flashlight.FlashLightActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Por fim o código, igualmente simples. Na função onCreate vamos associar um evento click ao botão para ligar e desligar a luz, mas a parte mais difícil não é essa, primeiro temos de verificar se o programa já está em execução e não está a ser retomado, para isso temos uma variável boolean que passa de false para true quando o programa já está em execução.

Caso seja a primeira vez verificamos se temos camera e em caso afirmativo capturamos o dispositivo para o nosso programa.

Dentro da função onClick ligamos e desligamos o flash através da função setFlashMode.

Aqui fica o código completo:

public class FlashLightActivity extends Activity {

//luz ligada
protected boolean isLighOn = false;
//camera
private Camera camera;
//botao da atividade
private Button button;
private boolean repete=false;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if(repete==false){
repete=true;
button = (Button) findViewById(R.id.buttonFlashlight);
 
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 
Context context = this;
PackageManager pm = context.getPackageManager();
// if device support camera?
if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Log.e("err", "Dispositivo não tem camera!");
return;
}
camera = Camera.open();
final Parameters p = camera.getParameters();
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (isLighOn) {
Log.i("info", "luz está desligada!");
p.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
camera.stopPreview();
isLighOn = false;
} else {
Log.i("info", "luz está ligada!");
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
camera.startPreview();
isLighOn = true;
}
}
});
}
}
@Override
protected void onStop() {
super.onStop();

if (camera != null) {
camera.release();
}
}
}

Não esquecer a função onStop que liberta a camera quando o programa é fechado.

Para evitar problemas quando o telefone muda de posição a interface fica bloqueada em posição vertical.

O projeto pode ser retirado aqui.
A aplicação pronta a usar está aqui.

Espero que tenha gostado se sim passe pela nossa página web e do facebook.

sexta-feira, 10 de maio de 2013

Unity 3D - Jogo em Split Screen

Neste artigo vou criar um pequeno jogo para dois jogadores humanos em ecrã dividido utilizando o Unity 3D.

Para começar vou mostrar o resultado final.


Na parte de cima da imagem anterior temos a composição da cena e na parte de baixo a imagem que os jogadores vão ver quando jogarem.

Primeiro vamos preparar a cena e depois vamos ao código, assim adicione um plano para servir de chão e depois defina uma textura a aplicar.

Altere o tamanho do plano, nomeadamente a largura nos eixos x e z para acomodar os dois jogadores.

Agora que temos o campo de jogo vamos tratar dos jogadores, para isso adicione uma capsule.

Agora vamos posicionar esta capsula no lado esquerdo do ecrã.

De seguida vamos posicionar a camera que temos na cena atrás da capsula, assim:


Continuamos a preparar o jogador do lado esquerdo alterando a sua cor e definindo um ponto de disparo à sua frente, para isso vamos utilizar um ponto vazio.


O próximo passo é muito importante porque vai permitir organizar o nosso trabalho por isso muita atenção.

Primeiro alteramos o nome dos objetos para os podermos identificar mais facilmente, assim, Capsule passa a graficos, GameObject passa ponto_disparo e Main Camera a Camera_esquerda.

De seguida vamos criar um novo ponto vazio e arrastar para dentro desse ponto a capsula e o ponto de disparo. Agora mudamos o nome do novo ponto vazio para jogador. No final temos algo assim:

Agora a camera, vamos às propriedades e alteramos a largura para 0.5, o campo a alterar é o w (width). Assim ficamos com metade do ecrã preenchido com a imagem desta camera a outra metade vai ser preenchida com a outra.

Então para preencher a outra metade duplicamos a camera e alteramos o nome para camera_direita, de seguida arrastamos para a direita e rodamos a camera para mostrar o jogador a partir do outro lado do plano.
Agora basta alterar a posição da imagem para 0.5, a propriedade é X.


Agora já temos duas cameras vamos criar o código para os jogadores.

Crie um javascript com o nome jogador.js

Primeiro as variáveis, como vamos utilizar o mesmo código para os dois jogadores vamos criar variáveis para configurar as teclas que controlam os jogadores a partir do inspector.

public var tecla_esquerda : String = "z";
public var tecla_direita : String = "x";
public var tecla_dispara : String = "c";

As variáveis para associar ao jogador e a velocidade de movimento:
public var jogador : CharacterController;
public var velocidade : float = 0.5;

E algumas variáveis para o modelo da bola que vamos atirar:

public var modelo_bala : GameObject;

O ponto de disparo:
public var ponto_disparo : GameObject;

A força:
public var forca : float=200.0;
public var forcaTotal : float =0;
public var forcaMax : float= 1000;
public var barraForca : Texture;
public var posBarra : int=0;
private var temp : float;
public var boladas : float = 0;
public var posTexto : int=0;

A cor do nosso jogador, que também vamos atribuir à bola:
public var cor : Color = Color.red;

De seguida apresento a função que atualiza a interface, nós vamos mostrar duas informações ao utilizador: a força com que ele vai atirar a bola (esta força é controlada pelo tempo que fica a carregar na tecla de disparo) e quantas vezes já levou com a bola.

function OnGUI(){
    if(forcaTotal<0) temp = forcaTotal * (-1);
    else temp=forcaTotal;
   
    if(temp>0){
        GUI.DrawTexture(Rect(posBarra,10,temp/forcaMax*100,10),barraForca);
    }

    GUI.TextArea(Rect(posTexto,20,30,20),boladas.ToString());
}

 A função mais importante:
function Update () {

    if (Input.GetKey(tecla_esquerda)) jogador.transform.position.z +=(velocidade*Time.deltaTime);
    if (Input.GetKey(tecla_direita)) jogador.transform.position.z -=(velocidade*Time.deltaTime);
    if (Input.GetKey(tecla_dispara)){
        forcaTotal += (forca*Time.deltaTime);
    }
    if(Input.GetKeyUp(tecla_dispara)){
        var bala : GameObject;
        bala=Instantiate(modelo_bala,ponto_disparo.transform.position,this.transform.rotation);
        bala.gameObject.renderer.material.color = cor;
       
        bala.rigidbody.AddForce(Vector3(forcaTotal,0,0));
        forcaTotal=0;
    }
   
}

Nesta função controlamos a posição do jogador bem como a força a atribuir à bola quando a lançamos.

Agora vamos criar uma função que vai ser chamada sempre que a bola acertar no jogador:

function bolada(x : float){

    boladas += x;
   
}

Passamos à bola, para isso adicionamos uma esfera e associamos-lhe um rigidbody.

Agora criamos outro ficheiro javascript com o nome bola.js, neste colocamos o seguinte código:

var tempo : float =4.0;

function Start () {

    Destroy(this.gameObject,tempo);
}

function OnCollisionEnter(col:Collision){
    if(col.gameObject.tag=="Player"){
        col.gameObject.SendMessage("bolada",1.0,SendMessageOptions.DontRequireReceiver);
        Destroy(this.gameObject);
    }
}

A função start é utilizada para controlar o tempo que a bola vai viver, depois temos a função que deteta as colisões e chama a função para contar mais um tiro certeiro.

Agora associamos este código à esfera e criamos um prefab com a esfera, para isso basta arrastar da hierarchy para a pasta project. Depois apagamos da hierarchy a cópia uma vez que vamos criar cópias por código.

Também pode criar um material para definir as propriedades da bola.

Agora duplicamos o jogador e arrastamos para o outro lado do ecrã, isto já com o script jogador.js associado. De seguida configuramos o script através do inspector para podermos definir teclas diferentes para os dois jogadores.

O jogador da direita tem de ser rodado para ficar de frente para o outro jogador, para isso devemos rodar o ponto vazio criado.

Outro ponto importante é o código que deve ser associado ao elemento gráfico do jogador e não ao ponto vazio.

Para terminar de preparar os jogadores devemos definir a tag Player nos dois jogadores.

A velocidade e a força fica ao critério de cada um basta testar e afinar até atingir os valores desejados.

Os meus valores ficaram assim:



Antes de terminar podemos adicionar algumas luzes e definir alguns pormenores visuais como um rasto para as bolas ou sons.

O projeto pode ser retirado aqui.

sexta-feira, 26 de abril de 2013

Tem troco

Para hoje um pequeno programa que dá troco, bem dar não dá mas calcula o troco a dar em função das moedas disponíveis.

Neste projeto vamos utilizar o novo Visual Studio 2012.



Como era de se esperar vamos iniciar um projeto novo:


Agora adicionamos os seguintes elementos:
 - um botão para calcular as moedas a dar de troco
 - um botão para repor o número de moedas iniciais disponíveis
 - uma textbox para introduzir o valor a pagar
 - uma textbox para introduzir o valor entregue
 - umas labels para informar o utilizador do que deve introduzir e outra para mostrar o troco
 - por fim uma grelha para mostrar os valores das moedas e as quantidades disponíveis de cada uma.

A janela principal do programa fica assim:


Agora o código, primeiro o evento load do formulário, neste vamos definir os valores das moedas e as respetivas quantidades

Para guardar estes valores vamos necessitar de uma variável definida ao nível do formulário, logo abaixo da definição da class:

Public Class Form1
    Public moedas(0 To 7, 0 To 2) As Double


Assim no load fica:


        'valor das moedas
        moedas(0, 0) = 0.01
        moedas(1, 0) = 0.02
        moedas(2, 0) = 0.05
        moedas(3, 0) = 0.1
        moedas(4, 0) = 0.2
        moedas(5, 0) = 0.5
        moedas(6, 0) = 1
        moedas(7, 0) = 2
        'número de moedas
        moedas(0, 1) = 5
        moedas(1, 1) = 5
        moedas(2, 1) = 5
        moedas(3, 1) = 5
        moedas(4, 1) = 5
        moedas(5, 1) = 5
        moedas(6, 1) = 5
        moedas(7, 1) = 5
        'moedas dadas como troco
        moedas(0, 2) = 0
        moedas(1, 2) = 0
        moedas(2, 2) = 0
        moedas(3, 2) = 0
        moedas(4, 2) = 0
        moedas(5, 2) = 0
        moedas(6, 2) = 0
        moedas(7, 2) = 0

Como podemos verificar na matriz temos três colunas: a primeira para o valor facial das moedas, a segunda para a quantidade de moedas disponíveis e a terceira para a quantidade de moedas a dar de troco.

Precisamos, ainda, de uma função para atualizar a grelha:

    Sub grelha()
        Dim l, c As Integer

        If Me.DataGridView1.Rows.Count < moedas.Length / 3 Then

            For l = 0 To 7
                Me.DataGridView1.Rows.Add()
                For c = 0 To 2
                    Me.DataGridView1.Rows(l).Cells(c).Value = moedas(l, c)
                Next
            Next
        Else
            For l = 0 To 7
                For c = 0 To 2
                    Me.DataGridView1.Rows(l).Cells(c).Value = moedas(l, c)
                Next
            Next
        End If

    End Sub

Esta função começa por verificar se a grelha está ou não preenchida, se sim atualiza os valores senão adiciona linhas e atualiza os valores.
A função deve ser chamada no evento load, mesmo no final.


O botão para repor é muito simples:

    Sub repor()
        'número de moedas
        moedas(0, 1) = 5
        moedas(1, 1) = 5
        moedas(2, 1) = 5
        moedas(3, 1) = 5
        moedas(4, 1) = 5
        moedas(5, 1) = 5
        moedas(6, 1) = 5
        moedas(7, 1) = 5
        'moedas dadas como troco
        moedas(0, 2) = 0
        moedas(1, 2) = 0
        moedas(2, 2) = 0
        moedas(3, 2) = 0
        moedas(4, 2) = 0
        moedas(5, 2) = 0
        moedas(6, 2) = 0
        moedas(7, 2) = 0

        grelha()

    End Sub

Primeiro altera os valores disponíveis de cada tipo de moeda e por fim limpa os valores referentes às moedas retiradas como troco.

Agora o código do botão calcular:

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim v_pagar, v_entregue, v_troco, s_troco, m As Double

        If IsNumeric(TextBox1.Text) = False Then Exit Sub
        If IsNumeric(TextBox2.Text) = False Then Exit Sub

        Double.TryParse(TextBox1.Text, v_pagar)
        Double.TryParse(TextBox2.Text, v_entregue)
        v_troco = v_entregue - v_pagar
        v_troco = Math.Round(v_troco, 2)
        Me.Label3.Text = v_troco

        If Me.Label3.Text = "0" Then Exit Sub

        s_troco = 0
        m = 7
        Do While s_troco < v_troco And m >= 0
            If s_troco + moedas(m, 0) <= v_troco And moedas(m, 1) > 0 Then
                s_troco = s_troco + moedas(m, 0)
                moedas(m, 1) -= 1
                moedas(m, 2) += 1
            Else
                m -= 1
            End If
        Loop
        If s_troco < v_troco Then
            MessageBox.Show("Não existem moedas suficientes para processar o troco!")
        End If
        grelha()

    End Sub
Esta função começa por tentar retirar os valores das textboxes, depois calcula o valor do troco.
De seguida arredonda o troco só para duas casas decimais e se o troco foi diferente de 0 então vamos procurar moedas até atingir o valor do troco.
Para dar o troco começamos pelo fim da matriz à procura das moedas de maior valor até não termos mais moedas ou até satisfazermos o valor do troco.

E pronto, mais um projeto disponível aqui.


quinta-feira, 18 de abril de 2013

Atualizar uma página html com jquery

Neste post vamos implementar uma página web que atualiza o seu conteúdo sem ter de recarregar a página toda.

A estrutura básica da página tem as seguintes pastas:
\ajax - pasta com ficheiro php que pesquisa a base de dados e devolve o valor encontrado
\db - pasta com ficheiro php com instruções para ligação à base dados
\js - pasta com código javascript que utiliza a livraria JQuery para atualizar o ficheiro index.html com os dados devolvidos pelo ficheiro php que pesquisa a base de dados.

O resultado final será:



Se a página fosse construída somente com código html ao clicar no botão "Pesquisar" o browser seria redirecionado para outra página ou para a mesma mas fazendo um reload.

Para implementarmos a página sem reload utilizamos código que vai alterar o DOM da página com os dados recolhidos na base de dados.

Começamos pela página principal, index.html, com o seguinte código:


<!DOCTYPE html>
<html>
<head>
<title>AJAX Database</title>
</head>
<body>
Nome: <input type="text" id="name">
<input type="submit" id="name-submit" value="Pesquisar">
<div id="name-data"></div>
<script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script src="js/global.js"></script>
</body>
</html>


Neste código é importante recordar os nomes do botão (name-submit), o nome do campo de introdução de texto (name) e por fim o nome da div (name-data). Estes nomes são importantes porque vamos ter de nos referir a eles no código javascript.

Antes de continuarmos vamos criar a base de dados MySQL que vai conter o dados a apresentar.

Primeiro criar a base de dados com o seguinte comando:

create database ajaxdb;

Depois criar uma tabela com nome names, assim:

create table names(name_id int,name varchar(50),location varchar(50));

Agora que temos a base de dados podemos continuar.

Olhando para o código html apresentado encontramos uma referencia a um ficheiro global.js que se encontra na pasta js. Este ficheiro vai, utilizando javascript, implementar o método post através do controlo do clique com o rato no botão.

O código javascript tem uma particularidade com a qual estou pouco à vontade que são as funções callback anónimas, desde que comecei a ver código javascript com este tipo de funções fiquei espantado! Como é que alguém consegue perceber aquilo?! Assim vou apresentar duas versões do ficheiro global.js, uma sem funções anónimas muito mais fácil de entender e outra com as funções anónimas.

Ficheiro global.js, versão sem funções anónimas:


$('input#name-submit').on('click',f_click());

function f_click(){
var name = $('input#name').val();

if($.trim(name)!=''){
$.post('ajax/name.php',{name: name},f_recebe(data));
}
}

function f_recebe(data){
$('div#name-data').text(data);
}


A primeira linha associa a função f_click ao evento click do botão, ou seja, quando o utilizador clica no botão é chamada a dita função.

A função f_click começa por recolher o valor do campo de texto e guarda-o na variável name, como pretendemos que o valor esteja preenchido utilizamos a função trim para remover espaços em branco antes de verificar se está em branco.

Se tudo correu bem e existe um valor para pesquisar na base de dados utilizamos a função post para receber valores do servidor chamando uma página, neste caso a página name.php e passando o parâmetro name para a página. Definimos, ainda, uma função callback (f_recebe) para receber o resultado do servidor através do parâmetro data.

Dentro da função f_recebe colocamos o valor de data na div.

Antes de avançarmos para o PHP aqui fica o código da versão com funções callback anónimas:

$('input#name-submit').on('click',function(){
var name = $('input#name').val();

if($.trim(name)!=''){
$.post('ajax/name.php',{name: name},function(data){

$('div#name-data').text(data);
});
}
});



Agora o PHP, a página name.php, tem o seguinte código:

<?php
if(isset($_POST['name'])===true && empty($_POST['name'])===false){
require '../db/connect.php';

$query = mysql_query("
SELECT names.location
FROM names
WHERE names.name='".mysql_real_escape_string(trim($_POST['name']))."'
");
echo (mysql_num_rows($query)!==0) ? mysql_result($query,0,'location') : 'Nome não encontrado';
}
?>


Primeiro verificamos se o parâmetro name está preenchido, em caso afirmativo fazemos o require do ficheiro connect.php (ver código abaixo) e consultamos a base de dados com um select. O resultado da consulta é devolvido com a função echo.

O código do ficheiro connect.php é simples, estabelece a ligação à base de dados:

<?php
mysql_connect('localhost','utilizador','password');
mysql_select_db('ajaxdb');
?>

Assim temos uma página que consulta a base de dados e coloca o resultado dinamicamente na página sem recarregar a página, ao estilo gmail.




Fontes:
http://api.jquery.com/jQuery.post/
http://www.w3schools.com/jquery/jquery_syntax.asp
http://www.youtube.com/watch?v=Yb3c-HljFro

sábado, 13 de abril de 2013

Game of 15

Toda a gente conhece o jogo de puzzle em que existe um espaço livre para mover as peças para os lugares certos. Para quem não conhece pode sempre clicar aqui.

Imagem da wikipedia

Hoje vamos resolver o jogo em C.



Para começar utilizamos uma matriz 4x4 para o jogo.

int jogo[4][4];

Além desta matriz vamos definir outra para armazenar a solução do jogo.

int solucao[4][4];

Antes de mais nada criamos uma função para limpar e preparar a matriz de jogo e a matriz da solução:

//prepara a matriz do jogo
void limpar(void)
{
int l,c,conta=1;

    n_jogadas=0;
    for(l=0;l<4;l++){
        for(c=0;c<4;c++){
            jogo[l][c]=conta;
            solucao[l][c]=conta;
            conta++;
        }
    }
    jogo[3][3]=0;
    solucao[3][3]=0;
}

Também precisamos de uma função para mostrar o estado da matriz do jogo, assim:

//mostra a matriz do jogo
void mostrar(void)
{
int l,c;
    system("cls");
    for(l=0;l<4;l++){
        for(c=0;c<4;c++){
            if(jogo[l][c]>0){
                goto_xy(10+c*3,10+l*2);
                printf("%d",jogo[l][c]);
            }
        }
    }
}

Esta função utiliza a instrução goto_xy que não existe em C mas que está definida num header file que acompanha o código fonte do projeto.

Com as duas matrizes é fácil saber se o jogo foi resolvido, basta comparar as posições de uma matriz com a outra:

//terminou?!
int resolvido(void)
{
int l,c,r=1;
    for(l=0;l<4;l++){
        for(c=0;c<4;c++){
            if(solucao[l][c]!=jogo[l][c]) r=0;
        }
    }
    return r;
}

Como queremos que o computador resolva o jogo vamos utilizar uma tática simples, sempre que fizermos uma jogada guardamos o movimento realizado para mais tarde podermos reverter todos os movimentos até à posição inicial da matriz. Para isso vamos ter um vetor onde guardamos as jogadas e uma variável com o número de jogadas feitas.


int jogadas[100];
int n_jogadas;

Agora as funções que implementam as jogadas:


//move uma peça para a direita
void mover_direita(void)
{
int l,c;
int temp;

    pos_livre(c,l);
    if(coord_validas(c-1,l)==0) return;
    temp=jogo[l][c-1];
    jogo[l][c]=temp;
    jogo[l][c-1]=0;
    //guarda a jogada
    jogadas[n_jogadas]=DIREITA;
    n_jogadas++;
}
//move uma peça para a esquerda
void mover_esquerda(void)
{
int l,c;
int temp;

    pos_livre(c,l);
    if(coord_validas(c+1,l)==0) return;
    temp=jogo[l][c+1];
    jogo[l][c]=temp;
    jogo[l][c+1]=0;
    //guarda a jogada
    jogadas[n_jogadas]=ESQUERDA;
    n_jogadas++;
}
//move uma peça para cima
void mover_baixo(void)
{
int l,c;
int temp;

    pos_livre(c,l);
    if(coord_validas(c,l-1)==0) return;
    temp=jogo[l-1][c];
    jogo[l][c]=temp;
    jogo[l-1][c]=0;
    //guarda a jogada
    jogadas[n_jogadas]=BAIXO;
    n_jogadas++;
}
//move uma peça para baixo
void mover_cima(void)
{
int l,c;
int temp;

    pos_livre(c,l);
    if(coord_validas(c,l+1)==0) return;
    temp=jogo[l+1][c];
    jogo[l][c]=temp;
    jogo[l+1][c]=0;
    //guarda a jogada
    jogadas[n_jogadas]=CIMA;
    n_jogadas++;
}

Cada uma destas funções utiliza o seguinte algoritmo:
1. Descobrir as coordenadas do espaço livre na matriz (função pos_livre, apresentada a seguir)
2. Se as coordenadas do movimento não são válidas (função coord_validas, apresentada a seguir) não joga.
3. Guarda o número da peça a mover e troca com o 0 (zero) do espaço livre.
4. Guarda a jogada feita para mais tarde poder voltar atrás.
5. Adiciona um à variável n_jogadas.


//procura a posicao livre
void pos_livre(int &x,int &y)
{
int l,c;

    for(l=0;l<4;l++){
        for(c=0;c<4;c++){
            if(jogo[l][c]==0){
                x=c;
                y=l;
                return;
            }
        }
    }
}
//devolve 0 se as coordenadas estão fora da matriz
//devolve 1 se as coordenadas são válidas
int coord_validas(int x,int y)
{
    if(x<0 || y<0) return 0;
    if(x>3 || y>3) return 0;
    return 1;
}

Para terminar o programa faltam duas funções, uma para baralhar o puzzle e outra para resolver.
Aqui ficam:

//resolve o jogo
void resolver(void)
{
int n;

    for(n=n_jogadas-1;n>=0;n--){
        if(jogadas[n]==ESQUERDA) mover_direita();
        if(jogadas[n]==DIREITA) mover_esquerda();
        if(jogadas[n]==CIMA) mover_baixo();
        if(jogadas[n]==BAIXO) mover_cima();
        mostrar();
        Sleep(50);
    }
}
//baralha
void baralhar(void)
{
int movimento,temp,sorteia;
    srand(time(NULL));
    for(temp=0;temp<50;temp++){
        mostrar();
        Sleep(50);
        sorteia=rand()%4+1;
        switch(sorteia){
            case ESQUERDA :
                            mover_esquerda();
                            break;
            case DIREITA :
                            mover_direita();
                            break;
            case CIMA :
                            mover_cima();
                            break;
            case BAIXO :
                            mover_baixo();
                            break;
        }
    }
}

Esta versão da função baralhar mostra as jogadas ao mesmo tempo que baralha isso pode ser alterado removendo a linha que chama a função mostrar().

Agora para terminar de verdade aqui fica a função main:

int main(int argc,char *argv[])
{
char op;

    limpar();
    baralhar();
    while(1){
        mostrar();
        printf("\n\n\nOpcao (e,d,c,b,r):");
        scanf("%c",&op);
        if(op=='e') mover_esquerda();
        if(op=='d') mover_direita();
        if(op=='c') mover_cima();
        if(op=='b') mover_baixo();
        if(op=='r') resolver();
        if(resolvido()) break;
    }
    mostrar();
    system("pause");
    return 1;
}

Aqui chegados só falta jogar e quando não conseguir resolver o puzzle basta escolher r.

O código fonte.







sexta-feira, 8 de março de 2013

Arduino & Motor DC

Neste post vou apresentar um pequeno projeto com o Arduino, a ideia é simples, controlar um motor DC.





O projeto vai incluir um potenciómetro para regular a velocidade do motor.

O circuito é o apresentado a seguir, criado com o fritzing.

Como o motor consome mais energia do que o Arduino lhe pode fornecer vamos utilizar uma pilha de 9V só para o motor. O truque está no transistor IRF520 MOSFET que vai controlar a energia que o motor recebe, da pilha de 9V, em função do valor que o Arduino lhe vai enviar.

O transistor tem 3 pernas: a base, o coletor e o emissor. A base está ligada ao pino digital do Arduino, o coletor é ligado ao motor e o emissor é ligado no neutro. O transistor além de funcionar como interruptor, ligado e desligado o motor, vai funcionar como um acelerador pois quanto maior o valor da base maior a corrente que flui entre o emissor e o coletor.

Antes de definir a velocidade do motor o Arduino lê o valor do potenciómetro, ajusta a escala, no potenciómetro vai de 0 a 1023, para um valor entre 0 e 255 e depois envia esse valor para a porta onde a base do transistor está ligada.

A porta do potenciómetro é analógica o que permite ler valores entre 0 e 1023.

Por outro lado a porta do transistor é digital e a variação da velocidade é conseguida através da técnica PWM - Pulse With Modulation.

Por fim temos de ligar o Arduino à terra da pilha de 9V.

O código fica assim:
Primeiro as constantes e as variáveis

const int potPin=0;  //pino onde o potenciometro fica ligado
const int transistorPin=9;  //pino onde fica ligado o transistor
int potValue=0;  //valor lido do potenciometro

Depois a função setup (é executada uma vez quando o programa arranca)
void setup(){
  pinMode(transistorPin,OUTPUT);
  Serial.begin(9600);
}

Por fim o ciclo (Repetido eternamente)
void loop(){
  potValue=analogRead(potPin)/4;
  analogWrite(transistorPin,potValue);
  Serial.println(potValue);
}


Além do código que lê os valores do potenciómetro e escreve para a porta do transistor incluí código para debug, enviando os valores para o computador através do cabo USB.

E a magia acontece...

Mas, sim tem um mas, o motor só pode rodar numa direção.

É um projeto simples mas que pode ser reutilizado para energias maiores, dependendo dos valores que o transistor suportar.

Por segurança incluí um diodo para proteger o Arduino de eventuais descargas que o motor possa gerar quando pára.

Projeto para download.

quinta-feira, 28 de fevereiro de 2013

CalcNotas - WindowsPhone

Para este post vamos desenvolver uma aplicação, ou como se dizia antigamente um programa, para calcular notas finais de uma disciplina do ensino secundário português.

Como a interface é relativamente grande precisamos de permitir deslocar o conteúdo verticalmente.




Para validar os dados nas textboxes vamos criar uma função que implementa a função isNumeric da versão desktop do Visual Basic.


    Public Function isNumeric(ByVal str As String) As Boolean
        Dim t As Decimal = 0
        Return Decimal.TryParse(str, t)
    End Function

Se a string poder ser convertida num número devolve true se não devolve false.

O primeiro botão serve para calcular a chamada CIF (Classificação Interna Final) que corresponde à média das notas do 10º, do 11º e do 12º ano.

Para isso temos de verificar se cada textbox tem um valor numérico caso contrário não consideramos o seu conteúdo.


    Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
        Dim n10, n11, n12, media, exame, conta As Integer
        Dim notamin As Double

        If isnumeric(Me.tb_nota10.Text) = True Then
            n10 = Me.tb_nota10.Text
            conta = 1
        End If
        If isnumeric(Me.tb_nota11.Text) = True Then
            n11 = Me.tb_nota11.Text
            conta = conta + 1
        End If
        If isnumeric(Me.tb_nota12.Text) = True Then
            n12 = Me.tb_nota12.Text
            conta = conta + 1
        End If
        If conta = 0 Then
            MessageBox.Show("Tem de introduzir pelo menos uma nota!")
            Exit Sub
        End If
        media = (n10 + n11 + n12) / conta
        Me.lb_media.Text = media

        notamin = media * 0.7
        For exame = 1 To 20
            If notamin + exame * 0.3 >= 9.5 Then
                Exit For
            End If
        Next
        Me.tb_exame.Text = exame

    End Sub

O segundo botão calcula a CFD (classificação Final da Disciplina).


    Private Sub Button2_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button2.Click
        Dim cif, exame, cfd As Integer

        If isnumeric(lb_media.Text) = False Then
            MessageBox.Show("Calcule primeiro a CIF")
            Exit Sub
        End If
        If isnumeric(tb_nota_exame.Text) = False Then
            MessageBox.Show("Indique a nota do exame!")
            Exit Sub
        End If
        cif = lb_media.Text
        exame = tb_nota_exame.Text
        cfd = cif * 0.7 + exame * 0.3
        Me.tb_cfd.Text = cfd

    End Sub

O terceiro botão guarda a CFD na listbox.


    Private Sub Button3_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button3.Click
        If isnumeric(Me.tb_cfd.Text) = False Then
            MessageBox.Show("Calcule primeiro a CFD!")
            Exit Sub
        End If
        Me.ListBox1.Items.Add(Me.tb_cfd.Text)
    End Sub

Por fim temos uma hiperligação que permite abrir uma página da net.


    Private Sub HyperlinkButton1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles HyperlinkButton1.Click
        Dim pagina As WebBrowserTask = New WebBrowserTask()
        pagina.Uri = New Uri("http://alunosnet.pt.vu", UriKind.Absolute)
        pagina.Show()
    End Sub

Projeto para download




sexta-feira, 8 de fevereiro de 2013

RFID Tags

As etiquetas RFID são, hoje em dia, muito comuns em diversas atividades, desde cartões de identificação a etiquetas para identificar produtos.

RFID significa Radio Frequency Identification (Identificação por rádio frequência).

O principio é simples, existe um leitor e uma etiqueta que comunicam, mas ao contrário dos rádios a etiqueta não tem de ser alimentada (apesar de existirem algumas que são) por baterias, esta é alimentada pelo leitor por um período breve de tempo durante o qual é enviado para o leitor o número de identificação da etiqueta.

Para este pequeno projeto vou utilizar uma placa RFID USB da SparkFun para comunicar com um leitor RFID.





O leitor encaixa na placa que por sua vez liga-se ao computador via USB. Nada mais fácil.




Agora precisamos dos drivers da placa para isso basta seguir este link.

Depois do dispositivo estar instalado temos de saber qual o número da porta que lhe foi atribuído  para isso basta ir ao gestor de dispositivos e procurar na secção portas.



No meu caso é a porta COM31.

Agora vamos até ao Visual Basic fazer um pequeno programa para ler as etiquetas.


No formulário vamos utilizar o componente SerialPort para receber do leitor RFID os dados das etiquetas.


Agora o código.

Primeiro o botão que atualiza a porta de comunicação e abre a porta.



    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click


        If Me.SerialPort1.IsOpen = True Then Me.SerialPort1.Close()

        Try
            Me.SerialPort1.PortName = Me.TextBox1.Text

            If Me.SerialPort1.IsOpen = False Then Me.SerialPort1.Open()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try


    End Sub


Agora o componente SerialPort, por defeito este já está configurado para um baud rate de 9600 que é a mesma velocidade da placa da SparkFun, como já deve ter percebido esta porta apesar de ser usb utiliza um protocolo de comunicação série tal como o arduino.

Para ler os dados da SerialPort adicionamos um timer que quando detetar dados lê-os e adiciona-os à listbox, o código do timer:


    Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
        Dim letra As Char
        Static texto As String

        If Me.SerialPort1.IsOpen = False Then Exit Sub
        letra = ChrW(Me.SerialPort1.ReadChar())
        If Char.IsLetterOrDigit(letra) Then
            texto = texto & letra
        Else
            If texto = "" Then Exit Sub
            If texto <> "" Then
                Me.ListBox1.Items.Add(texto)
                texto = ""
            End If
        End If

    End Sub

Com este código cada letra da tag é lida individualmente e adicionada à string quando a letra lida não é válida verificamos se terminamos de ler para adicionar à listbox.



O projeto pode ser encontrado aqui.

sexta-feira, 25 de janeiro de 2013

Vamos acelerar


Como é do conhecimento geral os telemóveis Android têm um sensor designado de acelerómetro.
Este sensor permite avaliar os movimentos a que o dispositivo está sujeito num sistema de três eixos.
O eixo dos x permite avaliar a inclinação do dispositivo para a esquerda ou para a direita. O eixo dos y é controlado pela inclinação do dispositivo para a frente ou para trás. O eixo dos z reflete o movimento para cima e para baixo.





Para este pequeno projeto vamos fazer um labirinto cujo objetivo é levar uma esfera até ao buraco inclinando o dispositivo tal como  se se trata-se um jogo físico.



Primeiro vamos criar um projeto novo.

Na atividade principal (MainActivity) vamos implementar uma função que fica associada ao sensor, é o que se designa por SensorEventListener.

Assim alteramos a declaração da class para

       public class MainActivity extends Activity implements SensorEventListener{

De seguida na função onCreate temos de "capturar" o sensor, para isso criamos um objeto SensorManager e outro objeto Sensor.


        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mSensorManager.registerListener(this,mSensor,SensorManager.SENSOR_DELAY_NORMAL);


Posto isto temos de implementar a função onSensorChanged, que vai receber os valores do sensor sempre que este sofrer alterações.


public void onSensorChanged(SensorEvent event) {
//recolher os três valores para as variáveis
x=event.values[0];
y=event.values[1];
z=event.values[2];
}

Com estas funções implementadas vamos passar à fase gráfica, para implementar a interface vamos utilizar uma ImageView que depois associamos ao xml do layout do programa.

Vamos, então, adicionar uma class nova que vai implementar a lógica e os gráficos.

public class ecran extends ImageView{

Nesta class vamos implementar a função onSizeChanged que vai permitir saber o tamanho do ecrã, para, em função desse tamanho, implementarmos as paredes do labirinto.

Precisamos, ainda, da função onDraw, que além de desenhar tudo no ecrã vai calcular a posição da esfera em função dos valores do sensor. Como o sensor é controlado na MainActivity é necessário implementar três métodos públicos na MainActivity para podermos aceder aos valores do sensor.
Primeiro um método que nos dá a instancia atual.


public static MainActivity getInstance(){
return instance;
}

Este método vai permitir à class ecran, que é a que desenha no ecrã do dispositivo, ter acesso aos outros dois métodos, um que devolve o valor x e outro para o valor y do sensor.


public float getX()
{
return x;
}
public float getY()
{
return y;
}
No projeto também está implementado o método para o z mas não é utilizado.

Para as paredes do labirinto criei um vetor de retângulos.
As paredes são definidas por código e desenhadas com a cor vermelha.

A função principal é a onDraw que trata de:
1º desenhar o buraco de saída do labirinto.
2º desenhar as paredes.
3º receber os valores da inclinação do dispositivo.
4º calcular a nova posição da esfera calculado se esta bate em alguma parede.
5º se a esfera está suficientemente perto do buraco para declarar vitória.

Por fim o layout da atividade que fica assim:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"    
    android:background="#FFFFFF">
    <edu.pjcferreira.labirinto.ecran
        android:id="@+id/ecran"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"/>
</LinearLayout>


É um layout linear que associa a class ecran ao ecrã.

Em resumo: este projeto demonstra como desenhar no ecrã utilizando as funções gráficas do sistema operativo Android, desde imagens a figuras geométricas bem como escrever texto e ainda a utilização do sensor acelerómetro.

O projeto e a aplicação.




sexta-feira, 4 de janeiro de 2013

i-Racer

Neste post vamos criar um programa que permite controlar um i-Racer com um dispositivo Android através do Bluetooth.
Para quem ainda não conhece este pequeno carro fica aqui um vídeo.




O i-Racer responde a um conjunto limitado de comandos em hexadecimal cujo significado pode ser encontrado aqui.

O objetivo é demonstrar o funcionamento do envio dos comandos através do Bluetooth, para isso vamos implementar quatro comandos: andar para a frente, andar para trás, virar rodas para direita e virar rodas para a esquerda. Os restantes comandos são igualmente fáceis de implementar basta alterar os códigos enviados ao i-Racer.

Para começar a interface.
O design:
Em execução:
Resumindo:
- oito botões;
- duas listviews, uma onde estão os botões a outra para apresentar os dispositivos Bluetooth emparelhados e detetados.

O xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="false"
        android:layout_alignParentTop="true"
        android:layout_centerInParent="true"
        android:layout_marginTop="4dp"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"

            android:onClick="onLigarClick"
            android:text="@string/ligar" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onProcurarClick"
            android:text="@string/procurar" />
        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onAbrirClick"
            android:text="@string/abrir" />
        </LinearLayout>
    <LinearLayout
        android:id="@+id/linearLayout4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="false"
        android:layout_alignParentTop="true"
        android:layout_centerInParent="true"
        android:layout_marginTop="58dp"
        android:orientation="horizontal" >
    
    <Button
            android:id="@+id/button4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onFrenteClick"
            android:text="@string/frente" />
       <Button
            android:id="@+id/button5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onPararClick"
            android:text="@string/parar" />
        
       <Button
            android:id="@+id/button6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onEsquerdaClick"
            android:text="@string/esquerda" />
       <Button
            android:id="@+id/button7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onDireitaClick"
            android:text="@string/direita" />
<Button
            android:id="@+id/button8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onSairClick"
            android:text="@string/sair" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/linearLayout1"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="82dp"
        android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

    </ListView>
</LinearLayout>
</RelativeLayout>


Agora uma classe para controlar as comunicações. Os tutoriais da google sobre o Bluetooth do Android são muito completos mas também algo complexos, ainda que isso seja normal quando estamos a criar programas de comunicação entre dispositivos.

Para este pequeno dispositivo nós só temos de enviar os comandos não temos de receber, assim a classe criada permite abrir um canal de comunicação, estabelecer uma ligação, enviar dados, devolver o estado da ligação e terminar a ligação.

O código é algo complexo mas está comentado e envia mensagens para o Log de modo que a que seja mais fácil fazer o debug da aplicação.


package edu.pjcferreira.btremote;

import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

public class ConnectThread extends Thread{
private BluetoothAdapter mBluetoothAdapter;//dispositivo local
private BluetoothSocket mmSocket;
private BluetoothDevice mmDevice; //dispositivo remoto
    private static final UUID MY_UUID =
            UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //para ligar a uma board serial tem que ser com este UUID
    private int estado;
    private OutputStream mmOutStream=null;
    
    //recebe o dispositivo remoto ao qual ligar
public ConnectThread(BluetoothDevice device){
BluetoothSocket tmp=null;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mmDevice=device;
estado=-1;
try{
Log.d("BT","Abre o canal de ligação");
tmp=mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
mmSocket=tmp;
estado=0;
Log.d("BT","Canal aberto!");
}catch(IOException e){
estado=-1;
}
}
//método para enviar os comandos
    public void enviar(byte x){
    if (mmOutStream==null){
    try{
    mmOutStream=mmSocket.getOutputStream();
    }catch(IOException e){
    return;
    }
    }
    try{
    mmOutStream.write(x);
    }catch(IOException ee){
    return;
    }
    Log.d("BT","ENVIADO COM SUCESSO!");
    }
    //função que devolve o estado da ligação
    public String getEstado(){
    return Integer.toString(estado);
    }
//estabelece a ligação
public void run(){
mBluetoothAdapter.cancelDiscovery();

try{
mmSocket.connect();
Log.d("BT","LIGADO");
estado=1;
}catch(IOException connectException){
try{
mmSocket.close();
Log.d("BT","ERRO A LIGAR");
estado=-1;
}catch(IOException closeException){}
}
return;
}
//termina a ligação
public void cancel(){
try{
mmSocket.close();
estado=-1;
}catch(IOException e){}
}
}

Agora com esta classe podemos iniciar a comunicação mas primeiro precisamos de verificar se o dispositivo tem Bluetooth, isso é feito na função onCreate que se apresenta a seguir.
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //verifica se existe bt neste dispositivo
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter==null){
        showMessage("Não tem suporte para bluetooth!");
        }else{
        showMessage("Tem suporte para bluetooth!");
        }
        //lista de dispositivos
        mArrayAdapter = new ArrayAdapter<String>(this,R.layout.simplerow,0);
        //registar a função que vai receber os dispositivos encontrados
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        //tambem recebe a mensagem que terminou a pesquisa
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(mReceiver, filter);
        //lista de dispositivos
        listView = (ListView) findViewById(R.id.listView1);
    }

Esta função também regista uma função callback para que quando os dispositivos Bluetooth são encontrados poderem ser adicionados à listview. O código dessa função é este:
    private final BroadcastReceiver mReceiver = new BroadcastReceiver(){
    public void onReceive(Context context, Intent intent){
    String action = intent.getAction();
    if (BluetoothDevice.ACTION_FOUND.equals(action)){
    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    showMessage(device.getName());
    }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                // showMessage("Terminado! Encontrados " + mArrayAdapter.getCount() + " dispositivos!");
                listView.setAdapter(mArrayAdapter);
                listView.setClickable(true);
                //função a chamar quando clicar num item da lista
                listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                 public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
                   Object o = listView.getItemAtPosition(position);
                   showMessage("Selecionou " + o.toString());
                   //tenta ligar ao dispositivo
                   dispositivo=position;
                   String[] endereco=o.toString().split("\n");
                  /* showMessage(endereco[0]);
                   showMessage(endereco[1]);*/
                   remoteBluetoothDevice=  mBluetoothAdapter.getRemoteDevice(endereco[1]);
                 }
                });
            }
    }
    };

De seguida precisamos de uma função para pesquisar dispositivos Bluetooth, quer os que estão emparelhados quer outros:
    public void onProcurarClick(View botton) {
    //primeiro vamos procurar dispositivos emparelhados
    pairedDevices=mBluetoothAdapter.getBondedDevices();
    //se existem
    if(pairedDevices.size()>0){
    for(BluetoothDevice device : pairedDevices){
    mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    showMessage(device.getName());
    }
    }
    //procurar novos dispositivos
      mBluetoothAdapter.startDiscovery();
    }

Posto isto podemos abrir uma ligação com o dispositivo selecionado:
    public void onAbrirClick(View botton) {
    if(remoteBluetoothDevice==null){
    showMessage("Primeiro deve selecionar o dispositivo!");
    return;
    }
    ligacao=new ConnectThread(remoteBluetoothDevice);
   ligacao.run();
   showMessage(ligacao.getEstado());
    
    }

Agora podemos enviar os comandos, para isso temos uma função para cada comando:
    public void onFrenteClick(View botton) {
    byte x;
    x=0x1B;
    if(ligacao==null){
    showMessage("Primeiro tem de abrir uma ligação.");
    return;
    }
    ligacao.enviar(x);
    }
    public void onEsquerdaClick(View botton) {
    byte x;
    x=0x36;
if(ligacao==null){
showMessage("Primeiro tem de abrir uma ligação.");
return;
}
    ligacao.enviar(x);
    }
    public void onDireitaClick(View botton) {
    byte x;
    x=0x46;
if(ligacao==null){
showMessage("Primeiro tem de abrir uma ligação.");
return;
}
    ligacao.enviar(x);
    }
    public void onPararClick(View botton){
    byte x;
    x=0x00;
if(ligacao==null){
showMessage("Primeiro tem de abrir uma ligação.");
return;
}
    ligacao.enviar(x);
    }

Antes de terminarmos precisamos de limpar a casa, o botão sair e ainda a função onDestroy:
    public void onSairClick(View botton) {
    byte x;
    x=0x00;
if(ligacao!=null){
ligacao.enviar(x);
ligacao.cancel();
}
    finish();
    }
    protected void onDestroy() {
    byte x;

    x=0x00;
    if(ligacao!=null){
    ligacao.enviar(x);
    ligacao.cancel();
    }
       this.unregisterReceiver(mReceiver);
    super.onDestroy();
    }

Quase me esquecia as permissões, neste projeto precisamos de duas:
    - Permissão para utilizar Bluetooth:
<uses-permission android:name="android.permission.BLUETOOTH"/>
    - Permissão para pesquisar dispositivos com o Bluetooth:
<uses-permission  android:name="android.permission.BLUETOOTH_ADMIN"/>

E pronto temos um programa que permite controlar o pequeno i-Racer. Como sempre o projeto e aplicação    estão disponíveis para download.