Você está na página 1de 51

UNIVERSIDADE FEDERAL DE GOIÁS

ESCOLA DE ENGENHARIA ELÉTRICA

CONTROLE DE UM ROBÔ AUTÔNOMO VIA


WEB E RÁDIO ENLACE

Rafael José Cantero


Ronaldo Peixoto

Orientador: Prof. José Wilson Lima Nerys, Ph.D.


2

SUMÁRIO

INTRODUÇÃO....................................................................................................................04
DESENVOLVIMENTO......................................................................................................05
Códigos em Bloco ........................................................................................................05
Largura de Hamming ...................................................................................................05
Distância Hamming......................................................................................................05
Códigos Cíclicos...........................................................................................................06
Mensagens CRC (Códigos de Redundância Cíclica)...................................................07
Escolha de um Polinômio.............................................................................................08
Erros de Bit Simples............................................................................................08
Erros de Dois Bits (Erros Duplos).......................................................................09
Erros com um Número Impar de Bits..................................................................09
Erros em Rajada...................................................................................................09
Vantagens das Técnicas CRC para as Técnicas de Somatório Simples.......................10
Algoritmos para calculo de CRC..................................................................................10
Algoritmos de Tabela de Busca...........................................................................12
Algoritmo padrão de Tabela de Busca.................................................................12
Algoritmo reduzido de Tabela de Busca..............................................................13
Estratégias de Correção de Erro...................................................................................14
Implementação.............................................................................................................15
Justificativas........................................................................................................17
MySQL.........................................................................................................................24
Instalação e Implementação................................................................................25
PHP...............................................................................................................................26
Instalação e Implementação................................................................................26
Apache...........................................................................................................................31
Instalação e Configuração...................................................................................31
CONCLUSÃO......................................................................................................................33
REFERÊNCIAS...................................................................................................................34
APÊNDICE..........................................................................................................................35
3

RESUMO

Durante a transmissão de pacotes de mensagens de um robô autônomo para um


centro de controle e vice-versa, é normal surgirem erros, em grande parte, devido à
atenuação ou distorção do sinal, além de interferências e ruídos na linha de transmissão.
Para evitar o recebimento de mensagens com erros, é normal o uso de técnicas
para detecção e correção de erros.
Após o recebimento dos pacotes de mensagens, é sempre interessante que haja
um modo de armazenar e distribuir as informações recebidas para que estas possam ser
monitoradas à distância. Neste trabalho, procurou-se discutir e implementar formas para
detecção e correção de erros introduzidos em um canal de comunicação de rádio enlace por
um robô autônomo, além da implementação de uma forma de armazenar e distribuir as
informações obtidas.
A técnica discutida e utilizada para detecção e correção de erros é a CRC
(Cyclic Redundancy Check) devido às inúmeras vantagens que serão relatadas neste
trabalho e para a implementação do mesmo, utilizou-se da ferramenta Delphi.
Para disponibilizar as informações obtidas, optou-se por usar um Banco de
Dados servidor MySQL e o Apache como servidor de HTTP (Hiper Text Transfer
Protocol), fazendo uso da linguagem PHP para a implementação de páginas dinâmicas.
Este trabalho não tem por finalidade aprofundar exaustivamente as técnicas de
detecção e correção de erros, assim como as técnicas de armazenamento e distribuição de
informações. Contudo, fornece uma discussão de algumas das técnicas mais usadas, além
de exemplificar através de algoritmos e programas as técnicas escolhidas, facilitando,
assim, trabalhos futuros.
4

ABSTRACT

During the transmition of a autonomus robot`s message pakage for a control


center and vice versa, is normal erros appear, in the most, because of the attenuation or
signal distortion as well as noise of transmission line.
To prevent the act of receiving of messages with errors, is normal the use of
techniques for detection and correction of erros.
After the act of receiving of the packages of messages, is always interesting that
has a way to store and to distribute the received information os that these can be monitored
long-distance.
In this approach, it was looked to discuss and to implement forms for detection
and correction of erros introduced in a communication channel of radio enlace for an
autonomus robot, beyond the implementation of a form of storing and distributing the
gotten information.
The discussed technique and used for detection and correction of errors is the

CRC (Cyclic Redundancy Check) because of the innumerable advantages that will be told

in this work and for the implementation, was used the Delphi tool.

To arrange the gotten information, it was opted to use the Data Base Server
MySQL and the Apache for HTTP (Hiper Text Transfer Protocol) Server, making use of
the PHP language to build dynamics pages.
This approach doesn’ t have for purpose, exhaustingly deepen the techniques of
detection and correction of erros, as well as the techniques of storage and distribution of
information. However, it supplies a quarrel of some of the techniques most used, besides
examplification through algorithms and programs the shosen techniques, facilitating
futures approaches.
5

1 – Introdução

Para um canal de transmissão por rádio enlace, é necessária a utilização de


técnicas de controle de fluxo e controle de erro para que erros de transmissão sejam
evitados.
Mensagens de correção de erro promovem uma maneira de detectar e corrigir
erros introduzidos em um canal de transmissão. Duas categorias principais de mensagens
existem: mensagens de bloco e mensagens convolucionais. Ambas introduzem redundância
pela adição de símbolos de paridade na mensagem de dados.
As mensagens de checagem de redundância cíclica são um subconjunto das
mensagens cíclicas que são, por suas vez, subconjunto das mensagens de bloco.
Implementações CRC podem ser implementadas por hardware ou software. Em
uma implementação tradicional de hardware, há um simples circuito registrador de
deslocamento que permite a computação através da manipulação de um bit de dado por
vez. Na implementação em software, manipulações de dados como bytes ou words se
tornam mais convenientes e rápidas. Escolhe-se um algoritmo particular dependendo da
quantidade de memória e velocidade requeridos. Diferentes tipos de algoritmos e
resultados serão apresentados neste trabalho.
Após a recepção destes pacotes de mensagens, algumas vezes é necessário a
disponibilização dos mesmos para que várias pessoas tenham a possibilidade de acessá-los.
Uma das maneiras mais utilizadas é o uso de um servidor HTTP (Hiper Text Transfer
Protocol) e um banco de dados servidor para disponibilizá-las para que possam ser
acessadas por outros computadores conectados a uma rede.
6

02- Desenvolvimento

Códigos em Bloco

Uma mensagem em bloco consiste de um conjunto de vetores de largura fixa


chamados pacotes de mensagem. A largura de um pacote de mensagem é o número de
elementos do vetor, denominado por n. Os elementos de um pacote de mensagem são
selecionados de um alfabeto de q elementos.
Existem 2n possíveis pacotes de mensagem em uma mensagem de bloco binário
de largura n. Desses 2n pacotes de mensagem, podem ser selecionados M = 2k pacotes de
mensagem (k < n) para formar uma mensagem. Logo, um bloco de k bits de informação é
mapeado em um pacote de mensagem de largura n, selecionado de um conjunto de M = 2k
pacotes de mensagem. Isto é definido como uma mensagem (n,k) e a relação k/n é definida
como sendo a taxa da mensagem.

Largura de Hamming

A largura Hamming de um vetor X = (x1, x2,...,xn), definida por w(X), é o


número de componentes não-zero de X. Cada componente xi é um elemento de GF(q) e o
vetor X é chamado de word .

Distância Hamming

A distância Hamming entre dois vetores X e Y, definida por d(X,Y), é a largura


Hamming de X – Y. É igual ao número de posições no qual os dois vetores se diferem. Ela
é dada por:
d(X,Y) = w(X – Y) = w(Y – X)
7

A distância mínima, geralmente chamada de dmin de um código C, é a menor


distância entre todos os pares de palavras de código, ou seja, a menor distância de
Hamming.
É necessário e suficiente que a distância (dmin) de um código seja no mínimo d
para detectar qualquer erro padrão de largura d – 1 ou menor.
Um código C pode detectar e corrigir todos os padrões de erros t ou menores
se, e somente se, o código possuir distância ≥ 2t + 1.

Códigos Cíclicos

Códigos cíclicos são uma importante classe dos códigos lineares. Estes códigos
possuem uma estrutura algébrica muito interessante que é bem adequada para
implementação e construção de muitas subclasses de códigos. Existem códigos cíclicos
eficientes para detecção/correção de múltiplos erros randômicos, erros de byte e erros em
rajada. Esses códigos podem ser implementados eficientemente por circuitos de
registradores de deslocamento de realimentação linear (LFSR) para codificação e
decodificação serial.
Um código linear C é dito código cíclico se, para qualquer vetor de código u =
(u0, ..., u n-1 ) ∈ C, o vetor u` = ( u n-1 , u0 , ..., u n-2 ) obtido pelo deslocamento dos
componentes para a direita ciclicamente é também um vetor de código em C.
Um deslocamento cíclico para a direita de n do vetor (u0, ..., u n-1 ) é ( u n-1 , u0 ,
..., u n-2 ) o qual é denotado por u(1). Mas genericamente denotamos um deslocamento
cíclico para a direita de i posições de u ou u(x) por ui ou ui(x).
Por esta definição, qualquer deslocamento cíclico por j posições para esquerda
(ou direita) de um vetor de código será também um vetor de código.
Para rotações cíclicas o coeficiente que deveria ser de xn é, ao invés disso,
usado como o coeficiente de x0 = 1. Portanto, a rotação cíclica à direita difere do produto
com x por um múltiplo de xn – 1. Este fato é apresentado formalmente pelo seguinte
teorema:

Teorema: A rotação cíclica à direita de u(x) é u(1)(x) = x u(x)mod(xn – 1).

Prova: u(1)(x) = u n-1 + u0x + u1x + ... + u n-2xn-1


8

u n-1 + u0x + u1x + ... + u n-2xn-1 + un-1xn - un-1xn


xu(x) - u n-1(xn – 1) = x u(x)mod(xn – 1)

A maior parte dos pacotes em uso atual é cíclica ou relacionada a pacotes


cíclicos. Estes pacotes são melhores descritos se os vetores forem interpretados como
polinômios. E em um pacote cíclico, todos os polinômios de pacote de mensagens são
múltiplos de um polinômio gerador g(x) de grau n – k. Este polinômio deve ser um divisor
de xn – 1, logo, uma mudança cíclica de um vetor de pacote nos rende outro vetor de
pacote. Um polinômio de mensagem mi(x) pode ser mapeado por um polinômio de pacote
ci(x) = mi(x)xn-k – ri(x) (i = 0,1,...,2k – 1), em que ri(x) é o resto da divisão de mi(x)xn-k por
g(x).
Para a codificação de mensagens, o primeiro passo é determinar se o pacote
recebido é múltiplo de g(x). Isto é feito dividindo o pacote recebido por g(x) e examinando
o resto. Cada divisão polinomial é uma operação linear, a síndrome s(x) resultante depende
somente do padrão de erro. Se s(x) for um polinômio todo zero, a transmissão não possui
erros ou um erro indetectável ocorreu. Se s(x) for não-zero, no mínimo um erro ocorreu.
Este é o principio do CRC. A mais poderosa tentativa de corrigir erros é usar a síndrome
para determinar os locais e valores de múltiplos erros.

Mensagens CRC (Códigos de Redundância Cíclica)

Mensagens CRC são um subconjunto das mensagens cíclicas e usam um


alfabeto binário de 0 e 1. A aritmética é baseada em GF(2) (Galois Field), por exemplo,
adição em módulo-2 (XOR lógico) e multiplicação em módulo-2 (AND lógico).
Assume-se a convenção de que o bit mais significativo representa o grau de
maior ordem do polinômio. Suponha m(x) o polinômio de mensagem, c(x) o polinômio de
pacote e g(x) o polinômio gerador, temos que c(x) = m(x)g(x) que pode ser sempre escrito
usando uma forma sistemática c(x) = m(x)xn-k + r(x), onde r(x) é o remanescente da
divisão de m(x)xn-k por g(x) e r(x) representa os bits CRC. A mensagem transmitida c(x)
contem k bits de informação e n – k bits de CRC, por exemplo, c(x) = mk-1xn-1 + .... +
m0xn-k + rn-k-1xn-k-1 + r0. Multiplicando m(x) por xn-k, estamos adicionando n – k bits na
mensagem, calculando os bits CRC pela divisão de m(x)xn-k por g(x), e adicionando os n –
k bits de CRC na mensagem.
9

Para a parte de decodificação, o mesmo algoritmo pode ser usado. Se c’(x)


for a mensagem recebida, então nenhum erro ocorreu ou erros indetectáveis ocorreram se
c’(x) é um múltiplo de g(x), que é equivalente a determinar que se c’(x)xn-k é múltiplo de
g(x), se for, o remanescente da divisão de c’(x)xn-k por g(x) é 0 (zero). A figura 01
exemplifica essa situação.

Figura 01 – Geração e checagem de mensagens CRC

Escolha de um Polinômio

A performance de uma mensagem CRC é dependente de seu polinômio


gerador. Para podermos escolher um polinômio eficaz, devemos antes estudar os possíveis
padrões de erros que estamos querendo detectar e como detecta-los.

Erros de Bit Simples

Um erro de bit simples é do tipo E = 1000...000. Podemos assegurar que


esta classe de erro é sempre detectada garantindo que o polinômio gerador ( g(x) ) possui
no mínimo dois bits iguais a 1. Qualquer polinômio múltiplo de g(x) será criado por
10

adições e deslocamentos e é impossível criar um valor com um simples bit por


deslocamentos e adições de um valor com mais de um bit igual a 1.

Erros de Dois Bits (Erros Duplos)

Para detectar todos os erros da forma 100...000100...000, devemos escolher


um g(x) que não seja múltiplo de 11, 101, 1001, 10001, 100001, etc. Ou seja, todos os
erros duplos serão detectados se g(x) não dividir “xk + 1” para qualquer “k”, até o valor
máximo do tamanho do quadro.

Erros com um Número Impar de Bits

Podemos detectar todos os erros que consistem em um número impar de bits


tornando “x + 1” um fator de g(x), pois não existe nenhum polinômio com número impar
de termos que tenha “x + 1” como fator no sistema modulo 2.

Erros em Rajada

Um erro em rajada é do tipo E=000...000111...1110000....00. Ou seja,


consiste de zeros com exceção de uma linha de 1s em algum lugar. Esse tipo de erro pode
ser reescrito como E = (1000...00)(11111...111) onde existem z zeros na parte a esquerda e
n uns na parte direita. Para detectar erros desse tipo, devemos escolher um g(x) com o bit
menos significativo igual a 1.
Os polinômios mais usados atualmente, buscando a detecção dos padrões de
erros vistos, são mostrados na Tabela 01.

Mensagem CRC polinômio Gerador


CRC-CCITT (x25) x16 + x12 + x5 + 1
CRC-32 (Ethernet) x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 +
x8 + x7 + x5 + x4 + x2 + x + 1
GSM TCH/FS-HS-EFS (Channel coding for x3 + x + 1
speech traffic channels)
11

GSM TCH/EFS pre-coding (Preliminary x8 + x4 + x3 + x2 + 1


channel coding for Enhanced Full Rate)
GSM control channels – FIRE cod (Channel x40 + x26 + x23 + x17 + x3 + 1
coding for control channels)

Tabela 01 – CRC comumente usados e polinômios Geradores associados

Vantagens das Técnicas CRC para as Técnicas de Somatório Simples

A geração do CRC possui várias vantagens sobre as técnicas de somatório


ou checagem de paridade. A correção de erros CRC pode detectar:

1. Erros de bit simples;


2. Erros de bits duplos;
3. Erros de bits em rajada (bits próximos).

Uma checagem de bit de paridade detecta apenas erros de bits simples. A


correção de erros CRC e mais usada onde grandes pacotes de dados são transmitidos, por
exemplo, em locais com redes de computadores como a Ethernet.

Algoritmos para calculo de CRC

O algoritmo “bitwise” (CRCB) é simplesmente uma implementação de


software sobre o que pode ser feito em hardware usando registrador de deslocamento de
realimentação linear (LFSR). A figura 02 ilustra uma implementação de hardware
genérica. Este registrador de deslocamento é controlado por um clock. A cada pulso de
clock, o dado de entrada é rotacionado no registrador em adição para transmissão do dado.
Quando todos os bits de entrada tiverem sido processados, o registrador de deslocamento
irá conter os bits de CRC, que serão entregues na linha de dados.
12

Figura 02. Geração de CRC usando registrador de deslocamento de


realimentação linear (LFSR)

Assuma agora que os bits de checagem são armazenados em um registrador


referido como um registrador CRC, uma implementação em software poderia ser:

1. CRC ← 0
2. Desloque a mensagem para a esquerda de W bits (Mensagem XOR W)
3. Enquanto (mais bits da mensagem) faça passos 4 e 5
4. Desloque o CRC para a esquerda por um bit, adicionando o próximo bit da
mensagem no bit menos significativo
5. Se (um bit “pulou” do registrador durante o passo 4) então
CRC ← CRC XOR Polinômio

Implementações mais rápidas podem ser atingidas pela utilização de dados de


unidades mais largas que bits, desde que o tamanho não exceda o grau do polinômio
gerador. No entanto um ganho de velocidade corresponde a um aumento de memória, pois
valores pré-calculados (tabelas de procura) serão usados.
13

Algoritmos de Tabela de Busca

Um pacote de mensagem pode ser escrito como c(x) = xn-km(x) + r(x) =


a(x)g(x) + r(x), onde r(x) é o polinômio CRC da mensagem de entrada m(x). Vamos
aumentar a mensagem por α bits. Nos consequentemente temos m’(x) = xαc(x) + b(x),
onde b(x) = bα-1xa-1 + ... + b0 é o novo pacote de α bits adicionado. O CRC da mensagem
adicionada é o remanescente de xn-km’(x) dividido por g(x), chamado por r’(x). Temos que
r’(x) = Rg(x)xn-km’(x). Expandindo o dividendo iremos obter:

xn-km’(x) = xn-kxαc(x) + b(x) = xn-kb(x) + xαa(x)g(x) + xαr(x), então:


r’(x) = Rg(x) xn-kb(x) + xαr(x). Expandindo o resultado, teremos
r’(x) = Rg(x)(bα-1 + rn-k-1) xn-k-1+α + ... + (b0 + rn-k-α) xn-k + rn-k-α-1 xn-k-1 + ...
+r0xα

A ultima equação relata os bits de checagem para uma mensagem acrescida


de bits de checagem da mensagem original. Note que se n – k = α, então:

r’(x) = Rg(x)(bα-1 + rn-k-1) xn-k-1+α + ... + (b0 + rn-k-α) xn-k

Diferentes algoritmos de calculo de CRC devem ser vistos como métodos


para calcular r’(x) de r(x) e b(x). Valores práticos de α são 8 ou 16, visto que ele
corresponde a vários comprimentos de palavra de maquina.

Algoritmo padrão de Tabela de Busca

A idéia por traz dos algoritmos padrões de Tabela de Busca é pre-calcular os


valores CRC de todas as combinações de bits almejados. Portanto, 2α(n – k) valores de “bit
word” são necessários, que limita implementações praticas para valores pequenos de α.
Assuma agora que os bits de checagem são armazenados em um registrador
denominado CRC, o algoritmo será:
14

(Se α < n – k):

1) CRC ← 0, que é, atribuir 0 ao conjunto de bits (rn-k-1, .., r0)


2) Faça uma XOR com os α bits de entrada e com o conteúdo do registrador
CRC rotacionado para a direita por n – k - α bits, que é, fazer uma XOR com os bits
(rn-k-1, ..., rn-k-α)
3) Encontre o valor correspondente na tabela de busca e faça uma XOR com o
conteúdo do registrador CRC rotacionado a esquerda por α bits, que é, fazer uma XOR com
os bits (rα-1, ..., r0). Este é o novo valor CRC.
4) Repita os passos 2 e 3 até alcançar o final da mensagem. No caso onde α = n
– k, os passos 2 e 3 vão ser um pouco diferentes:
2) Faça uma XOR com os α bits de entrada e o registrador CRC, que é, fazer
uma XOR com os bits (rn-k-1, ..., r0).
Encontre o valor correspondente na tabela de busca. Este é o novo valor CRC.

Algoritmo reduzido de Tabela de Busca

Este algoritmo é uma variante do algoritmo padrão de tabela de busca para


aplicações onde o espaço de memória é de maior importância. O montante de memória
requerido para armazenar a tabela de busca é significamente reduzido e igual a α(n – k)
“bit words”.
A idéia básica é lançar a expressão Rg(x)(bα-1 + rn-k-1) xn-k-1+α + ... + (b0 + rn-k-α)
xn-k no somatório Rg(x)(bα-1 + rn-k-1) xn-k-1+α + ... + Rg(x)(b0 + rn-k-α) xn-k. Cada termo do
somatório pode ser 0 ou 1. Se (bα-1-i + rn-k-1-i) é 0, então Rg(x)(bα-1-i + rn-k-1-i) xn-k-1+α-i é
igual a 0. Logo você apenas necessita pre-calcular os valores α correspondentes a Rg(x)xn-
k-1+α-i
 com i = 0, ..., (α - 1). O algoritmo será:

(Se α < n – k):


15

1) CRC ← 0, que é, atribuir 0 ao conjunto de bits (rn-k-1, .., r0)


2) Faça uma XOR com os α bits de entrada e com o conteúdo do registrador
CRC rotacionado para a direita por α bits, que é, fazer uma XOR com os bits
(rn-k-1, ..., rn-k-α)
3) Para cada bit deste valor (α bits), se ele for igual a 1, encontre o valor
correspondente na tabela de busca e faça uma XOR com o conteúdo do registrador CRC e
este.
4) Faça uma XOR com este valor e o CRC rotacionado para a esquerda de α
bits, isto é, faça uma XOR com os bits (rα-1, ..., r0). Este é o novo valor do CRC.
5) Repita os passos de 2 a 4 até alcançar o final da mensagem. No caso onde α
= n – k, os passos 2 e 4 vão ser um pouco diferentes:
2) Faça uma XOR com os α bits de entrada e o CRC, isto é, faça uma XOR
com os bits (rn-k-1, ...,r0).
3) O valor calculado no passo 3 é o novo valor de CRC

Note que apenas o passo 3 difere do algoritmo padrão de tabela de busca. No


entanto, há um incremento de processamento pelo fato que cada bit deve ser testado e se
este for igual a 1, uma operação XOR deve ser feita.

Estratégias de Correção de Erro

Após a detecção de erros no canal de comunicação com o uso de CRC, há


basicamente dois modos de se obter a mensagem correta. Pode-se tentar corrigir os erros
transmitidos com o uso da Síndrome, sem necessidade de retransmissão dos mesmos ou
simplesmente identifica-los e pedir retransmissão da mensagem. Comunicações digitais
modernas tendem a favor da técnica de retransmissão enquanto tecnologias de
armazenamento (HDD) tendem a usar técnicas de correção.
16

Implementação

Para fornecer um meio seguro de comunicação por rádio frequência entre o


robô autônomo e a central, onde as informações recebidas com erros possam ser detectadas
e corrigidas, buscou-se utilizar os módulos TX2 e RX2 da Radiometrix –
http://www.radiometrix.com/ (transmissor e receptor UHF FM) pois os mesmos já foram
adquiridos pelo Núcleo PEQ.
A figura 03 ilustra os módulos de transmissão e recepção (TX2 e RX2).

Figura 03 – Módulos TX2 e RX2

Algumas especificações dos módulos (Datasheet com todas as especificações


dos módulos pode ser encontrado no endereço citado):

• Taxas de transmissão de até 160 kbps;


• Distâncias de até 75 m em áreas construídas;
• Distâncias de até 300 m em áreas abertas;
• Frequência de 433,92 MHz;
• Tensão de 2,2V a 6V (para o transmissor);
• Tensão de 3V a 6V (para receptor).
17

Para testes no Laboratório PEQ dos módulos TX2 e RX2 da Radiometrix,


foram criadas pelos mestrandos Wanir e Antônio, duas placas, uma com um modulo de
transmissão e outra com um modulo de recepção, conforme figura 04.

Figura 04 – Módulos TX2 e RX2 em placa para teste

A figura 05 mostra o circuito impresso das placas para teste. Este circuito já foi
projetado para permitir a conexão dos módulos TX2 e RX2.

Figura 05 – Circuito impresso das placas para teste


18

Componentes utilizados para montagem da placa para teste:


Componentes Quantidade
Max232 01
Capacitores de 1 µF 05
Regulador de Tensão 7805 01
Módulo TX2 da Radiometrix 01
Módulo RX2 da Radiometrix 01
Conector db9 fêmea 01

Foram realizados testes simples com o uso do Hiperterminal de dois


computadores, e com a digitação de algumas palavras, verificou-se o funcionamento dos
módulos e a necessidade de um controle de erro poderoso.
Constatada a necessidade de um controle de erro poderoso, decidiu-se utilizar a
técnica de CRC (“Cyclic Redundancy Check”) devido às inúmeras vantagens dela sobre as
demais técnicas já apresentadas neste trabalho.
Optou-se por desenvolver um programa para geração e verificação de códigos
CRC com as seguintes características:

• Polinômio gerador: x8 + x4 + x3 + x2 + 1;
• Algoritmo para calculo do CRC: algoritmo “bitwise” (CRCB);
• Linguagem para desenvolvimento: Delphi;
• Sistema Operacional de desenvolvimento: Windows 9x e 2000;
• Pedido de retransmissão caso seja identificado alguma mensagem com erro.

Justificativas:

Optou-se pela utilização do polinômio gerador “x8 + x4 + x3 + x2 + 1” para


facilitar a implementação de programas para calculo de CRC em microcontroladores da
família 8051, pois o mesmo possui, na sua maioria, registradores de 8 bits e um polinômio
de grau nove gera mensagens CRC com oito bits.
O algoritmo “bitwise” (CRCB) foi utilizado devido sua maior facilidade de
implementação e também por termos verificado que a taxa de transmissão de pacotes de
mensagens seria relativamente baixa, devido a restrições do microcontrolador 8051 (menor
19

que 19600 bps) e que a quantidade de mensagens enviadas também seria baixa, podendo
assim ser usado o algoritmo “bitwise”(CRCB).
O desenvolvimento de um programa para geração e verificação de códigos
CRC foi realizado com o auxilio da ferramenta Delphi devido aos seguintes fatos:

• maior conhecimento e bagagem sobre esta ferramenta e linguagem;


• possibilidade do uso da mesma ferramenta para a comunicação com o
Banco de Dados MySQL;
• utilização de um componente já conhecido (Async32) para comunicação
serial;
• pouco tempo disponível para aprendizagem de uma nova linguagem.

No entanto, esta ferramenta apresenta a desvantagem de não ser gratuita, sendo


possível adquiri-la gratuitamente somente por intervalos curtos de tempo e em versões
anteriores.
O sistema operacional utilizado para o desenvolvimento do programa foi o
Windows pelo simples fato do uso da ferramenta Delphi e principalmente do uso do
componente para comunicação serial (Async32) que utiliza a API do windows.
A utilização do pedido de retransmissão para mensagens com erros detectados
se deve ao fato da taxa de transmissão dos pacotes de mensagem ser relativamente baixa e
a quantidade de mensagens enviadas também ser baixa, além do fato do pouco tempo para
um estudo dos métodos e algoritmos para correção de erros com o uso da Síndrome.
As funções e procedimentos mais importantes do programa para a geração e
verificação de códigos CRC são apresentadas abaixo:

function MSB(valor: word): byte;


begin
if (valor and $8000) = $8000 then result := 1
else result := 0;
end;
20

Function CRC(msg: String) : byte;


const
poly = $11D; //100011101
var
i: byte;
msg_int: word;
sai_um: boolean;
begin
result := 0;
msg_int := ord(msg[1]) shl 8;
for i := 1 to 16 do
begin
if (result and $80) = $80 then sai_um := true
else sai_um := false;
result := (result shl 1) + MSB(msg_int);
msg_int := msg_int shl 1;
if sai_um = true then result := result xor poly;
end;
end;

function TesteCrc(msg: word):byte;


const
poly = $11D; //100011101
var
i: byte;
sai_um: boolean;
begin
result := 0;
for i := 1 to 16 do
begin
if (result and $80) = $80 then sai_um := true
else sai_um := false;
result := (result shl 1) + MSB(msg);
21

msg := msg shl 1;


if sai_um = true then result := result xor poly;
end;
end;

O programa trabalha com mensagens de 8 bits e gera para estas um código CRC
também com 8 bits.
O programa trabalha com a mensagem da seguinte forma:
Os primeiros três bits da mensagem representam a distância percorrida pelo
robô na posição “x” (em centímetros).
O quarto bit da mensagem é responsável por determinar o sentido do
deslocamento na posição “x”. Se este bit for zero, houve um deslocamento no sentido
positivo do eixo “x”, caso contrário, houve um deslocamento no sentido negativo do eixo
“x”.
Do quinto ao sétimo bit são usados para representar o deslocamento do robô na
direção “y” (em centímetros).
O oitavo bit da mensagem é responsável por determinar o sentido do
deslocamento na posição “y”. Se este bit for zero, houve um deslocamento no sentido
positivo do eixo “y”, caso contrário, houve um deslocamento no sentido negativo do eixo
“y”.
A figura abaixo representa a mensagem com suas divisões.

Sy Y Y Y Sx X X X

Figura 06 – Mensagem enviada

Todo o código do programa para a geração e verificação de códigos CRC é


apresentado no APÊNDICE deste trabalho.
Abaixo as figuras dos programas testes para geração e verificação de códigos
CRC.
22

Figura 07 – Programa teste

Figura 08 – Programa Teste

Abaixo a figura do programa para a geração e verificação de códigos CRC,


assim como atualização do servidor MYSQL, desenvolvido com a ferramenta Delphi.
23

Figura 09 – Programa para geração e verificação


De códigos CRC e atualização do MYSQL

Para testes do componente para comunicação serial (Async32) que utiliza a API
do windows, conectou-se dois computadores com o uso de um cabo db9-db9 cruzado com
as seguintes características:
• Pinagem:

Número do pino Nome Descrição


1 DCD Data Carrier Detect
2 RD Receive Data
3 TD Transmit Data
4 DTR Data Terminal Ready
5 SGND Ground
6 DSR Data Set Ready
7 RTS Request To Send
8 CTS Clear To Send
9 RI Ring Indicator

• Conexão dos seguintes pinos dos conectores:


24

Pino do conector A Pino do conector B


2 3
3 2
4 6
5 5
6 4
7 8
8 7
25

MySQL

O servidor de banco de dados MySQL foi escolhido pois apresenta as


seguintes vantagens:

• servidor de banco de dados muito rápido;


• multi-usuario;
• multi-threaded;
• multi-plataforma (AIX, BSDI, FreeBSD, HP-UX, Linux, Solaris, Win95,
Win98, NT, and Win2000, SunOS, etc);
• robusto SQL (Structured Query Languange);
• gratuito (licenciado com o GNU GENERAL PUBLIC LICENSE);
• estável;
• APIs para C, C++, Eiffel, Java, Perl, PHP, Python, Delphi e Tcl;
• atualizado constantemente.

Em fevereiro de 2002, no teste, que é ponto de referência de bancos de dados,


realizado por Ziff Davis Media Inc., a companhia por traz da PC Magazine, eWeek e
outras bem conhecidas publicações, o servidor MySQL foi considerado com melhor
performance e estabilidade juntamente com o Oracle9i.
Os bancos de dados testados foram: IBM DB2 7.2, Microsoft SQL Server 2000,
MySQL-Max 4.0.1, Oracle 9i 9.0.1.1.1 and Sybase ASE 12.5.0.1.
A figura abaixo mostra graficamente os resultados obtidos com o teste.
26

Figura 10 – Resultados do teste realizado por Ziff Davis Media Inc.

Instalação e Implementação

O servidor MySQL utilizado foi o MySQL versão 3.23.49.


Inicialmente, instalou-se o servidor no diretório c:\mysql e, em seguida, a senha
de root foi alterada com o seguinte comando no shell:

mysqladmin -u root “password” “new_password”

A tabela Robô foi criada na base de dados test (base de dados já existente no
servidor) com o seguinte comando SQL:

CREATE TABLE ROBO (I AUTO_INCREMENT INT(11), POSX NOT NULL INT(11),


POSY NOT NULL INT(11), T TIME);
27

PHP

PHP é uma linguagem que permite criar sites WEB dinâmicos, possibilitando
uma interação com o usuário através de formulários, parâmetros da URL e links. A
diferença de PHP com relação a linguagens semelhantes a Javascript é que o código PHP é
executado no servidor, sendo enviado para o cliente apenas o html puro. Desta maneira é
possível interagir com bancos de dados e aplicações existentes no servidor, com a
vantagem de não expor o código fonte para o cliente. Isso pode ser útil quando o programa
está lidando com senhas ou qualquer tipo de informação confidencial.

O que diferencia PHP de um script CGI escrito em C ou Perl é que o código


PHP fica embutido no próprio HTML, enquanto nos outros casos, é necessário que o script
CGI gere todo o código HTML, ou leia de um outro arquivo.
A linguagem PHP foi escolhida, pois apresenta as seguintes vantagens:

• maior velocidade de resposta e criação de sites devido a sua syntax superior


a ASP e JSP;
• maior possibilidade de desenvolvimento de aplicativos Web poderosos;
• multi-plataforma (Windows 98, 2000, NT, Linux, Unix, IIS, Apache, etc);
• permite acesso a várias funções e ferramentas (funções WDDX, XML,
Oracle, MySQL, IMAP, etc);
• atualizado constantemente;
• gratuito.

Instalação e Implementação

Foi criada a pasta: “C:\php3”


O arquivo “php-3.0.16-win32.zip” foi descompactado neste diretório.
O arquivo “php3.ini.dist.txt” foi copiado para o diretório “C:\Windows”,
renomeando este para “php3.ini”.
Procurou-se pela linha “extension_dir” no arquivo “php3.ini” e inclui-se o
seguinte parâmetro: “c:\php3”.
28

O trecho do arquivo abaixo mostra como a linha “extension_dir” deve ser


modificada.

;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;
include_path=; UNIX: "/path1:/path2" Windows: "\path1;\path2"
doc_root=; the root of the php pages, used only if nonempty
user_dir=; the directory under which php opens the script using /~username, used only if
nonempty
;upload_tmp_dir=; temporary directory for HTTP uploaded files (will use system default if
not specified)
upload_max_filesize=2097152 ; 2 Meg default limit on file uploads
extension_dir=C:\PHP3 ./

Procurou-se pelo trecho “Dynamic Extensions” no arquivo de configuração do


PHP3 e descomentou-se as linhas (apagou-se o ponto e vírgula que antecede cada
parâmetro de configuração).

;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
; if you wish to have an extension loaded automaticly, use the
; following syntax: extension=modulename.extension
; for example, on windows,
; extension=msql.dll
; or under UNIX,
; extension=msql.so
; Note that it should be the name of the module only, no directory information
; needs to go here. Specify the location of the extension with the extension_dir directive
above.
29

;Windows Extensions
extension=php3_mysql.dll
extension=php3_calendar.dll
extension=php3_dbase.dll
extension=php3_gd.dll
extension=php3_dbm.dll
extension=php3_mssql.dll
extension=php3_zlib.dll
extension=php3_filepro.dll
extension=php3_imap4r1.dll
extension=php3_ldap.dll
extension=php3_crypt.dll
extension=php3_msql2.dll
extension=php3_odbc.dll

Após a instalação do PHP 3.0.16 para Windows, criou-se o seguinte código em


PHP para conexão com o Servidor MYSQL e para visualização dos dados da tabela ROBO
em um navegador Web.

<html>
<head><title>Posicoes do Robo</title></head>
<body
BGCOLOR=black>
<font color=white font size=5>
<center>
<h2> Posicoes do Robo durante intervalos de tempo!</h2>
<?
// variáveis usadas na conexão ao DBMS
$host = "localhost";
$user = "root";
$pwd = "eletrica";
30

$base = "test";
$table = "Robo";
// estabelecer conexão com o DBMS
mysql_connect($host, $user, $pwd)
OR die ("Falhou na coneccao!!");
// selecionar uma base de dados
mysql_select_db( "$base")
OR die( "Falhou ao selecionar a base");
// construir a query
$query = "select * from $table";
// aplicar a query no DBMS
$result = mysql_query($query);

echo "<table border=1>\n";


echo "<tr><td><font color=white>Qtde</td><td><font color=white>Posx</td><td><font
color=white>Posy</td><td><font color=white>Tempo</tr>\n";
while ($linha = mysql_fetch_row($result))
{
printf("<tr><td><font color=white>$linha[0]</td>");
printf("<td><font color=white>$linha[1]</td>");
printf("<td><font color=white>$linha[2]</td>");
printf("<td><font color=white>$linha[3]</tr>");
}

// fechar a conexão com o DBMS


mysql_close();
?>
</center>
</body>
</html>

Este código produz a página da figura abaixo:


31

Figura 11 – Página produzida pelo código em PHP


32

Apache
O Servidor Apache foi escolhido, pois apresenta as seguintes vantagens:
• Fácil implantação e administração;
• Permite criar sites usando domínios virtuais;
• Permite criação de sites dinâmicos usando CGIs ou linguagens como PHP;
• Permite criar sites protegidos por senhas;
• Implementação de acesso seguro (https);
• Alto nível de customização e confiabilidade;
• Implementação para páginas wap;
• Multi-plataforma (Windows, Linux, etc);
• Gratuito.

Instalação e Configuração

Execute o utilitário de instalação (apache1.3.1.exe), que esta disponível para


download no site http://www.apache.org/ e seguiu-se os passos de instalação normalmente.
O próximo passo foi a configuração do servidor de páginas HTTP. Começando
pelo arquivo “httpd.conf”, localizado em “C:\Apache\conf”, editou-se este, adicionando as
seguintes linhas no final do mesmo.

ServerName localhost
ScriptAlias /php3/ "c:/php3/"
AddType application/x-httpd-php3 .php3 .php
Action application/x-httpd-php3 "/php3/php.exe"

A primeira linha informa ao apache o nome do servidor.


A segunda linha informa ao apache que execute scripts php.
A terceira informa as extensões dos scripts php que serão executados pelo
servidor de web, ou seja, qualquer arquivo com extensão .php3 ou php ativará o “client
side script”.
A quarta linha informa o caminho “path” do PHP.
33

Após a configuração do servidor, criou-se uma página inicial no diretório


“htdocs/homepage” no diretório de instalação do Apache.
A figura abaixo mostra a página criada.

Figura 12 – Página inicial


34

CONCLUSÃO

Este trabalho buscou fornecer uma discussão de algumas das técnicas mais
usadas para detecção e correção de erros em mensagens recebidas, além de exemplificar
através de algoritmos e programas as técnicas escolhidas.
Este trabalho também teve por finalidade demonstrar uma técnica de
disponibilizar as informações recebidas para uma posterior utilização das mesmas. Para
esta demonstração, utilizou-se da linguagem PHP, do banco de dados servidor MYSQL e
do servidor de HTTP APACHE.
Os resultados obtidos na implementação foram satisfatórios, provando a
vantagem da técnica CRC para detecção de erros e provando também que é possível
implementar o controle de um robô autônomo via rádio enlace, armazenando os dados
obtidos para serem visualizados por um computador em uma rede de computadores.
Como proposta para melhoria do projeto pode-se destacar o uso dos módulos
TX2 e RX2 na implementação, o uso da Sindrome para correção das mensagens recebidas
com erros ao invés de pedir retransmissão das mesmas, um método em Java para atualizar
a página sempre que houver alteração e a união com o projeto final “Robô Autônomo para
Mapeamento de Ambientes” desenvolvido pelos alunos Jorge Humberto e Renato Alves
Borges.
35

REFERÊNCIAS

[01] STALLINGS, W. Data and Computer Communications, sixth edition, Prentice-


Hall Inc., 2000
[02] RODEN, M. S. Digital and Data Communication Systems, first edition, Prentice-
Hall Inc. 1982
[03] GIBSON, J. D. Principles of Digital and Analog Communication Systems,
second edition, Macmillian Inc., 1993
[04] LATHI, B. P. Modern Digital and Analog Communication Systems, first
edition, Oxford University Press, 1998
[05] EE 387 Error-Correcting Codes, May 3,2002.
[06] GEREMIA, P Cyclic Redundancy Check Computation: An Implementation
Using the TMS320C54x, Application Report, Texas Instruments
[07] WILLIAMS, R. N. A Painless Guide to CRC Error Detection Algorithms, third
edition, 1993
36

APÊNDICE

unit UProjetoFinal;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, StdCtrls, Grids, DBGrids, libmysql, CommInt, ExtCtrls,
Menus, ComCtrls, ToolWin, ImgList, VaClasses, VaComm, VaModem;

type
TFrmUpdate = class(TForm)
MmRx: TMemo;
cbcrc: TCheckBox;
Timer: TTimer;
CoolBar1: TCoolBar;
ToolBar1: TToolBar;
TBConfig: TToolButton;
TBConc: TToolButton;
TBDesconec: TToolButton;
PopMCom: TPopupMenu;
StatusBar1: TStatusBar;
Porta1: TMenuItem;
COM11: TMenuItem;
COM21: TMenuItem;
BaudRate1: TMenuItem;
N3001: TMenuItem;
N12001: TMenuItem;
N96001: TMenuItem;
N24001: TMenuItem;
N192001: TMenuItem;
N560001: TMenuItem;
37

ImageList1: TImageList;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
ToolButton3: TToolButton;
Label1: TLabel;
EdtError: TEdit;
Comm: TVaComm;
VaModem1: TVaModem;
Pacote: TMenuItem;
Unido1: TMenuItem;
Separado1: TMenuItem;
ToolButton4: TToolButton;
ToolButton5: TToolButton;
procedure TimerTimer(Sender: TObject);
procedure TBConcClick(Sender: TObject);
procedure TBDesconecClick(Sender: TObject);
procedure TBConfigClick(Sender: TObject);
procedure N3001Click(Sender: TObject);
procedure N12001Click(Sender: TObject);
procedure N24001Click(Sender: TObject);
procedure N96001Click(Sender: TObject);
procedure N192001Click(Sender: TObject);
procedure N560001Click(Sender: TObject);
procedure COM21Click(Sender: TObject);
procedure COM11Click(Sender: TObject);
procedure CommError(Sender: TObject; Errors: Integer);
procedure CommRxBuf(Sender: TObject; Data: PVaData; Count: Integer);
procedure cbcrcClick(Sender: TObject);
procedure Unido1Click(Sender: TObject);
procedure Separado1Click(Sender: TObject);
procedure ToolButton4Click(Sender: TObject);
private
{ Private declarations }
38

public
{ Public declarations }
end;

var
FrmUpdate: TFrmUpdate;
procedure UpdateMySQL(x,y: string);
procedure FindXY(Chr: string);
procedure UpdateGrafic(x,y: integer);
function TesteCrc(msg: word):byte;
function MSB(valor: word): byte;
Function CRC(msg: String) : byte;

implementation

uses UProjetoFinalGrafic;

{$R *.dfm}

var
// MySQL data
FMYSQL: PMYSQL;
robox, roboy, LineData: string;
LineDataCrc, send, first: word;
Erro, count: integer;
iniciar: boolean;

function MSB(valor: word): byte;


begin
if (valor and $8000) = $8000 then result := 1
else result := 0;
end;
39

Function CRC(msg: String) : byte;


const
poly = $11D; //100011101
var
i: byte;
msg_int: word;
sai_um: boolean;
begin
result := 0;
msg_int := ord(msg[1]) shl 8;
for i := 1 to 16 do
begin
if (result and $80) = $80 then sai_um := true
else sai_um := false;
result := (result shl 1) + MSB(msg_int);
msg_int := msg_int shl 1;
if sai_um = true then result := result xor poly;
end;
end;

function TesteCrc(msg: word):byte;


const
poly = $11D; //100011101
var
i: byte;
sai_um: boolean;
begin
result := 0;
for i := 1 to 16 do
begin
if (result and $80) = $80 then sai_um := true
else sai_um := false;
40

result := (result shl 1) + MSB(msg);


msg := msg shl 1;
if sai_um = true then result := result xor poly;
end;
end;

procedure FindXY(Chr: string);


var
letra: char;
numero: word;
sinalx, sinaly, numerox, numeroy: integer;
begin
letra := char(Chr[1]);
numero := ord(letra);
if (numero and $08) = $08 then sinalx := -1;
if (numero and $08) = $00 then sinalx := 1;
if (numero and $80) = $80 then sinaly := -1;
if (numero and $80) = $00 then sinaly := 1;
numerox := sinalx*(numero and $07);
numeroy := sinaly*((numero and $70) div 10);
robox := inttostr(numerox);
roboy := inttostr(numeroy);
end;

procedure UpdateMySQL(x,y: string);


var
Query, t: string;
begin
t := FormatDateTime('hh:nn:ss',Now);
Query := 'insert into robo(posx, posy, t) values (' + x + ',' + y +',"' + t + '")';
//parametros para conectar com o mysql
FMYSQL := mysql_connect(nil, PChar('localhost'), PChar('root'), PChar('eletrica'));
41

if FMYSQL = nil then DatabaseError('Erro ao connectar com o MySQL server!');


//parametros para conectar com um banco especifico
if mysql_select_db(FMYSQL, PChar('test')) <> 0 then
DatabaseError(mysql_error(FMYSQL));
//executa a query
if mysql_query(FMYSQL, PChar(Query)) <> 0 then
DatabaseError(mysql_error(FMYSQL));
//finaliza coneccao
mysql_close(FMYSQL);
end;

procedure TFrmUpdate.TimerTimer(Sender: TObject);


begin
StatusBar1.Panels[3].Text := FormatDateTime('hh:nn:ss',Now);
EdtError.Text := inttostr(erro);
end;

procedure TFrmUpdate.TBConcClick(Sender: TObject);


begin
try
Comm.Open;
first := 1;
MMRx.Clear;
FrmGrafic.Image1.Canvas.Rectangle(0,0,593,417);
iniciar := true;
TBConfig.Enabled := false;
TBConc.Enabled := false;
TBDesconec.Enabled := true;
StatusBar1.Panels[0].Text := 'Conectado ';
Erro := 0;
except
showmessage('Não foi possivel abrir a porta: ' + Comm.DeviceName);
end;
42

end;

procedure TFrmUpdate.TBDesconecClick(Sender: TObject);


begin
try
Comm.Close;
TBConfig.Enabled := true;
TBConc.Enabled := true;
TBDesconec.Enabled := false;
StatusBar1.Panels[0].Text := 'Desconectado ';
except
showmessage('Não foi possivel fechar a porta: ' + Comm.DeviceName);
end;
end;

procedure TFrmUpdate.TBConfigClick(Sender: TObject);


begin
PopMCom.Popup(FrmUpdate.Left+10,FrmUpdate.Top+60);
end;

procedure TFrmUpdate.N3001Click(Sender: TObject);


begin
N3001.Checked := true;
N12001.Checked := false;
N24001.Checked := false;
N96001.Checked := false;
N192001.Checked := false;
N560001.Checked := false;
Comm.BaudRate := br300;
StatusBar1.Panels[1].Text := '300';
end;

procedure TFrmUpdate.N12001Click(Sender: TObject);


43

begin
N3001.Checked := false;
N12001.Checked := true;
N24001.Checked := false;
N96001.Checked := false;
N192001.Checked := false;
N560001.Checked := false;
Comm.BaudRate := br1200;
StatusBar1.Panels[1].Text := '1200';
end;

procedure TFrmUpdate.N24001Click(Sender: TObject);


begin
N3001.Checked := false;
N12001.Checked := false;
N24001.Checked := true;
N96001.Checked := false;
N192001.Checked := false;
N560001.Checked := false;
Comm.BaudRate := br2400;
StatusBar1.Panels[1].Text := '2400';
end;

procedure TFrmUpdate.N96001Click(Sender: TObject);


begin
N3001.Checked := false;
N12001.Checked := false;
N24001.Checked := false;
N96001.Checked := true;
N192001.Checked := false;
N560001.Checked := false;
Comm.BaudRate := br9600;
StatusBar1.Panels[1].Text := '9600';
44

end;

procedure TFrmUpdate.N192001Click(Sender: TObject);


begin
N3001.Checked := false;
N12001.Checked := false;
N24001.Checked := false;
N96001.Checked := false;
N192001.Checked := true;
N560001.Checked := false;
Comm.BaudRate := br19200;
StatusBar1.Panels[1].Text := '19200';
end;

procedure TFrmUpdate.N560001Click(Sender: TObject);


begin
N3001.Checked := false;
N12001.Checked := false;
N24001.Checked := false;
N96001.Checked := false;
N192001.Checked := false;
N560001.Checked := true;
Comm.BaudRate := br1200;
StatusBar1.Panels[1].Text := '56000';
end;

procedure TFrmUpdate.COM21Click(Sender: TObject);


begin
COM11.Checked := false;
COM21.Checked := true;
Comm.DeviceName := 'Com2';
StatusBar1.Panels[2].Text := 'COM2';
end;
45

procedure TFrmUpdate.COM11Click(Sender: TObject);


begin
COM11.Checked := true;
COM21.Checked := false;
StatusBar1.Panels[2].Text := 'COM1';
Comm.DeviceName := 'Com1';
end;

procedure TFrmUpdate.CommError(Sender: TObject; Errors: Integer);


begin
if (Errors and CE_BREAK > 0) then
showmessage('The hardware detected a break condition.');
if (Errors and CE_DNS > 0) then
showmessage('Windows 95 only: A parallel device is not selected.');
if (Errors and CE_FRAME > 0) then
showmessage('The hardware detected a framing error.');
if (Errors and CE_IOE > 0) then
showmessage('An I/O error occurred during communications with the device.');
if (Errors and CE_MODE > 0) then
begin
showmessage('The requested mode is not supported, or the hFile parameter');
showmessage('is invalid. If this value is specified, it is the only valid error.');
end;
if (Errors and CE_OOP > 0) then
showmessage('Windows 95 only: A parallel device signaled that it is out of paper.');
if (Errors and CE_OVERRUN > 0) then
showmessage('A character-buffer overrun has occurred. The next character is lost.');
if (Errors and CE_PTO > 0) then
showmessage('Windows 95 only: A time-out occurred on a parallel device.');
if (Errors and CE_RXOVER > 0) then
showmessage('An input buffer overflow has occurred.');
if (Errors and CE_RXPARITY > 0) then
46

showmessage('The hardware detected a parity error.');


if (Errors and CE_TXFULL > 0) then
showmessage('The application tried to transmit a character.');
end;

procedure TFrmUpdate.CommRxBuf(Sender: TObject; Data: PVaData;


Count: Integer);
var
I: integer;
begin
if cbcrc.Checked = false then
begin
for I := 0 to Count - 1 do
begin
case Data^[I] of
#10:;
#13: MMRx.Lines.Add('');
else MMRx.Lines.Text := MMRx.Lines.Text + Data^[I];
end;
FindXY(Data^[I]); //divide valor recebido
UpdateGrafic(strtoint(robox),strtoint(roboy));
UpdateMySQL(robox,roboy); //Atualiza valores no banco de dados
end;
end
{FIM DO CBCRC = FALSE
================================================================
=
======= INICIO DO CBCRC = TRUE ===============
======= TESTE PARA SABER SE O CRC VIRÁ SEPARADO ===============
================================================================
=}
else
if Unido1.Checked = false then
47

begin
case first of
1: begin
for I := 0 to Count - 1 do
begin
first := 2;
LineDataCRC := ord(Data^[I]);
end;
end;
2: begin
for I := 0 to Count - 1 do
begin
first := 1;
LineDataCRC := (ord(Data^[I]) shl 8) + LineDataCRC;
end;
//Teste para saber se houve erro na transmissao...
if TesteCrc(LineDataCRC) = 0 then
begin
LineDataCRC := (LineDataCRC and $FF00) shr 8;
FindXY(chr(LineDataCRC)); //divide valor recebido
UpdateGrafic(strtoint(robox),strtoint(roboy));
UpdateMySQL(robox,roboy); //Atualiza valores no banco de dados
case chr(LineDataCRC) of
#0, #10:;
#13: begin
LineData := '';
MmRx.Lines.Add(chr(LineDataCRC));
end;
#27: begin //"ESC"
//Retransmissao do ultimo byte
Count := Comm.WriteBuf(send, 2);
if Count = 0 then MmRx.Lines.add('Erro ao enviar na porta: ' +
Comm.DeviceName);
48

end;
else MmRx.Lines.Text := MmRx.Lines.Text + chr(LineDataCRC);
end; //Fim do case
end //Fim do teste de CRC = 0
else //Se CRC <> 0
begin
inc(Erro);
//Transmissao da mensagem "ESC" com CRC para pedir retransmissao
Comm.PurgeWrite;
send := ($1B shl 8); //Transmite "ESC"
Count := Comm.WriteBuf(send, 1);
if Count = 0 then MmRx.Lines.add('Erro ao enviar na porta: ' + Comm.DeviceName)
else
begin
Comm.PurgeWrite;
send := CRC(chr($1B)); //Transmite "CRC"
Count := Comm.WriteBuf(send, 1);
if Count = 0 then MmRx.Lines.add('Erro ao enviar na porta: ' +
Comm.DeviceName);
end;
end; //Fim do teste se CRC <> 0
end; //Fim do first = 2
end; //Fim do case
end //Fim Unido1.Checked = false
{===========================================================
===========TESTE PARA SABER DE CRC VIRÁ JUNTO ============
============================================================}
else
begin
for I := 0 to Count - 2 do
begin
LineDataCRC := (ord(Data^[I+1]) shl 8) + ord(Data^[I]);
end;
49

//Teste para saber se houve erro na transmissao...


if TesteCrc(LineDataCRC) = 0 then
begin
LineDataCRC := (LineDataCRC and $FF00) shr 8;
FindXY(chr(LineDataCRC)); //divide valor recebido
UpdateGrafic(strtoint(robox),strtoint(roboy));
UpdateMySQL(robox,roboy); //Atualiza valores no banco de dados
case chr(LineDataCRC) of
#0, #10:;
#13: begin
LineData := '';
MmRx.Lines.Add(chr(LineDataCRC));
end;
#27: begin //"ESC"
//Retransmissao do ultimo byte
Count := Comm.WriteBuf(send, 2);
if Count = 0 then MmRx.Lines.add('Erro ao enviar na porta: ' +
Comm.DeviceName);
end;
else MmRx.Lines.Text := MmRx.Lines.Text + chr(LineDataCRC);
end; //Fim do case
end //Fim do teste de CRC = 0
else //Se CRC <> 0
begin
inc(Erro);
//Transmissao da mensagem "ESC" com CRC para pedir retransmissao
send := ($1B shl 8) + CRC(chr($1B));
if Comm.WriteBuf(send,2) = 0 then MmRx.Lines.add('Erro ao enviar na porta: ' +
Comm.DeviceName);
end; //Fim do teste se CRC <> 0
end; //Fim do else
Comm.PurgeRead; //Limpa buffer de leitura
end;
50

procedure TFrmUpdate.cbcrcClick(Sender: TObject);


begin
if cbcrc.Checked = false then Pacote.Enabled := false
else Pacote.Enabled := true;
end;

procedure TFrmUpdate.Unido1Click(Sender: TObject);


begin
Unido1.Checked := true;
Separado1.Checked := false;
end;

procedure TFrmUpdate.Separado1Click(Sender: TObject);


begin
Unido1.Checked := false;
Separado1.Checked := true;
end;

procedure UpdateGrafic(x,y: integer);


begin
FrmGrafic.image1.Canvas.Font.Size := 5;
if iniciar = true then
begin
count := 0;
FrmGrafic.image1.Canvas.MoveTo(200 + x,200 + y);
FrmGrafic.image1.Canvas.TextOut(204+x,204+y,concat(inttostr(count)));
iniciar := false;
end
else
begin
FrmGrafic.Image1.Canvas.LineTo(200 + 15*x,200 + 15*y);
FrmGrafic.image1.Canvas.TextOut(200+15*x,200+15*y,concat(inttostr(count)));
51

end;
FrmGrafic.Image1.Canvas.Refresh;
inc(count);
end;

procedure TFrmUpdate.ToolButton4Click(Sender: TObject);


begin
FrmGrafic.showmodal;
end;

end.

Você também pode gostar