Escola Superior de Tecnologia Projecto Sistemas em Tempo …

43
Instituto Politécnico de Viseu Escola Superior de Tecnologia Projecto Sistemas em Tempo Real Página 1 de 85 Índice 1. Introdução .................................................................................................................................. 2 2. Objectivo .................................................................................................................................... 3 2.1 Estrutura do trabalho...................................................................................................... 3 3. Hardware .................................................................................................................................... 4 3.1 Esquema da montagem................................................................................................. 4 3.2 Descrição dos componentes ........................................................................................ 5 3.3 Explicação do circuito ................................................................................................. 15 4. Software .................................................................................................................................... 16 4.1 Algoritmo de aquisição e transmissão de dados pelo porto paralelo do PC 17 4.2 Simples base de dados ................................................................................................. 19 4.3 Interface com o utilizador ........................................................................................... 21 4.4 Ficheiros de inicialização............................................................................................ 23 4.5 Biblioteca de manipulação de “strings”................................................................. 26 5. Comentários ............................................................................................................................. 29 6. Apêndice A............................................................................................................................... 31 6.1 Conteúdo do ficheiro “irclone.cpp” ......................................................................... 31 6.2 Conteúdo do ficheiro “ir.h”........................................................................................ 42 6.3 Conteúdo do ficheiro “dui.h” .................................................................................... 43 6.5 Conteúdo do ficheiro “inifiles.h” ............................................................................. 50 6.6 Conteúdo do ficheiro “strlib.h”................................................................................. 57 6.7 Conteúdo do ficheiro “exception.h”........................................................................ 67 7. Apêndice B ............................................................................................................................... 68 7.1 Datashet do foto-diodo ................................................................................................ 68 7.2 Datashet do foto-transistor ......................................................................................... 75 7.3 Datashet do transístor NPN 3904............................................................................. 77 8. Bibliografia ............................................................................................................................... 84 9. Avaliação................................................................................................................................... 85 9.1 Identificação.................................................................................................................... 85 9.2 Observações .................................................................................................................... 85 9.3 Classificação ................................................................................................................... 85 9.4 O docente......................................................................................................................... 85 Instituto Politécnico de Viseu Escola Superior de Tecnologia Projecto Sistemas em Tempo Real Página 2 de 85 1 1 . . I I n n t t r r o o d d u u ç ç ã ã o o Muitos dos dispositivos de electrónica de consumo modernos estão equipadas com um pequeno comando remoto. Estes comandos não são nada mais do que pequenos teclados sem fio que, quando um botão é pressionado, envia um sinal codificado para uma unidade receptora dentro de video, ou televisão. O sinal pode ser ultrasonico, rádio frequência, ou luz infravermelha. Os comandos remotos a infravermelhos são muito populares por causa do seu alcance limitado (só mesmo em linha de vista) o que reduz a interferência noutros dispositivos controlados pelo mesmo processo. Os comandos a infravermelhos geram um trem de impulos de radiação infravermelha que é modulada em amplitude para se produzir um sinal codificado. O video contém circuitos capazes de detectar e desmodular este sinal para recuperar o sinal original especificando o comando que vai ser executado (play ou ligar/desligar). A parte específica de como os sinais são codificados varia de fabricante para fabricante, e por vezes de modelo para modelo. Esta variação de frequência é a razão, porque por vezes um comando remoto de um video não funciona com a televisão e vice-versa. Felizmente, o computador não precisa de “entender” os sinais infravermelhos para aprender a reproduzi-los, então as várias variações de codificação do sinal não têm grande efeito no presente projecto.

Transcript of Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Page 1: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 1 de 85

Índice 1. Introdução.................................................................................................................................. 2 2. Objectivo .................................................................................................................................... 3

2.1 Estrutura do trabalho...................................................................................................... 3 3. Hardware .................................................................................................................................... 4

3.1 Esquema da montagem ................................................................................................. 4 3.2 Descrição dos componentes ........................................................................................ 5 3.3 Explicação do circuito ................................................................................................. 15

4. Software .................................................................................................................................... 16 4.1 Algoritmo de aquisição e transmissão de dados pelo porto paralelo do PC 17 4.2 Simples base de dados ................................................................................................. 19 4.3 Interface com o utilizador........................................................................................... 21 4.4 Ficheiros de inicialização............................................................................................ 23 4.5 Biblioteca de manipulação de “strings”................................................................. 26

5. Comentários............................................................................................................................. 29 6. Apêndice A............................................................................................................................... 31

6.1 Conteúdo do ficheiro “irclone.cpp” ......................................................................... 31 6.2 Conteúdo do ficheiro “ir.h”........................................................................................ 42 6.3 Conteúdo do ficheiro “dui.h” .................................................................................... 43 6.5 Conteúdo do ficheiro “inifiles.h” ............................................................................. 50 6.6 Conteúdo do ficheiro “strlib.h”................................................................................. 57 6.7 Conteúdo do ficheiro “exception.h”........................................................................ 67

7. Apêndice B............................................................................................................................... 68 7.1 Datashet do foto-diodo ................................................................................................ 68 7.2 Datashet do foto-transistor ......................................................................................... 75 7.3 Datashet do transístor NPN 3904............................................................................. 77

8. Bibliografia ............................................................................................................................... 84 9. Avaliação................................................................................................................................... 85

9.1 Identificação.................................................................................................................... 85 9.2 Observações .................................................................................................................... 85 9.3 Classificação ................................................................................................................... 85 9.4 O docente......................................................................................................................... 85

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 2 de 85

11.. IInnttrroodduuççããoo

Muitos dos dispositivos de electrónica de consumo modernos estão equipadas com um pequeno comando remoto. Estes comandos não são nada mais do que pequenos teclados sem fio que, quando um botão é pressionado, envia um sinal codificado para uma unidade receptora dentro de video, ou televisão. O sinal pode ser ultrasonico, rádio frequência, ou luz infravermelha. Os comandos remotos a infravermelhos são muito populares por causa do seu alcance limitado (só mesmo em linha de vista) o que reduz a interferência noutros dispositivos controlados pelo mesmo processo.

Os comandos a infravermelhos geram um trem de impulos de radiação infravermelha que é modulada em amplitude para se produzir um sinal codificado. O video contém circuitos capazes de detectar e desmodular este sinal para recuperar o sinal original especificando o comando que vai ser executado (play ou ligar/desligar). A parte específica de como os sinais são codificados varia de fabricante para fabricante, e por vezes de modelo para modelo. Esta variação de frequência é a razão, porque por vezes um comando remoto de um video não funciona com a televisão e vice-versa. Felizmente, o computador não precisa de “entender” os sinais infravermelhos para aprender a reproduzi-los, então as várias variações de codificação do sinal não têm grande efeito no presente projecto.

Page 2: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 3 de 85

22.. OObbjjeeccttiivvoo

Este projecto consiste em receber e emitir sinais por radiação infravermelha através da porta paralela de um computador. Isto é, a partir de um circuito electrónico ligado à porta paralela onde irá receber um sinal de frequência por radiação infravermelha através de um comando remoto (de televisão, vídeo, rádio, etc…) que depois é lido, gravado e tratado no computador através de um software programado em “ADA95” e enviado para o circuito electrónico onde este o envia também por radiação infravermelha para o respectivo aparelho fazendo a mesma função que o comando remoto faria. Tanto o hardware como o software é implementado por nós. 22..11 EEssttrruuttuurraa ddoo ttrraabbaallhhoo

O trabalho é dividido em duas partes distintas de desenvolvimento, a parte do hardware e a parte do software devidamente relatadas. Para cada parte são apresentados os objectivos específicos bem como resultados e conclusões.

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 4 de 85

33.. HHaarrddwwaarree 33..11 EEssqquueemmaa ddaa mmoonnttaaggeemm

Page 3: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 5 de 85

33..22 DDeessccrriiççããoo ddooss ccoommppoonneenntteess

•• FFoottoo--ddiiooddooss

O foto-diodo é um diodo de junção construído de forma especial, de modo a possibilitar a utilização da luz como factor determinante no controle da corrente eléctrica. Pode ser aplicado no foco automático de câmara de filmar, na unidade óptica do CD Player e em sistema contador de pulso. Num diodo comum polarizado reversamente, existe uma corrente reversa formada por portadores minoritários mantidos pela energia térmica a temperatura ambiente. Assim, se houver incidência de luz sobre a junção pn, essa energia também pode gerar portadores contribuindo para gerar corrente reversa. Portando, o foto-diodo possui uma abertura que permite a entrada de luz que produz electrões livres e lacunas, aumentando a quantidade de portadores minoritários, controlando assim, a corrente reversa. Dessa forma, quanto maior a incidência de luz, maior a corrente no foto-diodo polarizado reversamente. Por isso, quando o foto-diodo está trabalhando na região linear de sua curva característica, a corrente reversa tem a mesma forma de onda da amplitude da intensidade luminosa incidente. Apesar do foto-diodo produzir, normalmente, corrente reversa por volta de dezenas de microampères, deve ser ligado em série com uma resistência limitador de corrente.

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 6 de 85

Foto-diodo e sua simbologia

Curva característica do foto-diodo

Aplicações:

O foto-diodo é usado como sensor em controlo remoto, em sistemas de fibra óptica, leitoras de código de barras, scanner (digitalizador de imagens, para computador), canetas ópticas (que permitem escrever na tela do computador), gira-discos CD, fotómetros e como sensor indirecto de posição e velocidade. • Diodo

Os diodos e as pontes rectificadores e os capacitores são elementos de uma importância fundamental na electrónica. Iremos fazer agora um breve estudo destes dois elementos:

Os diodos são componentes electrónicos formados por semicondutores. São usados como semicondutores, por exemplo, o silício e o germânio, que em determinadas condições de polarização, possibilitam a circulação de corrente.

Page 4: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 7 de 85

Externamente, os diodos possuem dois terminais: ânodo (A) e o Cátodo (K) e há, próximo ao terminal Cátodo uma faixa que o indica. Possui formato cilíndrico. O diodo é a aplicação mais simples da união PN (semicondutores) e tem propriedades rectificadoras, ou seja, só deixa passar a corrente em um certo sentido (ânodo-cátodo), sendo o contrário impossível, excepto nos diodos zener, que nessa condição deixam passar uma voltagem constante. Existem certas variações na sua apresentação, de acordo com a corrente que o percorre. Existem também os diodos emissores de luz, os famosos LED's (light emissor diode), que são representados por um diodo normal mais duas pequenas flechas para fora, que indicam que emite luz. Possuem as mesmas propriedades dos diodos normais, porém, é claro, emitem luz. Pontes rectificadoras: Os diodos possuem propriedades rectificadoras. Mas na verdade o que é que isso significa? Isso quer dizer que eles só deixam a corrente fluir em um único sentido, sendo o contrário impossível. Essa propriedade dos diodos é largamente utilizada nos rectificadores. Rectificadores são artifícios utilizados na electrónica para transformar a corrente alternada em corrente contínua. Isso pode se dar de diversas maneiras. Seja através de rectificadores de meia onda ou de onda completa. • Foto-transístor É um transístor cuja junção colector-base fica exposta à luz e actua como um foto-diodo. O transístor amplifica a corrente, e fornece alguns mA com alta luminosidade. Sua velocidade é menor que a do foto-diodo. Suas aplicações são as do foto-diodo, excepto sistemas de fibra-óptica, pela operação em alta-frequência.

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 8 de 85

Células foto-voltaicas São dispositivos que convertem energia luminosa em eléctrica. O diodo iluminado intensamente na junção pode reverter a barreira de potencial em fonte de electrões, produzindo energia. A eficiência do processo é baixa devido a pouca transparência da junção (somente as camadas superficiais são iluminadas), apenas alguns %.

Constituição do foto-transístor e suas aplicações;

O foto-transístor é um dispositivo semicondutor bem mais sensível que o foto-diodo,

por isso é mais utilizado quando se deseja maior precisão. É utilizado em acoplador óptico, e aplicado em tacómetro digital e em servomecanismo de videocassete, além de poder ser utilizado em contador de eventos.

Características do foto-transístor;

O foto-transístor, como um transístor convencional, é uma combinação de dois diodos de junção, no entanto, associa ao efeito transístor o efeito fotoeléctrico. Em geral, possui apenas dois terminais acessíveis (colector e emissor), no entanto, alguns incorporam o terminal de base para uma eventual polarização ou controle eléctrico. Seu funcionamento é idêntico ao do foto-diodo, excepto que o foto-transístor é muito mais sensível, devido à acção amplificadora do efeito transístor. Se uma certa quantidade de radiação luminosa atinge a base, ocorre a geração de portadores, aumentando corrente de base, o que implica numa variação da corrente de colector beta vezes maior e proporcional à intensidade de luz incidente.

Page 5: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 9 de 85

Foto-transístor e sua Simbologia

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 10 de 85

Constituição do foto-transístor

Curva característica do foto-transístor

Page 6: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 11 de 85

• Transístor 3904-tipo NPN

Os transístores são dispositivos que possuem duas uniões PN (a mesma dos diodos), capazes de controlar a passagem de uma corrente. Podem ser de dois tipos, de acordo com as uniões: PNP ou NPN. Apresentam base, emissor e coletor:

A base é a parte que controla a passagem de corrente; quando a base esta energizada, há passagem de corrente do emissor para o colector, quando não há sinal na base, não existe essa condução. A base esquematicamente é o centro do transístor. O colector é uma das extremidades do transístor: é nele que "entra" a corrente a ser controlada. A relação existente entre o colector e a base é um parâmetro ou propriedade do transístor conhecido como ß e é diferente para cada modelo do mesmo. O emissor é outra extremidade, por onde sai a corrente que foi controlada. Algumas características que devemos observar nos transístores são: A voltagem máxima entre base e colector, potência máxima dissipável (no caso do seu uso para controle de potência) e frequência máxima de trabalho. Os transístores podem ter aparência externa completamente diferentes, dependendo da aplicação que se fará dele, por exemplo, um transístor de sinal não possui a mesma aparência externa de um transístor de potência, que controle grandes cargas. Os seus terminais são os seguintes:

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 12 de 85

Características do transístor

Page 7: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 13 de 85

• Porta Paralela

A ligação entre o circuito electrónico (controlo remoto) e o computador é feita pela porta paralela do computador, através de um componente de 25 pinos, isto é, a porta paralela consiste basicamente de três partes: porta de dados, status e controle. Estas portas e seus respectivos endereços estão em ordem sequencial. Então, se o endereço da porta de dados é 0x378, então sua porta correspondente de status é 0x379 e de controle é 0x37a.

Porta Porta Dados Status Controle LPT1 0x0378 0x0379 0x037a LPT2 0x0278 0x0279 0x027a

Para identificar o endereço das portas de um computador, use o debug do DOS para mostrar a localização de memória 0040:0008. Por exemplo: >debug -d 0040:0008 L8 0040:0008 78 03 78 02 00 00 00 00 Note neste exemplo que LPT1 é 0x0378, LPT2 é 0x0278 e LPT3 e LPT4 não estão disponíveis. Um outro modo é rodar o Microsoft Diagnostic (msd.exe) e verificar as configurações da LPT.

Saídas

Vejamos agora a sua pinagem – figura 1 e a configuração das portas – figura 2. As duas figuras seguintes ilustram a configuração dos pinos no conector de 25 pinos e as configurações dos bits nas três portas (dados, status e controle).

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 14 de 85

Fig 1. Pinagem

Fig 2. Configuração das Portas

Observe que estas portas possuem 8 saídas na porta data (Data 7(msb) - Data 0) e quatro saídas adicionais no nibble inferior da porta controle (/SELECT_IN, INIT, /AUTO FEED and /STROBE). Todas as saídas da porta de dados são de lógica directa. Isto é, colocando um bit desta porta em 1, sua saída correspondente vai ao nível alto. Entretanto, as saídas /SELECT_IN, /AUTOFEED e /STROBE da porta controle possuem lógica invertida. Isto é, colocando um destes em 1, sua saída correspondente vai ao nível baixo. Isto pode parecer complicado, mas basta inverter estes bits através de software usando uma instrução XOR.

Page 8: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 15 de 85

33..33 EExxpplliiccaaççããoo ddoo cciirrccuuiittoo

Este circuito é um controlo remoto por radiação infravermelha onde pode ligar, desligar (ou fazer todas as outras funções) aparelhos à distância (operação biestável) e utiliza poucos componentes de fácil obtenção. A alimentação do circuito pode ser obtida através de uma fonte ou bateria e para maior alcance os foto-diodos podem ser dotados de um sistema óptico. Este sistema consiste num tubo de papelão opaco com lenta convergente na sua frente. A resistência de 220 ohm na base do transístor fixa o ganho deste componente podendo ser alterado experimentalmente em função da aplicação. Quanto ao receptor, onde podemos ver que um foto-transístor IRX é que recebe o sinal do controlo remoto por radiação infravermelha e que o envia para o computador pela porta paralela através do pino 18.De seguida o sinal é lido, gravado e tratado no computador através de um software também implementado por nós que será descrito mais abaixo. Depois basta enviar esse mesmo sinal através da porta paralela do computador pelo pino 2 onde será amplificado pelo transístor 3904 e emitido através dos dois foto-diodos (IRD1, IRD2) por radiação infravermelha para o respectivo aparelho fazendo a mesma função que o controlo remoto faria. Com este circuito electrónico pondera-se receber e enviar enumeros sinais por radiação infravermelha de qualquer tipo de controlo remoto como por exemplo: de televisores, rádios, vídeos, etc….

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 16 de 85

44.. SSooffttwwaarree Quando se tem em mente desenvolver um software, a primeira pergunta que qualquer programador faz a si próprio é a seguinte:

“Que linguagem de programação usar ?” Sendo C/C++ uma das linguagens de programação mais populares que se usa hoje em dia a escolha é obvia. A linguagem C/C++ fornece um “esqueleto” estruturado, sem limitar a creatividade do programador, enquanto os compiladores dessa linguagem consistentemente produzem programas mais rápidos e eficientes. Por estas e outras razões, muitos pacotes de software são escritos integralmente em C/C++. Como existem mais programadores que conhecem C/C++ do que outras linguagens de programação actuais, tornou-se claro que para que o software tenha aplicabilidade no mundo real forçosamente têm que ser escrito em C/C++. Enquanto outras linguagens, tal como Pascal, Basic ou Ada95 são boas para aprender conceitos relacionados com programação, a linguagem C/C++ sobresai porque é uma linguagem de uso geral e em termos de portabilidade é possível escrever um software para Linux e compilado para correr em ambiente Windows sem alterar uma linha de código. Decidido qual era a linguagem de programação a adoptar, era imperativo a escolha de um bom compilador. Na escolha do compilador foram ponderados varios factores, um dos factores mais significativos foi a compatibilidade dos formatos dos ficheiros, entre este compilalor e o compilador usado nas aulas práticas de Ada95 da cadeira de “Sistemas em tempo real”. (Caso mais tarde se deseja-se implementar o software em Ada95 bastaria simplesmente importar as rotinas de C/C++ para Ada95 sem muito esforço) O compilador utilizado foi um porto para MS-DOS do famoso Gcc ligado ao movimento Linux. Apesar deste compilador ser destribuido na internet livremente (incluindo código fonte) não o faz de qualidade duvidosa, consta que o jogo Quake I tm que rendeu milhões à “Id Software” foi desenvolvido nesse compilador o que vem a vincular que “não existem maus compiladores, mas sim maus programadores”. O compilador encontra-se disponivel para download no endereço de internet:

http://www.delorie.com/djgpp/ Após ter sido instalado, a linha de comandos para compilar o programa principal escrito em C/C++ é a seguinte: Não querendo utilizar o programa “make” que vem com a distribuição do compilador a linha de comando para compilar o programa principal é a seguinte:

Page 9: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 17 de 85

gxx –o irclone.exe irclone.cpp Para correr o programa após a compilação, é necessário escrever na linha de comandos o nome “irclone.exe”. 44..11 AAllggoorriittmmoo ddee aaqquuiissiiççããoo ee ttrraannssmmiissssããoo ddee ddaaddooss ppeelloo ppoorrttoo ppaarraalleelloo ddoo PPCC Para que um computador consiga recriar um sinal infravermelho, o computador têm que primeiro ser capaz de “ver” como é que eles se parecem. Isto é feito amostrando um sinal através de um hardware ligado ao porto paralelo de um PC. O processo de aquisição de dados não envolve nada de mágico, cada amostra consiste numa operação de leitura de um porto e armazenamento na memória volatel do sistema.

O seguinte pseudo-código descreve o processo de amostragem do sinal em intervalos de tempo regulares:

De contador = 1 até ao número_de_amostras faz Começa Lê um byte do porto Armazena byte na memória apontada por P Incrementa P de modo a apontar para o próximo endereço Espera Acaba

A implementação em C/C++ deste pseudo-código pode ser conseguida da seguinte forma: unsigned int irRecord(char* buffer, unsigned int length, unsigned int baseport) { unsigned int i, j, len; unsigned char mask, d; // desliga momentaneamente as interrupções do processador _disable(); // liga a alimentação do fotodíodo outp(baseport,2); // espera até que exista sinal no porto while ((inp(baseport+1) & 16) == 0); while ((inp(baseport+1) & 16) == 16); for (i = 0; i < length; i++) { mask = 128; d = 0; for (j = 0; j < 8; j++){ if ((inp(baseport+1) & 16) == 0) d |= mask;

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 18 de 85

mask = mask >> 1; } buffer[i] = d; } // desliga a alimentação do fototransístor de emissão do sinal outp(baseport,0); // volta a inibir as interrupções do processador _enable(); // retira todos zeros a mais que estejam no fim da sequência for (len = length-1; len; len--) if (buffer[len]) break; // devolve o tamanho dos dados adquiridos return len; }

Deve-se salientar aqui que não se utilizou qualquer rotina de atraso, em vez disso

preferiu-se aumentar o tamanho do buffer de dados caso assim seja necessário. Para se poder obter melhores resultados na aquisição dos dados desligou-se momentâneamente o atendimento de interrupções pelo processador. Assim têm-se a certeza que se consegue amostrar o sinal em intervalos de tempo mais regulares. O envio de um sinal a um aparelho receptor de infravermelhos também é feito de modo expedito, em que o processo de amostragem é invertido. Utilizando o mesmo buffer onde os bits que representam o sinal amostrado foram guardados, o software sequencialmente lê um byte do buffer e envia-o para o porto paralelo, fazendo com que o bit mais significativo “alinhe” com o bit no porto de saída que controla o hardware. O seguinte pseudo-código descreve o processo de envio: P = endereço_do_primeiro_byte_no_buffer_de_saída De contador = 1 até ao número_de_bytes_a_enviar faz Começa Vai buscar o byte apontado por P Incrementa ponteiro P Escreve no porto o byte Espera Acaba

A implementação do pseudo-código de envio em C é o seguinte: void irPlay(char* buffer, unsigned int length, unsigned int baseport) { unsigned int i, j; unsigned char mask, d; // suspende as interrupções do processador _disable(); for (i = 0; i < length; i++) { mask = 128; d = buffer[i]; for (j = 0;j < 8; j++)

Page 10: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 19 de 85

{ if (d & mask) outp(baseport,1); else outp(baseport,0); mask = mask >> 1; } } // volta a inibir as interrupções do processador _enable(); // desliga a alimentação do fototransístor de emissão do sinal outp(baseport, 0); }

Se o envio do sinal for gerido com a mesma frequência de amostragem, consegue uma boa reprodução do sinal infravermelho original. 44..22 SSiimmpplleess bbaassee ddee ddaaddooss No desenvolvimento do projecto, foi necessário adquirir dados e guarda-los em disco rígido. Um dos métodos de armazenamento de dados, que nos ocorrem quase instantaneamente é guardar os dados adquiridos num ficheiro de texto.

Por exemplo:

<nome da entrada 1>:<dados><cr><lf> <nome da entrada 2>:<dados><cr><lf>

: : <nome da entrada n>:<dados><cr><lf>

Cada linha em ficheiro, representa um record na base de dados, e cada coluna representa um atributo do record, o nome da entrada no menu de transmissão de sinal, e os dados, sendo delimitada a linha pelo Carriage Return (Cr) e o Line feed (Lf). As colunas são delimitadas por um parenteses dois pontos (:), algo que depende do gosto de quem implementa tal esquema de armazenamento. Pode-se escolher qualquer caracter ou cadeia para separar os campos. Deve-se ter em conta que o delimitador não deve aparecer em nenhum dos campos, isto é, se algum dos campos tiver os dois pontos, a ocorrência desse caracter dever ser substituída por uma sequência de escape, ou por outra forma de representação, por exemplo substituir o caracter ‘:’ por “%3A” que é prática comum quando um browser de internet envia informação para o servidor a fim de ser processada.

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 20 de 85

Retirar os dados do ficheiro também pode ser feito de uma maneira expedita na maioria das linguagens de programação. Apesar deste tipo de armazenamento não ser muito aconselhável para sistemas de bases de dados muito grandes e de índole complexa, é excelente para bases de dados mais pequenas e compactas. Têm a grande vantagem de não ser necessário aprender a trabalhar com programas complexos para manipular a base de dados, um simples editor de texto ASCII serve para visionar e editar os dados (Isto pode comprometer a segurança em certos casos). Outra das formas de armazenar uma base de dados é utilizando o sistema de ficheiros inerente ao sistema operativo. A maioria dos sistemas de ficheiros seguem atentamente o paradigma relacional em que um directório representa uma tabela, o ficheiro representa uma linha na tabela, e os dados representam os atributos das colunas. Implementando uma base de dados baseada num sistema de ficheiros é também muito expedito, e têm enumeras vantagens comparativamente à implementação utilizando ficheiros de texto. Adicionar ou apagar um record não necessita de abrir o ficheiro e processa-lo tal como no método utilizado anteriormente; em vez disso só é necessário editar apenas um ficheiro. Uma base de dados baseada no sistema de ficheiro Também fornece um melhor suporte no contexto de uma base de dados multiutilizador (está opção foi pouco explorada no âmbito deste projecto). Com a implementação da base de dados, baseada num ficheiro ASCII, sempre que os utilizadores queiram modificar o ficheiro, o ficheiro deve ser bloqueado de modo a que os outros utilizadores fiquem impossibilitados de o fazer simultaneamente. Porque os records são entidades separadas na base de dados baseada no sistema de ficheiros, pode-se bloquear records individuais e mesmo assim deixar que os outros utilizadores modifiquem os outros records simultaneamente. Após esta ligeira dissertação sobre métodos de implementação do esquema de armazenamento dos sinais capturados em disco rígido. A solução acordada foi um misto destas duas metodologias de armazenamento. Utilizou-se um ficheiro de inicialização para guardar as entradas no menu de transmissão, e para guardar os dados utilizaram-se ficheiros binários. A metedologia adoptada na aquisição e armazenamento dos dados foi: Pedir ao utilizador um nome a atribuir ao sinal;

Adquirir dados do porto paralelo utilizando o driver do hardware; Gerar aleatóriamente um nome de um ficheiro; Abrir esse ficheiro para escrita e guardar nele os dados adquiridos; Adicionar ao ficheiro de inicialização (ficheiro com a extensão ini) a entrada no

menu de transmissão e o nome do ficheiro onde está o sinal.

Para mais informações sobre os ficheiros de inicialização sugere-se a consulta da alínea 3.4 do presente documento.

Page 11: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 21 de 85

44..33 IInntteerrffaaccee ccoomm oo uuttiilliizzaaddoorr A realidade fundamental do desenvolvimento de uma aplicação é que o interface com o utilizador é o sistema vocacionado para os utilizadores. O que os utilizadores querem é que os programadores construam aplicações que sejam coerentes com as suas necessidades. Basicamente um interface com o utilizador permite às pessoas que entendam o funcionamento da aplicação, sem ter de lêr os manuais ou ter formação. O design de um interface é importante por várias razões. Primeiro de tudo, quando mais intuitivo o interface com o utilizador for mas fácil é o seu uso. Quanto melhor for o interface com o utilizador mais fácil é dar formação às pessoas, reduzindo assim os custos de formação. Quando melhor for o interface com o utilizador, mais os utilizadores vão gostar de utiliza-lo, aumentando a sua satisfação.

Um bom interface com o utilizador deve ser influênciado pelos seguintes factores:

1. Consistência. A coisa mais importante que se pode fazer é ter a certeza que o interface com o utilizador funciona de uma forma consistente. Caso se clique numa lista e aconteceu algo, é de esperar que ao clicar noutra lista idêntica aconteça o mesmo.

2. Definir padrões e ser coerente com eles. A única maneira que se consegue assegurar consistência dentro de uma aplicação é definir os padrões de design e ser coerente com eles.

3. Explicar as regras. Os utilizadores precisam de saber como trabalhar com a aplicação que se construiu para eles. Quando uma aplicação funciona consistentemente significa que se só se deve explicar as regras uma vez. Isso é mais fácil do que explicar detalhadamente como utilizar cada feição da aplicação passo a passo.

4. Suporte para principiantes e peritos. Tomando como analogia uma biblioteca onde existem causais utilizadores a consultar e um bibliotecários, que são pessoas que tiveram formação a pesquisar mais eficientemente na base de dados.

5. A navegação entre os ecrãs de informação é importante. Se é dificil ir de um ecrã de informação para outro facilmente os utilizadores ficam frustrados e desistem. Quando a trasição entre ecrãs é coerente com o fluxo de trabalho que o utilizador está a tentar conseguir, então a aplicação fará sentido para os utilizadores. Porque varios utilizadores trabalham de maneiras diferentes é preciso que o sistema seja flexivel nas suas enumeras abordagens.

6. A navegação dentro do ecrã de informação é importante. Nas sociedades ocidentais as pessoas lêem da esquerda para a direita e de cima

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 22 de 85

para baixo. Deve-se organizar a navegação entre elementos no ecrã de maneira que seja familiar ao utilizador.

7. Atribuir às mensagens ao utilizador palavras apropriadas. O texto que se mostra nos ecrãs da aplicação é a uma fonte primária de informação para os utilizadores. Se o texto tiver um léxico empobrecido então o interface será entendido pelos utilizadores de uma forma diminuta. Utilizando boas palavras e frases, opostamente a abreviaturas e códigos faz com que o texto seja mais facil de entender. As mensagens devem ser entoadas positivamente, e dando opiniões ao utilizador de como resolver o problema. Por exemplo, qual a mensagem que parece mais apeladora “Vôce inseriu a informação errada” ou “Por favor insira um inteiro entre 8 a 100” ?

8. Compreendes os elementos do interface com o utilizador. Deve-se utilizar o elemento de interface certo, ajudando a aumentar a consistência na aplicação em desenvolvimento.

9. Usar as cores apropriadamente. A cor deve ser usada moderadamente nas aplicações, e caso se use deve-se ter em mente um indicador secundário. O problema prende-se com o facto de alguns utilizadores poderem vir a ser daltónicos, se se utilizar uma cor para sobresair algo no ecrã talvez seja necessário transmitir informação redundante (colocar um ícone ao pé do texto por exemplo). Também se deve ter em mente que algumas aplicações não conseguem traduzir fielmente as intenções dos programadores em diferentes sistemas.

10. Seguir a regra de contraste. Caso se utilize cor nas aplicações deve-se assegurar que os ecrãs de informação podem ser lidos pelos utilizadores.

11. Fazer um bom uso de tipos de letras. Entenda-se que alguns tipos de letra ficam bem em livros mas no ecrã são dificeis de ler.

12. Agrupar coisas efectivamente nos ecrãs de informação. Items que estão logicamente relacionados devem ser agrupados juntos no ecrã para comunicar ao utilizador que eles estão ligados, contrariamente items que não têm nada a ver uns com os outros devem ser separados.

Page 12: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 23 de 85

Figura 1 – Menu principal do programa de captura de dados

Na figura ilustra-se o ecrã principal do programa que nos permite capturar sinais infravermelhos através de um PC. As rotinas que nos permitiram criar um interface com o utilizador estão contidas no ficheiro “dui.h”, algumas rotinas foram inspiradas pelos sistemas operativos gráficos que proliferam nos computadores pessoais. Com o uso de um sistema de menus, o programa tornou-se simples de usar. 44..44 FFiicchheeiirrooss ddee iinniicciiaalliizzaaççããoo Os ficheiros de inicialização, são ficheiros que normalmente têm a extensão de “.ini” e fizeram a primeira aparição pública no windows 3.X tm da Microsoft ® . Estes tipos de ficheiros têm uma estrutura funcional muito simples, do género: ; comentário ; comentário ; : ; comentário [secção1] entrada1 = valor1 entrada2 = valor2 : : entradaK= valorK [secção2]

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 24 de 85

entrada1 = valor1 entrada2 = valor2 : :

Os comentários começam sempre com o caracter ‘;’, as secções do ficheiro são delimitadas por ‘[’ e ‘]’ e as entradas nas secções são separadas dos valores pelo caracter ‘=’. Como se pode ver um formato muito simples, tendo uma grande vantagem de poderem ser editados manualmente com a ajuda de um editor de texto ASCII, tal como o “notepad” do Windows 9X.

A classe em C++ capaz de lidar com este tipo de ficheiro é a seguinte: class inifile { public: inifile(const string&); ~inifile(); const string& readstring(const string&, const string&, const string&); void writestring(const string&, const string&, const string&); long readlong(const string&, const string& , const long); void writelong(const string&, const string&, const long); void removesection(const string&); void removekey(const string&, const string&); void readsection(const string&,stringlist&); private: string filename; int altered; class inisection { public: string name; class inientry { public: string key; string value; inientry(); inientry(const string&, const string&); ~inientry(); void add(const string&, const string&); void remove(const string&); inientry* find(const string&); friend class inifile; // cuidado, buraco na armadura friend class inisection; // cuidado, buraco na armadura private: inientry *next; } entries; inisection(const string); inisection(); ~inisection(); void add(const string &); void remove(const string&);

Page 13: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 25 de 85

inisection* find(const string&); friend class inifile; private: inisection* next; } sections; }; Esta classe tomou partido da biblioteca de “strings” que nos permite manipular “strings” de uma forma transparente. Como não é do âmbito deste projecto, explicar exaustivamente o que cada palavra de código faz concretamente vamos sim virar as nossas atenções para a parte do interface da classe (a secção debaixo do palavra chave “public”). O interface com o mundo externo da classe faz-se através de um constructor (inifile(const string&))que inicializa a classe, recebendo como parâmetro o nome do ficheiro que de seguida abre e carrega para a memória do sistema. Andando uma linha ou duas na secção pública da classe encontra-se o destructor que faz o efeito oposto do constructor, isto é guarda os dados em memória num ficheiro em disco. Uma linha mais abaixo encontra-se os métodos que nos permitem lêr e escrever dados no ficheiro: const string& readstring(const string&, const string&, const string&); void writestring(const string&, const string&, const string&); long readlong(const string&, const string& , const long); void writelong(const string&, const string&, const long); void readsection(const string&,stringlist&); Os nomes por si só são sugestivos em que os identificadores associados a “long” permitem ler valores inteiros e os nomes associados à palavra “string” permitem lêr ou escrever cadeias de caractéres. Salienta-se que o uso especial do método ”readsection” que serve para lêr as entradas todas debaixo de uma secção. void removesection(const string&); void removekey(const string&, const string&);

Por fim os métodos que nos permitem apagar entradas no ficheiro. O primeiro método permite remover uma secção inteira e o outro só uma única entrada.

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 26 de 85

44..55 BBiibblliiootteeccaa ddee mmaanniippuullaaççããoo ddee ““ssttrriinnggss”” Uma das coisas que qualquer programador de Pascal/Delphi sente falta quando contacta pela primeira vez com a linguagem de programação C, é o facto de não se poder manipular facilmente “strings”. Para executar operações com “strings” é preciso incluir um cabeçalho que disponibiliza funções idealizadas para a manipulação de “strings”. Uma das vantagens de C++ em relação a C é o facto de permitir um mecânismo denominado operator overloading, isto é, por exemplo redefinir o operador ‘+’ de modo que a instrucção

S1 = S2 + S3;

Permita concatenar duas “strings”. A definição da classe “string” é a seguinte: class string { private: char* _str; long _size; string& hex(char); public: string(); string(char*); string(const string&); ~string(); int length() const; // tamanho da string void urlencode(); void urldecode(); string& slice(int,int); string& operator= (const string&); string& operator= (const char*); string& operator+=(const string&); string& operator+=(const char*); char operator[](int) const; char& operator[](int); const char* c_str() const { return _str; } // buracos na armadura, possiveis fontes de "bugs" friend ostream& operator<<(ostream&,const string&); friend istream& operator>>(istream&,string&); friend string& operator+ (const string&, const string&); friend int operator==(const string&, const string&); friend int operator!=(const string&, const string&); friend int operator> (const string&, const string&); friend int operator< (const string&, const string&); friend class stringlist; };

Page 14: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 27 de 85

Não se vai entrar nos pormenore de implementação, nem explicar detalhadamente o que cada bocadinho de código faz mas sim a motivação que fez com que se cria-se esta classe. Uma das coisas que enervava bastante em C era ter de utilizar sempre as funções do cabeçalho “string.h” para lidar com ”strings”. Após a definição desta classe caso se queira comparar duas “strings” pode-se faze-lo do seguinte modo:

if(Str1 == “valor”) faz_qualquer_coisa();

Está instrução em C, não têm qualquer significado visto que a tradução que o compilador faria era comparar endereços de memória e não o conteúdo. Com o uso do operator overloading pode-se dizer ao compilador para tratar de um modo diferente as expressões que encontra. Nisto que se acabou de se ver, está a flexibilidade da língua C++. Apesar de Ada95 possuir o mesmo mecânismo existe muitos casos em que se torna impraticavel a implementação em Ada95, visto que é uma linguagem que visa agradar o leitor do código fonte e não o programador. Como C++ não têm esse intuito, é uma linguagem mais virada para o programador consegue reduzir o tempo de desenvolvimento para metade, desde que se saiba o que se está a fazer. Apesar de correr o boato que C++ é uma lingua complexa e que só algumas pessoas podem dominar isso é mentira, pense-se nos caractéres chineses à primeira vista pode parecer criptico mas quando se conhece a gramática e se sabe o que significa cada símbolo, as coisas mudam de figura, o que é desmotivamente por vezes é a evolução lenta na apreensão de novos conceitos. Mas adiante, após ter-se criado uma classe que facilita a manipulação de “strings” quase institivamente se pensa em criar uma classe que trate de várias “strings”. Esse objectivo materializou-se na forma da classe “stringlist” que está assim definida: class stringlist { private: string **table; int lines; public: stringlist(); stringlist(const char*); stringlist(const string&); stringlist(const stringlist&); stringlist(const char**, const int argc = 0); ~stringlist(); void clear(); void add(const string&); void add(const char*); void add(const stringlist&);

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 28 de 85

void insert(int,const char*); void insert(int,const string&); void insert(int,const stringlist&); void load(const string&); void load(const char*); void save(const char*) const; void remove(int); void slice(int, int); void split(const char*, const char*); void split(const char*, const string&); void split(const string&, const string&); void split(const string&, const char*); void replace(const char*, const char*); void join(const char*); void join(const string&); int count() const; string& operator[](int); const string& operator[](int) const; };

A funcionalidade desta classe foi inspirada na linguagem interpretada PERL muito popular no mundo Linux. Com esta classe pode-se fazer tudo o que é possível e imaginário com “strings” sendo por isso, usada intensivamente em quase todas as linhas de código que constituem o software de captura de sinais infravermelhos.

Page 15: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 29 de 85

55.. CCoommeennttáárriiooss Mediante o que foi feito no desenvolvimento deste projecto, o próximo passo será adquirir os sinais infravermelhos e detectar qual foi o botão pressionado no comando remoto. Descodificação de sinais infravermelhos Existem pelo menos dois padrões internacionais que são usados nos comandos remotos para codificar os comandos, o código RC5 e o RECS80. O código RECS 80 usa modulação por impulso. Cada bit que vai ser transmitido é codificado por um nível alto de duração T seguido de um nível baixo de duração 2T representando um nível lógico ‘0’ ou 3T representando o nível lógico ‘1’.

Note-se que o ‘1’ demora mais tempo a transmitir que o ‘0’. O código RC5 em vez de adoptar este método de transmissão de dados usa uma duração uniforme para codificar ambos os bits. A transição a meio do intervalo de tempo atribuido a cada bit codifica o sianl. Um ‘0’ é codificado por transição de alto para baixo e o ‘1’ por uma transição de baixo para alto. Contudo são necessárias transições adicionais no íncio de cada bit para se descodificar eficientemente o sinal uma série de bits iguais. Por isso que em algumas numenclaturas é dado a este tipo de codificação bifásica.

Em vez de se enviar este sinal directamente para o emissor de infravermelhos, a maioria dos controlos remotos modulam os dados com uma frequência portadora que ronda 20 a 30kHz. Um ‘1’ lógico é representado como sendo um trem de oscilações.

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 30 de 85

A razão para a qual se utiliza este esquema de transmissão é que deste modo pode-se utilizar um filtro sintonizado à frequência portadora e recuperar o sinal distinguindo assim o sinal do ruído proveniente da luz ambiente. Como é que os botões pressionados no controlo remoto são codificados? No caso da norma RC5 existe um standard internacional, em que cada comando é codificado por 14 bits. Os primeiros dois bits S são startbits para permitirem a sincronia entre o emissor e receptor do sinal. A seguir segue-se o bit T, que se liga cada vez que um botão é pressionado. A seguir vem o endereço A do dispositivo que deverá responder ao comando. Finalmente segue-se o comando em si.

| S | S | T | A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 |

Alguns endereços e comandos importantes:

Endereço Dispositivo Comando 0 TV1 0..9 (seleção de canais) 1 TV2 12 (standby) 6 VCR1 16 (incremento do volume) 17 VCR2 17 (decremento de volume) 18 Tuner 18 (incremento da luminosidade) 20 Audio Tape 19 (decremento da luminosidade) 6 CD Player 50 (fast rewind) 7 52 (fast run forward) 8 53 play 9 54 stop 55 recording

Page 16: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 31 de 85

66.. AAppêênnddiiccee AA 66..11 CCoonntteeúúddoo ddoo ffiicchheeiirroo ““iirrcclloonnee..ccpppp”” /* Instituto Politécnico de Viseu/Escola Superior de Tecnologia de Viseu Sistemas em tempo real Programa principal do software de captura de dados Copyright (c) 2002 N. Loureiro, H. Cardoso & F. Belo */ #include <iostream.h> #include <conio.h> #include <stdio.h> #include <dos.h> #include <time.h> #include <sys/stat.h> //#define DEBUG // usado na depuração para ligar e desligar o hardware #include "strlib.h" // biblioteca de manipulação de "strings" #include "inifiles.h" // ficheiros ini #include "dui.h" // dos user interface #include "ir.h" // driver do hardware #define INIFILENAME "irclone.ini" #define defaultLPTport 888 #define defaultMode 0 // transmissão do sinal por impulsos #define defaultBufsize 30*1024 // um buffer 30k, mais do que suficiente int lptport ; // porto da impressora int continuous; // transmissão continua do sinal int bufsize ; // tamanho do buffer // protótipos das funções utilizadas no programa void sendsignal(); void capturesignal(); void surgery(); void showcredit(); void showoptions(); void showhelp(); inifile ini(INIFILENAME); // ficheiro ini onde se guarda toda a informação inerente ao programa int main() { int option;

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 32 de 85

try { char* items[] = { " Transmitir sinal ", " Adquirir sinal ", " Surgeria ", " Op‡äes ", " Ajuda sobre o programa ", " Cr‚ditos ", " Òxodo " }; lptport = ini.readlong("options","lptport",1111); if(lptport == 1111) { // erro a entrada no ini não existe lptport = defaultLPTport; } if(ini.readstring("options","mode","error") == "continuous") continuous = 1; else continuous = defaultMode; // erro a entrada não existe bufsize = ini.readlong("options","bufsize",1111); if(bufsize == 1111) // a entrada não existe bufsize = defaultBufsize; wipescr(); do { _setcursortype(_NOCURSOR); background("PCircloner v1.0á",MENU_KEYS); switch((option=menu(items,7))) { case 1: wipescr(); sendsignal(); wipescr(); break; case 2: wipescr(); capturesignal(); wipescr(); break; case 3: wipescr(); surgery(); wipescr(); break; case 4: wipescr(); showoptions(); wipescr(); break; case 5: wipescr(); showhelp(); wipescr(); break; case 6: wipescr(); showcredit(); wipescr(); break; case 7: option = 0; break; } }while(option); wipescr(); cout << "PCircloner v1.0á "<< __DATE__ << endl; // actualiza o ficheiro ini referente às op‡äes if(continuous) ini.writestring("options","mode","continuous"); else ini.writestring("options","mode","burst"); ini.writelong("options","lptport",lptport); ini.writelong("options","bufsize",bufsize); } catch(exception &e) { textbackground(BLACK); clrscr(); cout << "\n DEBUG(" << e.code << "):" << e.msg << endl; cout << " " << e.src <<endl;

Page 17: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 33 de 85

} return 0; } void surgery() { stringlist entries; int item; char* items[]= { " Mudar de nome ao sinal ", " Apagar item ", " Apagar tudo ", " Continuar... " }; int option; string oldname; string newname; string value; _setcursortype(_NOCURSOR); do { background("Surgeria",MENU_KEYS); option = menu(items,4); switch(option) { case 1: // retira do ficheiro ini a listagem dos sinais ini.readsection("signals",entries); if(!entries.count()) { messagebox(" NÆo existe nenhum sinal capturado"); break; // lista vazia esquece } gotoxy(13,5); textcolor(YELLOW); textbackground(BLACK); highvideo(); cprintf("Por favor escolha o nome do sinal que deseja alterar"); item = listbox(entries,13,6,51,12); if(!item) break; // foi cancelado volta para o menu principal textbackground(BLACK); window(1,5,80,21); // limpa o ecrã na janela especificada clrscr(); window(1,1,80,25); // volta a restaurar o tamanho da janela textcolor(WHITE); gotoxy(13,8);

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 34 de 85

delaywrite("Nome antigo"); oldname = "-> \"" + entries[item-1] + "\""; gotoxy(14,9); delaywrite(oldname); oldname = entries[item-1]; gotoxy(13,11); delaywrite("Introduza o novo nome a atribuir … entrada"); gotoxy(14,12); newname = inputstr(PTFILTER,45); if(newname.length() == 0) break; // string vazia a função foi cancelada value = ini.readstring("signals",oldname,"ERROR"); // impossivel falhar ini.removekey("signals",oldname); ini.writestring("signals",newname,value); textbackground(BLACK); window(1,5,80,21); clrscr(); window(1,1,80,25); // volta a restaurar o tamanho da janela break; case 2: ini.readsection("signals",entries); if(entries.count() == 0) { messagebox("NÆo existe nenhum sinal capturado"); break; } item = listbox(entries,13,6,51,12); if(!item) break; // foi cancelado textbackground(BLACK); window(1,5,80,21); clrscr(); window(1,1,80,25); // volta a restaurar o tamanho da janela ini.removekey("signals",entries[item-1]); break; case 3: ini.readsection("signals",entries); if(entries.count() == 0) { messagebox(" NÆo existe nenhum sinal capturado"); break; } for(int i=0 ;i < entries.count(); i++) { ini.removekey("signals",entries[i]); }

Page 18: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 35 de 85

// apaga todos os ficheiros no direct¢rio utilizando a "DOS Shell" system("del ./signals/*.ir"); break; case 4: option = 0; break; } } while(option); _setcursortype(_NORMALCURSOR); } void sendsignal() { _setcursortype(_NOCURSOR); background("Transmitir sinal",MENU_KEYS); int option; char screen[4096]; char* buffer; long buflen; string filename; FILE* handle; // saca do ini os valores das secções stringlist list; ini.readsection("signals",list); if(!list.count()) { messagebox(" NÆo existe nenhum sinal capturado"); return; } do { option = listbox(list,13,6,51,12); if(option) { filename = ini.readstring("signals",list[option-1],"error"); if(filename == "error") { messagebox("Erro a ler o ficheiro ini"); return; } handle = fopen(filename.c_str(),"rb"); if(!handle) { messagebox("Erro a ler o ficheiro bin rio"); return; } // calcula o tamanho do ficheiro fseek(handle,0L,SEEK_END); buflen = ftell(handle); fseek(handle,0L,SEEK_SET); buffer = new char[buflen]; if(!buffer) { fclose(handle); messagebox("Erro falta de mem¢ria");

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 36 de 85

return; } if(!fread(buffer,buflen,1,handle)) { fclose(handle); delete []buffer; messagebox("Erro de leitura do ficheiro bin rio"); return; } if(continuous) { gettext(1,1,80,25,screen); textbackground(BLUE); window(20,10,60,15); clrscr(); window(1,1,80,25); textcolor(YELLOW); frame(20,10,60,15); // desenha um "frame" textcolor(WHITE); gotoxy(23,12); delaywrite("Modo de transmissÆo cont¡nuo activo"); gotoxy(26,13); delaywrite("Pressione <ESC> para terminar"); do { #ifndef DEBUG irPlay(buffer,buflen,lptport); #endif }while(getch() != ESC_KEY); puttext(1,1,80,25,screen); } else #ifndef DEBUG irPlay(buffer,buflen,lptport); #endif delete []buffer; fclose(handle); } } while(option); _setcursortype(_NORMALCURSOR); } void showhelp() { #define MAX_ITEMS 11 char* help[MAX_ITEMS] = { "O software, nÆo faz qualquer detec‡Æo de hardware ", "caso nÆo exista nenhuma placa de aquisi‡Æo dos ", "dados pelo porto paralelo, o programa bloqueia.", "Escolheu-se esta solu‡Æo para nÆo aumentar o n£mero ", "de componentes electr¢nicos necess rios ao projecto.", "",

Page 19: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 37 de 85

"Antes de se poder utilizar este software deve-se", "configurar o endere‡o do porto paralelo e o tamanho", "do buffer de aquisi‡Æo de dados do receptor de", "infravermelhos. (Est tudo debaixo do item \"Op‡äes\"", "referente ao menu principal)" }; _setcursortype(_NOCURSOR); background("Ajuda sobre o programa"," Pressione <ESC> para continuar "); textbackground(BLACK); textcolor(YELLOW); highvideo(); gotoxy(14,6); delaywrite("Importante"); textcolor(WHITE); for(int i=0;i<MAX_ITEMS;i++) { gotoxy(14,8+i); cprintf(help[i]); } pause(); _setcursortype(_NORMALCURSOR); #undef MAX_ITEMS // já não precisamos deste #define } void showcredit() { _setcursortype(_NOCURSOR); background("Cr‚ditos"," Pressione <ESC> para continuar "); textbackground(BLACK); textcolor(WHITE); highvideo(); gotoxy(36,5); delaywrite("ISPV/ESTV"); gotoxy(20,6); delaywrite("Departamento de Engenharia Electr¢tecnica"); gotoxy(40-11,7); delaywrite("Licenciatura 2001/2002"); textcolor(YELLOW); highvideo(); gotoxy(13,9); delaywrite("¶mbito"); gotoxy(18,10); textcolor(WHITE); lowvideo(); cprintf("Sistemas em tempo real"); gotoxy(13,12); highvideo(); textcolor(YELLOW); delaywrite("Programa‡Æo & Design"); textcolor(WHITE);

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 38 de 85

lowvideo(); gotoxy(18,13); cprintf("Nuno Loureiro (n§ 2810)"); gotoxy(13,15); highvideo(); textcolor(YELLOW); delaywrite("Depura‡Æo & Sugestäes"); textcolor(WHITE); lowvideo(); gotoxy(18,16); cprintf("Henrique Cardoso(n§ 3485) & Fernando Belo(n§ 3424)"); gotoxy(13,18); highvideo(); textcolor(YELLOW); delaywrite("SupervisÆo"); textcolor(WHITE); lowvideo(); gotoxy(18,19); cprintf("Paulo Mois‚s, Eng§"); pause(); _setcursortype(_NORMALCURSOR); } void showoptions() { int key,i; int index = 0; struct point{ int x; int y; } points[3] = {{49,11},{49,13},{49,15}}; int ports[2] = {888,0x238}; int bufsizes[8]= {8*1024,16*1024,32*1024,64*1024,128*1024,256*1024,512*1024,1024*1024}; int portindex = 0; int bfindex = 0; _setcursortype(_NOCURSOR); background("Op‡äes",MENU_KEYS); textbackground(BLACK); textcolor(WHITE); highvideo(); frame(18,7,62,19); textcolor(GREEN); gotoxy(22,11); cprintf("Endere‡o base do porto : [ ]"); gotoxy(22,13); cprintf("Tamanho do buffer : [ ]"); gotoxy(22,15); cprintf("Modo de transmissÆo : [ ]");

Page 20: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 39 de 85

do { textcolor(WHITE); lowvideo(); for(i=0;i<3;i++) { switch(i) { case 0: gotoxy(points[i].x,points[i].y); cprintf("%7xh",lptport); break; case 1: gotoxy(points[i].x,points[i].y); cprintf("%8i",bufsize); break; case 2: gotoxy(points[i].x,points[i].y); if(continuous) cprintf("cont¡nuo"); else cprintf("impulso "); break; } } highvideo(); switch(index) { case 0: gotoxy(points[index].x,points[index].y); cprintf("%7xh",lptport); break; case 1: gotoxy(points[index].x,points[index].y); cprintf("%8i",bufsize); break; case 2: gotoxy(points[index].x,points[index].y); if(continuous) cprintf("cont¡nuo"); else cprintf("impulso "); break; } key = getch(); switch(key) { case UPARROW_KEY : index--; break; case DOWNARROW_KEY : index++; break; case ENTER_KEY: switch(index) { case 0 : lptport = ports[portindex & 0x1]; portindex++; break; case 1 : bufsize=bufsizes[bfindex & 0x7]; bfindex++; break;

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 40 de 85

case 2 : continuous = ! continuous; break; } break; } if(index < 0) index = 0; if(index >=3) index = 2; }while(key != ESC_KEY); _setcursortype(_NORMALCURSOR); } string& randfilename() { const string letters("abcdefghijklmnopqrstuvwxyz012345678_$"); static string res; char dummy[2] = {'?','\0'}; time_t t; srand((unsigned)time(&t)); // inicia gerador de números aleatórios res=""; for(int i=0;i<8;i++) { dummy[0] = letters[rand() % letters.length()]; res +=dummy; } res = "./signals/"+res+".ir"; // extensão do ficheiro return res; } void capturesignal() { _setcursortype(_NOCURSOR); string filename(randfilename()); // cria um nome de um ficheiro aleatóriamente FILE* handle; // handle para um ficheiro binário char* buffer; // buffer para os dados unsigned int length; // comprimento do buffer de dados adquiridos background("Adquirir sinal",""); textcolor(WHITE); textbackground(BLACK); gotoxy(16,8); highvideo(); textcolor(WHITE); delaywrite("Nome a atribuir ao sinal"); string entry; _setcursortype(_NORMALCURSOR); // mostra cursor textcolor(WHITE); gotoxy(16,9); cprintf("["); gotoxy(16+48,9); cprintf("]"); frame(14,7,14+52,7+3); // nome do sinal gotoxy(18,9);

Page 21: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 41 de 85

entry = inputstr(PTFILTER,45); if(!entry.length()) return; // foi cancelado highvideo(); _setcursortype(_NOCURSOR); textcolor(WHITE); gotoxy(15,12); cprintf("Aponte o comando remoto na direc‡Æo do receptor"); gotoxy(15,13); cprintf("de infravermelhos."); gotoxy(15,14); textcolor(RED); cprintf("(Caso o programa bloqueie, verifique as liga‡äes"); gotoxy(15,15); cprintf("da placa acoplada ao porto paralelo)"); gotoxy(15,17); textcolor(WHITE); delaywrite("Aguardando a presen‡a de sinal no porto..."); buffer = new char[bufsize]; _assert(!buffer,exception(1,"void capturesignal()","falta de mem¢ria")); mkdir("./signals",S_IWUSR); #ifndef DEBUG length = irRecord(buffer,bufsize,lptport); #else length = bufsize; #endif handle = fopen(filename.c_str(),"wb"); if(!handle) { delete buffer; throw exception(1,"void capturesignal()","erro de escrit no ficheiro"); } fwrite(buffer,length,1,handle); // salva o sinal num ficheiro binário fclose(handle); delete buffer; gotoxy(25,19); delaywrite("Dados adquiridos com sucesso"); gotoxy(25,20); delaywrite("Pressione <ESC> para continuar"); pause(); ini.writestring("signals",entry,filename); // adiciona a entrada ao ficheiro ini }

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 42 de 85

66..22 CCoonntteeúúddoo ddoo ffiicchheeiirroo ““iirr..hh”” /* Instituto Politécnico de Viseu/Escola Superior de Tecnologia de Viseu Sistemas em tempo real Software para controlar o hardware de aquisição do sinal infravermelho Copyright (c) 2002 N. Loureiro, H. Cardoso & F. Belo */ #ifndef __IR_H #define __IR_H #include <conio.h> // Interface unsigned int irRecord(char* buffer, unsigned int length, unsigned int baseport); /* Rotina que captura o sinal do porto paralelo do PC e armazena os dados num buffer, passado como parâmetro à rotina e devolve o número de bytes escritos no buffer */ void irPlay(char* buffer, unsigned int length, unsigned int baseport); /* Rotina que reproduz os dados no porto paralelo do PC */ // Implementação unsigned int irRecord(char* buffer, unsigned int length, unsigned int baseport) { unsigned int i, j, len; unsigned char mask, d; // desliga momentaneamente as interrupções do processador _disable(); // liga a alimentação do fotodíodo outp(baseport,2); // espera até que exista sinal no porto while ((inp(baseport+1) & 16) == 0); while ((inp(baseport+1) & 16) == 16); for (i = 0; i < length; i++) { mask = 128; d = 0; for (j = 0; j < 8; j++){ if ((inp(baseport+1) & 16) == 0) d |= mask; mask = mask >> 1; } buffer[i] = d;

Page 22: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 43 de 85

} // desliga a alimentação do fototransístor de emissão do sinal outp(baseport,0); // volta a inibir as interrupções do processador _enable(); // retira todos zeros a mais que estejam no fim da sequência for (len = length-1; len; len--) if (buffer[len]) break; // devolve o tamanho dos dados adquiridos return len; } void irPlay(char* buffer, unsigned int length, unsigned int baseport) { unsigned int i, j; unsigned char mask, d; // suspende as interrupções do processador _disable(); for (i = 0; i < length; i++) { mask = 128; d = buffer[i]; for (j = 0;j < 8; j++) { if (d & mask) outp(baseport,1); else outp(baseport,0); mask = mask >> 1; } } // volta a inibir as interrupções do processador _enable(); // desliga a alimentação do fototransístor de emissão do sinal outp(baseport, 0); } #endif 66..33 CCoonntteeúúddoo ddoo ffiicchheeiirroo ““dduuii..hh”” /* Instituto Politécnico de Viseu/Escola Superior de Tecnologia de Viseu Sistemas em tempo real Interface com o utilizador no modo de texto Copyright (c) 2002 N. Loureiro, H. Cardoso & F. Belo */ #ifndef __DUI_H #define __DUI_H

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 44 de 85

#include <conio.h> #include <dos.h> #include <ctype.h> #include "strlib.h" /* Interface */ #define MENU_KEYS " cancelar <ESC> aceitar <\xC0\x10> escolher <\x18> , <\x19> " #define PTFILTER "abcdefgqhijklmnopqrstuvwxyz0123456789Š¡¢£… Æä " #define ENTER_KEY 13 #define ESC_KEY 27 #define UPARROW_KEY 72 #define DOWNARROW_KEY 80 #define PAGEUP_KEY 73 #define PAGEDOWN_KEY 81 #define BACKSPACE 8 void background(const string& title,const string& keys); int menu(char* items[],int MAX_ITEMS); void wipescr(); void frame(int x1, int y1, int x2, int y2); void hscrollbar(int x, int y, int size,int pos, int max); int listbox(stringlist list, int x, int y, int sizeX, int sizeY); void delaywrite(const string &s); void pause(); void vsync(); string& inputstr(const string& filter, int size); void messagebox(const string& str); /* Implementação */ static void hline(int y, int x1, int x2) { for(int i=x1;i<x2;i++) { gotoxy(i,y); cprintf("%c",205); } } //pseudo função #define putchxy(x,y,ch) gotoxy(x,y); cprintf("%c",ch) void frame(int x1, int y1, int x2, int y2) { int i; putchxy(x1,y1,218); putchxy(x2,y1,191); putchxy(x1,y2,192); putchxy(x2,y2,217); for(i = x1 + 1; i < x2;i++){

Page 23: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 45 de 85

putchxy(i,y1,196); putchxy(i,y2,196); } for(i = y1 + 1; i < y2;i++){ putchxy(x1,i,179); putchxy(x2,i,179); } } void background(const string& title,const string& keys) { textbackground(BLACK); clrscr(); highvideo(); textcolor(GREEN); hline(4,1,80-12); hline(22,12,80); textcolor(WHITE); lowvideo(); gotoxy(13,23); cprintf(" Copyright (c) 2002 N. Loureiro, H. Cardoso & F. Belo"); gotoxy(80-12-title.length()-6,3); cprintf("%s",title.c_str()); textbackground(BLUE); textcolor(WHITE); gotoxy(13,21); cprintf("%s",keys.c_str()); } int menu(char* items[],int MAX_ITEMS) { int index = 1; int key; int i; int centerX = 40 - strlen(items[0])/2; _setcursortype(_NOCURSOR); textbackground(BLACK); textcolor(WHITE); frame(centerX-1,9,centerX+strlen(items[0]),9+MAX_ITEMS+1); do { for (i=0;i<MAX_ITEMS;i++) { lowvideo(); textcolor(WHITE); textbackground(BLACK); gotoxy(centerX,10+i); cprintf(items[i]); } highvideo(); textcolor(WHITE); textbackground(GREEN); gotoxy(centerX,10+index-1); cprintf(items[index-1]); key = getch();

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 46 de 85

switch(key) { case UPARROW_KEY : index--; break; case DOWNARROW_KEY: index++; break; } if(index < 1) index = 1; if(index >= MAX_ITEMS) index = MAX_ITEMS; } while((key != ENTER_KEY) && (key != ESC_KEY)); _setcursortype(_NORMALCURSOR); // cancelado if(key == ESC_KEY) return 0; else return index; } void wipescr() { textbackground(BLACK); clrscr(); } void hscrollbar(int x, int y, int size,int pos, int max) { char* sep = "\xC3\xC4\xB4"; int i; if(size <= 0) size = 1; if(max <= 0) max = 1; frame(x,y,x+2,y+size+6); gotoxy(x,y+2); cprintf(sep); gotoxy(x,y+size+6-2); cprintf(sep); gotoxy(x+1,y+1); cprintf("\x1E"); gotoxy(x+1,y+size+6-1); cprintf("\x1F"); for(i= y+3 ;i <= y+size+3;i++) { gotoxy(x+1,i); cprintf(" "); } float location; if(pos > max) location = size; else location = ((float) pos / (float)max)* (float) size; gotoxy(x+1,y+3+(int)location); cprintf("\xDB"); gotoxy(x+1,y+1); if((int)location == size) textcolor(GREEN); cprintf("\x1E"); textcolor(WHITE); if(((int)location != size) && ((int) location != max)) textcolor(GREEN);

Page 24: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 47 de 85

gotoxy(x+1,y+size+6-1); cprintf("\x1F"); } int listbox(stringlist list, int x, int y, int sizeX, int sizeY) { static int index = 0; int page,offset; char spaces[81]; int key,i; if(list.count() == 0) return 0 ; if(sizeY == 0) sizeY = 1; if (index >= list.count()) index = 0; textcolor(WHITE); textbackground(BLACK); frame(x,y,x + sizeX, y + sizeY+1); for(i=0;i<81;i++) { spaces[i] = ' '; } if(sizeX < 80) spaces[sizeX-1] = '\0'; else spaces[80] = '\0'; for(i=0;i < list.count();i++) { if(list[i].length() > sizeX) { list[i].slice(0,sizeX-5); list[i] += "..."; } } _setcursortype(_NOCURSOR); do { offset = index % sizeY; page = index/sizeY; textcolor(WHITE); textbackground(BLACK); vsync(); hscrollbar(x+sizeX,y,sizeY-5,index+1,list.count()); for(i=0;i < sizeY;i++) { textcolor(WHITE); textbackground(BLACK); gotoxy(x+1,y+1+i); cprintf("%s",spaces); gotoxy(x+1,y+1+i); if(i+page*sizeY < list.count()) cprintf("%s",list[i+page*sizeY].c_str());

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 48 de 85

} textcolor(BLACK); textbackground(GREEN); gotoxy(x+1,y + 1 + offset); cprintf("%s",spaces); gotoxy(x+1,y + 1 + offset); cprintf("%s",list[page*sizeY + offset].c_str()); key = getch(); switch(key) { case UPARROW_KEY : index--; break; case DOWNARROW_KEY : index++; break; case PAGEUP_KEY : index-=sizeY; break; case PAGEDOWN_KEY : index+=sizeY; break; } if(index < 0) index = 0; if(index >= list.count()) index = list.count()-1; } while((key != ESC_KEY) && (key != ENTER_KEY)); _setcursortype(_NORMALCURSOR); if(key == ESC_KEY) { // foi cancelado return 0; } else // devolve o ìndice da "string" seleccionada return index+1; } void delaywrite(const string &s) { int tm = 1200 / (s.length()+1); int x1,y1; int i; x1 = wherex(); y1 = wherey(); for (i=0;i < s.length();i++) { delay(tm); cprintf("%c",s[i]); if(kbhit()) break; } gotoxy(x1,y1); cprintf("%s",s.c_str()); } void pause() { do {} while(getch() != ESC_KEY); } static int checkfilter(const string& filter,char ch) { for(int i=0;i<filter.length();i++) // o caracter existe no filtro if(filter[i] == tolower(ch)) return 1; // o caracter não existe no filtro return 0;

Page 25: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 49 de 85

} string& inputstr(const string& filter, int size) { static string res; char dummy[2] = {'?','\0'}; string spaces(""); int key; int x,y; x = wherex(); y = wherey(); dummy[0] = '.'; for(int i=0;i < size;i++) spaces += dummy; lowvideo(); gotoxy(x,y); cprintf("%s",spaces.c_str()); gotoxy(x,y); res = ""; do { key = getch(); if(checkfilter(filter,key)) { // converte um caracter para uma "string" dummy[0] = key; res += dummy; vsync(); gotoxy(x,y); cprintf("%s",spaces.c_str()); gotoxy(x,y); cprintf("%s",res.c_str()); } else if((key == BACKSPACE) && (res.length())) { if(res.length() == 1) res = ""; else // limpa o último caracter da cadeia res.slice(0,res.length()-2); // actualiza o ecrã vsync(); gotoxy(x,y); cprintf("%s",spaces.c_str()); gotoxy(x,y); cprintf("%s",res.c_str()); } if(res.length() > size) { // simula a tecla enter key = ENTER_KEY; break; // sai do loop } if((key == ENTER_KEY) && (!res.length())) // nada de "strings" vazias key = 'x'; } while((key != ESC_KEY) && (key != ENTER_KEY));

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 50 de 85

if(key == ESC_KEY) { // a operação foi cancelada res = ""; } return res; } void vsync() { while(!(inp(0x03DA) & 0x08)); while(!(inp(0x03DA) & 0x08)); } void messagebox(const string& str) { char screen[4096]; // captura o ecrã gettext(1,1,80,25,screen); textbackground(RED); _setcursortype(_NOCURSOR); window(20,11,60,15); clrscr(); window(1,1,80,25); textcolor(YELLOW); // desenha um frame frame(20,11,60,15); textcolor(WHITE); gotoxy(22,12); cprintf("%s",str.c_str()); // restaura o ecrã gotoxy(25,14); delaywrite("Pressione <ESC> para continuar"); // espera até que se pressione a tecla de ESC pause(); puttext(1,1,80,25,screen); } #endif

66..55 CCoonntteeúúddoo ddoo ffiicchheeiirroo ““iinniiffiilleess..hh”” /* Instituto Politécnico de Viseu/Escola Superior de Tecnologia de Viseu Sistemas em tempo real Class criada com o intuito de fornecer suporte para ficheiros de inicialização debaixo de MS-DOS Copyright (c) 2002 N. Loureiro, H. Cardoso & F. Belo */ #ifndef __INIFILES_H #define __INIFILES_H

Page 26: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 51 de 85

#include <stdlib.h> #include <string.h> #include <stdio.h> #include "exception.h" #include "strlib.h" #define TMPINI "tempini.$$$" // nome do ficheiro ini temporàrio class ifexception : public exception { public: ifexception(int _code, char* _src, char* _msg) { code = _code; src = _src; msg = _msg; } virtual ~ifexception() {} }; class inifile { public: inifile(const string&); ~inifile(); const string& readstring(const string&, const string&, const string&); void writestring(const string&, const string&, const string&); long readlong(const string&, const string& , const long); void writelong(const string&, const string&, const long); void removesection(const string&); void removekey(const string&, const string&); void readsection(const string&,stringlist&); private: string filename; int altered; class inisection { public: string name; class inientry { public: string key; string value; inientry(); inientry(const string&, const string&); ~inientry(); void add(const string&, const string&); void remove(const string&); inientry* find(const string&); friend class inifile; // cuidado, buraco na armadura friend class inisection; // cuidado, buraco na armadura private: inientry *next; } entries; inisection(const string); inisection(); ~inisection(); void add(const string &); void remove(const string&); inisection* find(const string&); friend class inifile;

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 52 de 85

private: inisection* next; } sections; }; inifile::inifile(const string& fn) { altered = 0; filename = fn; stringlist tmp; ifstream in(filename.c_str()); string str; string csection; inisection *section; if(!in.fail()) { // o ficheiro existe carrega-o para a memória do { in >> str; if((str[0] == '[') && (str[str.length()-1] == ']')) { csection = str.slice(1,str.length()-2); sections.add(csection); // adiciona secção } else if ((str[0] == ';') || (str.length() == 0)) { // não faz nada ignora é o começo de um comentário } else { tmp.split(str,"="); // parte a string pelo '=' if(tmp.count() == 2) { section = sections.find(csection); if(section) { // adiciona entradas caso contrário ignora section->entries.add(tmp[0],tmp[1]); } } } } while(in.get() != EOF); } } inifile::~inifile() { if(altered) { // artimanhã para libertar o handle do ficheiro ofstream out(TMPINI); inisection* section = sections.next; inisection::inientry* entry; _assert(out.fail(),ifexception(4,"inifile::~inifile()","erro de escrita no ficheiro")); out << endl;

Page 27: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 53 de 85

while(section) { out << "[" << section->name << "]\n" << endl; entry = section->entries.next; _assert(out.fail(),ifexception(4,"inifile::~inifile()","erro de escrita no ficheiro")); while(entry) { out << entry->key << "=" << entry->value << endl; _assert(out.fail(),ifexception(4,"inifile::~inifile()","erro de escrita no ficheiro")); entry = entry->next; } out << endl; // muda de linha, não é necessário mas melhora o aspecto do ficheiro section = section->next; } out.close(); // liberta o handle do ficheiro remove(filename.c_str()); // apaga o ficheiro do disco rename(TMPINI,filename.c_str());// muda de nome ao ficheiro temporário } } void inifile::removekey(const string& section, const string& key) { inisection* ref = sections.find(section); if(ref) ref->entries.remove(key); } void inifile::removesection(const string& section) { sections.remove(section); } void inifile::readsection(const string& section, stringlist& list) { inisection* ref = sections.find(section); inisection::inientry * entry; list.clear(); if(ref) { entry = ref->entries.next; while(entry) { //cout << entry->key << endl; list.add(entry->key); // adiciona os elementos à lista entry = entry->next; } } }

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 54 de 85

const string& inifile::readstring(const string& section, const string& key, const string& def) { inisection* sec; inisection::inientry* ent; sec = sections.find(section); if(!sec) return def; // devolve a string por omissão ent = sec->entries.find(key); if(!ent) return def; // devolve a string por omissão return ent->value; // valor da string associada à entrada } void inifile::writestring(const string& section, const string& key, const string& value) { inisection *ref; sections.add(section); // adiciona as secções ref = sections.find(section); // impossivel falhar ref->entries.add(key,value); altered = 1; } void inifile::writelong(const string& section, const string& key, const long value) { char buffer[256]; sprintf(buffer,"%li",value); writestring(section,key,buffer); } long inifile::readlong(const string& section, const string& key, const long def) { string tmp = readstring(section,key,"#ERROR#"); long t; if(tmp != "#ERROR#") { t = -9999; sscanf(tmp.c_str(), "%li",&t); if(t != -9999) return t; else return def; } else return def; } inifile::inisection::inisection(const string nm) { next = NULL; name = nm; } inifile::inisection::inisection() { next = NULL; name = ""; }

Page 28: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 55 de 85

inifile::inisection::~inisection() { delete next; // apaga recursivamente os outros nodos } void inifile::inisection::remove(const string& _name) { inisection* ptr = this; inisection* prior= this; while((ptr = ptr->next)) { if(ptr->name == _name) { prior->next = ptr->next; ptr->next = NULL; delete ptr; return; } prior = ptr; ptr = ptr->next; } } void inifile::inisection::add(const string& _name) { if(find(_name)) return; // o nome da seccão já existe aborta if(next) { inisection* ptr = this; while(ptr->next) ptr = ptr->next; ptr->next = new inisection(_name); _assert(!ptr->next,ifexception(1,"void inifile::inisection::add(const string& _name)","falta de mem¢ria")); } else { next = new inisection(_name); _assert(!next,ifexception(1,"void inifile::inisection::add(const string& _name)","falta de mem¢ria")); } } inifile::inisection* inifile::inisection::find(const string& _name) { inisection* ptr = next; while(ptr) { if(ptr->name == _name) return ptr; ptr = ptr->next; } return NULL; } inifile::inisection::inientry::inientry() { next = NULL; key = ""; value= ""; }

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 56 de 85

inifile::inisection::inientry::inientry(const string& _key, const string& _value) { next = NULL; key = _key; value = _value; } inifile::inisection::inientry::~inientry() { delete next; // apaga recursivamente os outros nodos } inifile::inisection::inientry* inifile::inisection::inientry::find(const string& _key) { // pesquina linear iterativa inientry* ptr = this; // começa na raíz while((ptr = ptr->next)) if(ptr->key == _key) return ptr; return NULL; } void inifile::inisection::inientry::remove(const string& _key) { inientry* ptr = next; inientry* prior = this; while(ptr) { if(ptr->key == _key) { prior->next = ptr->next; ptr->next = NULL; delete ptr; return; } prior = ptr; ptr = ptr->next; } } void inifile::inisection::inientry::add(const string& _key, const string& _value) { inientry* entry = find(_key); if(entry) { // a entrada já existe actualiza entry->value = _value; return; } if(next) { inientry* ptr = next; while(ptr->next) ptr = ptr->next; ptr->next = new inientry(_key,_value); _assert(!ptr->next,ifexception(1,"void inifile::inisection::inientry::add(const string& _key, const string& _value)","falta de mem¢ria")); } else { next = new inientry(_key,_value);

Page 29: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 57 de 85

_assert(!next,ifexception(1,"void inifile::inisection::inientry::add(const string& _key, const string& _value)","falta de mem¢ria")); } } #endif

66..66 CCoonntteeúúddoo ddoo ffiicchheeiirroo ““ssttrrlliibb..hh”” /* Instituto Politécnico de Viseu/Escola Superior de Tecnologia de Viseu Sistemas em tempo real Classes que facilitam o manuseamento de "strings" em C++ Copyright (c) 2002 N. Loureiro, H. Cardoso & F. Belo */ #ifndef __STRLIB_H #define __STRLIB_H #include <string.h> #include <iostream.h> #include <fstream.h> #include "exception.h" class strexception: public exception { public: strexception(int c, char* s, char* m) { code=c; src = s; msg=m; } virtual ~strexception() {} }; // protótipo da class class stringlist; class string { private: char* _str; long _size; string& hex(char); public: string(); string(char*); string(const string&); ~string(); int length() const; // tamanho da string void urlencode(); void urldecode(); string& slice(int,int); string& operator= (const string&); string& operator= (const char*); string& operator+=(const string&); string& operator+=(const char*); char operator[](int) const;

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 58 de 85

char& operator[](int); const char* c_str() const { return _str; } // buracos na armadura, possiveis fontes de "bugs" friend ostream& operator<<(ostream&,const string&); friend istream& operator>>(istream&,string&); friend string& operator+ (const string&, const string&); friend int operator==(const string&, const string&); friend int operator!=(const string&, const string&); friend int operator> (const string&, const string&); friend int operator< (const string&, const string&); friend class stringlist; }; class stringlist { private: string **table; int lines; public: stringlist(); stringlist(const char*); stringlist(const string&); stringlist(const stringlist&); stringlist(const char**, const int argc = 0); ~stringlist(); void clear(); void add(const string&); void add(const char*); void add(const stringlist&); void insert(int,const char*); void insert(int,const string&); void insert(int,const stringlist&); void load(const string&); void load(const char*); void save(const char*) const; void remove(int); void slice(int, int); void split(const char*, const char*); void split(const char*, const string&); void split(const string&, const string&); void split(const string&, const char*); void replace(const char*, const char*); void join(const char*); void join(const string&); int count() const; string& operator[](int); const string& operator[](int) const; }; string::string() { _str = new char[1]; _str[0]= '\0'; // string vazia _size = 0; }

Page 30: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 59 de 85

string::string(char* s) { _str = new char [strlen(s)+1]; _assert(!_str,strexception(1,"string::string(char* s)","falta de mem¢ria")); strcpy(_str,s); _size = strlen(_str); } string& string::slice(int start, int end) { int tmp; if(start > end) { // permuta valores tmp = start; start = end; end = tmp; } _assert((start < 0) || (start >= _size) || (end < 0) || (end >= _size), strexception(2,"string& string::slice(int start, int end) {","¡ndice fora de limites")); _str[end+1] = '\0'; strcpy(_str,_str+start); _size = strlen(_str); return *this; } string::string(const string& s) { _str = new char [strlen(s._str)+1]; _assert(!_str,strexception(1,"string::string(const string& s)","falta de mem¢ria")); strcpy(_str,s._str); _size = strlen(_str); } string::~string() { delete []_str; } int string::length() const{ return _size; } string& string::operator=(const string& s){ if(this != &s) { delete []_str; _str = new char[strlen(s._str)+1]; _assert(!_str,strexception(1,"string& string::operator=(const string& s)","falta de mem¢ria")); strcpy(_str,s._str); _size = strlen(_str); } return *this; }

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 60 de 85

string& string::operator=(const char* s){ delete []_str; _str = new char[strlen(s)+1]; _assert(!_str,strexception(1,"string& string::operator=(const char* s)","falta de mem¢ria")); strcpy(_str,s); _size = strlen(_str); return *this; } string& string::operator+=(const string& s){ return operator+=(s._str); } string& string::operator+=(const char* s){ char* tmp = new char[_size + strlen(s) + 1]; _assert(!_str,strexception(1,"string& string::operator+=(const char* s)","falta de mem¢ria")); *tmp = '\0'; // caso a _str seja NULL strcpy(tmp,_str); strcat(tmp,s); delete _str; _str = tmp; _size = strlen(_str); return *this; } char string::operator[](int pos) const{ _assert((pos < 0) || (pos > _size),strexception(2,"char string::operator[](int pos) const","¡ndice fora dos limites")); return _str[pos]; } char& string::operator[](int pos) { _assert((pos < 0) || (pos > _size),strexception(2,"char& string::operator[](int pos)","¡ndice fora dos limites")); return _str[pos]; } string& string::hex(char ch) { const char hextable[] = "0123456789ABCDEF"; static string tmp; char dummy[2]; dummy[1] = 0; dummy[0] = hextable[ch & 0x0F]; tmp = dummy; dummy[0] = hextable[(ch >> 4) & 0x0F]; tmp = dummy + tmp; return tmp; } void string::urlencode() { const char* ptr = _str; char dummy[2] = {' ','\0'};

Page 31: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 61 de 85

string tmp; if(!ptr) return; while(*ptr) { switch(*ptr) { case '\n': case '\r': case '\t': case '=' : case '%' : case '&' : tmp += "%" + hex(*ptr); break; default : dummy[0] = *ptr; tmp += dummy; } ptr++; } operator=(tmp); } void string::urldecode() { } ostream& operator<<(ostream &out, const string& s) { out << s._str; return out; } istream& operator>>(istream &in, string& s) { char buf[2] = {' ','\0'}; int ch; s = ""; while ((ch = in.get()) != EOF) { _assert(ch == '\0',strexception(5,"istream& operator>>(istream &in, string& s)","ficheiro bin rio")); if(ch != '\n') { buf[0] = ch; s += buf; } else break; // a "string" acaba com um '\n' } in.putback(ch); return in; } string& operator+(const string& s1, const string& s2) { static string tmp; tmp = s1; tmp +=s2; return tmp; } int operator==(const string& s1, const string& s2) { return !strcmp(s1._str,s2._str); }

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 62 de 85

int operator!=(const string& s1, const string& s2) { return strcmp(s1._str, s2._str); } int operator>(const string& s1, const string& s2) { return strcmp(s1._str, s2._str) > 0; } int operator<(const string& s1, const string& s2) { return strcmp(s1._str, s2._str) < 0; } stringlist::stringlist() { table = NULL; lines = 0; } stringlist::stringlist(const char** s,const int argc) { table = NULL; lines = 0; if(argc == 0) { for (int i=0; s[i]; i++) { add(s[i]); } } else for (int i=0; i < argc; i++) add(s[i]); } stringlist::~stringlist() { clear(); } void stringlist::clear() { for(int i=0;i<lines;i++) { delete table[i]; // liberta a memória dos ponteiros } delete []table; lines = 0; } int stringlist::count() const { return lines; } string& stringlist::operator[](int pos) { _assert((pos < 0) || (pos >= lines),strexception(2,"string& stringlist::operator[](int pos)","¡ndice fora dos limites")); return *table[pos]; } const string& stringlist::operator[](int pos) const{

Page 32: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 63 de 85

_assert((pos < 0) || (pos >= lines),strexception(2,"const string& stringlist::operator[](int pos) const","¡ndice fora dos limites")); return *table[pos]; } void stringlist::add(const char* s) { int i; if(lines == 0) { table = new string*[1]; table[0]= new string((char*) s); _assert(!table[0],strexception(1,"void stringlist::add(const char* s)","falta de mem¢ria")); } else { string **tmp = new string*[lines + 1]; _assert(!tmp,strexception(1,"void stringlist::add(const char* s)","falta de mem¢ria")); for(i=0;i < lines;i++) tmp[i] = table[i]; _assert(!(tmp[i] = new string((char*) s)),strexception(1,"void stringlist::add(const char* s)","falta de mem¢ria")); delete []table; table = tmp; } lines++; } void stringlist::add(const string& s) { add(s._str); } void stringlist::add(const stringlist &list) { for(int i=0;i<list.count();i++) add(list[i]); } stringlist::stringlist(const char* s) { table = NULL; lines = 0; add(s); } stringlist::stringlist(const string& s) { table = NULL; lines = 0; add(s); } stringlist::stringlist(const stringlist& list) { table = NULL; lines = 0; add(list); }

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 64 de 85

void stringlist::remove(int pos) { int i,j=0; _assert((pos < 0) || (pos >= lines),strexception(2,"void stringlist::remove(int pos) {","¡ndice fora de limites")); string** tmp = new string*[lines-1]; _assert(!tmp,strexception(1,"void stringlist::remove(int pos) {","falta de mem¢ria")); for(i=0;i < lines;i++) { if(i != pos) tmp[j++] = table[i]; } delete table[pos]; // apaga a string da tabela delete []table; table = tmp; lines--; } void stringlist::slice(int min, int max) { int tmp; if(min > max) { tmp = max; max = min; min = tmp; // permuta os valores ;) } _assert((min < 0) || (min >=lines) || (max < 0) || (max >= lines),strexception(2,"void stringlist::slice(int min, int max)","¡ndice fora de limites")); if((min == 0) && (max == lines-1)) { clear(); // no pior dos casos limpa o conteúdo ;) return; } for(int i=min; i <= max; i++) { remove(min); } } void stringlist::load(const string& fn) { stringlist::load(fn._str); } void stringlist::load(const char* fn) { ifstream in(fn); string tmp; _assert(in.fail(),strexception(6,"void stringlist::load(const char* fn)","ficheiro nÆo encontrado")); clear(); do { in>> tmp; _assert(in.fail(),strexception(3,"void stringlist::load(const char* fn)","erro de leitura do ficheiro")); add(tmp); } while (in.get() != EOF); remove(lines-1); }

Page 33: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 65 de 85

void stringlist::save(const char* fn) const { ofstream out(fn); _assert(out.fail(),strexception(4,"void stringlist::save(const char* fn) const","erro a escrever no ficheiro")); for(int i=0; i < lines; i++) { out << table[i] << endl; _assert(out.fail(),strexception(4,"void stringlist::save(const char* fn) const","erro a escrever no ficheiro")); } } void stringlist::insert(int pos, const char* s) { int i,j=0; _assert((pos < 0) || (pos > lines),strexception(2, "void stringlist::insert(int pos, const char* s)","¡ndice fora dos limites")); if(pos == lines) { add(s); return; } if(pos < 0) pos = 0; if(lines == 0) { add(s); return; } string** tmp = new string*[lines+1]; _assert(!tmp,strexception(1,"void stringlist::insert(int pos, const char* s)","falta de mem¢ria")); for(i=0; i <= lines; i++) { if(i != pos) tmp[i] = table[j++]; else _assert(!(tmp[i] = new string((char*) s)),strexception(1,"void stringlist::insert(int pos, const char* s)","falta de mem¢ria")); } delete []table; table = tmp; lines++; } void stringlist::insert(int pos, const string& s) { insert(pos,s._str); } void stringlist::insert(int pos, const stringlist& list) { for(int i=pos; i < pos+list.count(); i++) { insert(pos,list[pos+list.count()-1-i]); } } void stringlist::split(const string& what, const char* sep) { split(what._str,sep); }

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 66 de 85

void stringlist::split(const string& what, const string& sep) { split(what._str,sep._str); } void stringlist::split(const char* what, const string& sep) { split(what,sep._str); } void stringlist::split(const char* what, const char* sep) { char *str; clear(); if(!what || !sep) return; while((str=strstr(what,sep))) { *str = 0; add(what); *str = sep[0]; what = str + strlen(sep); } add(what); } void stringlist::join(const char* sep) { string tmp(""); for(int i=0; i< lines; i++) { if(i) tmp += (char *)sep + *table[i]; else tmp += *table[i]; // o primeiro caso é especial ;) } clear(); add(tmp); } void stringlist::join(const string& sep) { join(sep._str); } void stringlist::replace(const char* what, const char* for_what) { // ainda por implementar } #endif

Page 34: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 67 de 85

66..77 CCoonntteeúúddoo ddoo ffiicchheeiirroo ““eexxcceeppttiioonn..hh”” /* Instituto Politécnico de Viseu/Escola Superior de Tecnologia de Viseu Sistemas em tempo real Class básica para se poder manusear mais fácilmente as excepções Copyright (c) 2002 N. Loureiro, H. Cardoso & F. Belo */ #ifndef __EXCEPTION_H #define __EXCEPTION_H #include <stdlib.h> class exception { public: int code; char* src; char* msg; exception(int _code, char* _src, char* _msg) : code(_code), src(_src), msg(_msg) {} exception() { code = 0; src = NULL; msg = NULL; } virtual ~exception() {} }; void _assert(int condition,exception except) { if(condition) throw except; } #endif

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 68 de 85

77.. AAppêênnddiiccee BB 77..11 DDaattaasshheett ddoo ffoottoo--ddiiooddoo

Page 35: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 69 de 85

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 70 de 85

Page 36: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 71 de 85

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 72 de 85

Page 37: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 73 de 85

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 74 de 85

Page 38: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 75 de 85

77..22 DDaattaasshheett ddoo ffoottoo--ttrraannssiissttoorr

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 76 de 85

Page 39: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 77 de 85

77..33 DDaattaasshheett ddoo ttrraannssííssttoorr NNPPNN 33990044

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 78 de 85

Page 40: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 79 de 85

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 80 de 85

Page 41: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 81 de 85

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 82 de 85

Page 42: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 83 de 85

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 84 de 85

88.. BBiibblliiooggrraaffiiaa

Page 43: Escola Superior de Tecnologia Projecto Sistemas em Tempo …

Instituto Politécnico de Viseu Escola Superior de Tecnologia

Projecto Sistemas em Tempo Real

Página 85 de 85

99.. AAvvaalliiaaççããoo 99..11 IIddeennttiiffiiccaaççããoo Nuno Manuel Almeida Loureiro n.º 2810 1º turno Henrique Manuel Canário Cardoso n.º 3485 1º turno

Fernando José Belo n.º 3424 1º turno 99..22 OObbsseerrvvaaççõõeess

99..33 CCllaassssiiffiiccaaççããoo

Valores 99..44 OO ddoocceennttee

(Paulo Moisés, Engº)