sexta-feira, 11 de fevereiro de 2011

Transformando uma Caixa de HD Externo em DiskCase para MSX

Fudebas, nerds e indecisos... este é meu primeiro POST de 2011... e quero fazer algo diferente ... já que resolvi virar criança novamente e botar as mãozinhas em máquinas japonesas (calma gente , computadores, não pensem besteira!) ... eu resolvi colocar no ar um pouco do trabalho para preparar meu MSX 1.1 (Expert Gradiente) ...
Comprei uma interface e um drive de 3.5"para poder fazer meu pequeno MSX conversar com o mundo lá fora ... e deu certo ... vejam o processo de preparação do Case ...

Aqui as partes do case, observem o frame metálico com a fonte, e a frente com a tampa em formato 5.25" ...

Aqui um close no frame metálico... notem o led indicador de alimentação da fonte, um LUXO!


Aqui o drive de 3.5"que vamos colocar no frame metálico...


Aproveitando os postes metálicos do HD que tinha no lugar, encaixei o drive no frame. Como a furação deste tipo de periférico é padrão, facilitou muito a minha vida... Agora só falta a frente e as conexões elétricas...


Detalhe do drive encaixado por cima ...


Detalhe lateral do drive encaixado, notem os postes metálicos (Dourados) que sustentam o drive na posição...


Com a Dremel (tá uma cópia de Dremel), fiz o corte para passar a cabeça do Disk Drive ... esse ficou bao patrão, pra não falar que ficou "meio porco" (nada contra os Palmeirenses ok?) ... sem contar que fazer isso as 23:00 Hs ... numa quinta-feira em um prédio residencial pode render uma bela multa condominial... manzzz me tranquei no quartinho da bagunça e mandei bala... o resultado do corte é esse aí ó!


Mais um detalhe do corte ...


Para a ligação elétrica eu peguei um conector para drive de 3.5" de uma fonte de PC... foi só soldar os fios ligando as cores (duhhhhh) e fazer um acabamento com fita isolante... usei uma auto-fusão da 3M para que no futuro não fique com o adesivo melado (eu odeio isso!) ...


Mais um detalhe de ligação elétrica ...


Agora um detalhe com a tampa da frente encaixada... notem o logotipo do fabricante do case no lado direito... também foi devidamente retirado depois desta foto ... encaixamos o cabo do drive (vou fazer outro POST sobre a preparação do mesmo depois!) ... ligamos o mesmo na interface... eu estou usando uma interface da DDX versão 3.0 (valeu Paulo Maluf!) ...


E está aí o conjunto ligado com a indicação da versão do DiskBasic do cartucho DDX ...


Drive Fechado com o disquete sen introduzido (UI!) no drive ... olhem como ficou o aspecto geral da montagem... eu achei muito positivo! Só o MSX que tá lanhado e precisa de um TAPA... motivo pra outro POST!...


Detalhe do case ligado com o drive e disquete inserido!


Agora exibindo o diretório do disco ...


Carregando o programinha de teste ...


Rodando o programa de teste ...


CTRL-STOP ... Listagem do programa ... Salvando o programa com outro nome e exibindo o diretório do disco ...


Rodando o programa e capturando uma imagem em alta pra fazer um fundo de tela FUDEBA pro meu Windows....


Aqui... formatando um disquete...


Bom pessoal é isso ... grande abraço a todos e daqui há pouco tem mais MSX na parada !!!

Grande abraço do Pacman! e da turmo do 5vcc pra todo mundo! Feliz 2011

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!