PyObjC Python no XCode

0saves

Bom, faz uma semana que estou com meu macbook, mas estou em epoca de provas na faculdade e não tive muito tempo de estudar ObjC, mas queria fazer algo nativo para o mac. Então fui procurar como desenvolver em uma linguagem que eu ja conheço, no caso Python.
Acabei encontrando o PyObjC ( http://pyobjc.sourceforge.net/ ) que utilizado junto com o XCode é uma maravilha para desenvolver.

Primeiro vai precisar instalar o XCode ( http://developer.apple.com/technologies/xcode.html ) só seguir os passos ali do site que não tem erro.

Agora precisa baixar e instalar o PyObjC ( http://ioanna.me/2009/09/installing-pyobjc-xcode-templates-in-snow-leopard/ )

Pronto agora é só desenvolver, seguem dois videos que encontrei neste blog ( http://fiorix.wordpress.com/2008/07/23/xcode-31-e-cocoa-python/ ) , eles foram feitos no XCode 3.1 que é um pouco diferente do 3.2 (a versão que eu testei) mas muda pouca coisa, só ali na parte de atribuir as açoes aos componentes é em outra janela.

Parte 1:

Parte 2:

Agora passando as provas vou ter mais tempo de estudar ObjC, mas é bom saber que posso contar com python se necessario.
Quanto ao meu projeto do sistema de controle com PIC e porta serial (rs232), foi apresentado ja a parte basica (comandos enviados via console, e apenas ligando ou desligando dispositivos). Agora vou desenvolvendo ele no meu tempo livre, quero mudar algumas coisas nele ainda:

- Utilizar mais python e menos C por questão de portabilidade (antes tinha que utilizar C pois era para a cadeira de programação C)
- Desenvolver bibliotecas com funçoes basicas de controle para alguns modelos de PIC
- Montar um destes kits de desenvolvimento, para que mais pessoas possam testar mesmo que não entendam muito de eletronica

e claro que tem os planos futuros, que consomem mais tempo e dinheiro:
- Desenvolver um hardware para controle e monitoramento ( tela com toutchscreen e wireless)
- Desenvolver o software para alguns hardwares ja existentes, para que os usuarios finais não precisem novos hardwares (menos lixo eletronico, e menos custo) , sendo estes, smartphones (os que eu tiver acesso, por enquanto nokia e iphone), computadores em geral (linux, windows e mac), uma interface web, ipod toutch, ipad ( o qual seria perfeito para este proposito), e para o que tiver de tecnologia disponivel.
- Criar uma pagina especifica para o projeto, tanto em português quanto ingles.

Quanto a questão de distribuição ainda não sei como vou fazer, pensei em algumas opçoes, agora falta avaliar os prós e contras de cada uma.
Opção 1: Distribuir tudo como freeware ou donationware (mesmo duvidando que alguem doe alguma coisa aqui no brasil…)
Prós:
- Mais gente aprende
- Cada um poderia fazer o seu em casa, customizando como precisar
- Mais gente poderia ajudar no projeto, assim melhorando ele e não dependendo unica e exclusivamente de mim
- É um bom projeto para ter no curriculo ( de todos os que participam no projeto)
Contras:
- Algumas partes do projeto dependem de bastante tempo e dinheiro até chegar em algo satisfatorio.
- Pelo que eu conheço do povo brasileiro, certo que alguem modificaria o projeto gratuito e tentaria vender ele.
- Muitas pessoas com capacidade de ajudar no projeto não iriam, apenas utilizariam para seus proprios projetos.
Estes contras são baseados nas experiencias que tive com os projetos freeware que distribui.

Opção 2: Distribuir apenas os conceitos basicos como freeware, e comercializar o resto, e possivelmente abrir uma empresa baseada neste projeto.
Prós:
- Uma vez mostrado o caminho, acredito que ninguem teria muita dificuldade de desenvolver o que quiser.
- Eu teria retorno do tempo e dinheiro investido no projeto ( faculdade, componentes, finais de semana estudando…)
- Mais pessoas ainda poderiam ter acesso a esta tecnologia, sem precisar montar nada.
- A empresa faria as customizaçoes necessarias para cada cliente, sempre levando em conta o baixo custo.
Contras:
- O projeto dependeria unica e exclusivamente de mim, assim ficando limitado ao que eu conseguir desenvolver, mesmo tendo pessoas com mais experiencia na area que poderiam resolver problemas que levo um mes em algumas poucas horas.
- Para a comercialização demoraria um tempo, atualmente onde eu moro o custo é muito elevado (impostos absurdos), logo, seria viavel quando eu não morar mais no brasil (vou embora assim que me formar).

Por enquanto ainda acho que a segunda opção é mais interessante, estaria passando o conhecimento basico (que qualquer um aprende na faculdade se fizer Eng. Eletrica ou Eng. da Computação aplicada as engenharias) e tambem estaria recebendo um retorno pelo tempo dedicado ao projeto, e teria como manter os custos da pesquisa, dos materiais… sem que isso prejudique o meu orçamento ( tenho mais coisas para investir meu dinheiro ), depois quando a empresa estiver grande e conhecida no mercado talvez de para liberar mais coisas, isso quando a empresa tiver um historico de contrataçoes para customizaçoes especiais que possa manter a empres ativa.
Outro motivo pelo qual é interessante obter lucro com a empresa é ter como bancar pesquisas ecologicas, minhas pesquisas não foram aceitas pelo governo, então dependo do incentivo privado (por enquanto esta sendo o meu bolso hehe) para continuar, acho que existe pouco investimento nesta area, principalmente da parte do governo. Mas analizando bem, não é interessante pro governo e para um monte de gente que a energia limpa seja utilizada, que carros eletricos sejam produzidos em massa (assim diminuindo o custo e viabilizando a compra por pessoas “normais”), pois consideram o dinheiro mais importante do que tudo, é só ver quanto dinheiro o governo e acionistas da petrobras obtem do petroleo, isso não é só aqui, em mais paises é assim tambem, para eles não é interessante que parem de utilizar o petroleo. Eu acho que se o petroleo fosse utilizado somente para o que ainda não existe substituto para ele (como alguns tipos especificos de polimeros) não precisariamos de tanto petroleo assim, e poderiamos poluir menos.
A minha ideia é depois de ter uma renda mensal fixa boa (proveniente de aluguel, empresa…) me aposentar, e dedicar meu tempo e dinheiro a familia(isso tambem esta nos planos hehe) e a pesquisa, quero morar em algum lugar frio e tranquilo(canada ou europa), com tempo e dinheiro suficiente para pesquisas.

Sistema de controle com PIC e porta Serial (rs232) parte 2

0saves

Hoje vou mostrar como fazer a parte do PC para se conectar com o PIC , e tem algumas alteraçoes no codigo do pic tambem.
Não vou entrar em muitos detalhes sobre o codigo do PIC pois este era o foco da parte 1
Segue o codigo:

#include "16f628a.h"                           // Inclui o cabeçalho especifico do pic a ser utilizado
#include "stdio.h"                              // Inclui as funçoes padroes de entrada e saida
#fuses HS,NOWDT,NOPROTECT                       // Configuração dos fuses (ver manual)
#use delay(clock=4000000)                       // Seta o clock interno para 4Mhz
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)  // Seta o baud rate para 9600, e define o pino B2 como TX e B1 como RX
 
unsigned char x[4];  //Variavel do tipo char com 4 posiçoes (string de até 3 carateres) ou do tamanho do comando que desejarem utilizar
// lembrando que sempre deve ter um caractere a mais pois tem o '\0' no final da string
unsigned int pino; //Variavel que armazenara o pino que esta sendo utilizado
 
void main(void) // função principal
{
   delay_ms(100); //tempo para inicializar a conexão
   do {
      gets(x); // pega a string e coloca na variavel x
      if(x[0] == 'a' || x[0]=='A') // Fazer isso para todas as portas desejadas, podendo ser A,B,C.. depende do pic
      {
         switch(x[1]) // Ve se qual pino da porta quer controlar
         {
            case '0':
               pino = PIN_A0;
               break;
            case '1':
               pino = PIN_A1;
               break;
            case '2':
               pino = PIN_A2;
               break;
            case '3':
               pino = PIN_A3;
               break;
            default:
               pino = 0; // se não for nenhum, coloca como 0;
               break;
         }
      }
      else if(x[0] == 'b' || x[0]=='B') // mesma coisa que antes, porem agora para a porta B (e assim pode continuar)
      {
         switch(x[1])
         {
            case '0':
               pino = PIN_B0;
               break;
            case '1':
               pino = 0; // pino reservado para RS232
               break;
            case '2':
               pino = 0; // pino reservado para RS232
               break;
            case '3':
               pino = PIN_B3;
               break;
            case '4':
               pino = PIN_B4;
               break;
            case '5':
               pino = PIN_B5;
               break;
            case '6':
               pino = PIN_B6;
               break;
            case '7':
               pino = PIN_B7;
               break;
            default:
               pino = 0;
               break;
         }
      }
      else
      {
       pino=0;
       // Se não existir a porta que foi escolhida, seta o pino para 0 para que não mude o que foi escolhido anteriormente
      }
 
      if(pino != 0) // Se o pino existir (não for 0)
      {
         if(x[2]=='l' || x[2]=='L')// Se o comando for L ou l (de ligar) 
         {
            output_high(pino); // Coloca o valor 1 logico no pino escolhido
            printf("200\n\r");
         }
         else if(x[2]=='d' || x[2]=='D') // Se o comando for D ou d(de desligar) 
         {
            output_low(pino); // Coloca o valor 0 logico no pino escolhido 
            printf("200\n\r");
         }
         else // Se o comando não for de ligar ou desligar
         {
            printf("505\n\r"); //Avisa que o comando é invalido
         }
      }
      else // Se o pino não existir (variavel pino igual a 0)
      {
         printf("505\n\r");
      }
   } while (TRUE); // mantem o laço de repetição rodando em loop infinito
}

Bom, agora vamos ao que interessa, o software que controla o PIC pela porta serial de um PC.
Normalmente a conexão serial é meio chatinha de fazer (seja em linux, windows, mac..) então recomendo que usem a biblioteca que se encontra neste site ( http://www.teuniz.net/RS-232/ ) que facilita bastante o nosso trabalho, e ja deixa portavel para outros OS tambem. Essa biblioteca é extremamente simples de ser utilizada, não vejo sentido em reescrever todo o codigo para a comunicação serial se ja tem uma biblioteca boa que faz isso, a não ser para aprender como funciona (recomendo que leiam o codigo da biblioteca)

Segue o codigo:

#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#include "windows.h"
#include "string.h"
#include "rs232.h"
 
void loop(); // Declarando a função loop que está la em baixo
 
unsigned char comando[5]; // comando a ser enviado
unsigned char buff[1024]; // comando recebido
 
int main(void) // Função principal
{
    OpenComport(1,9600); // abre a porta desejada (ver documentação)
    loop(); // Chama a função loop
    return 0;
}
 
void loop() // Função loop
{
    int n; // variavel temporaria
    n = PollComport(1,buff,1024); // n != 0  se tiver algo pra ser recebido
    if(n == 0) // se não tiver recebendo nada
    {
        printf("Digite o seu comando: "); //pergunta qual comando quer executar
        gets(comando); // Pega o comando e coloca na variavel comando
        strcat(comando,"\n\r");// adiciona uma quebra de linha (mais por motivos esteticos se for testar em terminal ou quardar log)
        cprintf(1,comando); // manda o comando para a porta serial (ou USB com FTDI)
        _sleep(200); // delay de 200 milisegundos necessario para a sincronização (pode ser de 100)
    }
    else // Se tiver recebido algo
    {
        // Switch para ver o que cada codigo representa, e exibe para o usuario.
        switch(atoi(buff))
        {
            case 200:
                printf("OK!\n\r");
                break;
            case 505:
                printf("Erro!\n\r");
                break;
            default:
                break;
        }
    }
    loop(); // Chama a função novamente, assim mantendo um loop infinito
}

Acho que da pra entender como funciona só pelos comentarios.
Esse codigo foi testado no windows 7 ultimate 64bit, utilizando o code::blocks para programar, e o GNU GCC para compilar. Para funcionar para linux tambem é necessario alterar algumas coisas, mas a logica é a mesma.

Ah, não saiam ligando os fios da serial direto no pic é preciso utilizar um MAX232 para isso, pois o sinal da serial é diferente do TTL utilizado pelo pic. Para saber como ligar o MAX232 é só olhar no datasheet.

Se quiserem testar só a comunicação serial virtualmente, recomendo o uso do virtual serial port driver da eltima, e hyper terminal.

Ainda falta eu colocar aqui a parte dos sockets (para o controle remoto), que ja está pronta só tenho que juntar tudo, e a parte eletro-eletronica tambem, por exemplo um dimmer para uma lampada, como controlar interruptores… e alguns outros exemplos do que fazer. A principio quero montar uma placa que controle varios interruptores.

Qualquer duvida, sugestão ou critica, favor deixar nos comentarios

Sistema de controle com PIC e porta Serial (rs232)

0saves

Estou fazendo um projeto para a cadeira de programação C que tem o objetivo de controlar eletronicos (sejam interruptores, motores, ou até coisas mais completas como temperatura de um ar-condicionado) remotamente, e achei interessante postar aqui o projeto para que mais gente possa ver como isso é feito (e como é mais simples do que se imagina).
Por enquanto estou desenvolvendo o projeto em partes, para juntar tudo depois.
Hoje vou falar sobre a parte do PIC enviar e receber dados pela porta serial.

Material utilizado (para testar virtualmente):

- Proteus 7.1 (para a simulação)
- PCWH Compiler IDE (CCS) 4.038 (para programar e compilar o programa em C)

Passos da montagem no proteus:
Passo 1: Criar um novo arquivo no Proteus.
Passo 2: Adicionar o PIC de sua preferencia que tenha suporte a RS232, no caso do exemplo é o PIC16F628A.
Passo 3: Adicionar os leds que quiser (de acordo com o numero de pinos que deseja controlar).
Passo 4: Colocar um resistor de 470 Ohms em cada led.
Passo 5: Ligar o LED-Resistor ou Resistor-LED (tanto faz a ordem) ao terra.
Passo 6: Adicionar um terminal virtual ao projeto
Passo 7: Ligar o pino RX do pic no TX do terminal
Passo 8: Ligar o pino TX do pic no RX do terminal
Passo 9: Salve o projeto onde preferir
por enquanto é isso no proteus, agora precisamos do programa a ser inserido no pic.

Para o programa do PIC, cada um programa no editor que preferir, e usa o compilador que quiser(Lembrando que mudando de compilador o codigo sera diferente). No exemplo eu estou usando o compilador CCS.
O programa é o seguinte:

#include <16f628a.h>                            // Inclui o cabeçalho especifico do pic a ser utilizado
#include                               // Inclui as funçoes padroes de entrada e saida
#fuses HS,NOWDT,NOPROTECT                       // Configuração dos fuses (ver manual)
#use delay(clock=4000000)                       // Seta o clock interno para 4Mhz
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)  // Seta o baud rate para 9600, e define o pino B2 como TX e B1 como RX
 
unsigned char x[4];  //Variavel do tipo char com 4 posiçoes (string de até 3 carateres) ou do tamanho do comando que desejarem utilizar
// lembrando que sempre deve ter um caractere a mais pois tem o '\0' no final da string
unsigned int pino; //Variavel que armazenara o pino que esta sendo utilizado
 
void main(void) // função principal
{
   delay_ms(100); //tempo para inicializar a conexão
 
   printf("TESTE DE CONTROLE COM PIC\n\r"); // Manda esta mesagem para o terminal
   //Para testar se foi tudo ligado corretamente, feche a função aqui, compile e teste
   do {
      printf("\n\r");
      printf("Envie um comando de 3 caracteres");
      printf("sendo abc a=porta b=pino c=estado(l ou d) \n\r");
      gets(x); // pega a string e coloca na variavel x
      if(x[0] == 'a' || x[0]=='A') // Fazer isso para todas as portas desejadas, podendo ser A,B,C.. depende do pic
      {
         switch(x[1]) // Ve se qual pino da porta quer controlar
         {
            case '0':
               pino = PIN_A0;
               break;
            case '1':
               pino = PIN_A1;
               break;
            case '2':
               pino = PIN_A2;
               break;
            case '3':
               pino = PIN_A3;
               break;
            default:
               pino = 0; // se não for nenhum, coloca como 0;
               break;
         }
      }
      else if(x[0] == 'b' || x[0]=='B') // mesma coisa que antes, porem agora para a porta B (e assim pode continuar)
      {
         switch(x[1])
         {
            case '0':
               pino = PIN_B0;
               break;
            case '1':
               pino = 0; // pino reservado para RS232
               printf("Pino reservado!");
               break;
            case '2':
               pino = 0; // pino reservado para RS232
               printf("Pino reservado!");
               break;
            case '3':
               pino = PIN_B3;
               break;
            case '4':
               pino = PIN_B4;
               break;
            case '5':
               pino = PIN_B5;
               break;
            case '6':
               pino = PIN_B6;
               break;
            case '7':
               pino = PIN_B7;
               break;
            default:
               pino = 0;
               break;
         }
      }
      else
      {
       pino=0;
       // Se não existir a porta que foi escolhida, seta o pino para 0 para que não mude o que foi escolhido anteriormente
      }
 
      if(pino != 0) // Se o pino existir (não for 0)
      {
         if(x[2]=='l' || x[2]=='L')// Se o comando for L ou l (de ligar)
         {
            output_high(pino); // Coloca o valor 1 logico no pino escolhido
         }
         else if(x[2]=='d' || x[2]=='D') // Se o comando for D ou d(de desligar)
         {
            output_low(pino); // Coloca o valor 0 logico no pino escolhido
         }
         else // Se o comando não for de ligar ou desligar
         {
            printf("Comando invalido. Tente novamente \n\r"); //Avisa que o comando é invalido
         }
      }
      else // Se o pino não existir (variavel pino igual a 0)
      {
         printf("Comando invalido. Tente novamente \n\r");
      }
   } while (TRUE); // mantem o laço de repetição rodando em loop infinito
}

Os dois promeiros includes não aparecem bem com esse plugin, mas são:
#include <16f628a.h>
#include
Acho que não tem nada de muito complicado neste codigo, no máximo a parte de configuração dos fuses, o que pode ser visto no manual do compilador, ou em qualquer tutorial basico sobre o CCS. e o resto dos comandos são basicos da linguagem C (aprenda o basico de C antes de tentar fazer isso, aqueles programinhas em terminal). Qualquer outra coisa é só postar a duvida que eu respondo.

Agora precisa compilar o programa (sugiro copiar o .hex gerado para a pasta do projeto do proteus).

Voltando ao proteus agora,

Passo 10: Clique duas vezes sobre o PIC, sete o clock para 4Mhz (em Processor Clock Frequency) e em Program File coloque o caminho para o arquivo .hex gerado pelo compilador.

Pronto, agora depois de tudo configurado é só rodar a simulação que funcionara, a menos que tenha feito algo errado (antes de perguntar, favor ler novamente e ver se esta tudo igual). Lembrando que ao copiar e colar o codigo para o seu editor de textos normalmente tem que trocar as aspas pois vai como acento.

Esta é somente a base para algo mais complexo, se quiser controlar um motor, ler um valor analogico (potenciometro, ldr, temperatura…) ou qualquer outra coisa mais complexa, tera que implementar as suas funçoes e comandos para isso.

Conforme eu for fazendo o projeto, e tiver tempo, vou postando aqui.

Uma coisa que acho importante ao compartilhar este projeto, é mostrar para as pessoas que usam arduino, que não é preciso gastar muito com uma arduino para fazer projetos simples, os microcontroladores são baratos (em torno de uns 10 reais) e são super simples de programar.

Seguem algumas imagens de como fica o projeto:

Como fica no proteus

Como fica no proteus

Funcionando no proteus com o terminal

Funcionando no proteus com o terminal

Se a apple quer restriçoes nos seus aparelhos, vai ter!

0saves

Hoje escrevo como desenvolvedor, e como cliente decepcionado com a politica de restriçoes da Apple.
Como muitos devem saber, a apple não quer de modo algum flash rodando nos seu aparelho (ipad, iphone e ipod), antes muitos culpavam a adobe por não conseguir desenvolver um plugin que funcione no hardware restrito (e bem caro por sinal) desenvolvido pela apple. Porem a adobe apostou nos cross-compilers com o novo flash CS5, lançando alguns aplicativos que provaram que é possivel desenvolver aplicativos para o iphone OS em flash que funcione tão bem quanto os desenvolvidos em cocoa (Objective-C).
A apple vendo que com o lançamento do flash CS5 teria varios aplicativos em flash nas suas lojas, resolveu mudar a seção 3.3.1 do “”iPhone Developer Program License Agreement” restringindo o uso de outras ferramentas para o desenvolvimento de aplicaçoes para os seus aparelhos.

3.3.1 — Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs. Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine, and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs (e.g., Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited).

Isso ja gerou bastante polêmica, muitos desenvolvedores e usuarios ficaram decepcionados com a decisão da apple, eles alegam que não é seguro, e não é estavel. Não vou entrar em detalhes sobre o motivo pelo qual a apple não quer que muitas coisas funcionem nos seus produtos, pois boa parte de quem ja leu o post até aqui ja sabe.

Eu, esperando que fosse possivel desenvolver apps para o iphone OS em flash com o tempo, ou com alguma linguagem conhecida (usando windows) comprei os iPhones, um 3gs de 32Gb e outro 3G de 8Gb. Enquanto poderia ter esperado um pouco e ter comprado um nokia n900, nexus one…. qualquer outro telefone que facilite a vida dos desenvolvedores.
Eu ja achava ruim ter que pagar para poder desenvolver para o iphone, mas tudo bem, mesmo pagando as aplicaçoes tinham que passar pela avaliação da apple para o aplicativo ser lançado na appstore, mas tudo bem. Mas obrigar os desenvolvedores a utilizar a linguagem propria da empresa sendo que a maioria ja conhece bem as outras linguagens ja é exagero. Nessas horas sinto saudades do meu velho nokia E51 com symbian, eu tinha até um interpretador de python nele.
Acho que as aplicaçoes são vendidas devem passar por um teste de segurança (mas algo com sentido), ja as gratuitas, ou proprias deveriam ser gratuitas. Por exemplo, se eu quiser desenvolver algum aplicativo para o meu iPhone que utilize algo que a apple não acha seguro, não posso distribuir meu aplicativo.

Resumindo, enquanto varias empresas como: Adobe,Google, HTC, LG, Samsung, Cisco, Palm, Sony, Intel… apoiam o Open Screen Project que tem por objetivo facilitar a vida do desenvolvedor, e dos usuarios, a Apple faz exatamente o contrario da ideia.

Hoje inspirado por este post pensei, se a apple tem direito de bloquear alguns conteudos pelos motivos que alegam, nós desenvolvedores temos exatamente o mesmo direito. O que proponho é que sites bastante acessados, sejam grandes blogs, sites de empresas… coloquem restriçoes, não permitindo que o site seja visualizado no iPhone OS. Como fazer isto? clique aqui

Assim, ou a Apple deixa de frescura, ou vão ter o que querem, conteudo exclusivo cheio de restriçoes.
A ideia é criar um site explicando direito a ideia, mas não vou ter tempo para fazer isso nessas proximas semanas, mas acho que ja da para ter uma ideia de como a coisa funciona.
Eu como desenvolvedor, e cliente da Apple estou muito desapontado, não compro mais produtos deles. Meu proximo note vai ser outro HP.
Sou contra a ideia de ir contra coisas que podem ser melhoradas.
Se alguem bloquear o conteudo do seu site para usuarios do iPhone OS, comente e deixe o link. (depois quero ver se faço uma contagem disso para incentivar mais desenvolvedores)
Até a Apple mudar de ideia tem que ser assim, eles acham que só por que são grandes e desenvolvem aparelhos bonitos podem sair mudando tudo.

Qualquer duvida, ou pelos comentarios, ou por email.

Mudanças…

0saves

Bom, como muitos devem ter percebido, faz tempo que não posto nada aqui no blog, as vezes por falta de assunto, tempo… Mas o motivo principal é a minha decepção com a programação, não sei se é pelas experiências que tive, mas toda aquela “mágica” que eu havia conhecido a 10 anos atrás já não existe mais para mim, é sempre a mesma coisa, pode parecer ser algo novo, porem a idéia é sempre a mesma, só que feito um pouco diferente (mas no fundo é a mesma coisa), e tirando os problemas em se trabalhar com terceiros em alguns projetos.
Até hoje o blog era unica e exclusivamente voltado a plataforma flash, não digo que não haverá mais posts relacionados a isso, de vez em quando ainda pode sair alguma coisa, mas em geral estou mudando o assunto do blog, e mudando bastante coisa tanto na minha vida (tanto profissional quando pessoal). Pretendo postar sobre assuntos diversos que eu achar interessante, sejam relacionado a engenharia elétrica ( que estou cursando na faculdade) , matemática (onde ainda vejo a tal da mágica) ou até coisas do meu dia-a-dia.
Acho que tenho que fazer o que eu gosto, e já não gosto mais de programar (pelo menos as coisas que eu programava antes, sejam sites, jogos…) ainda tem bastante coisa interessante para programar, mas por enquanto não vou mais programar comercialmente (só vou terminar os projetos nos quais ainda estou trabalhando), mesmo que a programação de um certo dinheiro (que muitas vezes é muito bom) isso não me deixa mais tão feliz, hoje prefiro algumas coisas que muitas vezes não me dão o mesmo retorno financeiro do que a programação (continuo gostando, e muito de dinheiro, porem ele só é util se der pra aproveitar ele), mas que por outro lado me deixem feliz enquanto eu estou fazendo isso, meu objetivo principal agora é me formar (mais uns 5 anos ainda) pois é algo que eu gosto, e que no futuro vai me trazer um bom retorno financeiro.

De Monster Debugger – como utilizar

0saves

Faz tempo que eu não posto nada, devido a falta de tempo , e de ideias sobre o que postar.
Hoje, resolvi postar sobre como utilizar o MonsterDebugger, o melhor debugger que eu ja vi para actionscript.

Primeiro, o que é esse MonsterDebugger ?
O MonsterDebugger ( http://demonsterdebugger.com/ ) é um debugger Open Source feito em AIR, que permite debugar aplicaçoes Actionscript (flash, flex, air …), não só dando trace, mas podendo editar as propriedades dos objetos em tempo real, e podendo executar os metodos dos objetos quando quiser. Alem de claro, dar trace nas coisas (se for algum array, xml, objeto … ele apresenta o conteudo em arvore, assim fica mais facil de debuggar).

Agora sim, vou mostrar como se usa ele.

1 – Instale o client:
Va em http://demonsterdebugger.com/ , pegue a versão mais recente do MonsterDebugger e instale ele no seu computador.

2 – Gere as classes necessarias:
Abra o client (instalado anteriormente) e va em File -> Export Client Class
Exportar Classe Cliente - MonsterDebugger

3 – Se quiser pode gerar um exemplo (File -> Export example), ou pode tentar usar direto sem o exemplo.

Como dar um simples Trace:

1
MonsterDebugger.trace(this, o_que_é_para_ir_no_trace)

Como ativar o live application:

1
2
var _debugger:MonsterDebugger;
_debugger = new MonsterDebugger(this);

A parte de utilizar o Client é bem intuitiva, caso alguem tenha duvidas de como utilizar, favor me avisar que eu coloco aqui detalhadamente como utilizar.

Lembrando que aceito sugestoes de posts, é só entrar em contato.

Conexão AS3 com python via socket (simplificado)

0saves

Algumas vezes me perguntei como fazer algumas coisas mais complexas em AIR de uma maneira rapida e segura, como por exemplo pegar informaçoes do usuario, conectar com um banco de dados (sem ser o nativo do AIR) como oracle,mssql… executar linha de comando, e outras coisas que só seriam possiveis utilizando alguma outra linguagem mais poderosa. Levando em conta que isto realmente era necessario para aumentar o “poder” do AIR e que o AMF fazia algo parecido, só que para a internet, resolvi criar uma classe em AS e uma função em Python que facilita a comunicação entre os dois (deixe o servidor python rodando de fundo e chame as funçoes dele :D )

Primeiro a classe Python.as que pode ser baixada aqui :

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
package
{
    import com.adobe.serialization.json.JSON;
    import flash.net.Socket;
   /**
     * Classe para conexao com python utilizando socket
     * @author    Armando Leopoldo Keller - (http://alkeller.wordpress.com) - alkeller@live.de
     */
    public class Python extends Socket
    {
        // TODO: Implementar um metodo de retorno, verificando o tipo do retorno, e passando como parametro na funcao associada
        /**
         * Cria um novo Socket
         * @param host    Host onde esta o socket
         * @param port    Porta que esta o socket
         * @see flash.net.Socket
         * @usage    var p:Python = new Python("10.1.1.23",2727);
         */
        public function Python(host:String=null, port:uint=0)        {
            super(host, port);
            host = null;
            port = 0;
        }
        /**
         * Chama uma funcao do python se o socket estiver conectado 
         * @param func    Nome da funcao a ser chamada no python
         * @param args    Argumentos a serem chamados no python
         * @usage p.call("teste",{um:1,dois:2,tres:3});
         * @usage p.call("teste");
         */
        public function call(func:String,args:Object=null):void
        {
            if(this.connected)
            {
                this.flush();
                var obj:Object = new Object();
                obj["funcao"] = func;
                for(var i:* in args)
                {
                    if(args[i] is String) args[i] = "'"+args[i]+"'";
                    obj[i]=args[i];
                }
                this.writeUTFBytes(JSON.encode(obj));
                obj = null;
            }
            else
                throw new Error("Voce deve estar conectado ao socket.")
            this.flush();
        }
    }
}

Depois é necessario a função em python que vai reconhecer o que está sendo chamado pelo flash, o arquivo pode ser baixado aqui :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import json;
def executar(objeto):
    __arr__ = [];
    __str__ = "";
    obj = json.loads(objeto);
    __str__ = str(obj["funcao"])+"(";
    obj.pop("funcao");
    if len(obj.keys()) >;= 1:
        for k in obj:
            __arr__.append(str(k)+"="+str(obj[k]));
        for x in xrange(len(__arr__)-1):
            __str__ = __str__+__arr__[x]+",";
        __str__ = __str__ +__arr__[len(__arr__)-1]+")";
    else:
        __str__ = __str__+")";
    return __str__;

Agora precisamos de um “servidor socket” rodando de fundo com as funçoes a serem chamadas, que pode ser baixado aqui :

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
import socket
import threading
import json
from JMF import executar
class ClientThread ( threading.Thread ):
    def __init__ ( self, channel, details ):
        self.channel = channel
        self.details = details
        threading.Thread.__init__ ( self );
    def run ( self ):
        print 'Conexao recebida: ', self.details [ 0 ]
        self.channel.send ( "resposta vinda do python" )
        for x in xrange ( 10 ):
            string = self.channel.recv ( 1024 )
            self.interpretaComando(string)
        self.channel.close();
        print 'Conexao fechada: ', self.details [ 0 ]
    def interpretaComando(self,string):
        eval("self."+executar(str(string)));
    def testar(self,arg1,arg2):
        print "Chamou testar: "+str(arg1)+","+str(arg2);
        self.channel.send("Chamou testar: "+str(arg1)+","+str(arg2));
    def pegaVariaveis(self):
        print "chamou pegaVariaveis"
        self.channel.send("chamou pegaVariaveis");
    def pegarArray(self):
        print "Chamou pegar Array";
        arr = ['a','b','c',1,2,3];
        txt = json.dumps(arr);
        self.channel.send(txt);
    def pegarObj(self):
        print "Chamou pegar Objeto";
        teste = {}
        teste["item1"]   =   "Primeiro item";
        teste["item2"]   =   "Segundo item";
        teste["numero"]  =   2;
        self.channel.send(json.dumps(teste));
# Inicia o servidor
server = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
server.bind ( ( socket.gethostbyname(socket.gethostname()), 2727 ) )
server.listen ( 5 )
print "Iniciando servidor..."
while True:
    channel, details = server.accept()
    ClientThread ( channel, details).start()

Pronto, agora só falta uma aplicação de exemplo chamando estas funçoes, que pode ser baixada aqui :

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?xml version="1.0" encoding="utf-8"?>;
<mx:WindowedApplication applicationComplete="iniciar()" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import com.adobe.serialization.json.JSON;
            private var py:Python
            [Bindable]
            public var texto:String = ""
            public function iniciar():void
            {
                py = new Python();
                py.addEventListener(ProgressEvent.SOCKET_DATA,onRecebe);
                py.addEventListener(Event.CONNECT,onConecta);
                py.addEventListener(IOErrorEvent.IO_ERROR,onErroIO);
                py.connect("10.1.1.3",2727);
            }
            public function onRecebe(e:ProgressEvent):void
            {
                var str:String = py.readUTFBytes(py.bytesAvailable);
                texto = str;
                py.flush();
            }
            public function onConecta(e:Event):void
            {
                trace("Conectou")
            }
            private function chamarTeste():void
            {
                if(py.connected)
                    py.call("testar",{arg1:"Argumento 1",arg2:"Argumento 2"})
                else
                    texto = "O socket esta desconectado";
            }
            private function chamarPegaVariaveis():void
            {
                if(py.connected)
                    py.call("pegaVariaveis")
                else
                    texto = "O socket esta desconectado"
            }
            private function pegarArray():void
            {
                if(py.connected)
                    py.call("pegarArray");
                else
                    texto = "O socket esta desconectado";
            }
            private function pegarObj():void
            {
                if(py.connected)
                    py.call("pegarObj");
                else
                    texto = "O socket esta desconectado";
            }
            private function matarServer():void
            {
                py.close();
                texto = "Desconectado"
            }
            public function onErroIO(e:IOErrorEvent):void
            {
                trace("Erro ao conectar com o socket");
            }
        ]]>
    </mx:Script>
    <mx:VBox>
        <mx:HBox>
            <mx:Button label = "Testar"         click = "chamarTeste()"         />
            <mx:Button label = "PegaVar"        click = "chamarPegaVariaveis()" />
            <mx:Button label = "pegarArray"     click = "pegarArray()"          />
            <mx:Button label = "pegarObj"       click = "pegarObj()"            />
            <mx:Button label = "Kill Server"    click = "matarServer()"         />
        </mx:HBox>
        <mx:Text text="{texto}" width="100%" height="115"/>
    </mx:VBox>
</mx:WindowedApplication>

Claro que esta aplicação ainda está bastante simples, mas o objetivo é demonstrar como pode ser facil conectar o AS3 com Python utilizando socket, para quem não conhece python, vale a pena dar uma estudada, é uma linguagem muito util, poderosa, e simples, que é utilizada em diversos lugares, alguns exemplos bons são nasa e google (precisa mais ? ), agora mistura isso com AS3 (tem algo MUITO funcional e bonito).

Explicação rapida

A sintaxe é muito parecida com a Tweener (classe de tween) que ja é bastante conhecida, então creio que não deve ter muita dificuldade para utilizar esta classe. Sendo que para chamar uma função do python é só chamar instancia.call(“nome_da_funcao”,{nome_do_argumento:valor_do_argumento…….});

Se alguem tiver alguma duvida, ou sugestão para esta classe ou para futuras classes, deixe um comentario ou envie por email mesmo.

A formatação dos codigos ainda não está boa, mas esta melhorando (plugin do Windows Live Writer) se alguem conhecer algum plugin para formatar codigos que tenha suporte a AS, Python, PHP,e C me avisa.

JSFL para converter png e jpg para swf (até 92% de compressão)

0saves

Aproveitando as ferias da faculdade e essa parada de final de ano para trazer mais um JSFL desta vez realmente util.

O que ele faz:

- Abre 3 janelas, a primeira para escolher em que pasta estão as imagens a serem convertidas, a segunda para ver onde vão ser salvos os swf , e a terceira para ver onde vão ser salvos os flas (essa pode ser cancelada caso não precise dos flas)

- Para cada imagem da pasta selecionada na primeira janela, ele vai criar um fla novo, importar a imagem, redimensionar o palco, colocar allowsmooth, e exportar o swf, se optou por salvar so flas, ele ira salvar o fla na pasta selecionada, caso contrario ira fechar o fla e ir para a proxima imagem.

Resultados:

- Com alguns testes que eu fiz nas ultimas semanas a compressão dos arquivos chegou até 92% (isso faz uma boa diferença em qualquer site).

- Está facil de usar, qualquer um consegue usar, pois o jsfl faz tudo praticamente sozinho.

O JSFL:

Salve o codigo a seguir em como um arquivo jsfl:

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
52
53
/*
* JSFL para converter imagens para swf
* Importa a imagem em um fla novo, e exporta o swf com a imagem. (redução de até 92% no "peso do arquivo")
* @author Armando Leopoldo Keller (alkeller@live.de)  http://alkeller.wordpress.com
*
* Quem utilizar esta classe, favor enviar um email para ALKELLER@LIVE.DE com o "peso" das imagens antes e depois de serem exportadas.
*
*/
 
var fotosURI = fl.browseForFolderURL("Armando Leopoldo Keller(alkeller@live.de)\n \nSelecione a pasta das imagens.\n ");
var swfsURI = fl.browseForFolderURL("Armando Leopoldo Keller(alkeller@live.de)\n \nSelecione a pasta dos swfs.\n ");
var flasURI = fl.browseForFolderURL("Armando Leopoldo Keller(alkeller@live.de)\n \nSelecione a pasta dos flas.\n ");
 
var fileMask1 = "*.png";
var fileMask2 = "*.jpg";
 
var list1 = FLfile.listFolder(fotosURI + "/" + fileMask1, "files");
var list2 = FLfile.listFolder(fotosURI + "/" + fileMask2, "files");
 
function converte(list)
{
	for(var i in list)
	{
		var doc = fl.createDocument();
		doc.importFile(fotosURI+"/"+list[i],true);
		var it = doc.library.items[0];
		it.quality = 80;
		it.allowSmoothing = true;
		doc.addItem({x:0,y:0},it);
		var selecionado = doc.getTimeline().layers[0].frames[0].elements[0];
		selecionado.x = 0;
		selecionado.y = 0;
		doc.width = parseInt(selecionado.width);
		doc.height = parseInt(selecionado.height);
		doc.frameRate = 1;
		if(flasURI)
		{
			fl.saveDocument(doc,(flasURI+'/')+list[i].split(".png").join("").split(".jpg").join("")+'.fla',false);
		}
		doc.exportSWF(swfsURI+'/'+list[i].split(".png").join("").split(".jpg").join("")+'.swf',true);
		doc.close(false);
	}
}
 
if(fotosURI && swfsURI)
{
	if(list1.length > 0)converte(list1); // png
	if(list2.length > 0)converte(list2); // jpg
}
else
{
	alert("Você deve selecionar todas as pastas.(a de .flas é opcional)")
}

Claro que ainda pode ser otimizado, assim que tiver mais tempo quero ver se otimizo ele.

Observaçoes importantes:

- Quando for converter pngs, exporte todos eles como interlaced (faça um batch no photoshop) assim ele não fica perguntando se quer importar como um bitmap flateado.

- Quem utilizar ele, favor mandar um email ou colocar aqui nos comentarios o tamanho dos arquivos convertidos antes e depois de converter (a soma de todos os arquivos) para motivos de estatistica e para ver se ainda tem como reduzir mais sem perder a qualidade da imagem.

Qualquer duvida é só colocar nos comentarios que eu respondo assim que tiver tempo.

BUG no flashplayer (votem para corrigirem)

0saves

Bom, como devem ter percebido o blog está meio abandonado já faz algum tempo, mas isso devido a falta de tempo, trabalho + faculdade = no time :P , agora nas ferias da faculdade vou ter mais tempo para escrever aqui.

Hoje quero pedir a ajuda de toso os desenvolvedores que estão lendo o blog, para votarem para a adobe corrigir este bug ( http://bugs.adobe.com/jira/browse/FP-501 ) , este bug é muito incomodo para a entrada de textos em flash (formularios), quando o wmode esta transparente é impossivel digitar caracteres como “ãéíúê”… e todos os outros caracteres que precisam de duas teclas para serem inseridos como por exemplo teclados que possuem a tecla ç conseguem inserir a mesma, ja teclados como os de notebooks que precisa digitar ‘ + c para inserir o ç não é possivel usar ç nos campos :P aqui tem um exemplo do bug acontecendo ( http://www.5etdemi.com/blog/archives/2005/06/firefox-wmodetransparent-is-completely-screwy-and-breaks-textfields/ ).

Quem encontrar outro bug no flashplayer ( mas que tenha certeza que é no flashplayer e não no seu codigo, e nem algo que foi alterado por questoes de segurança) por favor, verifique se o bug ja foi reportado, se foi reportado, comente e vote para que ele seja corrigido (isso agiliza o processo), caso contrario reporte ele.

Desde ja, obrigado a todos os que votarem, e provavelmente agora em dezembro eu volte a postar com mais frequencia.

Ideia dos proximos posts: Como usar o debuger, inserir flash no flex, inserir flex no flash, performance no AS3 …. Se alguem tiver mais alguma sugestão, avisa por email, ou por comentario.

JSFL para ajustar posiçoes dos itens como campos de texto com pixelFonts(pixel Snapping)

0saves

Olá, primeiramente quero dizer que não tenho postado muita coisa no blog devido a falta de tempo, e tambem de conteudo(até se alguem tiver alguma sugestão manda por email ou coloca aqui como comentario que eu farei o possivel para falar sobre o assunto).

Hoje a tarde depois de arrumar as posiçoes dezenas de movieClips para que não distorcessem eu pensei “por que eu estou fazendo isso? o flash poderia fazer sozinho”, então criei este JSFL que faz exatamente isto (link)

OBS: se o link não funcionar copie ele e cole no navegador;

Como utilizar: é só executar.

ele pega todos os itens(movieClip,Button,Graphic,TextField..) da timeline atual e ajusta as posiçoes dos mesmos.

para aplicar isto dentro de um movieClip , abra-o e execute o comando dentro do movie;

pra quem não conseguiu abrir o link aqui vai o codigo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Pixel Snapping [alk].jsfl
 
/*
Script criado por Armando Leopoldo Keller(http://alkeller.wordpress.com)
para instalar: só colar este arquivo em C:\Users\nome_do_usuario\AppData\Local\Adobe\Flash CS3\en\Configuration\Commands
obs: este é o caminho no windows vista
*/
for( var i = 0; i < fl.getDocumentDOM().getTimeline().layers.length; i++)
{
var layerAtual = fl.getDocumentDOM().getTimeline().layers[i];
for(var j = 0 ; j < layerAtual.frames.length ; j++)
{
var frameAtual = layerAtual.frames[j];
for(var k = 0 ; k < frameAtual.elements.length ; k++)
{
var elementoAtual = frameAtual.elements[k];
elementoAtual.x = parseInt(elementoAtual.x);
elementoAtual.y = parseInt(elementoAtual.y);
}
}
}

Qualquer coisa é só comentar, ou mandar email que eu respondo.