sábado, 25 de setembro de 2010

Promoção GM com RFID

No início do ano de 2010 começamos um projeto para a GM usando RFID para identificar os ganhadores de uma promoção de sorteio de carro por meio de uma gravata da GM (gravata = aquele simbolo da GM) que o consumidor recebia via revista e que depois foi entregue na rua, em semáforos pela cidade de São Paulo e outros locais.
Os leitores foram espalhados pelo Brasil afora.

Este é o Spot de TV da Promoção:



E aqui um pouco da produção:

Esta foto mostra o detalhe do carro e o local onde deveríamos aproximar a gravata para acionar o leitor RFID.

Esta foto mostra o painel inteiro.

Só por curiosidade (sei que alguns amigos vão gostar disso, né Sir Jorge!) ... é um ploter/router Zundy ... animal para cortar adesivo/materiais plásticos.

Aqui está a instalação do conjunto leitor por trás do painel.

Aqui uma visão mais ampla do painel.

Gravatas de teste que acompanhavam cada um dos equipamentos.

O pessoal embalando os painéis para seguir viagem até as concessionárias.

Mais uma vez o pessoal embalando tudo!

No final foi uma ação muito legal. Funcionou direitinho, fora a correria de produzir e conferir os equipamentos no tempo que foi necessário, tudo correu bem!

E vamos para o próximo trabalho. Depois vou colocar alguns detalhes do leitor de RFID utilizado para comunicar com as gravatas.

Enjoy!

sexta-feira, 10 de setembro de 2010

Arduino + .NET

É com imenso prazer que venho trazer pra vocês o NetDuíno!
Fantástico ... o sonho dourado de quem trabalha com .NET e também trabalha com microcontroladores...


Pessoalmente sempre achei o Arduino uma solução legal, mas com uso um pouco restrito na prática... sabe aquela coisa de achar legal, mas não usar por querer algo mais personalizado nos seus designs com MCUs.

Pensem bem nas vantagens:

- Ambiente único de desenvolvimento, tanto para MCUs quanto para Aplicações Desktop que podem inclusive comunicar-se com o NetDuíno!
- Não será necessário aprender novos conceitos de programação.
- É possível usar classes e orientação a objeto, o que traz uma certa flexibilidade de reaproveitamento de código!

Para quem quiser mais informações é só dar uma olhada no site http://netduino.com/.

Enjoy! ;-)

terça-feira, 31 de agosto de 2010

I2C BitBang Codigo Genérico

Pessoal,

Depois de muito penar com (PASMEM!) uma 24C02, eu decidi rever meu código de I2C e encontrei um problema que foi solucionado (com o auxilio do nosso amigo Arão, lá da Onipresente PICLIST!), nesta nova versão que apresento do meu código de I2C.
O problema básico é que não estava sendo resetando o BUS I2C a cada transação, o que as vezes ocasionava uma travada no BUS que só voltava após o reset do circuito.
Também notei (à duras penas!) que os Datasheets em sua maioria não falam sobre este Reset no BUS, o que confundiu um pouco. Mas vamos deixar e palavras e vamos ao código.

Primeiro um .C + .H para as 24C02:

- Inicio de 24C02.c ----------------------------------------------------------------------------
#include "sfr_r81b.h"
#include "24C02.h"

// ---------------------- Low Level Functions ---------------

void waitFactor(unsigned int factor) {
unsigned int fc=0;
factor*=waitUnit;
for(fc=0; fc<factor; fc++) asm("NOP");
}
unsigned char getSDAState(void) { _24C02_sda_d = 0; asm("NOP"); return(_24C02_sda); }
unsigned char getSCLState(void) { _24C02_scl_d = 0; asm("NOP"); return(_24C02_scl); }
void setSDAHigh(void) { _24C02_sda_d = 1; _24C02_sda = 1; }
void setSCLHigh(void) { _24C02_scl_d = 1; _24C02_scl = 1; }
void setSDALow(void) { _24C02_sda_d = 1; _24C02_sda = 0; }
void setSCLLow(void) { _24C02_scl_d = 1; _24C02_scl = 0; }
void clockToHigh(void) { setSCLHigh(); waitFactor(1); }
void clockToLow(void) { setSCLLow(); waitFactor(1); }
void clockPulse(void) { clockToHigh(); clockToLow(); }
void sendBit(unsigned char bit) {
if(bit) {
setSDAHigh();
} else {
setSDALow();
}
waitFactor(1);
setSCLHigh(); waitFactor(1);
setSCLLow();  waitFactor(1);
}
unsigned char resetBus (void) {
unsigned char sdaStatus;
clockToHigh();
sdaStatus=getSDAState();
clockToLow();
return(sdaStatus==0?BUSY:ONLINE);
}
void startCondition(void) {
setSDAHigh(); waitFactor(1);
setSCLHigh(); waitFactor(1);
setSDALow(); waitFactor(1);
setSCLLow(); waitFactor(1);
}
void stopCondition(void) {
setSDALow(); waitFactor(1);
setSCLHigh(); waitFactor(1);
setSDAHigh(); waitFactor(1);
setSCLHigh(); waitFactor(1);
}
void writeByte(unsigned char byte) {
unsigned char rotateLeft;
unsigned char tmp;
unsigned char toReturn;
rotateLeft = 0;
while(rotateLeft<8) {
tmp=byte;
tmp=(tmp << rotateLeft) >> 7;
rotateLeft++;
sendBit(tmp);
}
}
unsigned char readByte(void) {
unsigned char byte=0;
unsigned char pos=0;
_24C02_sda_d=0;
while(pos<8) {
clockToHigh();
byte|=getSDAState();
if(pos<7) byte<<=1;
pos++;
clockToLow();
}
return(byte);
}
unsigned char readAck (void) {
unsigned char sdaStatus;
clockToHigh();
sdaStatus=getSDAState();
clockToLow();
return(sdaStatus==0?OK:NOK);
}

// ---------------------- High Level Functions ---------------

void Write_24C02(unsigned char deviceAddress, unsigned char menAddress, unsigned char byte) {
unsigned char myAck=0;
reset_bus:
while(resetBus()==BUSY);
device_address:
startCondition();
writeByte(deviceAddress);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
men_address:
writeByte(menAddress);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
send_byte:
writeByte(byte);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
stopCondition();
}

unsigned char Read_24C02(unsigned char deviceAddress, unsigned char menAddress) {
unsigned char myAck=0;
unsigned char byte=0;
reset_bus:
while(resetBus()==BUSY);
device_address:
startCondition();
writeByte(deviceAddress);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
men_address:
writeByte(menAddress);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
restart_condition:
startCondition();
device_address_read:
writeByte(deviceAddress | 0x01);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
read_byte:
byte = readByte();
sendBit(1);
stopCondition();
return(byte);
}

- Final de 24C02.c ----------------------------------------------------------------------------

- Inicio de 24C02.h ----------------------------------------------------------------------------
#ifndef _24C02_H
#define _24C02_H

#define _24C02_sda_d pd3_4
#define _24C02_sda p3_4
#define _24C02_scl_d pd3_5
#define _24C02_scl p3_5

#define BUSY 0
#define ONLINE 1
#define OK 1
#define NOK 0

#define waitUnit 2

// ---------------------- High Level Functions ---------------

void Write_24C02(unsigned char deviceAddress, unsigned char menAddress, unsigned char byte);
unsigned char Read_24C02(unsigned char deviceAddress, unsigned char menAddress);

#endif
- Final de 24C02.h ----------------------------------------------------------------------------


E agora o mesmo para 24C256:

- Inicio de 24C256.c ----------------------------------------------------------------------------
#include "sfr_r81b.h"
#include "24C256.h"

// ---------------------- Low Level Functions ---------------
void waitFactor(unsigned int factor) {
unsigned int fc=0;
factor*=waitUnit;
for(fc=0; fc<factor; fc++) asm("NOP");
}
unsigned char getSDAState(void) { _24C256_sda_d = 0; asm("NOP"); return(_24C256_sda); }
unsigned char getSCLState(void) { _24C256_scl_d = 0; asm("NOP"); return(_24C256_scl); }
void setSDAHigh(void) { _24C256_sda_d = 1; _24C256_sda = 1; }
void setSCLHigh(void) { _24C256_scl_d = 1; _24C256_scl = 1; }
void setSDALow(void) { _24C256_sda_d = 1; _24C256_sda = 0; }
void setSCLLow(void) { _24C256_scl_d = 1; _24C256_scl = 0; }
void clockToHigh(void) { setSCLHigh(); waitFactor(1); }
void clockToLow(void) { setSCLLow(); waitFactor(1); }
void clockPulse(void) { clockToHigh(); clockToLow(); }
void sendBit(unsigned char bit) {
if(bit) {
setSDAHigh();
} else {
setSDALow();
}
waitFactor(1);
setSCLHigh(); waitFactor(1);
setSCLLow();  waitFactor(1);
}
unsigned char resetBus (void) {
unsigned char sdaStatus;
clockToHigh();
sdaStatus=getSDAState();
clockToLow();
return(sdaStatus==0?BUSY:ONLINE);
}
void startCondition(void) {
setSDAHigh(); waitFactor(1);
setSCLHigh(); waitFactor(1);
setSDALow(); waitFactor(1);
setSCLLow(); waitFactor(1);
}
void stopCondition(void) {
setSDALow(); waitFactor(1);
setSCLHigh(); waitFactor(1);
setSDAHigh(); waitFactor(1);
setSCLHigh(); waitFactor(1);
}
void writeByte(unsigned char byte) {
unsigned char rotateLeft;
unsigned char tmp;
unsigned char toReturn;
rotateLeft = 0;
while(rotateLeft<8) {
tmp=byte;
tmp=(tmp << rotateLeft) >> 7;
rotateLeft++;
sendBit(tmp);
}
}
unsigned char readByte(void) {
unsigned char byte=0;
unsigned char pos=0;
_24C256_sda_d=0;
while(pos<8) {
clockToHigh();
byte|=getSDAState();
if(pos<7) byte<<=1;
pos++;
clockToLow();
}
return(byte);
}
unsigned char readAck (void) {
unsigned char sdaStatus;
clockToHigh();
sdaStatus=getSDAState();
clockToLow();
return(sdaStatus==0?OK:NOK);
}

// ---------------------- High Level Functions ---------------
void Write_24C256(unsigned char deviceAddress, unsigned int menAddress, unsigned char byte) {
unsigned char myAck=0;
unsigned int tmsb,tlsb;
unsigned char msb, lsb;
tlsb = tmsb = menAddress;
tmsb = tmsb >> 8; 
tlsb = (tlsb << 8) >> 8;
msb = (unsigned char) tmsb; 
lsb = (unsigned char) tlsb;
reset_bus:
while(resetBus()==BUSY);
device_address:
startCondition();
writeByte(deviceAddress);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
men_address:
writeByte(msb);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
men_address1:
writeByte(lsb);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
send_byte:
writeByte(byte);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
stopCondition();
}

unsigned char Read_24C256(unsigned char deviceAddress, unsigned int menAddress) {
unsigned char myAck=0;
unsigned char byte=0;
unsigned int tmsb,tlsb;
unsigned char msb, lsb;
tlsb = tmsb = menAddress;
tmsb = tmsb >> 8; 
tlsb = (tlsb << 8) >> 8;
msb = (unsigned char) tmsb; 
lsb = (unsigned char) tlsb;
reset_bus:
while(resetBus()==BUSY);
device_address:
startCondition();
writeByte(deviceAddress);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
men_address:
writeByte(msb);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
men_address1:
writeByte(lsb);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
restart_condition:
startCondition();
device_address_read:
writeByte(deviceAddress | 0x01);
myAck=readAck();
if(myAck==NOK) goto reset_bus;
read_byte:
byte = readByte();
sendBit(1);
stopCondition();
return(byte);
}

- Final de 24C256.c ----------------------------------------------------------------------------

- Inicio de 24C256.h ----------------------------------------------------------------------------
#ifndef _24C256_H
#define _24C256_H

#define _24C256_sda_d pd3_4
#define _24C256_sda p3_4
#define _24C256_scl_d pd3_5
#define _24C256_scl p3_5

#define BUSY 0
#define ONLINE 1
#define OK 1
#define NOK 0

#define waitUnit  2

// ---------------------- High Level Functions ---------------

void Write_24C256(unsigned char deviceAddress, unsigned int menAddress, unsigned char byte);
unsigned char Read_24C256(unsigned char deviceAddress, unsigned int menAddress);

#endif
- Final de 24C256.h ----------------------------------------------------------------------------

Para utilizar os códigos é bem simples.

Basta incluir o arquivo equivalente no header do programa onde vai usar, obviamente colocar o arquivo .C no projeto para ser compilado, e chamar as funções do que se deseja fazer, ler ou gravar.

Exemplo:
#include "24C02.h"

// Protótipos
void main(void);

// Variáveis Globais
unsigned char i=0;
unsigned char carToWrite;
unsigned char car;
unsigned char paraGravar;
unsigned char inicio, final;
unsigned char sdaState;
// Ponto de Entrada
void main(void) {
carToWrite=0;
car=0;
for(;;) {
inicio=0;
final=255;
for(i=inicio;i
Write_24C02(0xA0, i, i);
car=0xFF;
car=Read_24C02(0xA0, i);
if(i!=car) {
asm("nop");
}
}
asm("nop");
}
}

Bom é isso ...

Espero que o código ajude... se precisarem de algo, tipo um projeto pronto e rodando para o R8C/1A por exemplo.. é só me avisar que eu posto um link de download aqui!

Enjoy!


domingo, 1 de agosto de 2010

Apple Lisa

Quando me deparei com este video nao pude deixar de posta-lo.... eh o principio de tudo que conhecemos hoje como informatica, interface homem-maquina ...



Enjoy!

domingo, 13 de junho de 2010

Moon, Beauty Moon

Quero inaugurar aqui um pouco do que venho conhecendo de novas tecnologias, aliás este sempre foi o intuito deste blog... vamos lá... neste final de semana após vários meses, resolvi dar uma olhada no Lua...

Lua é uma linguagem nacional, desenvolvida pelo pessoal da PUC-Rio... me pareceu bem legal, e como eu costumo sempre postar um programinha de exemplo no que mostro pro pessoal, vamos lá... dando um bypass no velho hello world, eu preferi algo um pouco mais efetivo, um programa que imprime a tabuada de um determinado número passado como parâmetro. Veja abaixo:


#!/usr/bin/lua
-- ****************************************************
-- * Tabuada
-- * O argumento de linha e o numero da tabuada que deseja imprimir
-- * Por: Pacman (Alexandre Pereira)
-- * Data: 13/06/2010 - (Um domingo Frio pra Kct!)
-- ****************************************************

numero = arg[1]
if numero == nil then
print("E necessario passar um numero como argumento para imprimir sua tabuada...")
else
print("Tabuada do numero " .. numero)
for multiplicador = 1,10 do
print(multiplicador * numero)
end
end

-- *******************************

Vamos comentar o programa linha por linha,

numero = arg[1]

Com isso pegamos o primeiro parametro da linha de comando;

if numero == nil the

Neste if, verificamos se foi passado o parametro por linha de comando;

Se não foi nós mostramos a seguinte mensagem:

print("E necessario passar um numero como argumento para imprimir sua tabuada...")

caso tenha sido passado o valor como parâmetro executamos as seguintes passos ...

Primeiro imprimimos uma mensagem para mostrar de qual numero a tabuada que está sendo impressa faz parte:

print("Tabuada do numero " .. numero)

em seguida executamos um laço for:

for multiplicador = 1,10 do 

Contando de 1 a 10, e colocando seu valor na variável multiplicador, em seguida imprimimos o valor de numero multiplicado pela variável multiplicador ...

print(multiplicador * numero)

...

Espero que gostem do post e que isso incentive vocês a estudarem mais esta interessante linguagem ...

Na sequencia, vou fazer o mesmo com Python, e posto aqui as impressões ...

Enjoy!

quarta-feira, 19 de maio de 2010

Trocando o o Bom e Velho Max232 por circuitos alternativos

Pessoal,

Posto esta preciosidade aqui mais como curiosidade e não como algo que eu recomende ... (e parafraseando meu amigo Cabelo lá da piclistbr no googlegroups) Alguém gritou lá no fundo: - Trocando o certo pelo duvidoso!

Mas vale a pena!

A origem destes circuitos está no onipresente e fantástico site eletronica.org... pra quem quiser conferir o Original, vai lá: http://www2.eletronica.org/hack-s-dicas/alternativas-de-baixo-custo-ao-max-232/

Bom... vamos aos intrépidos RS-232 Drivers:

Primeiro segue o já tradicional esquema com Max232 com o requinte dos leds de RX/TX:


O que as vezes incomoda neste tradicional circuito são os capacitores... mas já montei tantos que já faço de olho fechado praticamente!

PS: Daqui pra frente segue o texto original do artigo lá do eletronica.org!

O MAX 232 é um circuito integrado conversor de nível, que converte sinais TTL em RS232 e virse-versa. Ele fornece uma ótima rejeição de ruído e é mais robusto à descargas e curtos. Se o seu projeto for mais avançado, você deve utilizar um CI especializado para esta tarefa. No entanto, soluções especializadas são mais caras que as outras.

Este é um exemplo de circuito com transistor para executar a tarefa de conversão:
interface_schematic.gif
Os transistores podem ser todos de uso geral. Este circuito é muito simples e trabalha sem problemas. É a solução mais barata, pois requer apenas um par de transistor e quatro resistores. Os dois transistores executam um truque para ter a tensão negativa necessária por alguns PCs. Quando o PC não transmite dados, seu pino TX está com uma tensão negativa. A tensão negativa presente é então trazida através do resistor R3 ao pino RD (recepção) do PC.

Alternativamente, RS232 pode ser conseguido utilizando portas lógicas. Isto é acessível quando sua aplicação já está utilizando elementos lógicos e há portas sobreando em algum CI. Como alguns PCs trabalhar bem apenas com tensões positivas, tudo que nós precisamos é inverter a lógica do sinal e para isso utilizamos as portas lógicas. Por exemplo, utilizando o CI CMOS CD4066B:

interface_4066.gif
E, é claro, utilizando circuitos NAND e NOR:
interface_4001.gif
interface_4011.gif

E não se esqueça de alimentar os CI's com 5V.

Enjoy!

domingo, 2 de maio de 2010

Tablado Final do Chute em Gol

Pessoal,

Para comemorar o dia do trabalho! Fomos todos aqui do 5VCC trabalhar arduamente no tablado do chute em GOL! ;-)



Primeiro um ajuste na organização dos cabinhos dos sensores...



Um detalhe de como ficou tudo montado pelo lado de trás! Olha a placa da Renesas lá na ponta!



Agora um ajuste no recorte das gramas ao redor dos sensores para reduzir os falsos chutes por conta do reflexo da própria grama.



Aparência final do tablado!



Aparência final dos sensores no tablado!



Tablado já ligado na CPU.



Finalmente a recompensa! let's play!



Um pouco de descanso após o árduo trabalho de um sábado à tarde no escritório do papai...



Um pouquinho da organização do Papai! ahuahuauhahu



E no final para o nosso amigo do TabajaraLabs (Essa é pra vc taba!) ...

- "Esse ficou bão patrão!"

No final das contas, temos:

- Chute em Gol funcionando!
- Renderização das seqüencias de defesa no Maya;
- Software embarcado de controle dos sensores no R8C/1A da Renesas;
- Software no PC em C#.NET;

E mais 87 destes pra entregar até o início da Copa do Mundo!

Valeu aí pessoal que acompanhou o desenvolvimento desde o início!

quinta-feira, 15 de abril de 2010

GPS LEA-5H e GSM LEON-G200 da uBlox

Pintou um projeto aqui e tive a necessidade de usar um módulo GPS juntamente com um módulo GSM ...
Por padrão sempre usei módulos GSM da Cinterion (Antiga Siemens) e sempre me antenderam muito bem! no entanto conversando com o pessoal da Smartcore (vai lá http://www.smartcore.com.br/ ) me apresentaram uma solução muito interessante que até então não havia testado... os equipamentos da Austríaca uBlox!
A minha percepção inicial, avaliando através de um StarterKit deles foi F A N T Á S T I C A !
O GSM me pareceu muito estável. Com comandos AT comuns compatível na maioria com o que existe no mercado para SMS, GPRS e CSD ... e o mais legal ... uma interface onde você liga o GPS via SPI/I2C com o GSM e via comandos AT recupera posições do GPS ... em outras palavras.. com um MCU de uma uart só dá pra comunicar com os dois aparelhos simultaneamente!
Segue algumas fotos do starter kit:


Esta é a maleta onde vem o KIT...

A maleta aberta, tá... eu já tinha tirado tudo de dentre então não vale muito...

Um CD com o Software dos Drivers (FTDI + Softwares para verificar funcionamento do GPS!)

Esta é a placa do KIT... vemos menor logo acima o LEA e abaixo um pouco maior o LEON, um chip da vivo inserido do SIMCARD HOLDER, uma barra de pinos. E eu liguei ela no PC via USB ...
Notem que temos duas saídas USB, uma delas para acesso ao GSM e outra para o GPS... sendo que se ligarmos via GSM, temos acesso via comandos AT ao GPS...

Detalhe (desfocado) do LEON, e logo acima o LEA ... ao lado do LEON a barra de pinos para prototipagem ...

Um overview da placa só pra ver um pouco mais de detalhes ...

E aqui o software uCenter da uBlox, acessando o GPS, mostrando o SkyView em primeiro plano e ao lado outros parâmetros que o GPS retorna! MUITO LEGAL!

A sensibilidade da antena que vem com o KIT em conjunto com o GPS é muito boa... sincronizando e encontrando satélites, e já triangulando em ambiente sem visada, por volta de 9 minutos... e em ambientes com visada praticamente instantêneo! ou cerca de 30 segundos a 3 minutos dependendo do tempo que o GPS ficou desligado!

O próximo trabalho agora é ligar os módulos via interface num R8C e começar a pegar os dados... quando acontecer, já coloco um post novo por aqui!

Enjoy!

sábado, 3 de abril de 2010

Apresentação do R8C/2B no DevMonkey















O site DevMonkey mostra muitas coisas legais, vários kits e ferramentas interessantes. Não poderia deixar de mostrar o que tem de melhor dos Renesas é claro!

Este link mostra um vídeo desmonstrando o RSK (Renesas Starter Kit) do R8C/2B

http://www.developmentmonkey.com/videos/index.php?bcpid=1358313811&bclid=1358639275&bctid=1453516465

Nice JoB Guys! ;-)

Enjoy!