Controlador de Reles Utilizando A Porta Universal Serial Bus - Usb
Controlador de Reles Utilizando A Porta Universal Serial Bus - Usb
Controlador de Reles Utilizando A Porta Universal Serial Bus - Usb
BELÉM
2006
UNIVERSIDADE DA AMAZÔNIA – UNAMA
CCET – CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS
BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO
BELÉM
2006
UNIVERSIDADE DA AMAZÔNIA - UNAMA
CCET – CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS
BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO
Banca Examinadora:
_______________________________________
_______________________________________
_______________________________________
BELÉM
2006
Dedico este projeto a Deus e a meus pais, que me
deram força e coragem para enfrentar as dificuldades
e fraquezas por quais passei.
Chico Science
RESUMO
possível fornecer (ou cortar) corrente a um dispositivo elétrico qualquer, como exemplo uma
executada, é necessário um chipset (FT232BM) que interprete os sinais gerados pelo software
The present work describes the development of a controlling relays system, using the
universal serial bus - USB, where through a microcomputer application it is possible give (or
cut) current to some electric device, for example a 12 V lamp, through a relay. So that this
communication through this bus it is necessary a chipset (FT232BM) to interprets the signals
generated by software and it give command strings to a microcontroller (PIC 16F877) that
will make the verification of relay’s status to set or not the present electric device.
1 INTRODUÇÃO............................................................................................. 15
2.3.1.1 Endpoints........................................................................................................ 24
2.3.1.2 Pipes................................................................................................................ 24
2.3.1.2.1 Stream.............................................................................................................. 25
2.3.1.3 Descritores....................................................................................................... 26
3 CHIPSET FT232BM..................................................................................... 29
POWERED..................................................................................................... 35
4.2 PINAGEM………………………………………………………………….. 38
CONTROLADOR DE RELÉS....................................................................... 46
7 CONCLUSÃO............................................................................................... 61
8 REFERÊNCIAS BIBLIOGRÁFICAS....................................................... 62
1. INTRODUÇÃO
elétrico, com intuito de cortar ou fornecer corrente elétrica a um dispositivo por meio de um
relé, utilizando uma porta USB convencional de um microcomputador. Para que o objetivo
seja atingido, foi necessário desenvolver um software em C/C++ que utiliza bibliotecas da dll
FTD2xx, os quais possuem suas próprias funções descritas no site do fabricante do chipset
utilizado para comunicação USB, no caso deste projeto, o chipset FT232BM. O chip após
PIC 16F877, que por sua vez enviará a um driver que deve ativar ou não o fornecimento de
chegando podendo até utilizar tecnologia sem fio, controlando todo ou parte de uma
O barramento USB é o dispositivo de hardware que será usado para interligar a placa
controladora de relés à CPU, que portará um software gerenciador de “estados” nos atuadores
interligados à placa.
barramento USB estará em destaque. Este tipo de tecnologia está presente em muitos
players, impressoras, webcams, entre outros. É possível até se dizer que é algo indispensável
para técnicos, programadores e webdesigners, já que sem seus pendrivers seria muito
armazenamento de dados.
A tecnologia de Universal Serial Bus chega a substituir outras tecnologias com menor
que ser conectado à CPU, em seqüência instalar o driver através de um software de instalação
Operacional) e instalado sem maiores preocupações e com desempenho muito maior que os
A popularidade do barramento USB também à sua velocidade: USB versão 1.1 (low-
speed) varia entre 1,5 Mbits/s e 12 Mbits/s e USB versão 2.0 (high-speed) alcança até 480
Mbits/s, velocidade esta trinta vezes superior ao barramento paralelo, o qual funciona à 16
Mbits/s na sua forma ECP (Enhanced Capabilities Port) e à 80 Mbits/s na sua forma IEEE
1284 (ECP + EPP – Enhanced Parallel Port). Se comparado ao barramento serial que funciona
no máximo a velocidade de 115 Mbits/s, a versão USB 4.0 é quatro vezes mais veloz.
fêmea e um tipo macho, conforme a ilustração da Figura 1. Os conectores do tipo macho são
aqueles encontrados numa das extremidades de um cabo USB e devem ser conectados ao
um Hub (dispositivo que tem como finalidade aumentar o número de portas). Os conectores
tipo fêmea são os localizados na Root Hub e nas portas downstream de um Hub, onde
Os conectores da série ”B” têm um formato quadrado com um achatado nas pontas
Figura 1. Os conectores tipo macho são aqueles encontrados em uma das extremidades de um
cabo USB e devem ser conectados a um dispositivo. Os conectores do tipo fêmea são aqueles
encontrados em dispositivos como impressoras, scanners, máquinas digitais, entre outros onde
recebem o conector tipo “B” macho. Os conectores, tanto da série “A” quanto da série “B”,
séries diferentes.
Figura 1: Tipagem do cabo USB.
receptor da série “A”, encontrado no Root Hub (Host) e na Downstream do Hub, como dito
anteriormente, recebe uma identificação nos pinos, identificando-os por números, começando
conector macho da mesma séria recebe uma identificação também numérica, porém
identificação por números em seus pinos, que começa da direita para esquerda na parte
Figura 2: Conector fêmea série “A”. Figura 3: Conector macho série “A”.
Figura 4: Conector fêmea série “B”. Figura 5: Conector macho série “B”.
Assim, o cabo USB possui 4 fios, haja vista que dois são para transferência de dados e
os restantes para transporte de energia. O fio Vbus (cor vermelha) possui 5 V, sendo o fio
positivo, enquanto que GND (cor preta) possui 0 V, fechando o circuito de corrente com o
Vbus. Os fios D+ (cor verde) e D- (cor branca) são responsáveis pela transferência de dados
usando a codificação NRZI - No Return to Zero Inverted. Eles estarão entrelaçados, com o
dispositivos. Este resistor estará ligado ao sinal D+ ou D-, havendo uma tensão circulando
entre eles definindo se funcionará em alta ou baixa velocidade, e caso não haja tensão no
resistor pull-up por mais de 2,5 microssegundos o controlador Host interpretará a desconexão
do dispositivo, assim como este tempo é necessário para a detecção. É por meio desse sistema
O dispositivo USB pode trabalhar com duas formas de interface: Bus-powered e Self-
O computador fornece a cada porta a corrente de 500 mA, igualmente a um hub que
possua fonte própria de energia. Hubs que não possuem fonte própria recebem do Root Hub
(porta USB encontrado no computador) 500 mA, que serão distribuídos em suas portas,
alimentado pelo próprio Host do computador, ou mesmo por uma porta Downstream de Hub.
Esses dispositivos são geralmente configurados para receber 100 mA, já que poderão ser
alimentados por Downstream com apenas essa quantidade de corrente. Em casos onde um
dispositivo Bus-powered consuma mais de 100 mA, seu funcionamento só ocorrerá caso o
dispositivo esteja ligado no computador ou em Hub com fonte de energia. Dispositivos Bus-
powered tem suas vantagens e desvantagens. Como vantagens citamos: a praticidade de seu
pendrivers e Mp3 players são dispositivos que possuem uma interface Bus-powered. A figura
fornecida pela porta onde esteja conectado. Scanners, impressoras e alguns modelos de Hubs
Paralela ou Serial, que utiliza sinais elétricos através de seus pinos. Na comunicação USB o
específico, como o PIC ou em um chipset. Neste será utilizado um microcontrolador PIC, que
hexadecimal, e será utilizado um chipset FT232BM da FTDI, que já possui em seu interior
Através do protocolo, é possível se ter quatro tipos de transferências USB, que são:
dispositivo.
constante.
tipo de transferência.
o dispositivo através do envio de pacotes. A comunicação se inicia pelo pacote Token, gerado
pelo Host, com intuito de descrever o que virá no próximo pacote, e se é uma escrita ou
leitura; seguido do próximo pacote, o Data, que possui todos os dados que serão lidos ou
escritos e finalizando com o pacote Handshake, que informa se houve falha ou sucesso na
enviando informações a serem armazenadas nos Endpoints. Esta comunicação possui alguns
Endpoints estão localizados no dispositivo, como uma área de memória reservada para
armazenar dados e informações que trafegam nos Pipes, sendo que um dispositivo USB pode
ter no máximo 16 Endpoints na versão 2.0 do USB. É também através do Endpoint que o Host
comandos de controle de baixa velocidade, pelo Host, que obtém informações como: o
número de série, fabricante, classe, subclasse, versão do Bus USB, tipo de protocolo, número
Pipes não são visíveis, nem físicos, e podem ser comparados como uma via de
momento em que um dispositivo USB for conectado no computador. Sendo que, antes do
dispositivo ser configurado pelo Host, haverá um Pipe de controle (Control Default) que
Este Pipe possui uma via de comunicação unidirecional, sendo que o Endpoint pode
ser do tipo Interrupção, Isossíncrono ou Bulk. Se o dispositivo com o Pipe Stream precisar
transferir de forma bidirecional um dos tipos de Endpoint, o sistema USB estabelecerá dois
canais de Pipes, sendo o primeiro definido com o Endpoint de saída (Out) e o segundo
Este Pipe possui um via de comunicação bidirecional, sendo que o Endpoint será do
tipo Controle. Essa via possui dois Endpoints, um de entrada (In) e outro de saída (Out) e
possui uma estrutura definida de dados. Este Pipe é usado pelo Endpoint 0 para obter
2.3.1.3 – Descritores
Dispositivo. As informações cedidas pelo dispositivo são muito importantes para o Host, pois
através delas, o Host poderá saber a versão do USB que o dispositivo suporta.
do produto.
Endpoint 0 é assumido pelo sistema com um endpoint de controle, e será configurado antes
que qualquer descritor. Este descritor possui informações sobre o número de Endpoints,
2 Dispositivos de comunicação.
barras, etc.
7 Impressoras
flash, ATAPI.
9 Hub.
10 Interface de dados.
11 Chip/Smart card.
Tabela 1: Descritores
O projeto controlador de relés através da porta USB com o uso da freqüência de rádio
seguirá uma seqüência de seis passos para sua perfeita execução. Esse passos são:
1 – Aplicação cliente desenvolvida em C++ na máquina teste chamada rotina da API,
2 – A API por sua vez faz a chamada do software básico do fabricante do dispositivo
USB, mais conhecido como o driver do cliente. Este driver geralmente acompanha o produto
USB que foi adquirido, como no caso da compra de uma impressora ou de um scanner, porém
neste caso o driver será instalado e configurado no sistema operacional conforme o capítulo
anterior;
3 – Este driver terá a função de fazer com que o sistema operacional garanta o suporte
USB, fazendo com que ele interprete e traduza os comandos do driver e envie-os para o
Host (HCD) – fornecido pelo fabricante da placa – trabalhar diretamente com o controlador
Host;
USB – seu chipset e controlador host – que serão enviados para o HCD que por sua vez
O chipset FT232BM da FTDI – Future Technology Devices Ltd. será o chip usado no
configuração do mesmo e a comunicação com o Bus USB, visto que o FT232BM já possui o
protocolo USB.
O chip possui uma velocidade de até 3Mbps através de sinais TTL: RS422 e RS485 e
Host USB versões 1.1 e 2.0. Possui suporte a uma memória externa EEPROM, que pode ser
usada opcionalmente para armazenar descritores para personalizar o produto (dispositivo).
Esta memória pode ser programada pela própria placa via USB.
Tensão de alimentação entre 4,35V a 5,25V com suporte para alimentar dispositivos
diretamente no Bus USB através do pino PWREN#. Regulador integrado de 3.3V para
entrada/saída USB. Um chip manipula tanto transferências USB como Serial, além de ser
Na Figura 13 pode-se obter uma visão geral em blocos do chipset FT323BM. Em sua
possui uma célula reguladora de tensão que fornece 3.3v no pino 3v3OUT; uma célula USB
transeiver que trata diretamente os sinais D+ e D- através do cabo; o USB DPL que trata a
codificação NRZI; um multiplicador de sinal clock; uma interface Serial avançada (SIE); a
UART que disponibiliza os dados seriais para comunicação externa (RS232/RS422/RS485);
uma célula para controle dos Buffers FIFO; o USB Protocol Engine, que trata a pilha de
EEPROM serial (SPI), com 64 palavras de 16 bits de largura, podendo armazenar 1024 bits.
Esta memória tem como função personalizar a placa criada, armazenando o nome do
fabricante, número de série, versão, vendedor e outras especificações. No caso desta memória
placa assumirão valores da própria fabricante do chip, FTDI. As figuras e a tabela mostrada
abaixo descreverão a pinagem e descrição da memória 93C46, e sua conexão com o chipset.
Pino Descrição
CS Chip Select (Seleção do chip)
14-PWRCTL deve ser levado a nível baixo (0 V). A ferrite é ligada em série 1-Vbus (+5 V do
Bus USB) para eliminar ruídos que possam afetar o bom funcionamento do dispositivo.
Figura 17: Configuração da interface Bus-Powered.
14-PWRCTL deve ser levado a nível alto (+5 V). Nesta interface será preciso dois resistores,
o dispositivo está com os relés acionados ou não de forma a suspender ou fornecer energia ao
pinos de I/O. Possui 8k de memória de programa FLASH com 8192 palavras de 14 bits, 368
bytes de memória RAM e memória EEPROM com 256 bytes. Sua freqüência de operação
5,5V.
4.2 – PINAGEM
A pinagem do PIC 16F877 é formada por 40 pinos, sendo que a maioria possui mais
de uma função, que pode ser verificado na figura 20. Como exemplo pode-se ver o pino 10
que tem as funções de entrada/saída digital (RE2) ou de selecionar um chip SPI (CS) ou a
função de um canal A/D (AN7). Os pinos (RA0 a RA5) estão associados a porta ‘A’, (RE0,
RE1, RE2) associados a porta ‘E’, (RC0 a RC7) a porta ‘C’, (RD0 a RD7) a porta ‘D’ e os
pinos (RB0 a RB7) associados ao porta ‘B’. Cada um desses pinos pode ser usado como
sua pinagem. Possui um modulo lógico e de controle, módulos de memória RAM e ROM,
outros periféricos.
No PIC, os pinos de I/O podem ser configurados tanto com entradas ou saídas, em um
único pino. Essa configuração é feita através de sua programação em C, que será mostrado
porta que será configurada e Y o parâmetro que será enviado a função configurando quais
portas serão de entrada e quais serão de saída. O parâmetro deve seguir o padrão obZZZZZZZ,
onde Z será definido por 1 ou 0, haja visto que 1 para entrada e 0 para saída seguindo a ordem
nos pinos da direita para esquerda. Como exemplo, a configuração da porta D, onde o pino
RD7 e RD1 estivessem que ser configurados para entrada e o resto dos pinos para saída,
registradores do microcontrolador. Mas isso não significa que apenas ela pode ser usada na
programas, e por este motivo a utilização do Assembler era obrigatória, já que finalizaria em
quantidade maior de memória, deixando assim a programação mais produtiva, segura e com
utilizada em projetos onde o hardware necessita de toda a velocidade que ele dispõe para
Neste projeto, o PIC 16F877 irá receber uma “string” do chipset e fará a sua devida
validação através de uma comparação. Caso seja válida ele irá executar uma ação que
//Controle de Relés
//TCC – UNAMA
//Rodrigo Tavares Condurú e Karla Luciana M. Freitas
//-------------------------------------------------------------------------------------------------------
#include <16F877.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#use delay(clock=4000000)
#define MAX_BUFFER 15
char BufferRX[MAX_BUFFER+1];
boolean CHEGOU_COMANDO = false;
//--------------------------------------------------------------------------
//Interrupção de recebimento de caracter pela UART.
//---------------------------------------------------------------------------
#int_rda
void Serial_Recebe_Car()
{
static unsigned char ch;
static int IndexBuf=0;
ch = getc(); //Pega o caracter no registrador da UART.
}
//--------------------------------------------------------------
//Para fazer o LED piscar.
#int_timer0
void MeuTimer()
{
static boolean led;
static int conta;
set_timer0(131-get_timer0());
conta++;
if(conta == 125)
{
conta=0;
led = !led;
output_bit(pin_d1, led); //pisca o LED1
}
}
//--------------------------------------------------------------
//Programa Principal.
void main(void)
{
char COMANDO[15];
set_timer0(131);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_64);
enable_interrupts(int_rda); //Habilita interrupção de recebimento.
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL); //Habilita registrador de interrupção.
set_tris_d(0b00000000); //Todos os pinos da porta D como saídas.
set_tris_b(0b00000000); //Todos os pinos da porta B como saídas.
output_b(0b00000000); //Desliga todos os pinos da porta B.
while( true ) //Loop infinito.
{
if(CHEGOU_COMANDO == true)
{
CHEGOU_COMANDO = false;
strcpy(COMANDO,">CMD#01#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b0); //Liga Relé 1.
printf("Relê #1 LIGADO\r\n");
continue; //volta para o início do loop while().
}
strcpy(COMANDO,">CMD#01#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b0); //Desliga Relé 1.
printf("Relê #1 DESLIGADO\r\n");
continue;
}
//--------------------------------------------------------------
strcpy(COMANDO,">CMD#02#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b1); //Liga LED.
printf("Relê #2 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#02#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b1); //Desliga LED.
printf("Relê #2 DESLIGADO\r\n");
continue;
}
//--------------------------------------------------------------
strcpy(COMANDO,">CMD#03#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b2); //Liga LED.
printf("Relê #3 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#03#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b2); //Desliga LED.
printf("Relê #3 DESLIGADO\r\n");
continue;
}
//--------------------------------------------------------------
strcpy(COMANDO,">CMD#04#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b3); //Liga LED.
printf("Relê #4 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#04#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b3); //Desliga LED.
printf("Relê #4 DESLIGADO\r\n");
continue;
}
//--------------------------------------------------------------
strcpy(COMANDO,">CMD#05#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b4); //Liga LED.
printf("Relê #5 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#05#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b4); //Desliga LED.
printf("Relê #5 DESLIGADO\r\n");
continue;
}
//--------------------------------------------------------------
strcpy(COMANDO,">CMD#06#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b5); //Liga LED.
printf("Relê #6 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#06#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b5); //Desliga LED.
printf("Relê #6 DESLIGADO\r\n");
continue;
}
//--------------------------------------------------------------
strcpy(COMANDO,">CMD#07#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b6); //Liga LED.
printf("Relê #7 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#07#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b6); //Desliga LED.
printf("Relê #7 DESLIGADO\r\n");
continue;
}
//--------------------------------------------------------------
strcpy(COMANDO,">CMD#08#ON*");
if( strcmp(BufferRX,COMANDO) == 0)
{
output_high(pin_b7); //Liga LED.
printf("Relê #8 LIGADO\r\n");
continue;
}
strcpy(COMANDO,">CMD#08#OFF*");
if(strcmp(BufferRX,COMANDO) == 0)
{
output_low(pin_b7); //Desliga LED.
printf("Relê #8 DESLIGADO\r\n");
continue;
}
//--------------------------------------------------------------
}
}
}
//--------------------------------------------------------------
cabeçalho FTD2XX.h, que deverão ser adicionados a biblioteca do programa utilizado para a
FTD2xx, outras terão que ser entendidas para o funcionamento do aplicativo em questão.
Primeiramente existem duas variáveis que serão utilizadas em qualquer função da dll da
FTDI, elas são: FT_STATUS, variável responsável pelo status geral do dispositivo conectado,
e assim entrando com outras funções que retornaram o valor FT_OK no caso de sucesso em
que deve ser usado pelas funções, para ter acesso ao dispositivo. Em suas funções utilizadas
computador e retorna um identificador (handle) para ser usado na maioria as funções, precisa
de dois parâmetros para sua execução, que na seqüência seria um inteiro para dizer qual
dispositivo será aberto, iniciando no 0 para o primeiro dispositivo e seguindo essa seqüência e
função que seta os timeouts de leitura e escrita do dispositivo, possui três parâmetros, em
buffer a ser feito a limpeza (FT_PURGE_RX e/ou FT_PURGE_TX); FT_Close(), função que
FT_Write(), função responsável por escrever dados para um dispositivo, possui quatro
que obtém o número de bytes escritos no dispositivo; FT_Read(), função responsável pela
leitura dos dados para um dispositivo, possui quatro parâmetros que tem funcionalidade igual
ao FT_Warite(), só que para leitura. Todas essas funções descritas acima retornam um
CONTROLADOR DE RELÉS
O código para o software em questão foi contruido no C++ Builder possuindo apenas
uma tela de controle, sendo possível abrir e fechar a USB e ligar e desligar os relés ligados no
dispositivo, mostrando uma tela de status. Haja visto que sua codificação e funções estão
//---------------------------------------------------------------------------
//CURSO USB/Serial
//Liga/Desliga 8 Relês através do CI USB FT232BM e PIC16F877.
//LOOP: Usando Thead.
//---------------------------------------------------------------------------
#include <vcl.h>
#include <stdio.h>
#pragma hdrstop
#include "ftd2xx.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PERFGRAP"
#pragma resource "*.dfm"
//Variáveis globais.
TForm1 *Form1;
TMultLinha *MultLinha; //Classe Thread. declarada em Unit1.h
boolean CONECTADO=false;
FT_HANDLE ftHandle;
FT_STATUS ftStatus;
char RxBuffer[100];
char AuxBuffer[100];
void Status(String Comando);
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//------------------------------------------------------------------------------
__fastcall TMultLinha::TMultLinha(bool CreateSuspended) : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonAbrirClick(TObject *Sender)
{
ftStatus = FT_Open(0, &ftHandle); //Abre USB DEV0.
FT_SetDataCharacteristics(ftHandle,FT_BITS_8,FT_STOP_BITS_1,FT_PARITY_NONE);
FT_SetBaudRate(ftHandle,FT_BAUD_9600); //Define velocidade bps.
FT_SetTimeouts(ftHandle,1,0);
ButtonAbrir->Enabled = false;
ButtonFechar->Enabled = true;
Memo1->Enabled = true;
SpeedRele1->Enabled = true;
SpeedRele2->Enabled = true;
SpeedRele3->Enabled = true;
SpeedRele4->Enabled = true;
SpeedRele5->Enabled = true;
SpeedRele6->Enabled = true;
SpeedRele7->Enabled = true;
SpeedRele8->Enabled = true;
MultLinha->Resume(); //Inicia processo.
CONECTADO = true;
FT_Purge(ftHandle,FT_PURGE_RX | FT_PURGE_TX); //Limpa os buffers TX e RX do
dispositivo.
}else{
ShowMessage("Erro ao abrir o dispositivo USB (DEV0).");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonFecharClick(TObject *Sender)
{
if(ftStatus == FT_OK) //Se USB DEV0 está aberto.
{
FT_Close(ftHandle);
ButtonFechar->Enabled = false;
ButtonAbrir->Enabled = true;
Memo1->Enabled = false;
SpeedRele1->Enabled = false;
SpeedRele2->Enabled = false;
SpeedRele3->Enabled = false;
SpeedRele4->Enabled = false;
SpeedRele5->Enabled = false;
SpeedRele6->Enabled = false;
SpeedRele7->Enabled = false;
SpeedRele8->Enabled = false;
}else{
ShowMessage("Erro ao fechar dispositivo USB (DEV0).");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedRele1Click(TObject *Sender)
{
ULONG TamaDados;
ULONG BytesEscritos=0;
char *StrON=">CMD#01#ON*";
char *StrOFF=">CMD#01#OFF*";
if(SpeedRele1->Down)
{
TamaDados = strlen(StrON);
ftStatus = FT_Write(ftHandle,StrON,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enniar dados.");
}
}
if(!SpeedRele1->Down)
{
TamaDados = strlen(StrOFF);
ftStatus = FT_Write(ftHandle,StrOFF,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedRele2Click(TObject *Sender)
{
ULONG TamaDados;
ULONG BytesEscritos=0;
char *StrON=">CMD#02#ON*";
char *StrOFF=">CMD#02#OFF*";
if(SpeedRele2->Down)
{
TamaDados = strlen(StrON);
ftStatus = FT_Write(ftHandle,StrON,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
if(!SpeedRele2->Down)
{
TamaDados = strlen(StrOFF);
ftStatus = FT_Write(ftHandle,StrOFF,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedRele3Click(TObject *Sender)
{
ULONG TamaDados;
ULONG BytesEscritos=0;
char *StrON=">CMD#03#ON*";
char *StrOFF=">CMD#03#OFF*";
if(SpeedRele3->Down)
{
TamaDados = strlen(StrON);
ftStatus = FT_Write(ftHandle,StrON,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
if(!SpeedRele3->Down)
{
TamaDados = strlen(StrOFF);
ftStatus = FT_Write(ftHandle,StrOFF,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedRele4Click(TObject *Sender)
{
ULONG TamaDados;
ULONG BytesEscritos=0;
char *StrON=">CMD#04#ON*";
char *StrOFF=">CMD#04#OFF*";
if(SpeedRele4->Down)
{
TamaDados = strlen(StrON);
ftStatus = FT_Write(ftHandle,StrON,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
if(!SpeedRele4->Down)
{
TamaDados = strlen(StrOFF);
ftStatus = FT_Write(ftHandle,StrOFF,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedRele5Click(TObject *Sender)
{
ULONG TamaDados;
ULONG BytesEscritos=0;
char *StrON=">CMD#05#ON*";
char *StrOFF=">CMD#05#OFF*";
if(SpeedRele5->Down)
{
TamaDados = strlen(StrON);
ftStatus = FT_Write(ftHandle,StrON,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
if(!SpeedRele5->Down)
{
TamaDados = strlen(StrOFF);
ftStatus = FT_Write(ftHandle,StrOFF,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedRele6Click(TObject *Sender)
{
ULONG TamaDados;
ULONG BytesEscritos=0;
char *StrON=">CMD#06#ON*";
char *StrOFF=">CMD#06#OFF*";
if(SpeedRele6->Down)
{
TamaDados = strlen(StrON);
ftStatus = FT_Write(ftHandle,StrON,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
if(!SpeedRele6->Down)
{
TamaDados = strlen(StrOFF);
ftStatus = FT_Write(ftHandle,StrOFF,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedRele7Click(TObject *Sender)
{
ULONG TamaDados;
ULONG BytesEscritos=0;
char *StrON=">CMD#07#ON*";
char *StrOFF=">CMD#07#OFF*";
if(SpeedRele7->Down)
{
TamaDados = strlen(StrON);
ftStatus = FT_Write(ftHandle,StrON,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
if(!SpeedRele7->Down)
{
TamaDados = strlen(StrOFF);
ftStatus = FT_Write(ftHandle,StrOFF,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedRele8Click(TObject *Sender)
{
ULONG TamaDados;
ULONG BytesEscritos=0;
char *StrON=">CMD#08#ON*";
char *StrOFF=">CMD#08#OFF*";
if(SpeedRele8->Down)
{
TamaDados = strlen(StrON);
ftStatus = FT_Write(ftHandle,StrON,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
else
{
TamaDados = strlen(StrOFF);
ftStatus = FT_Write(ftHandle,StrOFF,TamaDados,&BytesEscritos);
if(ftStatus != FT_OK)
{
ShowMessage("Erro ao tentar enviar os dados.");
}
}
}
//---------------------------------------------------------------------------
void Status(String Comando)
{
if(Comando == "Relê #1 LIGADO\r\n")
{
Form1->ShapeRele1->Brush->Color = clLime;
Form1->SpeedRele1->Font->Color = clBlack;
Form1->SpeedRele1->Caption = "Relê #1 LIGADO";
}else
if(Comando == "Relê #1 DESLIGADO\r\n")
{
Form1->ShapeRele1->Brush->Color = clGreen;
Form1->SpeedRele1->Font->Color = clWhite;
Form1->SpeedRele1->Caption = "Relê #1 DESLIGADO";
}else
if(Comando == "Relê #2 LIGADO\r\n")
{
Form1->ShapeRele2->Brush->Color = clLime;
Form1->SpeedRele2->Font->Color = clBlack;
Form1->SpeedRele2->Caption = "Relê #2 LIGADO";
}else
if(Comando == "Relê #2 DESLIGADO\r\n")
{
Form1->ShapeRele2->Brush->Color = clGreen;
Form1->SpeedRele2->Font->Color = clWhite;
Form1->SpeedRele2->Caption = "Relê #2 DESLIGADO";
}else
if(Comando == "Relê #3 LIGADO\r\n")
{
Form1->ShapeRele3->Brush->Color = clLime;
Form1->SpeedRele3->Font->Color = clBlack;
Form1->SpeedRele3->Caption = "Relê #3 LIGADO";
}else
if(Comando == "Relê #3 DESLIGADO\r\n")
{
Form1->ShapeRele3->Brush->Color = clGreen;
Form1->SpeedRele3->Font->Color = clWhite;
Form1->SpeedRele3->Caption = "Relê #3 DESLIGADO";
}else
if(Comando == "Relê #4 LIGADO\r\n")
{
Form1->ShapeRele4->Brush->Color = clLime;
Form1->SpeedRele4->Font->Color = clBlack;
Form1->SpeedRele4->Caption = "Relê #4 LIGADO";
}else
if(Comando == "Relê #4 DESLIGADO\r\n")
{
Form1->ShapeRele4->Brush->Color = clGreen;
Form1->SpeedRele4->Font->Color = clWhite;
Form1->SpeedRele4->Caption = "Relê #4 DESLIGADO";
}else
if(Comando == "Relê #5 LIGADO\r\n")
{
Form1->ShapeRele5->Brush->Color = clLime;
Form1->SpeedRele5->Font->Color = clBlack;
Form1->SpeedRele5->Caption = "Relê #5 LIGADO";
}else
if(Comando == "Relê #5 DESLIGADO\r\n")
{
Form1->ShapeRele5->Brush->Color = clGreen;
Form1->SpeedRele5->Font->Color = clWhite;
Form1->SpeedRele5->Caption = "Relê #5 DESLIGADO";
}else
if(Comando == "Relê #6 LIGADO\r\n")
{
Form1->ShapeRele6->Brush->Color = clLime;
Form1->SpeedRele6->Font->Color = clBlack;
Form1->SpeedRele6->Caption = "Relê #6 LIGADO";
}else
if(Comando == "Relê #6 DESLIGADO\r\n")
{
Form1->ShapeRele6->Brush->Color = clGreen;
Form1->SpeedRele6->Font->Color = clWhite;
Form1->SpeedRele6->Caption = "Relê #6 DESLIGADO";
}else
if(Comando == "Relê #7 LIGADO\r\n")
{
Form1->ShapeRele7->Brush->Color = clLime;
Form1->SpeedRele7->Font->Color = clBlack;
Form1->SpeedRele7->Caption = "Relê #7 LIGADO";
}else
if(Comando == "Relê #7 DESLIGADO\r\n")
{
Form1->ShapeRele7->Brush->Color = clGreen;
Form1->SpeedRele7->Font->Color = clWhite;
Form1->SpeedRele7->Caption = "Relê #7 DESLIGADO";
}else
if(Comando == "Relê #8 LIGADO\r\n")
{
Form1->ShapeRele8->Brush->Color = clLime;
Form1->SpeedRele8->Font->Color = clBlack;
Form1->SpeedRele8->Caption = "Relê #8 LIGADO";
}else
if(Comando == "Relê #8 DESLIGADO\r\n")
{
Form1->ShapeRele8->Brush->Color = clGreen;
Form1->SpeedRele8->Font->Color = clWhite;
Form1->SpeedRele8->Caption = "Relê #8 DESLIGADO";
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Memo1->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonSairClick(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
MultLinha = new TMultLinha(true); //Aloca memória para o objeto.
MultLinha->Priority = tpNormal; //Define a prioridade.
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
MultLinha = NULL;
delete MultLinha;
//Somente se TMultLinha for false "new TMultLinha(false);"
//MultLinha->Terminate();
//MultLinha->WaitFor();
if(CONECTADO)
FT_Close(ftHandle);
}
void __fastcall TMultLinha::MostraString(void)
{
Form1->Caption = AuxBuffer;
}
//---------------------------------------------------------------------------
void __fastcall TMultLinha::Execute()
{
static DWORD BytesRecebidos;
static String StrComandos;
static unsigned int cont=0;
FreeOnTerminate = true; //O objeto é destruído automaticamente quando a Thead terminar.
while(!Terminated) //loop infinito. Vida do programa.
{
if(CONECTADO == true) //Se está conectado.
{
ftStatus = FT_Read(ftHandle,RxBuffer,100,&BytesRecebidos);
if(ftStatus == FT_OK)
{
cont=0;
if(BytesRecebidos > 0)
{
RxBuffer[BytesRecebidos] = '\0'; //Finaliza string.
StrComandos += RxBuffer;
Os arquivos dll para a comunicação com o BUS USB estão disponíveis, como dito nos
capítulos anteriores, no site da FTDI no link Drivers. Lá podem ser encontrados drivers
D2XX para várias versões do Windows e outros sistemas operacionais, no caso o Microsoft
arquivos próprios para serem adicionados nas bibliotecas de programação e outros para
instalação do dispositivo.
Figura 22: Arquivos necessários para instalação do dispositivo.
no host USB do computador, que neste caso será reconhecido pelo sistema operacional. Em
pasta onde o arquivo baixado foi descompactado. Com isso o dispositivo esta pronto para ser
utilizado.
Neste capítulo não será explanado a programação em si, e sim como fazê-la. Sendo
microcontrolador). Para essa tarefa, foi utilizado o CSS C Compiler, versão Trial Evaluation.
IDE versão 7.21, que por meio da porta serial e do arquivo antes compilado pelo CCS, faz a
gravação no PIC 16F877. O programa também disponibiliza uma opção para verificar se o
programa foi gravado corretamente ou mesmo apagá-lo para inserir novos códigos.
Para a montagem do dispositivo e de seu circuito, foi encomendada uma placa com o
chipset FT232BM juntamente com o receptor USB da série “B”, que esta ligada a um
microcontrolador PIC 16F877 onde fará a comparação de strings para ligar e desligar o pino
que esta ligado ao driver ULN 2803. Este driver possui oito entradas TTL e oito saídas que
podem controlar até 45V/500mA. Neste projeto será utilizada uma fonte de 12v controlando
relés de 12v, no caso, apenas um. Este relé consome em média 50mA, o que da para ligar
mais sete outros relés, o que daria 400mA de consumo, sobrando ainda 100mA de folga para
o ULN 2803.
Figura 24: Chipset FT232BM juntamente com um receptor USB série “B”
as especificações da figura 25. Em seu teste, ligando apenas um circuito de controle de relé na
entrada RL1 do ULN 2803, sendo este o dispositivo relé de 12 V, foi possível pelo software
ligar e desligar o dispositivo, apesar de que a garantia do PIC esta em apenas desligar e ligar
um pino corretamente, mas não garantindo se realmente o relé foi desligado ou ligado.